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