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