130015Sminshall /* 230015Sminshall * Copyright (c) 1984, 1985, 1986 by the Regents of the 330015Sminshall * University of California and by Gregory Glenn Minshall. 430015Sminshall * 530015Sminshall * Permission to use, copy, modify, and distribute these 630015Sminshall * programs and their documentation for any purpose and 730015Sminshall * without fee is hereby granted, provided that this 830015Sminshall * copyright and permission appear on all copies and 930015Sminshall * supporting documentation, the name of the Regents of 1030015Sminshall * the University of California not be used in advertising 1130015Sminshall * or publicity pertaining to distribution of the programs 1230015Sminshall * without specific prior permission, and notice be given in 1330015Sminshall * supporting documentation that copying and distribution is 1430015Sminshall * by permission of the Regents of the University of California 1530015Sminshall * and by Gregory Glenn Minshall. Neither the Regents of the 1630015Sminshall * University of California nor Gregory Glenn Minshall make 1730015Sminshall * representations about the suitability of this software 1830015Sminshall * for any purpose. It is provided "as is" without 1930015Sminshall * express or implied warranty. 2030015Sminshall */ 2130015Sminshall 2230015Sminshall 2330015Sminshall #ifndef lint 2430015Sminshall static char sccsid[] = "@(#)inbound.c 3.1 10/29/86"; 2530015Sminshall #endif /* ndef lint */ 2630015Sminshall 2730015Sminshall 2830015Sminshall #include "../general.h" 2930015Sminshall #include "function.h" 3030015Sminshall #include "hostctlr.h" 3130015Sminshall #include "scrnctlr.h" 3230015Sminshall #include "screen.h" 3330015Sminshall #include "options.h" 3430015Sminshall #include "dctype.h" 3530015Sminshall #include "ebc_disp.h" 3630015Sminshall 3730015Sminshall #include "../system/globals.h" 3830015Sminshall #include "inbound.ext" 3930015Sminshall #include "outbound.ext" 4030015Sminshall #include "../telnet.ext" 4130015Sminshall 4230015Sminshall #define EmptyChar() (ourPTail == ourPHead) 4330015Sminshall #define FullChar() (ourPHead == ourBuffer+sizeof ourBuffer) 4430015Sminshall 4530015Sminshall 4630015Sminshall /* 4730015Sminshall * We define something to allow us to to IsProtected() quickly 4830015Sminshall * on unformatted screens (with the current algorithm for fields, 4930015Sminshall * unprotected takes exponential time...). 5030015Sminshall * 5130015Sminshall * The idea is to call SetXIsProtected() BEFORE the 5230015Sminshall * loop, then use XIsProtected(). 5330015Sminshall */ 5430015Sminshall 5530015Sminshall #define SetXIsProtected() XFormattedScreen = FormattedScreen() 5630015Sminshall #define XIsProtected(p) (XFormattedScreen && IsProtected(p)) 5730015Sminshall 5830015Sminshall static char ourBuffer[400]; 5930015Sminshall 6030015Sminshall static char *ourPHead = ourBuffer, 6130015Sminshall *ourPTail = ourBuffer; 6230015Sminshall 6330015Sminshall static int HadAid = 0; /* Had an AID haven't sent */ 6430015Sminshall 6530015Sminshall static int XFormattedScreen = 0; /* For optimizations */ 6630015Sminshall 6730015Sminshall #include "3270pc.out" 6830015Sminshall 6930015Sminshall /* the following are global variables */ 7030015Sminshall 7130015Sminshall extern int UnLocked; /* keyboard is UnLocked? */ 7230015Sminshall 7330015Sminshall /* Tab() - sets cursor to the start of the next unprotected field */ 7430015Sminshall static void 7530015Sminshall Tab() 7630015Sminshall { 7730015Sminshall register int i, j; 7830015Sminshall 7930015Sminshall i = CursorAddress; 8030015Sminshall j = WhereAttrByte(CursorAddress); 8130015Sminshall do { 8230015Sminshall if (IsStartField(i) && IsUnProtected(ScreenInc(i))) { 8330015Sminshall break; 8430015Sminshall } 8530015Sminshall i = FieldInc(i); 8630015Sminshall } while (i != j); 8730015Sminshall if (IsStartField(i) && IsUnProtected(ScreenInc(i))) { 8830015Sminshall CursorAddress = ScreenInc(i); 8930015Sminshall } else { 9030015Sminshall CursorAddress = SetBufferAddress(0,0); 9130015Sminshall } 9230015Sminshall } 9330015Sminshall 9430015Sminshall 9530015Sminshall /* BackTab() - sets cursor to the start of the most recent field */ 9630015Sminshall 9730015Sminshall static void 9830015Sminshall BackTab() 9930015Sminshall { 10030015Sminshall register int i; 10130015Sminshall 10230015Sminshall i = ScreenDec(CursorAddress); 10330015Sminshall for (;;) { 10430015Sminshall if (IsStartField(ScreenDec(i)) && IsUnProtected(i)) { 10530015Sminshall CursorAddress = i; 10630015Sminshall break; 10730015Sminshall } 10830015Sminshall if (i == CursorAddress) { 10930015Sminshall CursorAddress = SetBufferAddress(0,0); 11030015Sminshall break; 11130015Sminshall } 11230015Sminshall i = ScreenDec(i); 11330015Sminshall } 11430015Sminshall } 11530015Sminshall 11630015Sminshall 11730015Sminshall /* EraseEndOfField - erase all characters to the end of a field */ 11830015Sminshall 11930015Sminshall static void 12030015Sminshall EraseEndOfField() 12130015Sminshall { 12230015Sminshall register int i; 12330015Sminshall 12430015Sminshall if (IsProtected(CursorAddress)) { 12530015Sminshall RingBell("Protected Field"); 12630015Sminshall } else { 12730015Sminshall TurnOnMdt(CursorAddress); 12830015Sminshall if (FormattedScreen()) { 12930015Sminshall i = CursorAddress; 13030015Sminshall do { 13130015Sminshall AddHost(i, 0); 13230015Sminshall i = ScreenInc(i); 13330015Sminshall } while ((i != CursorAddress) && !IsStartField(i)); 13430015Sminshall } else { /* Screen is Unformatted */ 13530015Sminshall i = CursorAddress; 13630015Sminshall do { 13730015Sminshall AddHost(i, 0); 13830015Sminshall i = ScreenInc(i); 13930015Sminshall } while (i != HighestScreen()); 14030015Sminshall } 14130015Sminshall } 14230015Sminshall } 14330015Sminshall 14430015Sminshall /* Delete() - deletes a character from the screen 14530015Sminshall * 14630015Sminshall * What we want to do is delete the section 14730015Sminshall * [where, from-1] from the screen, 14830015Sminshall * filling in with what comes at from. 14930015Sminshall * 15030015Sminshall * The deleting continues to the end of the field (or 15130015Sminshall * until the cursor wraps). 15230015Sminshall * 15330015Sminshall * From can be a start of a field. We 15430015Sminshall * check for that. However, there can't be any 15530015Sminshall * fields that start between where and from. 15630015Sminshall * We don't check for that. 15730015Sminshall * 15830015Sminshall * Also, we assume that the protection status of 15930015Sminshall * everything has been checked by the caller. 16030015Sminshall * 16130015Sminshall */ 16230015Sminshall 16330015Sminshall static void 16430015Sminshall Delete(where, from) 16530015Sminshall register int where, /* Where to start deleting from */ 16630015Sminshall from; /* Where to pull back from */ 16730015Sminshall { 16830015Sminshall register int i; 16930015Sminshall 17030015Sminshall TurnOnMdt(where); /* Only do this once in this field */ 17130015Sminshall i = where; 17230015Sminshall do { 17330015Sminshall if (IsStartField(from)) { 17430015Sminshall AddHost(i, 0); /* Stick the edge at the start field */ 17530015Sminshall } else { 17630015Sminshall AddHost(i, GetHost(from)); 17730015Sminshall from = ScreenInc(from); /* Move the edge */ 17830015Sminshall } 17930015Sminshall i = ScreenInc(i); 18030015Sminshall } while ((!IsStartField(i)) && (i != where)); 18130015Sminshall } 18230015Sminshall 18330015Sminshall static void 18430015Sminshall ColBak() 18530015Sminshall { 18630015Sminshall register int i; 18730015Sminshall 18830015Sminshall i = ScreenLineOffset(CursorAddress); 18930015Sminshall for (i = i-1; i >= 0; i--) { 19030015Sminshall if (OptColTabs[i]) { 19130015Sminshall break; 19230015Sminshall } 19330015Sminshall } 19430015Sminshall if (i < 0) { 19530015Sminshall i = 0; 19630015Sminshall } 19730015Sminshall CursorAddress = SetBufferAddress(ScreenLine(CursorAddress), i); 19830015Sminshall } 19930015Sminshall 20030015Sminshall static void 20130015Sminshall ColTab() 20230015Sminshall { 20330015Sminshall register int i; 20430015Sminshall 20530015Sminshall i = ScreenLineOffset(CursorAddress); 20630015Sminshall for (i = i+1; i < NumberColumns; i++) { 20730015Sminshall if (OptColTabs[i]) { 20830015Sminshall break; 20930015Sminshall } 21030015Sminshall } 21130015Sminshall if (i >= NumberColumns) { 21230015Sminshall i = NumberColumns-1; 21330015Sminshall } 21430015Sminshall CursorAddress = SetBufferAddress(ScreenLine(CursorAddress), i); 21530015Sminshall } 21630015Sminshall 21730015Sminshall static void 21830015Sminshall Home() 21930015Sminshall { 22030015Sminshall register int i; 22130015Sminshall register int j; 22230015Sminshall 22330015Sminshall i = SetBufferAddress(OptHome, 0); 22430015Sminshall j = WhereLowByte(i); 22530015Sminshall do { 22630015Sminshall if (IsUnProtected(i)) { 22730015Sminshall CursorAddress = i; 22830015Sminshall return; 22930015Sminshall } 23030015Sminshall /* the following could be a problem if we got here with an 23130015Sminshall * unformatted screen. However, this is "impossible", since 23230015Sminshall * with an unformatted screen, the IsUnProtected(i) above 23330015Sminshall * should be true. 23430015Sminshall */ 23530015Sminshall i = ScreenInc(FieldInc(i)); 23630015Sminshall } while (i != j); 23730015Sminshall CursorAddress = LowestScreen(); 23830015Sminshall } 23930015Sminshall 24030015Sminshall static 24130015Sminshall LastOfField(i) 24230015Sminshall register int i; /* position to start from */ 24330015Sminshall { 24430015Sminshall register int j; 24530015Sminshall register int k; 24630015Sminshall 24730015Sminshall k = j = i; 24830015Sminshall SetXIsProtected(); 24930015Sminshall while (XIsProtected(i) || Disspace(GetHost(i))) { 25030015Sminshall i = ScreenInc(i); 25130015Sminshall if (i == j) { 25230015Sminshall break; 25330015Sminshall } 25430015Sminshall } 25530015Sminshall /* We are now IN a word IN an unprotected field (or wrapped) */ 25630015Sminshall while (!XIsProtected(i)) { 25730015Sminshall if (!Disspace(GetHost(i))) { 25830015Sminshall k = i; 25930015Sminshall } 26030015Sminshall i = ScreenInc(i); 26130015Sminshall if (i == j) { 26230015Sminshall break; 26330015Sminshall } 26430015Sminshall } 26530015Sminshall return(k); 26630015Sminshall } 26730015Sminshall 26830015Sminshall 26930015Sminshall static void 27030015Sminshall FlushChar() 27130015Sminshall { 27230015Sminshall ourPTail = ourPHead = ourBuffer; 27330015Sminshall } 27430015Sminshall 27530015Sminshall 27630015Sminshall /* 27730015Sminshall * Add one EBCDIC (NOT display code) character to the buffer. 27830015Sminshall */ 27930015Sminshall 28030015Sminshall static void 28130015Sminshall AddChar(character) 28230015Sminshall char character; 28330015Sminshall { 28430015Sminshall if (FullChar()) { 28530015Sminshall ourPTail += DataToNetwork(ourPTail, ourPHead-ourPTail, 0); 28630015Sminshall if (EmptyChar()) { 28730015Sminshall FlushChar(); 28830015Sminshall } else { 289*30073Sminshall char buffer[100]; 290*30073Sminshall 291*30073Sminshall sprintf(buffer, "File %s, line %d: No room in network buffer!\n", 29230015Sminshall __FILE__, __LINE__); 293*30073Sminshall ExitString(buffer, 1); 294*30073Sminshall /*NOTREACHED*/ 29530015Sminshall } 29630015Sminshall } 29730015Sminshall *ourPHead++ = character; 29830015Sminshall } 29930015Sminshall 30030015Sminshall 30130015Sminshall static void 30230015Sminshall SendUnformatted() 30330015Sminshall { 30430015Sminshall register int i, j; 30530015Sminshall register int Nulls; 30630015Sminshall register int c; 30730015Sminshall 30830015Sminshall /* look for start of field */ 30930015Sminshall Nulls = 0; 31030015Sminshall i = j = LowestScreen(); 31130015Sminshall do { 31230015Sminshall c = GetHost(i); 31330015Sminshall if (c == 0) { 31430015Sminshall Nulls++; 31530015Sminshall } else { 31630015Sminshall while (Nulls) { 31730015Sminshall Nulls--; 31830015Sminshall AddChar(EBCDIC_BLANK); /* put in blanks */ 31930015Sminshall } 32030015Sminshall AddChar(disp_ebc[c]); 32130015Sminshall } 32230015Sminshall i = ScreenInc(i); 32330015Sminshall } while (i != j); 32430015Sminshall } 32530015Sminshall 32630015Sminshall static 32730015Sminshall SendField(i, command) 32830015Sminshall register int i; /* where we saw MDT bit */ 32930015Sminshall int command; /* The command code (type of read) */ 33030015Sminshall { 33130015Sminshall register int j; 33230015Sminshall register int k; 33330015Sminshall register int Nulls; 33430015Sminshall register int c; 33530015Sminshall 33630015Sminshall /* look for start of field */ 33730015Sminshall i = j = WhereLowByte(i); 33830015Sminshall 33930015Sminshall /* On a test_request_read, don't send sba and address */ 34030015Sminshall if ((AidByte != AID_TREQ) 34130015Sminshall || (command == CMD_SNA_READ_MODIFIED_ALL)) { 34230015Sminshall AddChar(ORDER_SBA); /* set start field */ 34330015Sminshall AddChar(BufferTo3270_0(j)); /* set address of this field */ 34430015Sminshall AddChar(BufferTo3270_1(j)); 34530015Sminshall } 34630015Sminshall /* 34730015Sminshall * Only on read_modified_all do we return the contents 34830015Sminshall * of the field when the attention was caused by a 34930015Sminshall * selector pen. 35030015Sminshall */ 35130015Sminshall if ((AidByte != AID_SELPEN) 35230015Sminshall || (command == CMD_SNA_READ_MODIFIED_ALL)) { 35330015Sminshall if (!IsStartField(j)) { 35430015Sminshall Nulls = 0; 35530015Sminshall k = ScreenInc(WhereHighByte(j)); 35630015Sminshall do { 35730015Sminshall c = GetHost(j); 35830015Sminshall if (c == 0) { 35930015Sminshall Nulls++; 36030015Sminshall } else { 36130015Sminshall while (Nulls) { 36230015Sminshall Nulls--; 36330015Sminshall AddChar(EBCDIC_BLANK); /* put in blanks */ 36430015Sminshall } 36530015Sminshall AddChar(disp_ebc[c]); 36630015Sminshall } 36730015Sminshall j = ScreenInc(j); 36830015Sminshall } while ((j != k) && (j != i)); 36930015Sminshall } 37030015Sminshall } else { 37130015Sminshall j = FieldInc(j); 37230015Sminshall } 37330015Sminshall return(j); 37430015Sminshall } 37530015Sminshall 37630015Sminshall /* Various types of reads... */ 37730015Sminshall void 37830015Sminshall DoReadModified(command) 37930015Sminshall int command; /* The command sent */ 38030015Sminshall { 38130015Sminshall register int i, j; 38230015Sminshall 38330015Sminshall if (AidByte) { 38430015Sminshall if (AidByte != AID_TREQ) { 38530015Sminshall AddChar(AidByte); 38630015Sminshall } else { 38730015Sminshall /* Test Request Read header */ 38830015Sminshall AddChar(EBCDIC_SOH); 38930015Sminshall AddChar(EBCDIC_PERCENT); 39030015Sminshall AddChar(EBCDIC_SLASH); 39130015Sminshall AddChar(EBCDIC_STX); 39230015Sminshall } 39330015Sminshall } else { 39430015Sminshall AddChar(AID_NONE); 39530015Sminshall } 39630015Sminshall if (((AidByte != AID_PA1) && (AidByte != AID_PA2) 39730015Sminshall && (AidByte != AID_PA3) && (AidByte != AID_CLEAR)) 39830015Sminshall || (command == CMD_SNA_READ_MODIFIED_ALL)) { 39930015Sminshall if ((AidByte != AID_TREQ) 40030015Sminshall || (command == CMD_SNA_READ_MODIFIED_ALL)) { 40130015Sminshall /* Test request read_modified doesn't give cursor address */ 40230015Sminshall AddChar(BufferTo3270_0(CursorAddress)); 40330015Sminshall AddChar(BufferTo3270_1(CursorAddress)); 40430015Sminshall } 40530015Sminshall i = j = WhereAttrByte(LowestScreen()); 40630015Sminshall /* Is this an unformatted screen? */ 40730015Sminshall if (!IsStartField(i)) { /* yes, handle separate */ 40830015Sminshall SendUnformatted(); 40930015Sminshall } else { 41030015Sminshall do { 41130015Sminshall if (HasMdt(i)) { 41230015Sminshall i = SendField(i, command); 41330015Sminshall } else { 41430015Sminshall i = FieldInc(i); 41530015Sminshall } 41630015Sminshall } while (i != j); 41730015Sminshall } 41830015Sminshall } 41930015Sminshall ourPTail += DataToNetwork(ourPTail, ourPHead-ourPTail, 1); 42030015Sminshall if (EmptyChar()) { 42130015Sminshall FlushChar(); 42230015Sminshall HadAid = 0; /* killed that buffer */ 42330015Sminshall } 42430015Sminshall } 42530015Sminshall 42630015Sminshall /* A read buffer operation... */ 42730015Sminshall 42830015Sminshall void 42930015Sminshall DoReadBuffer() 43030015Sminshall { 43130015Sminshall register int i, j; 43230015Sminshall 43330015Sminshall if (AidByte) { 43430015Sminshall AddChar(AidByte); 43530015Sminshall } else { 43630015Sminshall AddChar(AID_NONE); 43730015Sminshall } 43830015Sminshall AddChar(BufferTo3270_0(CursorAddress)); 43930015Sminshall AddChar(BufferTo3270_1(CursorAddress)); 44030015Sminshall i = j = LowestScreen(); 44130015Sminshall do { 44230015Sminshall if (IsStartField(i)) { 44330015Sminshall AddChar(ORDER_SF); 44430015Sminshall AddChar(BufferTo3270_1(FieldAttributes(i))); 44530015Sminshall } else { 44630015Sminshall AddChar(disp_ebc[GetHost(i)]); 44730015Sminshall } 44830015Sminshall i = ScreenInc(i); 44930015Sminshall } while (i != j); 45030015Sminshall ourPTail += DataToNetwork(ourPTail, ourPHead-ourPTail, 1); 45130015Sminshall if (EmptyChar()) { 45230015Sminshall FlushChar(); 45330015Sminshall HadAid = 0; /* killed that buffer */ 45430015Sminshall } 45530015Sminshall } 45630015Sminshall /* Try to send some data to host */ 45730015Sminshall 45830015Sminshall void 45930015Sminshall SendToIBM() 46030015Sminshall { 46130015Sminshall extern int TransparentClock, OutputClock; 46230015Sminshall 46330015Sminshall if (TransparentClock == OutputClock) { 46430015Sminshall if (HadAid) { 46530015Sminshall AddChar(AidByte); 46630015Sminshall HadAid = 0; 46730015Sminshall } else { 46830015Sminshall AddChar(AID_NONE_PRINTER); 46930015Sminshall } 47030015Sminshall do { 47130015Sminshall ourPTail += DataToNetwork(ourPTail, ourPHead-ourPTail, 1); 47230015Sminshall } while (!EmptyChar()); 47330015Sminshall FlushChar(); 47430015Sminshall } else if (HadAid) { 47530015Sminshall DoReadModified(CMD_READ_MODIFIED); 47630015Sminshall } 47730015Sminshall netflush(); 47830015Sminshall } 47930015Sminshall 48030015Sminshall /* This takes in one character from the keyboard and places it on the 48130015Sminshall * screen. 48230015Sminshall */ 48330015Sminshall 48430015Sminshall static void 48530015Sminshall OneCharacter(c, insert) 48630015Sminshall int c; /* character (Ebcdic) to be shoved in */ 48730015Sminshall int insert; /* are we in insert mode? */ 48830015Sminshall { 48930015Sminshall register int i, j; 49030015Sminshall 49130015Sminshall if (IsProtected(CursorAddress)) { 49230015Sminshall RingBell("Protected Field"); 49330015Sminshall return; 49430015Sminshall } 49530015Sminshall if (insert) { 49630015Sminshall /* is the last character in the field a blank or null? */ 49730015Sminshall i = ScreenDec(FieldInc(CursorAddress)); 49830015Sminshall j = GetHost(i); 49930015Sminshall if (!Disspace(j)) { 50030015Sminshall RingBell("No more room for insert"); 50130015Sminshall return; 50230015Sminshall } else { 50330015Sminshall for (j = ScreenDec(i); i != CursorAddress; 50430015Sminshall j = ScreenDec(j), i = ScreenDec(i)) { 50530015Sminshall AddHost(i, GetHost(j)); 50630015Sminshall } 50730015Sminshall } 50830015Sminshall } 50930015Sminshall AddHost(CursorAddress, c); 51030015Sminshall TurnOnMdt(CursorAddress); 51130015Sminshall CursorAddress = ScreenInc(CursorAddress); 51230015Sminshall if (IsStartField(CursorAddress) && 51330015Sminshall ((FieldAttributes(CursorAddress)&ATTR_AUTO_SKIP_MASK) == 51430015Sminshall ATTR_AUTO_SKIP_VALUE)) { 51530015Sminshall Tab(); 51630015Sminshall } 51730015Sminshall } 51830015Sminshall 51930015Sminshall /* go through data until an AID character is hit, then generate an interrupt */ 52030015Sminshall 52130015Sminshall int 52230015Sminshall DataFrom3270(buffer, count) 52330015Sminshall unsigned char *buffer; /* where the data is */ 52430015Sminshall int count; /* how much data there is */ 52530015Sminshall { 52630015Sminshall int origCount; 52730015Sminshall register int c; 52830015Sminshall register int i; 52930015Sminshall register int j; 53030015Sminshall static int InsertMode = 0; /* is the terminal in insert mode? */ 53130015Sminshall enum type type; 53230015Sminshall extern int OutputClock, TransparentClock; 53330015Sminshall static int shifted = 0, alted = 0; 53430015Sminshall # define HITNUM() ((shifted? 1:0) + ((alted?1:0)<<1)) 53530015Sminshall 53630015Sminshall if (*buffer >= numberof(hits)) { 537*30073Sminshall ExitString("Unknown scancode encountered in DataFrom3270.\n", 1); 53830015Sminshall /*NOTREACHED*/ 53930015Sminshall } 54030015Sminshall type = hits[*buffer].hit[HITNUM()].type; 54130015Sminshall c = hits[*buffer].hit[HITNUM()].code; 54230015Sminshall 54330015Sminshall if (!UnLocked || HadAid) { 54430015Sminshall if (HadAid) { 54530015Sminshall SendToIBM(); 54630015Sminshall if (!EmptyChar()) { 54730015Sminshall return(0); /* nothing to do */ 54830015Sminshall } 54930015Sminshall } 55030015Sminshall if (!HadAid && EmptyChar()) { 55130015Sminshall if ((type == function) && ((c == FCN_RESET) || 55230015Sminshall (c == FCN_MASTER_RESET))) { 55330015Sminshall UnLocked = 1; 55430015Sminshall } 55530015Sminshall } 55630015Sminshall if (!UnLocked) { 55730015Sminshall return(0); 55830015Sminshall } 55930015Sminshall } 56030015Sminshall /* now, either empty, or haven't seen aid yet */ 56130015Sminshall 56230015Sminshall origCount = count; 56330015Sminshall 56430015Sminshall if (TransparentClock == OutputClock) { 56530015Sminshall while (count) { 56630015Sminshall if (*buffer >= numberof(hits)) { 567*30073Sminshall ExitString( 56830015Sminshall "Unknown scancode encountered in DataFrom3270.\n", 1); 56930015Sminshall /*NOTREACHED*/ 57030015Sminshall } 57130015Sminshall type = hits[*buffer].hit[HITNUM()].type; 57230015Sminshall c = hits[*buffer].hit[HITNUM()].code; 57330015Sminshall buffer++; 57430015Sminshall count--; 57530015Sminshall if (type == aid) { 57630015Sminshall UnLocked = 0; 57730015Sminshall InsertMode = 0; 57830015Sminshall AidByte = (c); 57930015Sminshall HadAid = 1; 58030015Sminshall } else if (type == function) { 58130015Sminshall switch (c) { 58230015Sminshall case FCN_ESCAPE: 58330015Sminshall StopScreen(1); 58430015Sminshall command(0); 58530015Sminshall ConnectScreen(); 58630015Sminshall break; 58730015Sminshall 58830015Sminshall case FCN_RESET: 58930015Sminshall case FCN_MASTER_RESET: 59030015Sminshall UnLocked = 1; 59130015Sminshall break; 59230015Sminshall 59330015Sminshall default: 59430015Sminshall return(origCount-(count+1)); 59530015Sminshall } 59630015Sminshall } 59730015Sminshall } 59830015Sminshall } 59930015Sminshall 60030015Sminshall while (count) { 60130015Sminshall if (*buffer >= numberof(hits)) { 602*30073Sminshall ExitString("Unknown scancode encountered in DataFrom3270.\n", 1); 60330015Sminshall /*NOTREACHED*/ 60430015Sminshall } 60530015Sminshall type = hits[*buffer].hit[HITNUM()].type; 60630015Sminshall c = hits[*buffer].hit[HITNUM()].code; 60730015Sminshall buffer++; 60830015Sminshall count--; 60930015Sminshall 61030015Sminshall if (type == character) { 61130015Sminshall /* Add the character to the buffer */ 61230015Sminshall OneCharacter(c, InsertMode); 61330015Sminshall } else if (type == aid) { /* got Aid */ 61430015Sminshall if (c == AID_CLEAR) { 61530015Sminshall LocalClearScreen(); /* Side effect is to clear 3270 */ 61630015Sminshall } 61730015Sminshall UnLocked = 0; 61830015Sminshall InsertMode = 0; /* just like a 3278 */ 61930015Sminshall AidByte = c; 62030015Sminshall HadAid = 1; 62130015Sminshall SendToIBM(); 62230015Sminshall return(origCount-count); 62330015Sminshall } else if (type != function) { 624*30073Sminshall ExitString("Illegal or undefined scancode!\n", 1); 62530015Sminshall /*NOTREACHED*/ 62630015Sminshall } else { 62730015Sminshall switch (c) { 62830015Sminshall 62930015Sminshall case FCN_MAKE_SHIFT: 63030015Sminshall shifted++; 63130015Sminshall break; 63230015Sminshall case FCN_BREAK_SHIFT: 63330015Sminshall shifted--; 63430015Sminshall if (shifted < 0) { 635*30073Sminshall ExitString("More BREAK_SHIFT than MAKE_SHIFT.\n", 1); 63630015Sminshall /*NOTREACHED*/ 63730015Sminshall } 63830015Sminshall break; 63930015Sminshall case FCN_MAKE_ALT: 64030015Sminshall alted++; 64130015Sminshall break; 64230015Sminshall case FCN_BREAK_ALT: 64330015Sminshall alted--; 64430015Sminshall if (alted < 0) { 645*30073Sminshall ExitString("More BREAK_ALT than MAKE_ALT.\n", 1); 64630015Sminshall /*NOTREACHED*/ 64730015Sminshall } 64830015Sminshall break; 64930015Sminshall case FCN_CURSEL: 65030015Sminshall c = FieldAttributes(CursorAddress)&ATTR_DSPD_MASK; 65130015Sminshall if (!FormattedScreen() 65230015Sminshall || ((c != ATTR_DSPD_DSPD) && (c != ATTR_DSPD_HIGH))) { 65330015Sminshall RingBell("Cursor not in selectable field"); 65430015Sminshall } else { 65530015Sminshall i = ScreenInc(WhereAttrByte(CursorAddress)); 65630015Sminshall c = GetHost(i); 65730015Sminshall if (c == DISP_QUESTION) { 65830015Sminshall AddHost(i, DISP_GREATER_THAN); 65930015Sminshall TurnOnMdt(i); 66030015Sminshall } else if (c == DISP_GREATER_THAN) { 66130015Sminshall AddHost(i, DISP_QUESTION); 66230015Sminshall TurnOffMdt(i); 66330015Sminshall } else if (c == DISP_BLANK || c == DISP_NULL 66430015Sminshall || c == DISP_AMPERSAND) { 66530015Sminshall UnLocked = 0; 66630015Sminshall InsertMode = 0; 66730015Sminshall if (c == DISP_AMPERSAND) { 66830015Sminshall TurnOnMdt(i); /* Only for & type */ 66930015Sminshall AidByte = AID_ENTER; 67030015Sminshall } else { 67130015Sminshall AidByte = AID_SELPEN; 67230015Sminshall } 67330015Sminshall HadAid = 1; 67430015Sminshall SendToIBM(); 67530015Sminshall } else { 67630015Sminshall RingBell( 67730015Sminshall "Cursor not in a selectable field (designator)"); 67830015Sminshall } 67930015Sminshall } 68030015Sminshall break; 68130015Sminshall 682*30073Sminshall #if defined(FCN_ERASE) 68330015Sminshall case FCN_ERASE: 68430015Sminshall if (IsProtected(ScreenDec(CursorAddress))) { 68530015Sminshall RingBell("Protected Field"); 68630015Sminshall } else { 68730015Sminshall CursorAddress = ScreenDec(CursorAddress); 68830015Sminshall Delete(CursorAddress, ScreenInc(CursorAddress)); 68930015Sminshall } 69030015Sminshall break; 691*30073Sminshall #endif /* defined(FCN_ERASE) */ 69230015Sminshall 693*30073Sminshall #if defined(FCN_WERASE) 69430015Sminshall case FCN_WERASE: 69530015Sminshall j = CursorAddress; 69630015Sminshall i = ScreenDec(j); 69730015Sminshall if (IsProtected(i)) { 69830015Sminshall RingBell("Protected Field"); 69930015Sminshall } else { 70030015Sminshall SetXIsProtected(); 70130015Sminshall while ((!XIsProtected(i) && Disspace(GetHost(i))) 70230015Sminshall && (i != j)) { 70330015Sminshall i = ScreenDec(i); 70430015Sminshall } 70530015Sminshall /* we are pointing at a character in a word, or 70630015Sminshall * at a protected position 70730015Sminshall */ 70830015Sminshall while ((!XIsProtected(i) && !Disspace(GetHost(i))) 70930015Sminshall && (i != j)) { 71030015Sminshall i = ScreenDec(i); 71130015Sminshall } 71230015Sminshall /* we are pointing at a space, or at a protected 71330015Sminshall * position 71430015Sminshall */ 71530015Sminshall CursorAddress = ScreenInc(i); 71630015Sminshall Delete(CursorAddress, j); 71730015Sminshall } 71830015Sminshall break; 719*30073Sminshall #endif /* defined(WERASE) */ 72030015Sminshall 721*30073Sminshall #if defined(FCN_FERASE) 72230015Sminshall case FCN_FERASE: 72330015Sminshall if (IsProtected(CursorAddress)) { 72430015Sminshall RingBell("Protected Field"); 72530015Sminshall } else { 72630015Sminshall CursorAddress = ScreenInc(CursorAddress); /* for btab */ 72730015Sminshall BackTab(); 72830015Sminshall EraseEndOfField(); 72930015Sminshall } 73030015Sminshall break; 731*30073Sminshall #endif /* defined(FCN_FERASE) */ 73230015Sminshall 733*30073Sminshall #if defined(FCN_RESET) 73430015Sminshall case FCN_RESET: 73530015Sminshall InsertMode = 0; 73630015Sminshall break; 737*30073Sminshall #endif /* defined(FCN_RESET) */ 73830015Sminshall 739*30073Sminshall #if defined(FCN_MASTER_RESET) 74030015Sminshall case FCN_MASTER_RESET: 74130015Sminshall InsertMode = 0; 74230015Sminshall RefreshScreen(); 74330015Sminshall break; 744*30073Sminshall #endif /* defined(FCN_MASTER_RESET) */ 74530015Sminshall 74630015Sminshall case FCN_UP: 74730015Sminshall CursorAddress = ScreenUp(CursorAddress); 74830015Sminshall break; 74930015Sminshall 75030015Sminshall case FCN_LEFT: 75130015Sminshall CursorAddress = ScreenDec(CursorAddress); 75230015Sminshall break; 75330015Sminshall 75430015Sminshall case FCN_RIGHT: 75530015Sminshall CursorAddress = ScreenInc(CursorAddress); 75630015Sminshall break; 75730015Sminshall 75830015Sminshall case FCN_DOWN: 75930015Sminshall CursorAddress = ScreenDown(CursorAddress); 76030015Sminshall break; 76130015Sminshall 76230015Sminshall case FCN_DELETE: 76330015Sminshall if (IsProtected(CursorAddress)) { 76430015Sminshall RingBell("Protected Field"); 76530015Sminshall } else { 76630015Sminshall Delete(CursorAddress, ScreenInc(CursorAddress)); 76730015Sminshall } 76830015Sminshall break; 76930015Sminshall 77030015Sminshall case FCN_INSRT: 77130015Sminshall InsertMode = !InsertMode; 77230015Sminshall break; 77330015Sminshall 77430015Sminshall case FCN_HOME: 77530015Sminshall Home(); 77630015Sminshall break; 77730015Sminshall 77830015Sminshall case FCN_NL: 77930015Sminshall /* The algorithm is to look for the first unprotected 78030015Sminshall * column after column 0 of the following line. Having 78130015Sminshall * found that unprotected column, we check whether the 78230015Sminshall * cursor-address-at-entry is at or to the right of the 78330015Sminshall * LeftMargin AND the LeftMargin column of the found line 78430015Sminshall * is unprotected. If this conjunction is true, then 78530015Sminshall * we set the found pointer to the address of the LeftMargin 78630015Sminshall * column in the found line. 78730015Sminshall * Then, we set the cursor address to the found address. 78830015Sminshall */ 78930015Sminshall i = SetBufferAddress(ScreenLine(ScreenDown(CursorAddress)), 0); 79030015Sminshall j = ScreenInc(WhereAttrByte(CursorAddress)); 79130015Sminshall do { 79230015Sminshall if (IsUnProtected(i)) { 79330015Sminshall break; 79430015Sminshall } 79530015Sminshall /* Again (see comment in Home()), this COULD be a problem 79630015Sminshall * with an unformatted screen. 79730015Sminshall */ 79830015Sminshall /* If there was a field with only an attribute byte, 79930015Sminshall * we may be pointing to the attribute byte of the NEXT 80030015Sminshall * field, so just look at the next byte. 80130015Sminshall */ 80230015Sminshall if (IsStartField(i)) { 80330015Sminshall i = ScreenInc(i); 80430015Sminshall } else { 80530015Sminshall i = ScreenInc(FieldInc(i)); 80630015Sminshall } 80730015Sminshall } while (i != j); 80830015Sminshall if (!IsUnProtected(i)) { /* couldn't find unprotected */ 80930015Sminshall i = SetBufferAddress(0,0); 81030015Sminshall } 81130015Sminshall if (OptLeftMargin <= ScreenLineOffset(CursorAddress)) { 81230015Sminshall if (IsUnProtected(SetBufferAddress(ScreenLine(i), 81330015Sminshall OptLeftMargin))) { 81430015Sminshall i = SetBufferAddress(ScreenLine(i), OptLeftMargin); 81530015Sminshall } 81630015Sminshall } 81730015Sminshall CursorAddress = i; 81830015Sminshall break; 81930015Sminshall 82030015Sminshall case FCN_EINP: 82130015Sminshall if (!FormattedScreen()) { 82230015Sminshall i = CursorAddress; 82330015Sminshall TurnOnMdt(i); 82430015Sminshall do { 82530015Sminshall AddHost(i, 0); 82630015Sminshall i = ScreenInc(i); 82730015Sminshall } while (i != CursorAddress); 82830015Sminshall } else { 82930015Sminshall /* 83030015Sminshall * The algorithm is: go through each unprotected 83130015Sminshall * field on the screen, clearing it out. When 83230015Sminshall * we are at the start of a field, skip that field 83330015Sminshall * if its contents are protected. 83430015Sminshall */ 83530015Sminshall i = j = FieldInc(CursorAddress); 83630015Sminshall do { 83730015Sminshall if (IsUnProtected(ScreenInc(i))) { 83830015Sminshall i = ScreenInc(i); 83930015Sminshall TurnOnMdt(i); 84030015Sminshall do { 84130015Sminshall AddHost(i, 0); 84230015Sminshall i = ScreenInc(i); 84330015Sminshall } while (!IsStartField(i)); 84430015Sminshall } else { 84530015Sminshall i = FieldInc(i); 84630015Sminshall } 84730015Sminshall } while (i != j); 84830015Sminshall } 84930015Sminshall Home(); 85030015Sminshall break; 85130015Sminshall 85230015Sminshall case FCN_EEOF: 85330015Sminshall EraseEndOfField(); 85430015Sminshall break; 85530015Sminshall 85630015Sminshall case FCN_SPACE: 85730015Sminshall OneCharacter(DISP_BLANK, InsertMode); /* Add cent */ 85830015Sminshall break; 85930015Sminshall 86030015Sminshall case FCN_CENTSIGN: 86130015Sminshall OneCharacter(DISP_CENTSIGN, InsertMode); /* Add cent */ 86230015Sminshall break; 86330015Sminshall 86430015Sminshall case FCN_FM: 86530015Sminshall OneCharacter(DISP_FM, InsertMode); /* Add field mark */ 86630015Sminshall break; 86730015Sminshall 86830015Sminshall case FCN_DP: 86930015Sminshall if (IsProtected(CursorAddress)) { 87030015Sminshall RingBell("Protected Field"); 87130015Sminshall } else { 87230015Sminshall OneCharacter(DISP_DUP, InsertMode);/* Add dup character */ 87330015Sminshall Tab(); 87430015Sminshall } 87530015Sminshall break; 87630015Sminshall 87730015Sminshall case FCN_TAB: 87830015Sminshall Tab(); 87930015Sminshall break; 88030015Sminshall 88130015Sminshall case FCN_BTAB: 88230015Sminshall BackTab(); 88330015Sminshall break; 88430015Sminshall 88530015Sminshall #ifdef NOTUSED /* Actually, this is superseded by unix flow 88630015Sminshall * control. 88730015Sminshall */ 88830015Sminshall case FCN_XOFF: 88930015Sminshall Flow = 0; /* stop output */ 89030015Sminshall break; 89130015Sminshall 89230015Sminshall case FCN_XON: 89330015Sminshall if (!Flow) { 89430015Sminshall Flow = 1; /* turn it back on */ 89530015Sminshall DoTerminalOutput(); 89630015Sminshall } 89730015Sminshall break; 89830015Sminshall #endif /* NOTUSED */ 89930015Sminshall 900*30073Sminshall #if defined(FCN_ESCAPE) 90130015Sminshall case FCN_ESCAPE: 90230015Sminshall /* FlushChar(); do we want to flush characters from before? */ 90330015Sminshall StopScreen(1); 90430015Sminshall command(0); 90530015Sminshall ConnectScreen(); 90630015Sminshall break; 907*30073Sminshall #endif /* defined(FCN_ESCAPE) 90830015Sminshall 909*30073Sminshall #if defined(FCN_DISC) 91030015Sminshall case FCN_DISC: 91130015Sminshall StopScreen(1); 91230015Sminshall suspend(); 91330015Sminshall ConnectScreen(); 91430015Sminshall break; 915*30073Sminshall #endif /* defined(FCN_DISC) */ 91630015Sminshall 917*30073Sminshall #if defined(FCN_RESHOW) 91830015Sminshall case FCN_RESHOW: 91930015Sminshall RefreshScreen(); 92030015Sminshall break; 921*30073Sminshall #endif /* defined(FCN_RESHOW) */ 92230015Sminshall 923*30073Sminshall #if defined(FCN_SETTAB) 92430015Sminshall case FCN_SETTAB: 92530015Sminshall OptColTabs[ScreenLineOffset(CursorAddress)] = 1; 92630015Sminshall break; 927*30073Sminshall #endif /* defined(FCN_SETTAB) */ 92830015Sminshall 929*30073Sminshall #if defined(FCN_DELTAB) 93030015Sminshall case FCN_DELTAB: 93130015Sminshall OptColTabs[ScreenLineOffset(CursorAddress)] = 0; 93230015Sminshall break; 933*30073Sminshall #endif /* defined(FCN_DELTAB) */ 93430015Sminshall 935*30073Sminshall #if defined(FCN_CLRTAB) 93630015Sminshall /* 93730015Sminshall * Clear all tabs, home line, and left margin. 93830015Sminshall */ 93930015Sminshall case FCN_CLRTAB: 94030015Sminshall for (i = 0; i < sizeof OptColTabs; i++) { 94130015Sminshall OptColTabs[i] = 0; 94230015Sminshall } 94330015Sminshall OptHome = 0; 94430015Sminshall OptLeftMargin = 0; 94530015Sminshall break; 946*30073Sminshall #endif /* defined(FCN_CLRTAB) */ 94730015Sminshall 948*30073Sminshall #if defined(FCN_COLTAB) 94930015Sminshall case FCN_COLTAB: 95030015Sminshall ColTab(); 95130015Sminshall break; 952*30073Sminshall #endif /* defined(FCN_COLTAB) */ 95330015Sminshall 954*30073Sminshall #if defined(FCN_COLBAK) 95530015Sminshall case FCN_COLBAK: 95630015Sminshall ColBak(); 95730015Sminshall break; 958*30073Sminshall #endif /* defined(FCN_COLBAK) */ 95930015Sminshall 960*30073Sminshall #if defined(FCN_INDENT) 96130015Sminshall case FCN_INDENT: 96230015Sminshall ColTab(); 96330015Sminshall OptLeftMargin = ScreenLineOffset(CursorAddress); 96430015Sminshall break; 965*30073Sminshall #endif /* defined(FCN_INDENT) */ 96630015Sminshall 967*30073Sminshall #if defined(FCN_UNDENT) 96830015Sminshall case FCN_UNDENT: 96930015Sminshall ColBak(); 97030015Sminshall OptLeftMargin = ScreenLineOffset(CursorAddress); 97130015Sminshall break; 972*30073Sminshall #endif /* defined(FCN_UNDENT) */ 97330015Sminshall 974*30073Sminshall #if defined(FCN_SETMRG) 97530015Sminshall case FCN_SETMRG: 97630015Sminshall OptLeftMargin = ScreenLineOffset(CursorAddress); 97730015Sminshall break; 978*30073Sminshall #endif /* defined(FCN_SETMRG) */ 97930015Sminshall 980*30073Sminshall #if defined(FCN_SETHOM) 98130015Sminshall case FCN_SETHOM: 98230015Sminshall OptHome = ScreenLine(CursorAddress); 98330015Sminshall break; 984*30073Sminshall #endif /* defined(FCN_SETHOM) */ 98530015Sminshall 986*30073Sminshall #if defined(FCN_WORDTAB) 98730015Sminshall /* 98830015Sminshall * Point to first character of next unprotected word on 98930015Sminshall * screen. 99030015Sminshall */ 99130015Sminshall case FCN_WORDTAB: 99230015Sminshall i = CursorAddress; 99330015Sminshall SetXIsProtected(); 99430015Sminshall while (!XIsProtected(i) && !Disspace(GetHost(i))) { 99530015Sminshall i = ScreenInc(i); 99630015Sminshall if (i == CursorAddress) { 99730015Sminshall break; 99830015Sminshall } 99930015Sminshall } 100030015Sminshall /* i is either protected, a space (blank or null), 100130015Sminshall * or wrapped 100230015Sminshall */ 100330015Sminshall while (XIsProtected(i) || Disspace(GetHost(i))) { 100430015Sminshall i = ScreenInc(i); 100530015Sminshall if (i == CursorAddress) { 100630015Sminshall break; 100730015Sminshall } 100830015Sminshall } 100930015Sminshall CursorAddress = i; 101030015Sminshall break; 1011*30073Sminshall #endif /* defined(FCN_WORDTAB) */ 101230015Sminshall 1013*30073Sminshall #if defined(FCN_WORDBACKTAB) 101430015Sminshall case FCN_WORDBACKTAB: 101530015Sminshall i = ScreenDec(CursorAddress); 101630015Sminshall SetXIsProtected(); 101730015Sminshall while (XIsProtected(i) || Disspace(GetHost(i))) { 101830015Sminshall i = ScreenDec(i); 101930015Sminshall if (i == CursorAddress) { 102030015Sminshall break; 102130015Sminshall } 102230015Sminshall } 102330015Sminshall /* i is pointing to a character IN an unprotected word 102430015Sminshall * (or i wrapped) 102530015Sminshall */ 102630015Sminshall while (!Disspace(GetHost(i))) { 102730015Sminshall i = ScreenDec(i); 102830015Sminshall if (i == CursorAddress) { 102930015Sminshall break; 103030015Sminshall } 103130015Sminshall } 103230015Sminshall CursorAddress = ScreenInc(i); 103330015Sminshall break; 1034*30073Sminshall #endif /* defined(FCN_WORDBACKTAB) */ 103530015Sminshall 1036*30073Sminshall #if defined(FCN_WORDEND) 103730015Sminshall /* Point to last non-blank character of this/next 103830015Sminshall * unprotected word. 103930015Sminshall */ 104030015Sminshall case FCN_WORDEND: 104130015Sminshall i = ScreenInc(CursorAddress); 104230015Sminshall SetXIsProtected(); 104330015Sminshall while (XIsProtected(i) || Disspace(GetHost(i))) { 104430015Sminshall i = ScreenInc(i); 104530015Sminshall if (i == CursorAddress) { 104630015Sminshall break; 104730015Sminshall } 104830015Sminshall } 104930015Sminshall /* we are pointing at a character IN an 105030015Sminshall * unprotected word (or we wrapped) 105130015Sminshall */ 105230015Sminshall while (!Disspace(GetHost(i))) { 105330015Sminshall i = ScreenInc(i); 105430015Sminshall if (i == CursorAddress) { 105530015Sminshall break; 105630015Sminshall } 105730015Sminshall } 105830015Sminshall CursorAddress = ScreenDec(i); 105930015Sminshall break; 1060*30073Sminshall #endif /* defined(WORDEND) */ 106130015Sminshall 1062*30073Sminshall #if defined(FCN_FIELDEND) 106330015Sminshall /* Get to last non-blank of this/next unprotected 106430015Sminshall * field. 106530015Sminshall */ 106630015Sminshall case FCN_FIELDEND: 106730015Sminshall i = LastOfField(CursorAddress); 106830015Sminshall if (i != CursorAddress) { 106930015Sminshall CursorAddress = i; /* We moved; take this */ 107030015Sminshall } else { 107130015Sminshall j = FieldInc(CursorAddress); /* Move to next field */ 107230015Sminshall i = LastOfField(j); 107330015Sminshall if (i != j) { 107430015Sminshall CursorAddress = i; /* We moved; take this */ 107530015Sminshall } 107630015Sminshall /* else - nowhere else on screen to be; stay here */ 107730015Sminshall } 107830015Sminshall break; 1079*30073Sminshall #endif /* defined(FCN_FIELDEND) */ 108030015Sminshall 108130015Sminshall default: 108230015Sminshall /* We don't handle this yet */ 108330015Sminshall RingBell("Function not implemented"); 108430015Sminshall } 108530015Sminshall } 108630015Sminshall } 108730015Sminshall return(origCount-count); 108830015Sminshall } 1089