|
|
1.1 ! root 1: /* ! 2: * Copyright 1984, 1985 by the Regents of the University of ! 3: * California and by Gregory Glenn Minshall. ! 4: * ! 5: * Permission to use, copy, modify, and distribute these ! 6: * programs and their documentation for any purpose and ! 7: * without fee is hereby granted, provided that this ! 8: * copyright and permission appear on all copies and ! 9: * supporting documentation, the name of the Regents of ! 10: * the University of California not be used in advertising ! 11: * or publicity pertaining to distribution of the programs ! 12: * without specific prior permission, and notice be given in ! 13: * supporting documentation that copying and distribution is ! 14: * by permission of the Regents of the University of California ! 15: * and by Gregory Glenn Minshall. Neither the Regents of the ! 16: * University of California nor Gregory Glenn Minshall make ! 17: * representations about the suitability of this software ! 18: * for any purpose. It is provided "as is" without ! 19: * express or implied warranty. ! 20: */ ! 21: ! 22: ! 23: ! 24: /* test stub for DataFrom3270, etc. */ ! 25: ! 26: #define DEFINEAIDS ! 27: #include "m4.out" /* output of termcodes.m4 */ ! 28: #include "ascebc.h" ! 29: #include "3270.h" ! 30: #include "screen.h" ! 31: #include "options.h" ! 32: #include "ectype.h" ! 33: ! 34: #ifndef lint ! 35: static char sccsid[] = "@(#)keyboard.c 2.6 4/4/86"; ! 36: #endif /* ndef lint */ ! 37: ! 38: #define EmptyChar (ourPTail == ourBuffer) ! 39: #define FullChar (ourPTail == ourBuffer+sizeof ourBuffer) ! 40: ! 41: extern char ascebc[NASCEBC][NASCII]; ! 42: ! 43: static char ourBuffer[4000]; ! 44: ! 45: static char *ourPHead = ourBuffer, ! 46: *ourPTail = ourBuffer; ! 47: ! 48: static int trTbl = AE_IN; /* which ascii->ebcdic tr table */ ! 49: ! 50: static int HadAid = 0; /* Had an AID haven't sent */ ! 51: ! 52: /* the following are global variables */ ! 53: ! 54: extern int UnLocked; /* keyboard is UnLocked? */ ! 55: ! 56: /* Tab() - sets cursor to the start of the next unprotected field */ ! 57: static void ! 58: Tab() ! 59: { ! 60: register int i, j; ! 61: ! 62: i = CursorAddress; ! 63: j = WhereAttrByte(CursorAddress); ! 64: do { ! 65: if (IsStartField(i) && IsUnProtected(ScreenInc(i))) { ! 66: break; ! 67: } ! 68: i = FieldInc(i); ! 69: } while (i != j); ! 70: if (IsStartField(i) && IsUnProtected(ScreenInc(i))) { ! 71: CursorAddress = ScreenInc(i); ! 72: } else { ! 73: CursorAddress = SetBufferAddress(0,0); ! 74: } ! 75: } ! 76: ! 77: ! 78: /* BackTab() - sets cursor to the start of the most recent field */ ! 79: ! 80: static void ! 81: BackTab() ! 82: { ! 83: register int i; ! 84: ! 85: i = ScreenDec(CursorAddress); ! 86: for (;;) { ! 87: if (IsStartField(ScreenDec(i)) && IsUnProtected(i)) { ! 88: CursorAddress = i; ! 89: break; ! 90: } ! 91: if (i == CursorAddress) { ! 92: CursorAddress = SetBufferAddress(0,0); ! 93: break; ! 94: } ! 95: i = ScreenDec(i); ! 96: } ! 97: } ! 98: ! 99: ! 100: /* EraseEndOfField - erase all characters to the end of a field */ ! 101: ! 102: static ! 103: EraseEndOfField() ! 104: { ! 105: register int i; ! 106: ! 107: if (IsProtected(CursorAddress)) { ! 108: RingBell(); ! 109: } else { ! 110: TurnOnMdt(CursorAddress); ! 111: i = CursorAddress; ! 112: do { ! 113: AddHost(i, 0); ! 114: i = ScreenInc(i); ! 115: } while ((i != CursorAddress) && IsUnProtected(i)); ! 116: } ! 117: } ! 118: ! 119: /* Delete() - deletes a character from the screen ! 120: * ! 121: * What we want to do is delete the section ! 122: * [where, from-1] from the screen, ! 123: * filling in with what comes at from. ! 124: * ! 125: * The deleting continues to the end of the field (or ! 126: * until the cursor wraps). ! 127: * ! 128: * From can be a start of a field. We ! 129: * check for that. However, there can't be any ! 130: * fields that start between where and from. ! 131: * We don't check for that. ! 132: * ! 133: * Also, we assume that the protection status of ! 134: * everything has been checked by the caller. ! 135: * ! 136: */ ! 137: ! 138: static ! 139: Delete(where, from) ! 140: register int where, /* Where to start deleting from */ ! 141: from; /* Where to pull back from */ ! 142: { ! 143: register int i; ! 144: ! 145: TurnOnMdt(where); /* Only do this once in this field */ ! 146: i = where; ! 147: do { ! 148: if (IsStartField(from)) { ! 149: AddHost(i, 0); /* Stick the edge at the start field */ ! 150: } else { ! 151: AddHost(i, GetHost(from)); ! 152: from = ScreenInc(from); /* Move the edge */ ! 153: } ! 154: i = ScreenInc(i); ! 155: } while ((!IsStartField(i)) && (i != where)); ! 156: } ! 157: ! 158: ColBak() ! 159: { ! 160: register int i; ! 161: ! 162: i = ScreenLineOffset(CursorAddress); ! 163: for (i = i-1; i >= 0; i--) { ! 164: if (OptColTabs[i]) { ! 165: break; ! 166: } ! 167: } ! 168: if (i < 0) { ! 169: i = 0; ! 170: } ! 171: CursorAddress = SetBufferAddress(ScreenLine(CursorAddress), i); ! 172: } ! 173: ! 174: ColTab() ! 175: { ! 176: register int i; ! 177: ! 178: i = ScreenLineOffset(CursorAddress); ! 179: for (i = i+1; i < LINESIZE; i++) { ! 180: if (OptColTabs[i]) { ! 181: break; ! 182: } ! 183: } ! 184: if (i >= LINESIZE) { ! 185: i = LINESIZE-1; ! 186: } ! 187: CursorAddress = SetBufferAddress(ScreenLine(CursorAddress), i); ! 188: } ! 189: ! 190: static ! 191: Home() ! 192: { ! 193: register int i; ! 194: register int j; ! 195: ! 196: i = SetBufferAddress(OptHome, 0); ! 197: j = WhereLowByte(i); ! 198: do { ! 199: if (IsUnProtected(i)) { ! 200: CursorAddress = i; ! 201: return; ! 202: } ! 203: /* the following could be a problem if we got here with an ! 204: * unformatted screen. However, this is "impossible", since ! 205: * with an unformatted screen, the IsUnProtected(i) above ! 206: * should be true. ! 207: */ ! 208: i = ScreenInc(FieldInc(i)); ! 209: } while (i != j); ! 210: CursorAddress = LowestScreen(); ! 211: } ! 212: ! 213: static ! 214: LastOfField(i) ! 215: register int i; /* position to start from */ ! 216: { ! 217: register int j; ! 218: register int k; ! 219: ! 220: k = j = i; ! 221: while (IsProtected(i) || Eisspace(GetHost(i))) { ! 222: i = ScreenInc(i); ! 223: if (i == j) { ! 224: break; ! 225: } ! 226: } ! 227: /* We are now IN a word IN an unprotected field (or wrapped) */ ! 228: while (!IsProtected(i)) { ! 229: if (!Eisspace(GetHost(i))) { ! 230: k = i; ! 231: } ! 232: i = ScreenInc(i); ! 233: if (i == j) { ! 234: break; ! 235: } ! 236: } ! 237: return(k); ! 238: } ! 239: ! 240: ! 241: static ! 242: FlushChar() ! 243: { ! 244: ourPTail = ourPHead = ourBuffer; ! 245: } ! 246: ! 247: ! 248: static ! 249: AddChar(character) ! 250: char character; ! 251: { ! 252: *ourPHead++ = character; ! 253: } ! 254: ! 255: ! 256: static void ! 257: SendUnformatted() ! 258: { ! 259: register int i, j; ! 260: register int Nulls; ! 261: register int c; ! 262: ! 263: /* look for start of field */ ! 264: Nulls = 0; ! 265: i = j = LowestScreen(); ! 266: do { ! 267: c = GetHost(i); ! 268: if (c == 0) { ! 269: Nulls++; ! 270: } else { ! 271: while (Nulls) { ! 272: Nulls--; ! 273: AddChar(0x40); /* put in blanks */ ! 274: } ! 275: AddChar(c); ! 276: } ! 277: i = ScreenInc(i); ! 278: } while (i != j); ! 279: } ! 280: ! 281: static ! 282: SendField(i) ! 283: register int i; /* where we saw MDT bit */ ! 284: { ! 285: register int j; ! 286: register int k; ! 287: register int Nulls; ! 288: register int c; ! 289: ! 290: /* look for start of field */ ! 291: i = j = WhereLowByte(i); ! 292: ! 293: AddChar(ORDER_SBA); /* set start field */ ! 294: AddChar(BufferTo3270_0(j)); /* set address of this field */ ! 295: AddChar(BufferTo3270_1(j)); ! 296: ! 297: if (!IsStartField(j)) { ! 298: Nulls = 0; ! 299: k = ScreenInc(WhereHighByte(j)); ! 300: do { ! 301: c = GetHost(j); ! 302: if (c == 0) { ! 303: Nulls++; ! 304: } else { ! 305: while (Nulls) { ! 306: Nulls--; ! 307: AddChar(0x40); /* put in blanks */ ! 308: } ! 309: AddChar(c); ! 310: } ! 311: j = ScreenInc(j); ! 312: } while ((j != k) && (j != i)); ! 313: } ! 314: return(j); ! 315: } ! 316: ! 317: /* Various types of reads... */ ! 318: DoReadModified() ! 319: { ! 320: register int i, j; ! 321: ! 322: if (AidByte) { ! 323: AddChar(AidByte); ! 324: } else { ! 325: AddChar(0x60); ! 326: } ! 327: if ((AidByte != AID_PA1) && (AidByte != AID_PA2) && (AidByte != AID_PA3) ! 328: && (AidByte != AID_CLEAR)) { ! 329: AddChar(BufferTo3270_0(CursorAddress)); ! 330: AddChar(BufferTo3270_1(CursorAddress)); ! 331: i = j = WhereAttrByte(LowestScreen()); ! 332: /* Is this an unformatted screen? */ ! 333: if (!IsStartField(i)) { /* yes, handle separate */ ! 334: SendUnformatted(); ! 335: } else { ! 336: do { ! 337: if (HasMdt(i)) { ! 338: i = SendField(i); ! 339: } else { ! 340: i = FieldInc(i); ! 341: } ! 342: } while (i != j); ! 343: } ! 344: } ! 345: ourPTail += DataToNetwork(ourPTail, ourPHead-ourPTail); ! 346: if (ourPTail == ourPHead) { ! 347: FlushChar(); ! 348: HadAid = 0; /* killed that buffer */ ! 349: } ! 350: } ! 351: ! 352: /* A read buffer operation... */ ! 353: ! 354: DoReadBuffer() ! 355: { ! 356: register int i, j; ! 357: ! 358: if (AidByte) { ! 359: AddChar(AidByte); ! 360: } else { ! 361: AddChar(0x60); ! 362: } ! 363: AddChar(BufferTo3270_0(CursorAddress)); ! 364: AddChar(BufferTo3270_1(CursorAddress)); ! 365: i = j = LowestScreen(); ! 366: do { ! 367: if (IsStartField(i)) { ! 368: AddChar(ORDER_SF); ! 369: AddChar(BufferTo3270_1(FieldAttributes(i))); ! 370: } else { ! 371: AddChar(GetHost(i)); ! 372: } ! 373: i = ScreenInc(i); ! 374: } while (i != j); ! 375: ourPTail += DataToNetwork(ourPTail, ourPHead-ourPTail); ! 376: if (ourPTail == ourPHead) { ! 377: FlushChar(); ! 378: HadAid = 0; /* killed that buffer */ ! 379: } ! 380: } ! 381: /* Try to send some data to host */ ! 382: ! 383: SendToIBM() ! 384: { ! 385: extern int TransparentClock, OutputClock; ! 386: ! 387: if (TransparentClock == OutputClock) { ! 388: if (HadAid) { ! 389: AddChar(AidByte); ! 390: HadAid = 0; ! 391: } else { ! 392: AddChar(0xe8); ! 393: } ! 394: do { ! 395: ourPTail += DataToNetwork(ourPTail, ourPHead-ourPTail); ! 396: } while (ourPTail != ourPHead); ! 397: FlushChar(); ! 398: } else if (HadAid) { ! 399: DoReadModified(); ! 400: } ! 401: netflush(); ! 402: } ! 403: ! 404: /* This takes in one character from the keyboard and places it on the ! 405: * screen. ! 406: */ ! 407: ! 408: static ! 409: OneCharacter(c, insert) ! 410: int c; /* character (Ebcdic) to be shoved in */ ! 411: int insert; /* are we in insert mode? */ ! 412: { ! 413: register int i, j; ! 414: ! 415: if (IsProtected(CursorAddress)) { ! 416: RingBell(); ! 417: return; ! 418: } ! 419: if (insert) { ! 420: /* is the last character in the field a blank or null? */ ! 421: i = ScreenDec(FieldInc(CursorAddress)); ! 422: j = GetHost(i); ! 423: if (!Eisspace(j)) { ! 424: RingBell(); ! 425: return; ! 426: } else { ! 427: for (j = ScreenDec(i); i != CursorAddress; ! 428: j = ScreenDec(j), i = ScreenDec(i)) { ! 429: AddHost(i, GetHost(j)); ! 430: } ! 431: } ! 432: } ! 433: AddHost(CursorAddress, c); ! 434: TurnOnMdt(CursorAddress); ! 435: CursorAddress = ScreenInc(CursorAddress); ! 436: if (IsStartField(CursorAddress) && ! 437: ((FieldAttributes(CursorAddress)&ATTR_AUTO_SKIP_MASK) == ! 438: ATTR_AUTO_SKIP_VALUE)) { ! 439: Tab(); ! 440: } ! 441: } ! 442: ! 443: /* go through data until an AID character is hit, then generate an interrupt */ ! 444: ! 445: DataFrom3270(buffer, count) ! 446: char *buffer; /* where the data is */ ! 447: int count; /* how much data there is */ ! 448: { ! 449: int origCount; ! 450: register int c; ! 451: register int i; ! 452: register int j; ! 453: static int InsertMode = 0; /* is the terminal in insert mode? */ ! 454: ! 455: extern int OutputClock, TransparentClock; ! 456: ! 457: if (!UnLocked || HadAid) { ! 458: if (HadAid) { ! 459: SendToIBM(); ! 460: if (!EmptyChar) { ! 461: return(0); /* nothing to do */ ! 462: } ! 463: } ! 464: if (!HadAid && (((*buffer&0xff) == TC_RESET) || ! 465: ((*buffer&0xff) == TC_MASTER_RESET)) && EmptyChar) { ! 466: UnLocked = 1; ! 467: } ! 468: if (!UnLocked) { ! 469: return(0); ! 470: } ! 471: } ! 472: /* now, either empty, or haven't seen aid yet */ ! 473: ! 474: origCount = count; ! 475: ! 476: if (TransparentClock == OutputClock) { ! 477: while (count) { ! 478: c = (*buffer++)&0xff; ! 479: count--; ! 480: if (IsAid(c)) { ! 481: UnLocked = 0; ! 482: InsertMode = 0; ! 483: AidByte = TCtoAid(c); ! 484: HadAid = 1; ! 485: } else { ! 486: switch (c) { ! 487: case TC_ESCAPE: ! 488: Stop3270(1); ! 489: command(0); ! 490: ConnectScreen(); ! 491: break; ! 492: ! 493: case TC_RESET: ! 494: case TC_MASTER_RESET: ! 495: UnLocked = 1; ! 496: break; ! 497: ! 498: default: ! 499: return(origCount-(count+1)); ! 500: } ! 501: } ! 502: } ! 503: } ! 504: ! 505: while (count) { ! 506: c = (*buffer++)&0xff; ! 507: count--; ! 508: ! 509: if (!IsTc(c)) { ! 510: /* Add the character to the buffer */ ! 511: OneCharacter(ascebc[trTbl][c], InsertMode); ! 512: } else if (IsAid(c)) { /* got Aid */ ! 513: if (c == TC_CLEAR) { ! 514: LocalClear3270(); ! 515: } ! 516: UnLocked = 0; ! 517: InsertMode = 0; /* just like a 3278 */ ! 518: AidByte = TCtoAid(c); ! 519: HadAid = 1; ! 520: SendToIBM(); ! 521: return(origCount-count); ! 522: } else { ! 523: ! 524: /* non-AID TC character */ ! 525: switch (c) { ! 526: ! 527: case TC_ERASE: ! 528: if (IsProtected(ScreenDec(CursorAddress))) { ! 529: RingBell(); ! 530: } else { ! 531: CursorAddress = ScreenDec(CursorAddress); ! 532: Delete(CursorAddress, ScreenInc(CursorAddress)); ! 533: } ! 534: break; ! 535: ! 536: case TC_WERASE: ! 537: j = CursorAddress; ! 538: i = ScreenDec(j); ! 539: if (IsProtected(i)) { ! 540: RingBell(); ! 541: } else { ! 542: while ((!IsProtected(i) && Eisspace(GetHost(i))) ! 543: && (i != j)) { ! 544: i = ScreenDec(i); ! 545: } ! 546: /* we are pointing at a character in a word, or ! 547: * at a protected position ! 548: */ ! 549: while ((!IsProtected(i) && !Eisspace(GetHost(i))) ! 550: && (i != j)) { ! 551: i = ScreenDec(i); ! 552: } ! 553: /* we are pointing at a space, or at a protected ! 554: * position ! 555: */ ! 556: CursorAddress = ScreenInc(i); ! 557: Delete(CursorAddress, j); ! 558: } ! 559: break; ! 560: ! 561: case TC_FERASE: ! 562: if (IsProtected(CursorAddress)) { ! 563: RingBell(); ! 564: } else { ! 565: CursorAddress = ScreenInc(CursorAddress); /* for btab */ ! 566: BackTab(); ! 567: EraseEndOfField(); ! 568: } ! 569: break; ! 570: ! 571: case TC_RESET: ! 572: InsertMode = 0; ! 573: break; ! 574: ! 575: case TC_MASTER_RESET: ! 576: InsertMode = 0; ! 577: RefreshScreen(); ! 578: break; ! 579: ! 580: case TC_UP: ! 581: CursorAddress = ScreenUp(CursorAddress); ! 582: break; ! 583: ! 584: case TC_LEFT: ! 585: CursorAddress = ScreenDec(CursorAddress); ! 586: break; ! 587: ! 588: case TC_RIGHT: ! 589: CursorAddress = ScreenInc(CursorAddress); ! 590: break; ! 591: ! 592: case TC_DOWN: ! 593: CursorAddress = ScreenDown(CursorAddress); ! 594: break; ! 595: ! 596: case TC_DELETE: ! 597: if (IsProtected(CursorAddress)) { ! 598: RingBell(); ! 599: } else { ! 600: Delete(CursorAddress, ScreenInc(CursorAddress)); ! 601: } ! 602: break; ! 603: ! 604: case TC_INSRT: ! 605: InsertMode = !InsertMode; ! 606: break; ! 607: ! 608: case TC_HOME: ! 609: Home(); ! 610: break; ! 611: ! 612: case TC_NL: ! 613: /* The algorithm is to look for the first unprotected ! 614: * column after column 0 of the following line. Having ! 615: * found that unprotected column, we check whether the ! 616: * cursor-address-at-entry is at or to the right of the ! 617: * LeftMargin AND the LeftMargin column of the found line ! 618: * is unprotected. If this conjunction is true, then ! 619: * we set the found pointer to the address of the LeftMargin ! 620: * column in the found line. ! 621: * Then, we set the cursor address to the found address. ! 622: */ ! 623: i = SetBufferAddress(ScreenLine(ScreenDown(CursorAddress)), 0); ! 624: j = ScreenInc(WhereAttrByte(CursorAddress)); ! 625: do { ! 626: if (IsUnProtected(i)) { ! 627: break; ! 628: } ! 629: /* Again (see comment in Home()), this COULD be a problem ! 630: * with an unformatted screen. ! 631: */ ! 632: /* If there was a field with only an attribute byte, ! 633: * we may be pointing to the attribute byte of the NEXT ! 634: * field, so just look at the next byte. ! 635: */ ! 636: if (IsStartField(i)) { ! 637: i = ScreenInc(i); ! 638: } else { ! 639: i = ScreenInc(FieldInc(i)); ! 640: } ! 641: } while (i != j); ! 642: if (!IsUnProtected(i)) { /* couldn't find unprotected */ ! 643: i = SetBufferAddress(0,0); ! 644: } ! 645: if (OptLeftMargin <= ScreenLineOffset(CursorAddress)) { ! 646: if (IsUnProtected(SetBufferAddress(ScreenLine(i), ! 647: OptLeftMargin))) { ! 648: i = SetBufferAddress(ScreenLine(i), OptLeftMargin); ! 649: } ! 650: } ! 651: CursorAddress = i; ! 652: break; ! 653: ! 654: case TC_EINP: ! 655: i = j = ScreenInc(WhereAttrByte(LowestScreen())); ! 656: do { ! 657: if (IsUnProtected(i)) { ! 658: AddHost(i, 0); ! 659: TurnOnMdt(i); ! 660: } else { ! 661: /* FieldInc() puts us at the start of the next ! 662: * field. ! 663: * ! 664: * We don't want to skip to the start of the ! 665: * next field if we are on the attribute byte, ! 666: * since we may be skipping over an otherwise ! 667: * unprotected field. ! 668: * ! 669: * Also, j points at the first byte of the first ! 670: * field on the screen, unprotected or not. If ! 671: * we never point there, we might loop here for ! 672: * ever. ! 673: */ ! 674: if (!IsStartField(i)) { ! 675: i = FieldInc(i); ! 676: } ! 677: } ! 678: i = ScreenInc(i); ! 679: } while (i != j); ! 680: Home(); /* get to home position */ ! 681: break; ! 682: ! 683: case TC_EEOF: ! 684: EraseEndOfField(); ! 685: break; ! 686: ! 687: case TC_FM: ! 688: if (IsProtected(CursorAddress)) { ! 689: RingBell(); ! 690: } else { ! 691: OneCharacter(EBCDIC_FM, InsertMode); /* Add field mark */ ! 692: } ! 693: break; ! 694: ! 695: case TC_DP: ! 696: if (IsProtected(CursorAddress)) { ! 697: RingBell(); ! 698: break; ! 699: } ! 700: OneCharacter(EBCDIC_DUP, InsertMode); /* Add dup character */ ! 701: Tab(); ! 702: break; ! 703: ! 704: case TC_TAB: ! 705: Tab(); ! 706: break; ! 707: ! 708: case TC_BTAB: ! 709: BackTab(); ! 710: break; ! 711: ! 712: #ifdef NOTUSED /* Actually, this is superseded by unix flow ! 713: * control. ! 714: */ ! 715: case TC_XOFF: ! 716: Flow = 0; /* stop output */ ! 717: break; ! 718: ! 719: case TC_XON: ! 720: if (!Flow) { ! 721: Flow = 1; /* turn it back on */ ! 722: DoTerminalOutput(); ! 723: } ! 724: break; ! 725: #endif /* NOTUSED */ ! 726: ! 727: case TC_ESCAPE: ! 728: /* FlushChar(); do we want to flush characters from before? */ ! 729: Stop3270(1); ! 730: command(0); ! 731: ConnectScreen(); ! 732: break; ! 733: ! 734: case TC_DISC: ! 735: Stop3270(1); ! 736: suspend(); ! 737: ConnectScreen(); ! 738: break; ! 739: ! 740: case TC_RESHOW: ! 741: RefreshScreen(); ! 742: break; ! 743: ! 744: case TC_SETTAB: ! 745: OptColTabs[ScreenLineOffset(CursorAddress)] = 1; ! 746: break; ! 747: ! 748: case TC_DELTAB: ! 749: OptColTabs[ScreenLineOffset(CursorAddress)] = 0; ! 750: break; ! 751: ! 752: case TC_CLRTAB: ! 753: for (i = 0; i < sizeof OptColTabs; i++) { ! 754: OptColTabs[i] = 0; ! 755: } ! 756: break; ! 757: ! 758: case TC_COLTAB: ! 759: ColTab(); ! 760: break; ! 761: ! 762: case TC_COLBAK: ! 763: ColBak(); ! 764: break; ! 765: ! 766: case TC_INDENT: ! 767: ColTab(); ! 768: OptLeftMargin = ScreenLineOffset(CursorAddress); ! 769: break; ! 770: ! 771: case TC_UNDENT: ! 772: ColBak(); ! 773: OptLeftMargin = ScreenLineOffset(CursorAddress); ! 774: break; ! 775: ! 776: case TC_SETMRG: ! 777: OptLeftMargin = ScreenLineOffset(CursorAddress); ! 778: break; ! 779: ! 780: case TC_SETHOM: ! 781: OptHome = ScreenLine(CursorAddress); ! 782: break; ! 783: ! 784: /* ! 785: * Point to first character of next unprotected word on ! 786: * screen. ! 787: */ ! 788: case TC_WORDTAB: ! 789: i = CursorAddress; ! 790: while (!IsProtected(i) && !Eisspace(GetHost(i))) { ! 791: i = ScreenInc(i); ! 792: if (i == CursorAddress) { ! 793: break; ! 794: } ! 795: } ! 796: /* i is either protected, a space (blank or null), ! 797: * or wrapped ! 798: */ ! 799: while (IsProtected(i) || Eisspace(GetHost(i))) { ! 800: i = ScreenInc(i); ! 801: if (i == CursorAddress) { ! 802: break; ! 803: } ! 804: } ! 805: CursorAddress = i; ! 806: break; ! 807: ! 808: case TC_WORDBACKTAB: ! 809: i = ScreenDec(CursorAddress); ! 810: while (IsProtected(i) || Eisspace(GetHost(i))) { ! 811: i = ScreenDec(i); ! 812: if (i == CursorAddress) { ! 813: break; ! 814: } ! 815: } ! 816: /* i is pointing to a character IN an unprotected word ! 817: * (or i wrapped) ! 818: */ ! 819: while (!Eisspace(GetHost(i))) { ! 820: i = ScreenDec(i); ! 821: if (i == CursorAddress) { ! 822: break; ! 823: } ! 824: } ! 825: CursorAddress = ScreenInc(i); ! 826: break; ! 827: ! 828: /* Point to last non-blank character of this/next ! 829: * unprotected word. ! 830: */ ! 831: case TC_WORDEND: ! 832: i = ScreenInc(CursorAddress); ! 833: while (IsProtected(i) || Eisspace(GetHost(i))) { ! 834: i = ScreenInc(i); ! 835: if (i == CursorAddress) { ! 836: break; ! 837: } ! 838: } ! 839: /* we are pointing at a character IN an ! 840: * unprotected word (or we wrapped) ! 841: */ ! 842: while (!Eisspace(GetHost(i))) { ! 843: i = ScreenInc(i); ! 844: if (i == CursorAddress) { ! 845: break; ! 846: } ! 847: } ! 848: CursorAddress = ScreenDec(i); ! 849: break; ! 850: ! 851: /* Get to last non-blank of this/next unprotected ! 852: * field. ! 853: */ ! 854: case TC_FIELDEND: ! 855: i = LastOfField(CursorAddress); ! 856: if (i != CursorAddress) { ! 857: CursorAddress = i; /* We moved; take this */ ! 858: } else { ! 859: j = FieldInc(CursorAddress); /* Move to next field */ ! 860: i = LastOfField(j); ! 861: if (i != j) { ! 862: CursorAddress = i; /* We moved; take this */ ! 863: } ! 864: /* else - nowhere else on screen to be; stay here */ ! 865: } ! 866: break; ! 867: ! 868: default: ! 869: RingBell(); /* We don't handle this yet */ ! 870: } ! 871: } ! 872: } ! 873: return(origCount-count); ! 874: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.