|
|
1.1 ! root 1: /* ! 2: * Copyright (c) 1988 Regents of the University of California. ! 3: * All rights reserved. ! 4: * ! 5: * Redistribution and use in source and binary forms are permitted ! 6: * provided that the above copyright notice and this paragraph are ! 7: * duplicated in all such forms and that any documentation, ! 8: * advertising materials, and other materials related to such ! 9: * distribution and use acknowledge that the software was developed ! 10: * by the University of California, Berkeley. The name of the ! 11: * University may not be used to endorse or promote products derived ! 12: * from this software without specific prior written permission. ! 13: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR ! 14: * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED ! 15: * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. ! 16: */ ! 17: ! 18: #ifndef lint ! 19: static char sccsid[] = "@(#)inbound.c 4.2 (Berkeley) 10/31/89"; ! 20: #endif /* not lint */ ! 21: ! 22: #include <stdio.h> ! 23: ! 24: #include "../general/general.h" ! 25: #include "function.h" ! 26: #include "hostctlr.h" ! 27: #include "oia.h" ! 28: #include "scrnctlr.h" ! 29: #include "screen.h" ! 30: #include "options.h" ! 31: #include "../api/dctype.h" ! 32: #include "../api/ebc_disp.h" ! 33: ! 34: #include "../general/globals.h" ! 35: #include "externs.h" ! 36: #include "declare.h" ! 37: ! 38: #define EmptyChar() (ourPTail == ourPHead) ! 39: #define FullChar() (ourPHead == ourBuffer+sizeof ourBuffer) ! 40: ! 41: ! 42: /* ! 43: * We define something to allow us to to IsProtected() quickly ! 44: * on unformatted screens (with the current algorithm for fields, ! 45: * unprotected takes exponential time...). ! 46: * ! 47: * The idea is to call SetXIsProtected() BEFORE the ! 48: * loop, then use XIsProtected(). ! 49: */ ! 50: ! 51: #define SetXIsProtected() (XWasSF = 1) ! 52: #define XIsProtected(p) (IsStartField(p)? \ ! 53: XWasSF = 1 : \ ! 54: (XWasSF? \ ! 55: (XWasSF = 0, XProtected = IsProtected(p)) : \ ! 56: XProtected)) ! 57: ! 58: static char ourBuffer[400]; ! 59: ! 60: static char *ourPHead = ourBuffer, ! 61: *ourPTail = ourBuffer; ! 62: ! 63: static int HadAid; /* Had an AID haven't sent */ ! 64: ! 65: static int InsertMode; /* is the terminal in insert mode? */ ! 66: ! 67: static unsigned int ! 68: rememberedshiftstate; /* Shift (alt) state of terminal */ ! 69: ! 70: # define HITNUM(s) ((((s)&(SHIFT_CAPS|SHIFT_UPSHIFT))? 1:0) \ ! 71: + ((((s)&SHIFT_ALT)? 1:0)<<1)) ! 72: ! 73: static int XWasSF, XProtected; /* For optimizations */ ! 74: #if !defined(PURE3274) ! 75: extern int TransparentClock, OutputClock; ! 76: #endif /* !defined(PURE3274) */ ! 77: ! 78: #include "kbd.out" /* Get keyboard mapping function */ ! 79: ! 80: /* the following are global variables */ ! 81: ! 82: extern int UnLocked; /* keyboard is UnLocked? */ ! 83: ! 84: ! 85: /* ! 86: * init_inbound : ! 87: * ! 88: * Reset variables to initial state. ! 89: */ ! 90: ! 91: void ! 92: init_inbound() ! 93: { ! 94: ourPHead = ourPTail = ourBuffer; ! 95: HadAid = 0; ! 96: rememberedshiftstate = 0; ! 97: InsertMode = 0; ! 98: } ! 99: ! 100: ! 101: /* Tab() - sets cursor to the start of the next unprotected field */ ! 102: static void ! 103: Tab() ! 104: { ! 105: register int i, j; ! 106: ! 107: i = CursorAddress; ! 108: j = WhereAttrByte(CursorAddress); ! 109: do { ! 110: if (IsStartField(i) && IsUnProtected(ScreenInc(i))) { ! 111: break; ! 112: } ! 113: i = FieldInc(i); ! 114: } while (i != j); ! 115: if (IsStartField(i) && IsUnProtected(ScreenInc(i))) { ! 116: CursorAddress = ScreenInc(i); ! 117: } else { ! 118: CursorAddress = SetBufferAddress(0,0); ! 119: } ! 120: } ! 121: ! 122: ! 123: /* BackTab() - sets cursor to the start of the most recent field */ ! 124: ! 125: static void ! 126: BackTab() ! 127: { ! 128: register int i; ! 129: ! 130: i = ScreenDec(CursorAddress); ! 131: for (;;) { ! 132: if (IsStartField(ScreenDec(i)) && IsUnProtected(i)) { ! 133: CursorAddress = i; ! 134: break; ! 135: } ! 136: if (i == CursorAddress) { ! 137: CursorAddress = SetBufferAddress(0,0); ! 138: break; ! 139: } ! 140: i = ScreenDec(i); ! 141: } ! 142: } ! 143: ! 144: /* ! 145: * ModifyMdt() - Turn a modified data tag bit on or off (watch ! 146: * out for unformatted screens). ! 147: */ ! 148: ! 149: ModifyMdt(x,on) ! 150: int x; ! 151: int on; ! 152: { ! 153: int i = x; ! 154: ! 155: if (IsStartField(i)) { /* If we are at a start field position... */ ! 156: if (on) { ! 157: ModifyHost(i, |= ATTR_MDT); /* Turn it on */ ! 158: } else { ! 159: ModifyHost(i, &= ~ATTR_MDT); /* Turn it off */ ! 160: } ! 161: } else { ! 162: i = WhereAttrByte(i); /* Find beginning of field */ ! 163: if (IsStartField(i)) { /* Is there one? */ ! 164: if (on) { ! 165: ModifyHost(i, |= ATTR_MDT); /* Turn it on */ ! 166: } else { ! 167: ModifyHost(i, &= ~ATTR_MDT); /* Turn it off */ ! 168: } ! 169: } /* else, don't modify - this is an unformatted screen */ ! 170: } ! 171: } ! 172: ! 173: ! 174: /* EraseEndOfField - erase all characters to the end of a field */ ! 175: ! 176: static void ! 177: EraseEndOfField() ! 178: { ! 179: register int i; ! 180: ! 181: if (IsProtected(CursorAddress)) { ! 182: RingBell("Protected Field"); ! 183: } else { ! 184: TurnOnMdt(CursorAddress); ! 185: if (FormattedScreen()) { ! 186: i = CursorAddress; ! 187: do { ! 188: AddHost(i, 0); ! 189: i = ScreenInc(i); ! 190: } while ((i != CursorAddress) && !IsStartField(i)); ! 191: } else { /* Screen is Unformatted */ ! 192: i = CursorAddress; ! 193: do { ! 194: AddHost(i, 0); ! 195: i = ScreenInc(i); ! 196: } while (i != HighestScreen()); ! 197: } ! 198: } ! 199: } ! 200: ! 201: /* Delete() - deletes a character from the screen ! 202: * ! 203: * What we want to do is delete the section ! 204: * [where, from-1] from the screen, ! 205: * filling in with what comes at from. ! 206: * ! 207: * The deleting continues to the end of the field (or ! 208: * until the cursor wraps). ! 209: * ! 210: * From can be a start of a field. We ! 211: * check for that. However, there can't be any ! 212: * fields that start between where and from. ! 213: * We don't check for that. ! 214: * ! 215: * Also, we assume that the protection status of ! 216: * everything has been checked by the caller. ! 217: * ! 218: */ ! 219: ! 220: static void ! 221: Delete(where, from) ! 222: register int where, /* Where to start deleting from */ ! 223: from; /* Where to pull back from */ ! 224: { ! 225: register int i; ! 226: ! 227: TurnOnMdt(where); /* Only do this once in this field */ ! 228: i = where; ! 229: do { ! 230: if (IsStartField(from)) { ! 231: AddHost(i, 0); /* Stick the edge at the start field */ ! 232: } else { ! 233: AddHost(i, (char)GetHost(from)); ! 234: from = ScreenInc(from); /* Move the edge */ ! 235: } ! 236: i = ScreenInc(i); ! 237: } while ((!IsStartField(i)) && (i != where)); ! 238: } ! 239: ! 240: static void ! 241: ColBak() ! 242: { ! 243: register int i; ! 244: ! 245: i = ScreenLineOffset(CursorAddress); ! 246: for (i = i-1; i >= 0; i--) { ! 247: if (OptColTabs[i]) { ! 248: break; ! 249: } ! 250: } ! 251: if (i < 0) { ! 252: i = 0; ! 253: } ! 254: CursorAddress = SetBufferAddress(ScreenLine(CursorAddress), i); ! 255: } ! 256: ! 257: static void ! 258: ColTab() ! 259: { ! 260: register int i; ! 261: ! 262: i = ScreenLineOffset(CursorAddress); ! 263: for (i = i+1; i < NumberColumns; i++) { ! 264: if (OptColTabs[i]) { ! 265: break; ! 266: } ! 267: } ! 268: if (i >= NumberColumns) { ! 269: i = NumberColumns-1; ! 270: } ! 271: CursorAddress = SetBufferAddress(ScreenLine(CursorAddress), i); ! 272: } ! 273: ! 274: static void ! 275: Home() ! 276: { ! 277: register int i; ! 278: register int j; ! 279: ! 280: i = SetBufferAddress(OptHome, 0); ! 281: j = WhereLowByte(i); ! 282: /* ! 283: * If the initial value of i points to the field attribute of ! 284: * an unprotected field, we need to return the address of the ! 285: * first data byte in the field (assuming there are any!). ! 286: */ ! 287: if (IsStartField(i) && IsUnProtected(j)) { ! 288: CursorAddress = j; ! 289: return; ! 290: } ! 291: do { ! 292: if (IsUnProtected(i)) { ! 293: CursorAddress = i; ! 294: return; ! 295: } ! 296: /* the following could be a problem if we got here with an ! 297: * unformatted screen. However, this is "impossible", since ! 298: * with an unformatted screen, the IsUnProtected(i) above ! 299: * should be true. ! 300: */ ! 301: i = ScreenInc(FieldInc(i)); ! 302: } while (i != j); ! 303: CursorAddress = LowestScreen(); ! 304: } ! 305: ! 306: static ! 307: LastOfField(i) ! 308: register int i; /* position to start from */ ! 309: { ! 310: register int j; ! 311: register int k; ! 312: ! 313: k = j = i; ! 314: SetXIsProtected(); ! 315: while (XIsProtected(i) || Disspace(GetHost(i))) { ! 316: i = ScreenInc(i); ! 317: if (i == j) { ! 318: break; ! 319: } ! 320: } ! 321: /* We are now IN a word IN an unprotected field (or wrapped) */ ! 322: while (!XIsProtected(i)) { ! 323: if (!Disspace(GetHost(i))) { ! 324: k = i; ! 325: } ! 326: i = ScreenInc(i); ! 327: if (i == j) { ! 328: break; ! 329: } ! 330: } ! 331: return(k); ! 332: } ! 333: ! 334: ! 335: static void ! 336: FlushChar() ! 337: { ! 338: ourPTail = ourPHead = ourBuffer; ! 339: } ! 340: ! 341: ! 342: /* ! 343: * Add one EBCDIC (NOT display code) character to the buffer. ! 344: */ ! 345: ! 346: static void ! 347: AddChar(character) ! 348: char character; ! 349: { ! 350: if (FullChar()) { ! 351: ourPTail += DataToNetwork(ourPTail, ourPHead-ourPTail, 0); ! 352: if (EmptyChar()) { ! 353: FlushChar(); ! 354: } else { ! 355: char buffer[100]; ! 356: ! 357: sprintf(buffer, "File %s, line %d: No room in network buffer!\n", ! 358: __FILE__, __LINE__); ! 359: ExitString(buffer, 1); ! 360: /*NOTREACHED*/ ! 361: } ! 362: } ! 363: *ourPHead++ = character; ! 364: } ! 365: ! 366: ! 367: static void ! 368: SendUnformatted() ! 369: { ! 370: register int i, j; ! 371: register int Nulls; ! 372: register int c; ! 373: ! 374: /* look for start of field */ ! 375: Nulls = 0; ! 376: i = j = LowestScreen(); ! 377: do { ! 378: c = GetHost(i); ! 379: if (c == 0) { ! 380: Nulls++; ! 381: } else { ! 382: while (Nulls) { ! 383: Nulls--; ! 384: AddChar(EBCDIC_BLANK); /* put in blanks */ ! 385: } ! 386: AddChar((char)disp_ebc[c]); ! 387: } ! 388: i = ScreenInc(i); ! 389: } while (i != j); ! 390: } ! 391: ! 392: static ! 393: SendField(i, cmd) ! 394: register int i; /* where we saw MDT bit */ ! 395: int cmd; /* The command code (type of read) */ ! 396: { ! 397: register int j; ! 398: register int k; ! 399: register int Nulls; ! 400: register int c; ! 401: ! 402: /* look for start of field */ ! 403: i = j = WhereLowByte(i); ! 404: ! 405: /* On a test_request_read, don't send sba and address */ ! 406: if ((AidByte != AID_TREQ) ! 407: || (cmd == CMD_SNA_READ_MODIFIED_ALL)) { ! 408: AddChar(ORDER_SBA); /* set start field */ ! 409: AddChar(BufferTo3270_0(j)); /* set address of this field */ ! 410: AddChar(BufferTo3270_1(j)); ! 411: } ! 412: /* ! 413: * Only on read_modified_all do we return the contents ! 414: * of the field when the attention was caused by a ! 415: * selector pen. ! 416: */ ! 417: if ((AidByte != AID_SELPEN) ! 418: || (cmd == CMD_SNA_READ_MODIFIED_ALL)) { ! 419: if (!IsStartField(j)) { ! 420: Nulls = 0; ! 421: k = ScreenInc(WhereHighByte(j)); ! 422: do { ! 423: c = GetHost(j); ! 424: if (c == 0) { ! 425: Nulls++; ! 426: } else { ! 427: while (Nulls) { ! 428: Nulls--; ! 429: AddChar(EBCDIC_BLANK); /* put in blanks */ ! 430: } ! 431: AddChar((char)disp_ebc[c]); ! 432: } ! 433: j = ScreenInc(j); ! 434: } while ((j != k) && (j != i)); ! 435: } ! 436: } else { ! 437: j = FieldInc(j); ! 438: } ! 439: return(j); ! 440: } ! 441: ! 442: /* Various types of reads... */ ! 443: void ! 444: DoReadModified(cmd) ! 445: int cmd; /* The command sent */ ! 446: { ! 447: register int i, j; ! 448: ! 449: if (AidByte) { ! 450: if (AidByte != AID_TREQ) { ! 451: AddChar(AidByte); ! 452: } else { ! 453: /* Test Request Read header */ ! 454: AddChar(EBCDIC_SOH); ! 455: AddChar(EBCDIC_PERCENT); ! 456: AddChar(EBCDIC_SLASH); ! 457: AddChar(EBCDIC_STX); ! 458: } ! 459: } else { ! 460: AddChar(AID_NONE); ! 461: } ! 462: if (((AidByte != AID_PA1) && (AidByte != AID_PA2) ! 463: && (AidByte != AID_PA3) && (AidByte != AID_CLEAR)) ! 464: || (cmd == CMD_SNA_READ_MODIFIED_ALL)) { ! 465: if ((AidByte != AID_TREQ) ! 466: || (cmd == CMD_SNA_READ_MODIFIED_ALL)) { ! 467: /* Test request read_modified doesn't give cursor address */ ! 468: AddChar(BufferTo3270_0(CursorAddress)); ! 469: AddChar(BufferTo3270_1(CursorAddress)); ! 470: } ! 471: i = j = WhereAttrByte(LowestScreen()); ! 472: /* Is this an unformatted screen? */ ! 473: if (!IsStartField(i)) { /* yes, handle separate */ ! 474: SendUnformatted(); ! 475: } else { ! 476: do { ! 477: if (HasMdt(i)) { ! 478: i = SendField(i, cmd); ! 479: } else { ! 480: i = FieldInc(i); ! 481: } ! 482: } while (i != j); ! 483: } ! 484: } ! 485: ourPTail += DataToNetwork(ourPTail, ourPHead-ourPTail, 1); ! 486: if (EmptyChar()) { ! 487: FlushChar(); ! 488: HadAid = 0; /* killed that buffer */ ! 489: } ! 490: } ! 491: ! 492: /* A read buffer operation... */ ! 493: ! 494: void ! 495: DoReadBuffer() ! 496: { ! 497: register int i, j; ! 498: ! 499: if (AidByte) { ! 500: AddChar(AidByte); ! 501: } else { ! 502: AddChar(AID_NONE); ! 503: } ! 504: AddChar(BufferTo3270_0(CursorAddress)); ! 505: AddChar(BufferTo3270_1(CursorAddress)); ! 506: i = j = LowestScreen(); ! 507: do { ! 508: if (IsStartField(i)) { ! 509: AddChar(ORDER_SF); ! 510: AddChar(BufferTo3270_1(FieldAttributes(i))); ! 511: } else { ! 512: AddChar((char)disp_ebc[GetHost(i)]); ! 513: } ! 514: i = ScreenInc(i); ! 515: } while (i != j); ! 516: ourPTail += DataToNetwork(ourPTail, ourPHead-ourPTail, 1); ! 517: if (EmptyChar()) { ! 518: FlushChar(); ! 519: HadAid = 0; /* killed that buffer */ ! 520: } ! 521: } ! 522: ! 523: /* Send some transparent data to the host */ ! 524: ! 525: void ! 526: SendTransparent(buffer, count) ! 527: char *buffer; ! 528: int count; ! 529: { ! 530: char stuff[3]; ! 531: ! 532: stuff[0] = AID_NONE_PRINTER; ! 533: stuff[1] = BufferTo3270_0(count); ! 534: stuff[2] = BufferTo3270_1(count); ! 535: DataToNetwork(stuff, sizeof stuff, 0); ! 536: DataToNetwork(buffer, count, 1); ! 537: } ! 538: ! 539: ! 540: /* Try to send some data to host */ ! 541: ! 542: void ! 543: SendToIBM() ! 544: { ! 545: #if !defined(PURE3274) ! 546: if (TransparentClock >= OutputClock) { ! 547: if (HadAid) { ! 548: AddChar(AidByte); ! 549: HadAid = 0; ! 550: } else { ! 551: AddChar(AID_NONE_PRINTER); ! 552: } ! 553: do { ! 554: ourPTail += DataToNetwork(ourPTail, ourPHead-ourPTail, 1); ! 555: } while (!EmptyChar()); ! 556: FlushChar(); ! 557: } else if (HadAid) { ! 558: DoReadModified(CMD_READ_MODIFIED); ! 559: } ! 560: #else /* !defined(PURE3274) */ ! 561: if (HadAid) { ! 562: DoReadModified(CMD_READ_MODIFIED); ! 563: } ! 564: #endif /* !defined(PURE3274) */ ! 565: } ! 566: ! 567: /* This takes in one character from the keyboard and places it on the ! 568: * screen. ! 569: */ ! 570: ! 571: static void ! 572: OneCharacter(c, insert) ! 573: int c; /* character (Ebcdic) to be shoved in */ ! 574: int insert; /* are we in insert mode? */ ! 575: { ! 576: register int i, j; ! 577: ! 578: if (IsProtected(CursorAddress)) { ! 579: RingBell("Protected Field"); ! 580: return; ! 581: } ! 582: if (insert) { ! 583: /* is the last character in the field a blank or null? */ ! 584: i = ScreenDec(FieldInc(CursorAddress)); ! 585: j = GetHost(i); ! 586: if (!Disspace(j)) { ! 587: RingBell("No more room for insert"); ! 588: return; ! 589: } else { ! 590: for (j = ScreenDec(i); i != CursorAddress; ! 591: j = ScreenDec(j), i = ScreenDec(i)) { ! 592: AddHost(i, (char)GetHost(j)); ! 593: } ! 594: } ! 595: } ! 596: AddHost(CursorAddress, c); ! 597: TurnOnMdt(CursorAddress); ! 598: CursorAddress = ScreenInc(CursorAddress); ! 599: if (IsStartField(CursorAddress) && ! 600: ((FieldAttributes(CursorAddress)&ATTR_AUTO_SKIP_MASK) == ! 601: ATTR_AUTO_SKIP_VALUE)) { ! 602: Tab(); ! 603: } ! 604: } ! 605: ! 606: /* ! 607: * AcceptKeystroke() ! 608: * ! 609: * Processes one keystroke. ! 610: * ! 611: * Returns: ! 612: * ! 613: * 0 if this keystroke was NOT processed. ! 614: * 1 if everything went OK. ! 615: */ ! 616: ! 617: int ! 618: AcceptKeystroke(scancode, shiftstate) ! 619: unsigned int ! 620: scancode, /* 3270 scancode */ ! 621: shiftstate; /* The shift state */ ! 622: { ! 623: register int c; ! 624: register int i; ! 625: register int j; ! 626: enum ctlrfcn ctlrfcn; ! 627: ! 628: if (scancode >= numberof(hits)) { ! 629: ExitString( ! 630: "Unknown scancode encountered in AcceptKeystroke.\n", 1); ! 631: /*NOTREACHED*/ ! 632: } ! 633: ctlrfcn = hits[scancode].hit[HITNUM(shiftstate)].ctlrfcn; ! 634: c = hits[scancode].hit[HITNUM(shiftstate)].code; ! 635: ! 636: if (!UnLocked || HadAid) { ! 637: if (HadAid) { ! 638: SendToIBM(); ! 639: if (!EmptyChar()) { ! 640: return 0; /* nothing to do */ ! 641: } ! 642: } ! 643: #if !defined(PURE3274) ! 644: if (!HadAid && EmptyChar()) { ! 645: if ((ctlrfcn == FCN_RESET) || (ctlrfcn == FCN_MASTER_RESET)) { ! 646: UnLocked = 1; ! 647: } ! 648: } ! 649: #endif /* !defined(PURE3274) */ ! 650: if (!UnLocked) { ! 651: return 0; ! 652: } ! 653: } ! 654: ! 655: /* now, either empty, or haven't seen aid yet */ ! 656: ! 657: #if !defined(PURE3274) ! 658: /* ! 659: * If we are in transparent (output) mode, do something special ! 660: * with keystrokes. ! 661: */ ! 662: if (TransparentClock == OutputClock) { ! 663: if (ctlrfcn == FCN_AID) { ! 664: UnLocked = 0; ! 665: InsertMode = 0; ! 666: AidByte = (c); ! 667: HadAid = 1; ! 668: } else { ! 669: switch (ctlrfcn) { ! 670: case FCN_ESCAPE: ! 671: StopScreen(1); ! 672: command(0); ! 673: if (shell_active == 0) { ! 674: ConnectScreen(); ! 675: } ! 676: break; ! 677: ! 678: case FCN_RESET: ! 679: case FCN_MASTER_RESET: ! 680: UnLocked = 1; ! 681: break; ! 682: ! 683: default: ! 684: return 0; ! 685: } ! 686: } ! 687: } ! 688: #endif /* !defined(PURE3274) */ ! 689: ! 690: if (ctlrfcn == FCN_CHARACTER) { ! 691: /* Add the character to the buffer */ ! 692: OneCharacter(c, InsertMode); ! 693: } else if (ctlrfcn == FCN_AID) { /* got Aid */ ! 694: if (c == AID_CLEAR) { ! 695: LocalClearScreen(); /* Side effect is to clear 3270 */ ! 696: } ! 697: ResetOiaOnlineA(&OperatorInformationArea); ! 698: SetOiaTWait(&OperatorInformationArea); ! 699: ResetOiaInsert(&OperatorInformationArea); ! 700: InsertMode = 0; /* just like a 3278 */ ! 701: SetOiaSystemLocked(&OperatorInformationArea); ! 702: SetOiaModified(); ! 703: UnLocked = 0; ! 704: AidByte = c; ! 705: HadAid = 1; ! 706: SendToIBM(); ! 707: } else { ! 708: switch (ctlrfcn) { ! 709: ! 710: case FCN_CURSEL: ! 711: c = FieldAttributes(CursorAddress)&ATTR_DSPD_MASK; ! 712: if (!FormattedScreen() ! 713: || ((c != ATTR_DSPD_DSPD) && (c != ATTR_DSPD_HIGH))) { ! 714: RingBell("Cursor not in selectable field"); ! 715: } else { ! 716: i = ScreenInc(WhereAttrByte(CursorAddress)); ! 717: c = GetHost(i); ! 718: if (c == DISP_QUESTION) { ! 719: AddHost(i, DISP_GREATER_THAN); ! 720: TurnOnMdt(i); ! 721: } else if (c == DISP_GREATER_THAN) { ! 722: AddHost(i, DISP_QUESTION); ! 723: TurnOffMdt(i); ! 724: } else if (c == DISP_BLANK || c == DISP_NULL ! 725: || c == DISP_AMPERSAND) { ! 726: UnLocked = 0; ! 727: InsertMode = 0; ! 728: ResetOiaOnlineA(&OperatorInformationArea); ! 729: SetOiaTWait(&OperatorInformationArea); ! 730: SetOiaSystemLocked(&OperatorInformationArea); ! 731: ResetOiaInsert(&OperatorInformationArea); ! 732: SetOiaModified(); ! 733: if (c == DISP_AMPERSAND) { ! 734: TurnOnMdt(i); /* Only for & type */ ! 735: AidByte = AID_ENTER; ! 736: } else { ! 737: AidByte = AID_SELPEN; ! 738: } ! 739: HadAid = 1; ! 740: SendToIBM(); ! 741: } else { ! 742: RingBell( ! 743: "Cursor not in a selectable field (designator)"); ! 744: } ! 745: } ! 746: break; ! 747: ! 748: #if !defined(PURE3274) ! 749: case FCN_ERASE: ! 750: if (IsProtected(ScreenDec(CursorAddress))) { ! 751: RingBell("Protected Field"); ! 752: } else { ! 753: CursorAddress = ScreenDec(CursorAddress); ! 754: Delete(CursorAddress, ScreenInc(CursorAddress)); ! 755: } ! 756: break; ! 757: case FCN_WERASE: ! 758: j = CursorAddress; ! 759: i = ScreenDec(j); ! 760: if (IsProtected(i)) { ! 761: RingBell("Protected Field"); ! 762: } else { ! 763: SetXIsProtected(); ! 764: while ((!XIsProtected(i) && Disspace(GetHost(i))) ! 765: && (i != j)) { ! 766: i = ScreenDec(i); ! 767: } ! 768: /* we are pointing at a character in a word, or ! 769: * at a protected position ! 770: */ ! 771: while ((!XIsProtected(i) && !Disspace(GetHost(i))) ! 772: && (i != j)) { ! 773: i = ScreenDec(i); ! 774: } ! 775: /* we are pointing at a space, or at a protected ! 776: * position ! 777: */ ! 778: CursorAddress = ScreenInc(i); ! 779: Delete(CursorAddress, j); ! 780: } ! 781: break; ! 782: ! 783: case FCN_FERASE: ! 784: if (IsProtected(CursorAddress)) { ! 785: RingBell("Protected Field"); ! 786: } else { ! 787: CursorAddress = ScreenInc(CursorAddress); /* for btab */ ! 788: BackTab(); ! 789: EraseEndOfField(); ! 790: } ! 791: break; ! 792: ! 793: case FCN_RESET: ! 794: if (InsertMode) { ! 795: InsertMode = 0; ! 796: ResetOiaInsert(&OperatorInformationArea); ! 797: SetOiaModified(); ! 798: } ! 799: break; ! 800: case FCN_MASTER_RESET: ! 801: if (InsertMode) { ! 802: InsertMode = 0; ! 803: ResetOiaInsert(&OperatorInformationArea); ! 804: SetOiaModified(); ! 805: } ! 806: RefreshScreen(); ! 807: break; ! 808: #endif /* !defined(PURE3274) */ ! 809: ! 810: case FCN_UP: ! 811: CursorAddress = ScreenUp(CursorAddress); ! 812: break; ! 813: ! 814: case FCN_LEFT: ! 815: CursorAddress = ScreenDec(CursorAddress); ! 816: break; ! 817: ! 818: case FCN_RIGHT: ! 819: CursorAddress = ScreenInc(CursorAddress); ! 820: break; ! 821: ! 822: case FCN_DOWN: ! 823: CursorAddress = ScreenDown(CursorAddress); ! 824: break; ! 825: ! 826: case FCN_DELETE: ! 827: if (IsProtected(CursorAddress)) { ! 828: RingBell("Protected Field"); ! 829: } else { ! 830: Delete(CursorAddress, ScreenInc(CursorAddress)); ! 831: } ! 832: break; ! 833: ! 834: case FCN_INSRT: ! 835: InsertMode = !InsertMode; ! 836: if (InsertMode) { ! 837: SetOiaInsert(&OperatorInformationArea); ! 838: } else { ! 839: ResetOiaInsert(&OperatorInformationArea); ! 840: } ! 841: SetOiaModified(); ! 842: break; ! 843: ! 844: case FCN_HOME: ! 845: Home(); ! 846: break; ! 847: ! 848: case FCN_NL: ! 849: /* The algorithm is to look for the first unprotected ! 850: * column after column 0 of the following line. Having ! 851: * found that unprotected column, we check whether the ! 852: * cursor-address-at-entry is at or to the right of the ! 853: * LeftMargin AND the LeftMargin column of the found line ! 854: * is unprotected. If this conjunction is true, then ! 855: * we set the found pointer to the address of the LeftMargin ! 856: * column in the found line. ! 857: * Then, we set the cursor address to the found address. ! 858: */ ! 859: i = SetBufferAddress(ScreenLine(ScreenDown(CursorAddress)), 0); ! 860: j = ScreenInc(WhereAttrByte(CursorAddress)); ! 861: do { ! 862: if (IsUnProtected(i)) { ! 863: break; ! 864: } ! 865: /* Again (see comment in Home()), this COULD be a problem ! 866: * with an unformatted screen. ! 867: */ ! 868: /* If there was a field with only an attribute byte, ! 869: * we may be pointing to the attribute byte of the NEXT ! 870: * field, so just look at the next byte. ! 871: */ ! 872: if (IsStartField(i)) { ! 873: i = ScreenInc(i); ! 874: } else { ! 875: i = ScreenInc(FieldInc(i)); ! 876: } ! 877: } while (i != j); ! 878: if (!IsUnProtected(i)) { /* couldn't find unprotected */ ! 879: i = SetBufferAddress(0,0); ! 880: } ! 881: if (OptLeftMargin <= ScreenLineOffset(CursorAddress)) { ! 882: if (IsUnProtected(SetBufferAddress(ScreenLine(i), ! 883: OptLeftMargin))) { ! 884: i = SetBufferAddress(ScreenLine(i), OptLeftMargin); ! 885: } ! 886: } ! 887: CursorAddress = i; ! 888: break; ! 889: ! 890: case FCN_EINP: ! 891: if (!FormattedScreen()) { ! 892: i = CursorAddress; ! 893: TurnOffMdt(i); ! 894: do { ! 895: AddHost(i, 0); ! 896: i = ScreenInc(i); ! 897: } while (i != CursorAddress); ! 898: } else { ! 899: /* ! 900: * The algorithm is: go through each unprotected ! 901: * field on the screen, clearing it out. When ! 902: * we are at the start of a field, skip that field ! 903: * if its contents are protected. ! 904: */ ! 905: i = j = FieldInc(CursorAddress); ! 906: do { ! 907: if (IsUnProtected(ScreenInc(i))) { ! 908: i = ScreenInc(i); ! 909: TurnOffMdt(i); ! 910: do { ! 911: AddHost(i, 0); ! 912: i = ScreenInc(i); ! 913: } while (!IsStartField(i)); ! 914: } else { ! 915: i = FieldInc(i); ! 916: } ! 917: } while (i != j); ! 918: } ! 919: Home(); ! 920: break; ! 921: ! 922: case FCN_EEOF: ! 923: EraseEndOfField(); ! 924: break; ! 925: ! 926: case FCN_SPACE: ! 927: OneCharacter(DISP_BLANK, InsertMode); /* Add cent */ ! 928: break; ! 929: ! 930: case FCN_CENTSIGN: ! 931: OneCharacter(DISP_CENTSIGN, InsertMode); /* Add cent */ ! 932: break; ! 933: ! 934: case FCN_FM: ! 935: OneCharacter(DISP_FM, InsertMode); /* Add field mark */ ! 936: break; ! 937: ! 938: case FCN_DP: ! 939: if (IsProtected(CursorAddress)) { ! 940: RingBell("Protected Field"); ! 941: } else { ! 942: OneCharacter(DISP_DUP, InsertMode);/* Add dup character */ ! 943: Tab(); ! 944: } ! 945: break; ! 946: ! 947: case FCN_TAB: ! 948: Tab(); ! 949: break; ! 950: ! 951: case FCN_BTAB: ! 952: BackTab(); ! 953: break; ! 954: ! 955: #ifdef NOTUSED /* Actually, this is superseded by unix flow ! 956: * control. ! 957: */ ! 958: case FCN_XOFF: ! 959: Flow = 0; /* stop output */ ! 960: break; ! 961: ! 962: case FCN_XON: ! 963: if (!Flow) { ! 964: Flow = 1; /* turn it back on */ ! 965: DoTerminalOutput(); ! 966: } ! 967: break; ! 968: #endif /* NOTUSED */ ! 969: ! 970: #if !defined(PURE3274) ! 971: case FCN_ESCAPE: ! 972: /* FlushChar(); do we want to flush characters from before? */ ! 973: StopScreen(1); ! 974: command(0); ! 975: if (shell_active == 0) { ! 976: ConnectScreen(); ! 977: } ! 978: break; ! 979: ! 980: case FCN_DISC: ! 981: StopScreen(1); ! 982: suspend(); ! 983: setconnmode(); ! 984: ConnectScreen(); ! 985: break; ! 986: ! 987: case FCN_RESHOW: ! 988: RefreshScreen(); ! 989: break; ! 990: ! 991: case FCN_SETTAB: ! 992: OptColTabs[ScreenLineOffset(CursorAddress)] = 1; ! 993: break; ! 994: ! 995: case FCN_DELTAB: ! 996: OptColTabs[ScreenLineOffset(CursorAddress)] = 0; ! 997: break; ! 998: ! 999: /* ! 1000: * Clear all tabs, home line, and left margin. ! 1001: */ ! 1002: case FCN_CLRTAB: ! 1003: for (i = 0; i < sizeof OptColTabs; i++) { ! 1004: OptColTabs[i] = 0; ! 1005: } ! 1006: OptHome = 0; ! 1007: OptLeftMargin = 0; ! 1008: break; ! 1009: ! 1010: case FCN_COLTAB: ! 1011: ColTab(); ! 1012: break; ! 1013: ! 1014: case FCN_COLBAK: ! 1015: ColBak(); ! 1016: break; ! 1017: ! 1018: case FCN_INDENT: ! 1019: ColTab(); ! 1020: OptLeftMargin = ScreenLineOffset(CursorAddress); ! 1021: break; ! 1022: ! 1023: case FCN_UNDENT: ! 1024: ColBak(); ! 1025: OptLeftMargin = ScreenLineOffset(CursorAddress); ! 1026: break; ! 1027: ! 1028: case FCN_SETMRG: ! 1029: OptLeftMargin = ScreenLineOffset(CursorAddress); ! 1030: break; ! 1031: ! 1032: case FCN_SETHOM: ! 1033: OptHome = ScreenLine(CursorAddress); ! 1034: break; ! 1035: ! 1036: /* ! 1037: * Point to first character of next unprotected word on ! 1038: * screen. ! 1039: */ ! 1040: case FCN_WORDTAB: ! 1041: i = CursorAddress; ! 1042: SetXIsProtected(); ! 1043: while (!XIsProtected(i) && !Disspace(GetHost(i))) { ! 1044: i = ScreenInc(i); ! 1045: if (i == CursorAddress) { ! 1046: break; ! 1047: } ! 1048: } ! 1049: /* i is either protected, a space (blank or null), ! 1050: * or wrapped ! 1051: */ ! 1052: while (XIsProtected(i) || Disspace(GetHost(i))) { ! 1053: i = ScreenInc(i); ! 1054: if (i == CursorAddress) { ! 1055: break; ! 1056: } ! 1057: } ! 1058: CursorAddress = i; ! 1059: break; ! 1060: ! 1061: case FCN_WORDBACKTAB: ! 1062: i = ScreenDec(CursorAddress); ! 1063: SetXIsProtected(); ! 1064: while (XIsProtected(i) || Disspace(GetHost(i))) { ! 1065: i = ScreenDec(i); ! 1066: if (i == CursorAddress) { ! 1067: break; ! 1068: } ! 1069: } ! 1070: /* i is pointing to a character IN an unprotected word ! 1071: * (or i wrapped) ! 1072: */ ! 1073: while (!Disspace(GetHost(i))) { ! 1074: i = ScreenDec(i); ! 1075: if (i == CursorAddress) { ! 1076: break; ! 1077: } ! 1078: } ! 1079: CursorAddress = ScreenInc(i); ! 1080: break; ! 1081: ! 1082: /* Point to last non-blank character of this/next ! 1083: * unprotected word. ! 1084: */ ! 1085: case FCN_WORDEND: ! 1086: i = ScreenInc(CursorAddress); ! 1087: SetXIsProtected(); ! 1088: while (XIsProtected(i) || Disspace(GetHost(i))) { ! 1089: i = ScreenInc(i); ! 1090: if (i == CursorAddress) { ! 1091: break; ! 1092: } ! 1093: } ! 1094: /* we are pointing at a character IN an ! 1095: * unprotected word (or we wrapped) ! 1096: */ ! 1097: while (!Disspace(GetHost(i))) { ! 1098: i = ScreenInc(i); ! 1099: if (i == CursorAddress) { ! 1100: break; ! 1101: } ! 1102: } ! 1103: CursorAddress = ScreenDec(i); ! 1104: break; ! 1105: ! 1106: /* Get to last non-blank of this/next unprotected ! 1107: * field. ! 1108: */ ! 1109: case FCN_FIELDEND: ! 1110: i = LastOfField(CursorAddress); ! 1111: if (i != CursorAddress) { ! 1112: CursorAddress = i; /* We moved; take this */ ! 1113: } else { ! 1114: j = FieldInc(CursorAddress); /* Move to next field */ ! 1115: i = LastOfField(j); ! 1116: if (i != j) { ! 1117: CursorAddress = i; /* We moved; take this */ ! 1118: } ! 1119: /* else - nowhere else on screen to be; stay here */ ! 1120: } ! 1121: break; ! 1122: #endif /* !defined(PURE3274) */ ! 1123: ! 1124: default: ! 1125: /* We don't handle this yet */ ! 1126: RingBell("Function not implemented"); ! 1127: } ! 1128: } ! 1129: return 1; /* We did something! */ ! 1130: } ! 1131: ! 1132: ! 1133: /* ! 1134: * We get data from the terminal. We keep track of the shift state ! 1135: * (including ALT, CONTROL), and then call AcceptKeystroke to actually ! 1136: * process any non-shift keys. ! 1137: */ ! 1138: ! 1139: int ! 1140: DataFrom3270(buffer, count) ! 1141: unsigned char *buffer; /* where the data is */ ! 1142: int count; /* how much data there is */ ! 1143: { ! 1144: int origCount; ! 1145: ! 1146: origCount = count; ! 1147: ! 1148: while (count) { ! 1149: if (*buffer >= numberof(hits)) { ! 1150: ExitString("Unknown scancode encountered in DataFrom3270.\n", 1); ! 1151: /*NOTREACHED*/ ! 1152: } ! 1153: ! 1154: switch (hits[*buffer].hit[HITNUM(rememberedshiftstate)].ctlrfcn) { ! 1155: ! 1156: case FCN_MAKE_SHIFT: ! 1157: rememberedshiftstate |= (SHIFT_RIGHT|SHIFT_UPSHIFT); ! 1158: break; ! 1159: case FCN_BREAK_SHIFT: ! 1160: rememberedshiftstate &= ~(SHIFT_RIGHT|SHIFT_UPSHIFT); ! 1161: break; ! 1162: case FCN_MAKE_ALT: ! 1163: rememberedshiftstate |= SHIFT_ALT; ! 1164: break; ! 1165: case FCN_BREAK_ALT: ! 1166: rememberedshiftstate &= ~SHIFT_ALT; ! 1167: break; ! 1168: default: ! 1169: if (AcceptKeystroke(*buffer, rememberedshiftstate) == 0) { ! 1170: return(origCount-count); ! 1171: } ! 1172: break; ! 1173: } ! 1174: buffer++; ! 1175: count--; ! 1176: } ! 1177: return(origCount-count); ! 1178: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.