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

Defined functions

AddChar defined in line 246; used 20 times
BackTab defined in line 78; used 2 times
ColBak defined in line 156; used 2 times
ColTab defined in line 172; used 2 times
DataFrom3270 defined in line 443; used 1 times
Delete defined in line 136; used 3 times
DoReadBuffer defined in line 352; used 1 times
DoReadModified defined in line 316; used 2 times
EraseEndOfField defined in line 100; used 2 times
FlushChar defined in line 239; used 3 times
Home defined in line 188; used 2 times
LastOfField defined in line 211; used 2 times
OneCharacter defined in line 406; used 3 times
SendField defined in line 279; used 1 times
SendToIBM defined in line 381; used 3 times
SendUnformatted defined in line 254; used 1 times
Tab defined in line 55; used 3 times

Defined variables

HadAid defined in line 48; used 10 times
ourBuffer defined in line 41; used 6 times
ourPHead defined in line 43; used 8 times
sccsid defined in line 33; never used
trTbl defined in line 46; used 1 times

Defined macros

DEFINEAIDS defined in line 24; never used
EmptyChar defined in line 36; used 2 times
FullChar defined in line 37; never used
Last modified: 1994-01-01
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 4517
Valid CSS Valid XHTML 1.0 Strict