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: }

Defined functions

AddChar defined in line 248; used 20 times
BackTab defined in line 80; used 2 times
ColBak defined in line 158; used 2 times
ColTab defined in line 174; used 2 times
DataFrom3270 defined in line 445; used 1 times
Delete defined in line 138; used 3 times
DoReadBuffer defined in line 354; used 1 times
DoReadModified defined in line 318; used 2 times
EraseEndOfField defined in line 102; used 2 times
FlushChar defined in line 241; used 3 times
Home defined in line 190; used 2 times
LastOfField defined in line 213; used 2 times
OneCharacter defined in line 408; used 3 times
SendField defined in line 281; used 1 times
SendToIBM defined in line 383; used 3 times
SendUnformatted defined in line 256; used 1 times
Tab defined in line 57; used 3 times

Defined variables

HadAid defined in line 50; used 10 times
ourBuffer defined in line 43; used 6 times
ourPHead defined in line 45; used 8 times
sccsid defined in line 35; never used
trTbl defined in line 48; used 1 times

Defined macros

DEFINEAIDS defined in line 26; never used
EmptyChar defined in line 38; used 2 times
FullChar defined in line 39; never used
Last modified: 1986-04-05
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 2790
Valid CSS Valid XHTML 1.0 Strict