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 6730076Sminshall #if !defined(PURE3274) 6830076Sminshall extern int TransparentClock, OutputClock; 6930076Sminshall #endif /* !defined(PURE3274) */ 7030076Sminshall 7130015Sminshall #include "3270pc.out" 7230015Sminshall 7330015Sminshall /* the following are global variables */ 7430015Sminshall 7530015Sminshall extern int UnLocked; /* keyboard is UnLocked? */ 7630015Sminshall 7730015Sminshall /* Tab() - sets cursor to the start of the next unprotected field */ 7830015Sminshall static void 7930015Sminshall Tab() 8030015Sminshall { 8130015Sminshall register int i, j; 8230015Sminshall 8330015Sminshall i = CursorAddress; 8430015Sminshall j = WhereAttrByte(CursorAddress); 8530015Sminshall do { 8630015Sminshall if (IsStartField(i) && IsUnProtected(ScreenInc(i))) { 8730015Sminshall break; 8830015Sminshall } 8930015Sminshall i = FieldInc(i); 9030015Sminshall } while (i != j); 9130015Sminshall if (IsStartField(i) && IsUnProtected(ScreenInc(i))) { 9230015Sminshall CursorAddress = ScreenInc(i); 9330015Sminshall } else { 9430015Sminshall CursorAddress = SetBufferAddress(0,0); 9530015Sminshall } 9630015Sminshall } 9730015Sminshall 9830015Sminshall 9930015Sminshall /* BackTab() - sets cursor to the start of the most recent field */ 10030015Sminshall 10130015Sminshall static void 10230015Sminshall BackTab() 10330015Sminshall { 10430015Sminshall register int i; 10530015Sminshall 10630015Sminshall i = ScreenDec(CursorAddress); 10730015Sminshall for (;;) { 10830015Sminshall if (IsStartField(ScreenDec(i)) && IsUnProtected(i)) { 10930015Sminshall CursorAddress = i; 11030015Sminshall break; 11130015Sminshall } 11230015Sminshall if (i == CursorAddress) { 11330015Sminshall CursorAddress = SetBufferAddress(0,0); 11430015Sminshall break; 11530015Sminshall } 11630015Sminshall i = ScreenDec(i); 11730015Sminshall } 11830015Sminshall } 11930015Sminshall 12030015Sminshall 12130015Sminshall /* EraseEndOfField - erase all characters to the end of a field */ 12230015Sminshall 12330015Sminshall static void 12430015Sminshall EraseEndOfField() 12530015Sminshall { 12630015Sminshall register int i; 12730015Sminshall 12830015Sminshall if (IsProtected(CursorAddress)) { 12930015Sminshall RingBell("Protected Field"); 13030015Sminshall } else { 13130015Sminshall TurnOnMdt(CursorAddress); 13230015Sminshall if (FormattedScreen()) { 13330015Sminshall i = CursorAddress; 13430015Sminshall do { 13530015Sminshall AddHost(i, 0); 13630015Sminshall i = ScreenInc(i); 13730015Sminshall } while ((i != CursorAddress) && !IsStartField(i)); 13830015Sminshall } else { /* Screen is Unformatted */ 13930015Sminshall i = CursorAddress; 14030015Sminshall do { 14130015Sminshall AddHost(i, 0); 14230015Sminshall i = ScreenInc(i); 14330015Sminshall } while (i != HighestScreen()); 14430015Sminshall } 14530015Sminshall } 14630015Sminshall } 14730015Sminshall 14830015Sminshall /* Delete() - deletes a character from the screen 14930015Sminshall * 15030015Sminshall * What we want to do is delete the section 15130015Sminshall * [where, from-1] from the screen, 15230015Sminshall * filling in with what comes at from. 15330015Sminshall * 15430015Sminshall * The deleting continues to the end of the field (or 15530015Sminshall * until the cursor wraps). 15630015Sminshall * 15730015Sminshall * From can be a start of a field. We 15830015Sminshall * check for that. However, there can't be any 15930015Sminshall * fields that start between where and from. 16030015Sminshall * We don't check for that. 16130015Sminshall * 16230015Sminshall * Also, we assume that the protection status of 16330015Sminshall * everything has been checked by the caller. 16430015Sminshall * 16530015Sminshall */ 16630015Sminshall 16730015Sminshall static void 16830015Sminshall Delete(where, from) 16930015Sminshall register int where, /* Where to start deleting from */ 17030015Sminshall from; /* Where to pull back from */ 17130015Sminshall { 17230015Sminshall register int i; 17330015Sminshall 17430015Sminshall TurnOnMdt(where); /* Only do this once in this field */ 17530015Sminshall i = where; 17630015Sminshall do { 17730015Sminshall if (IsStartField(from)) { 17830015Sminshall AddHost(i, 0); /* Stick the edge at the start field */ 17930015Sminshall } else { 18030015Sminshall AddHost(i, GetHost(from)); 18130015Sminshall from = ScreenInc(from); /* Move the edge */ 18230015Sminshall } 18330015Sminshall i = ScreenInc(i); 18430015Sminshall } while ((!IsStartField(i)) && (i != where)); 18530015Sminshall } 18630015Sminshall 18730015Sminshall static void 18830015Sminshall ColBak() 18930015Sminshall { 19030015Sminshall register int i; 19130015Sminshall 19230015Sminshall i = ScreenLineOffset(CursorAddress); 19330015Sminshall for (i = i-1; i >= 0; i--) { 19430015Sminshall if (OptColTabs[i]) { 19530015Sminshall break; 19630015Sminshall } 19730015Sminshall } 19830015Sminshall if (i < 0) { 19930015Sminshall i = 0; 20030015Sminshall } 20130015Sminshall CursorAddress = SetBufferAddress(ScreenLine(CursorAddress), i); 20230015Sminshall } 20330015Sminshall 20430015Sminshall static void 20530015Sminshall ColTab() 20630015Sminshall { 20730015Sminshall register int i; 20830015Sminshall 20930015Sminshall i = ScreenLineOffset(CursorAddress); 21030015Sminshall for (i = i+1; i < NumberColumns; i++) { 21130015Sminshall if (OptColTabs[i]) { 21230015Sminshall break; 21330015Sminshall } 21430015Sminshall } 21530015Sminshall if (i >= NumberColumns) { 21630015Sminshall i = NumberColumns-1; 21730015Sminshall } 21830015Sminshall CursorAddress = SetBufferAddress(ScreenLine(CursorAddress), i); 21930015Sminshall } 22030015Sminshall 22130015Sminshall static void 22230015Sminshall Home() 22330015Sminshall { 22430015Sminshall register int i; 22530015Sminshall register int j; 22630015Sminshall 22730015Sminshall i = SetBufferAddress(OptHome, 0); 22830015Sminshall j = WhereLowByte(i); 22930015Sminshall do { 23030015Sminshall if (IsUnProtected(i)) { 23130015Sminshall CursorAddress = i; 23230015Sminshall return; 23330015Sminshall } 23430015Sminshall /* the following could be a problem if we got here with an 23530015Sminshall * unformatted screen. However, this is "impossible", since 23630015Sminshall * with an unformatted screen, the IsUnProtected(i) above 23730015Sminshall * should be true. 23830015Sminshall */ 23930015Sminshall i = ScreenInc(FieldInc(i)); 24030015Sminshall } while (i != j); 24130015Sminshall CursorAddress = LowestScreen(); 24230015Sminshall } 24330015Sminshall 24430015Sminshall static 24530015Sminshall LastOfField(i) 24630015Sminshall register int i; /* position to start from */ 24730015Sminshall { 24830015Sminshall register int j; 24930015Sminshall register int k; 25030015Sminshall 25130015Sminshall k = j = i; 25230015Sminshall SetXIsProtected(); 25330015Sminshall while (XIsProtected(i) || Disspace(GetHost(i))) { 25430015Sminshall i = ScreenInc(i); 25530015Sminshall if (i == j) { 25630015Sminshall break; 25730015Sminshall } 25830015Sminshall } 25930015Sminshall /* We are now IN a word IN an unprotected field (or wrapped) */ 26030015Sminshall while (!XIsProtected(i)) { 26130015Sminshall if (!Disspace(GetHost(i))) { 26230015Sminshall k = i; 26330015Sminshall } 26430015Sminshall i = ScreenInc(i); 26530015Sminshall if (i == j) { 26630015Sminshall break; 26730015Sminshall } 26830015Sminshall } 26930015Sminshall return(k); 27030015Sminshall } 27130015Sminshall 27230015Sminshall 27330015Sminshall static void 27430015Sminshall FlushChar() 27530015Sminshall { 27630015Sminshall ourPTail = ourPHead = ourBuffer; 27730015Sminshall } 27830015Sminshall 27930015Sminshall 28030015Sminshall /* 28130015Sminshall * Add one EBCDIC (NOT display code) character to the buffer. 28230015Sminshall */ 28330015Sminshall 28430015Sminshall static void 28530015Sminshall AddChar(character) 28630015Sminshall char character; 28730015Sminshall { 28830015Sminshall if (FullChar()) { 28930015Sminshall ourPTail += DataToNetwork(ourPTail, ourPHead-ourPTail, 0); 29030015Sminshall if (EmptyChar()) { 29130015Sminshall FlushChar(); 29230015Sminshall } else { 29330073Sminshall char buffer[100]; 29430073Sminshall 29530073Sminshall sprintf(buffer, "File %s, line %d: No room in network buffer!\n", 29630015Sminshall __FILE__, __LINE__); 29730073Sminshall ExitString(buffer, 1); 29830073Sminshall /*NOTREACHED*/ 29930015Sminshall } 30030015Sminshall } 30130015Sminshall *ourPHead++ = character; 30230015Sminshall } 30330015Sminshall 30430015Sminshall 30530015Sminshall static void 30630015Sminshall SendUnformatted() 30730015Sminshall { 30830015Sminshall register int i, j; 30930015Sminshall register int Nulls; 31030015Sminshall register int c; 31130015Sminshall 31230015Sminshall /* look for start of field */ 31330015Sminshall Nulls = 0; 31430015Sminshall i = j = LowestScreen(); 31530015Sminshall do { 31630015Sminshall c = GetHost(i); 31730015Sminshall if (c == 0) { 31830015Sminshall Nulls++; 31930015Sminshall } else { 32030015Sminshall while (Nulls) { 32130015Sminshall Nulls--; 32230015Sminshall AddChar(EBCDIC_BLANK); /* put in blanks */ 32330015Sminshall } 32430015Sminshall AddChar(disp_ebc[c]); 32530015Sminshall } 32630015Sminshall i = ScreenInc(i); 32730015Sminshall } while (i != j); 32830015Sminshall } 32930015Sminshall 33030015Sminshall static 33130015Sminshall SendField(i, command) 33230015Sminshall register int i; /* where we saw MDT bit */ 33330015Sminshall int command; /* The command code (type of read) */ 33430015Sminshall { 33530015Sminshall register int j; 33630015Sminshall register int k; 33730015Sminshall register int Nulls; 33830015Sminshall register int c; 33930015Sminshall 34030015Sminshall /* look for start of field */ 34130015Sminshall i = j = WhereLowByte(i); 34230015Sminshall 34330015Sminshall /* On a test_request_read, don't send sba and address */ 34430015Sminshall if ((AidByte != AID_TREQ) 34530015Sminshall || (command == CMD_SNA_READ_MODIFIED_ALL)) { 34630015Sminshall AddChar(ORDER_SBA); /* set start field */ 34730015Sminshall AddChar(BufferTo3270_0(j)); /* set address of this field */ 34830015Sminshall AddChar(BufferTo3270_1(j)); 34930015Sminshall } 35030015Sminshall /* 35130015Sminshall * Only on read_modified_all do we return the contents 35230015Sminshall * of the field when the attention was caused by a 35330015Sminshall * selector pen. 35430015Sminshall */ 35530015Sminshall if ((AidByte != AID_SELPEN) 35630015Sminshall || (command == CMD_SNA_READ_MODIFIED_ALL)) { 35730015Sminshall if (!IsStartField(j)) { 35830015Sminshall Nulls = 0; 35930015Sminshall k = ScreenInc(WhereHighByte(j)); 36030015Sminshall do { 36130015Sminshall c = GetHost(j); 36230015Sminshall if (c == 0) { 36330015Sminshall Nulls++; 36430015Sminshall } else { 36530015Sminshall while (Nulls) { 36630015Sminshall Nulls--; 36730015Sminshall AddChar(EBCDIC_BLANK); /* put in blanks */ 36830015Sminshall } 36930015Sminshall AddChar(disp_ebc[c]); 37030015Sminshall } 37130015Sminshall j = ScreenInc(j); 37230015Sminshall } while ((j != k) && (j != i)); 37330015Sminshall } 37430015Sminshall } else { 37530015Sminshall j = FieldInc(j); 37630015Sminshall } 37730015Sminshall return(j); 37830015Sminshall } 37930015Sminshall 38030015Sminshall /* Various types of reads... */ 38130015Sminshall void 38230015Sminshall DoReadModified(command) 38330015Sminshall int command; /* The command sent */ 38430015Sminshall { 38530015Sminshall register int i, j; 38630015Sminshall 38730015Sminshall if (AidByte) { 38830015Sminshall if (AidByte != AID_TREQ) { 38930015Sminshall AddChar(AidByte); 39030015Sminshall } else { 39130015Sminshall /* Test Request Read header */ 39230015Sminshall AddChar(EBCDIC_SOH); 39330015Sminshall AddChar(EBCDIC_PERCENT); 39430015Sminshall AddChar(EBCDIC_SLASH); 39530015Sminshall AddChar(EBCDIC_STX); 39630015Sminshall } 39730015Sminshall } else { 39830015Sminshall AddChar(AID_NONE); 39930015Sminshall } 40030015Sminshall if (((AidByte != AID_PA1) && (AidByte != AID_PA2) 40130015Sminshall && (AidByte != AID_PA3) && (AidByte != AID_CLEAR)) 40230015Sminshall || (command == CMD_SNA_READ_MODIFIED_ALL)) { 40330015Sminshall if ((AidByte != AID_TREQ) 40430015Sminshall || (command == CMD_SNA_READ_MODIFIED_ALL)) { 40530015Sminshall /* Test request read_modified doesn't give cursor address */ 40630015Sminshall AddChar(BufferTo3270_0(CursorAddress)); 40730015Sminshall AddChar(BufferTo3270_1(CursorAddress)); 40830015Sminshall } 40930015Sminshall i = j = WhereAttrByte(LowestScreen()); 41030015Sminshall /* Is this an unformatted screen? */ 41130015Sminshall if (!IsStartField(i)) { /* yes, handle separate */ 41230015Sminshall SendUnformatted(); 41330015Sminshall } else { 41430015Sminshall do { 41530015Sminshall if (HasMdt(i)) { 41630015Sminshall i = SendField(i, command); 41730015Sminshall } else { 41830015Sminshall i = FieldInc(i); 41930015Sminshall } 42030015Sminshall } while (i != j); 42130015Sminshall } 42230015Sminshall } 42330015Sminshall ourPTail += DataToNetwork(ourPTail, ourPHead-ourPTail, 1); 42430015Sminshall if (EmptyChar()) { 42530015Sminshall FlushChar(); 42630015Sminshall HadAid = 0; /* killed that buffer */ 42730015Sminshall } 42830015Sminshall } 42930015Sminshall 43030015Sminshall /* A read buffer operation... */ 43130015Sminshall 43230015Sminshall void 43330015Sminshall DoReadBuffer() 43430015Sminshall { 43530015Sminshall register int i, j; 43630015Sminshall 43730015Sminshall if (AidByte) { 43830015Sminshall AddChar(AidByte); 43930015Sminshall } else { 44030015Sminshall AddChar(AID_NONE); 44130015Sminshall } 44230015Sminshall AddChar(BufferTo3270_0(CursorAddress)); 44330015Sminshall AddChar(BufferTo3270_1(CursorAddress)); 44430015Sminshall i = j = LowestScreen(); 44530015Sminshall do { 44630015Sminshall if (IsStartField(i)) { 44730015Sminshall AddChar(ORDER_SF); 44830015Sminshall AddChar(BufferTo3270_1(FieldAttributes(i))); 44930015Sminshall } else { 45030015Sminshall AddChar(disp_ebc[GetHost(i)]); 45130015Sminshall } 45230015Sminshall i = ScreenInc(i); 45330015Sminshall } while (i != j); 45430015Sminshall ourPTail += DataToNetwork(ourPTail, ourPHead-ourPTail, 1); 45530015Sminshall if (EmptyChar()) { 45630015Sminshall FlushChar(); 45730015Sminshall HadAid = 0; /* killed that buffer */ 45830015Sminshall } 45930015Sminshall } 46030015Sminshall /* Try to send some data to host */ 46130015Sminshall 46230015Sminshall void 46330015Sminshall SendToIBM() 46430015Sminshall { 46530076Sminshall #if !defined(PURE3274) 46630015Sminshall if (TransparentClock == OutputClock) { 46730015Sminshall if (HadAid) { 46830015Sminshall AddChar(AidByte); 46930015Sminshall HadAid = 0; 47030015Sminshall } else { 47130015Sminshall AddChar(AID_NONE_PRINTER); 47230015Sminshall } 47330015Sminshall do { 47430015Sminshall ourPTail += DataToNetwork(ourPTail, ourPHead-ourPTail, 1); 47530015Sminshall } while (!EmptyChar()); 47630015Sminshall FlushChar(); 47730015Sminshall } else if (HadAid) { 47830015Sminshall DoReadModified(CMD_READ_MODIFIED); 47930015Sminshall } 48030076Sminshall #else /* !defined(PURE3274) */ 48130076Sminshall if (HadAid) { 48230076Sminshall DoReadModified(CMD_READ_MODIFIED); 48330076Sminshall } 48430076Sminshall #endif /* !defined(PURE3274) */ 48530015Sminshall } 48630015Sminshall 48730015Sminshall /* This takes in one character from the keyboard and places it on the 48830015Sminshall * screen. 48930015Sminshall */ 49030015Sminshall 49130015Sminshall static void 49230015Sminshall OneCharacter(c, insert) 49330015Sminshall int c; /* character (Ebcdic) to be shoved in */ 49430015Sminshall int insert; /* are we in insert mode? */ 49530015Sminshall { 49630015Sminshall register int i, j; 49730015Sminshall 49830015Sminshall if (IsProtected(CursorAddress)) { 49930015Sminshall RingBell("Protected Field"); 50030015Sminshall return; 50130015Sminshall } 50230015Sminshall if (insert) { 50330015Sminshall /* is the last character in the field a blank or null? */ 50430015Sminshall i = ScreenDec(FieldInc(CursorAddress)); 50530015Sminshall j = GetHost(i); 50630015Sminshall if (!Disspace(j)) { 50730015Sminshall RingBell("No more room for insert"); 50830015Sminshall return; 50930015Sminshall } else { 51030015Sminshall for (j = ScreenDec(i); i != CursorAddress; 51130015Sminshall j = ScreenDec(j), i = ScreenDec(i)) { 51230015Sminshall AddHost(i, GetHost(j)); 51330015Sminshall } 51430015Sminshall } 51530015Sminshall } 51630015Sminshall AddHost(CursorAddress, c); 51730015Sminshall TurnOnMdt(CursorAddress); 51830015Sminshall CursorAddress = ScreenInc(CursorAddress); 51930015Sminshall if (IsStartField(CursorAddress) && 52030015Sminshall ((FieldAttributes(CursorAddress)&ATTR_AUTO_SKIP_MASK) == 52130015Sminshall ATTR_AUTO_SKIP_VALUE)) { 52230015Sminshall Tab(); 52330015Sminshall } 52430015Sminshall } 52530015Sminshall 52630015Sminshall /* go through data until an AID character is hit, then generate an interrupt */ 52730015Sminshall 52830015Sminshall int 52930015Sminshall DataFrom3270(buffer, count) 53030015Sminshall unsigned char *buffer; /* where the data is */ 53130015Sminshall int count; /* how much data there is */ 53230015Sminshall { 53330015Sminshall int origCount; 53430015Sminshall register int c; 53530015Sminshall register int i; 53630015Sminshall register int j; 53730015Sminshall static int InsertMode = 0; /* is the terminal in insert mode? */ 53830076Sminshall enum ctlrfcn ctlrfcn; 53930015Sminshall static int shifted = 0, alted = 0; 54030015Sminshall # define HITNUM() ((shifted? 1:0) + ((alted?1:0)<<1)) 54130015Sminshall 54230015Sminshall if (*buffer >= numberof(hits)) { 54330073Sminshall ExitString("Unknown scancode encountered in DataFrom3270.\n", 1); 54430015Sminshall /*NOTREACHED*/ 54530015Sminshall } 54630076Sminshall ctlrfcn = hits[*buffer].hit[HITNUM()].ctlrfcn; 54730015Sminshall c = hits[*buffer].hit[HITNUM()].code; 54830015Sminshall 54930015Sminshall if (!UnLocked || HadAid) { 55030015Sminshall if (HadAid) { 55130015Sminshall SendToIBM(); 55230015Sminshall if (!EmptyChar()) { 55330015Sminshall return(0); /* nothing to do */ 55430015Sminshall } 55530015Sminshall } 55630076Sminshall #if defined(FCN_RESET) && defined(FCN_MASTER_RESET) 55730015Sminshall if (!HadAid && EmptyChar()) { 55830076Sminshall if ((ctlrfcn == FCN_RESET) || (ctlrfcn == FCN_MASTER_RESET)) { 55930015Sminshall UnLocked = 1; 56030015Sminshall } 56130015Sminshall } 56230076Sminshall #endif /* defined(FCN_RESET) && defined(FCN_MASTER_RESET) */ 56330015Sminshall if (!UnLocked) { 56430015Sminshall return(0); 56530015Sminshall } 56630015Sminshall } 56730015Sminshall /* now, either empty, or haven't seen aid yet */ 56830015Sminshall 56930015Sminshall origCount = count; 57030015Sminshall 57130076Sminshall #if !defined(PURE3274) 57230015Sminshall if (TransparentClock == OutputClock) { 57330015Sminshall while (count) { 57430015Sminshall if (*buffer >= numberof(hits)) { 57530073Sminshall ExitString( 57630015Sminshall "Unknown scancode encountered in DataFrom3270.\n", 1); 57730015Sminshall /*NOTREACHED*/ 57830015Sminshall } 57930076Sminshall ctlrfcn = hits[*buffer].hit[HITNUM()].ctlrfcn; 58030015Sminshall c = hits[*buffer].hit[HITNUM()].code; 58130015Sminshall buffer++; 58230015Sminshall count--; 58330076Sminshall if (ctlrfcn == FCN_AID) { 58430015Sminshall UnLocked = 0; 58530015Sminshall InsertMode = 0; 58630015Sminshall AidByte = (c); 58730015Sminshall HadAid = 1; 58830076Sminshall } else { 58930076Sminshall switch (ctlrfcn) { 59030015Sminshall case FCN_ESCAPE: 59130015Sminshall StopScreen(1); 59230015Sminshall command(0); 59330015Sminshall ConnectScreen(); 59430015Sminshall break; 59530015Sminshall 59630015Sminshall case FCN_RESET: 59730015Sminshall case FCN_MASTER_RESET: 59830015Sminshall UnLocked = 1; 59930015Sminshall break; 60030015Sminshall 60130015Sminshall default: 60230015Sminshall return(origCount-(count+1)); 60330015Sminshall } 60430015Sminshall } 60530015Sminshall } 60630015Sminshall } 60730076Sminshall #endif /* !defined(PURE3274) */ 60830015Sminshall 60930015Sminshall while (count) { 61030015Sminshall if (*buffer >= numberof(hits)) { 61130073Sminshall ExitString("Unknown scancode encountered in DataFrom3270.\n", 1); 61230015Sminshall /*NOTREACHED*/ 61330015Sminshall } 61430076Sminshall ctlrfcn = hits[*buffer].hit[HITNUM()].ctlrfcn; 61530015Sminshall c = hits[*buffer].hit[HITNUM()].code; 61630015Sminshall buffer++; 61730015Sminshall count--; 61830015Sminshall 61930076Sminshall if (ctlrfcn == FCN_CHARACTER) { 62030015Sminshall /* Add the character to the buffer */ 62130015Sminshall OneCharacter(c, InsertMode); 62230076Sminshall } else if (ctlrfcn == FCN_AID) { /* got Aid */ 62330015Sminshall if (c == AID_CLEAR) { 62430015Sminshall LocalClearScreen(); /* Side effect is to clear 3270 */ 62530015Sminshall } 62630015Sminshall UnLocked = 0; 62730015Sminshall InsertMode = 0; /* just like a 3278 */ 62830015Sminshall AidByte = c; 62930015Sminshall HadAid = 1; 63030015Sminshall SendToIBM(); 63130015Sminshall return(origCount-count); 63230015Sminshall } else { 63330076Sminshall switch (ctlrfcn) { 63430015Sminshall 63530015Sminshall case FCN_MAKE_SHIFT: 63630015Sminshall shifted++; 63730015Sminshall break; 63830015Sminshall case FCN_BREAK_SHIFT: 63930015Sminshall shifted--; 64030015Sminshall if (shifted < 0) { 64130073Sminshall ExitString("More BREAK_SHIFT than MAKE_SHIFT.\n", 1); 64230015Sminshall /*NOTREACHED*/ 64330015Sminshall } 64430015Sminshall break; 64530015Sminshall case FCN_MAKE_ALT: 64630015Sminshall alted++; 64730015Sminshall break; 64830015Sminshall case FCN_BREAK_ALT: 64930015Sminshall alted--; 65030015Sminshall if (alted < 0) { 65130073Sminshall ExitString("More BREAK_ALT than MAKE_ALT.\n", 1); 65230015Sminshall /*NOTREACHED*/ 65330015Sminshall } 65430015Sminshall break; 65530015Sminshall case FCN_CURSEL: 65630015Sminshall c = FieldAttributes(CursorAddress)&ATTR_DSPD_MASK; 65730015Sminshall if (!FormattedScreen() 65830015Sminshall || ((c != ATTR_DSPD_DSPD) && (c != ATTR_DSPD_HIGH))) { 65930015Sminshall RingBell("Cursor not in selectable field"); 66030015Sminshall } else { 66130015Sminshall i = ScreenInc(WhereAttrByte(CursorAddress)); 66230015Sminshall c = GetHost(i); 66330015Sminshall if (c == DISP_QUESTION) { 66430015Sminshall AddHost(i, DISP_GREATER_THAN); 66530015Sminshall TurnOnMdt(i); 66630015Sminshall } else if (c == DISP_GREATER_THAN) { 66730015Sminshall AddHost(i, DISP_QUESTION); 66830015Sminshall TurnOffMdt(i); 66930015Sminshall } else if (c == DISP_BLANK || c == DISP_NULL 67030015Sminshall || c == DISP_AMPERSAND) { 67130015Sminshall UnLocked = 0; 67230015Sminshall InsertMode = 0; 67330015Sminshall if (c == DISP_AMPERSAND) { 67430015Sminshall TurnOnMdt(i); /* Only for & type */ 67530015Sminshall AidByte = AID_ENTER; 67630015Sminshall } else { 67730015Sminshall AidByte = AID_SELPEN; 67830015Sminshall } 67930015Sminshall HadAid = 1; 68030015Sminshall SendToIBM(); 68130015Sminshall } else { 68230015Sminshall RingBell( 68330015Sminshall "Cursor not in a selectable field (designator)"); 68430015Sminshall } 68530015Sminshall } 68630015Sminshall break; 68730015Sminshall 68830073Sminshall #if defined(FCN_ERASE) 68930015Sminshall case FCN_ERASE: 69030015Sminshall if (IsProtected(ScreenDec(CursorAddress))) { 69130015Sminshall RingBell("Protected Field"); 69230015Sminshall } else { 69330015Sminshall CursorAddress = ScreenDec(CursorAddress); 69430015Sminshall Delete(CursorAddress, ScreenInc(CursorAddress)); 69530015Sminshall } 69630015Sminshall break; 69730073Sminshall #endif /* defined(FCN_ERASE) */ 69830015Sminshall 69930073Sminshall #if defined(FCN_WERASE) 70030015Sminshall case FCN_WERASE: 70130015Sminshall j = CursorAddress; 70230015Sminshall i = ScreenDec(j); 70330015Sminshall if (IsProtected(i)) { 70430015Sminshall RingBell("Protected Field"); 70530015Sminshall } else { 70630015Sminshall SetXIsProtected(); 70730015Sminshall while ((!XIsProtected(i) && Disspace(GetHost(i))) 70830015Sminshall && (i != j)) { 70930015Sminshall i = ScreenDec(i); 71030015Sminshall } 71130015Sminshall /* we are pointing at a character in a word, or 71230015Sminshall * at a protected position 71330015Sminshall */ 71430015Sminshall while ((!XIsProtected(i) && !Disspace(GetHost(i))) 71530015Sminshall && (i != j)) { 71630015Sminshall i = ScreenDec(i); 71730015Sminshall } 71830015Sminshall /* we are pointing at a space, or at a protected 71930015Sminshall * position 72030015Sminshall */ 72130015Sminshall CursorAddress = ScreenInc(i); 72230015Sminshall Delete(CursorAddress, j); 72330015Sminshall } 72430015Sminshall break; 72530073Sminshall #endif /* defined(WERASE) */ 72630015Sminshall 72730073Sminshall #if defined(FCN_FERASE) 72830015Sminshall case FCN_FERASE: 72930015Sminshall if (IsProtected(CursorAddress)) { 73030015Sminshall RingBell("Protected Field"); 73130015Sminshall } else { 73230015Sminshall CursorAddress = ScreenInc(CursorAddress); /* for btab */ 73330015Sminshall BackTab(); 73430015Sminshall EraseEndOfField(); 73530015Sminshall } 73630015Sminshall break; 73730073Sminshall #endif /* defined(FCN_FERASE) */ 73830015Sminshall 73930073Sminshall #if defined(FCN_RESET) 74030015Sminshall case FCN_RESET: 74130015Sminshall InsertMode = 0; 74230015Sminshall break; 74330073Sminshall #endif /* defined(FCN_RESET) */ 74430015Sminshall 74530073Sminshall #if defined(FCN_MASTER_RESET) 74630015Sminshall case FCN_MASTER_RESET: 74730015Sminshall InsertMode = 0; 74830015Sminshall RefreshScreen(); 74930015Sminshall break; 75030073Sminshall #endif /* defined(FCN_MASTER_RESET) */ 75130015Sminshall 75230015Sminshall case FCN_UP: 75330015Sminshall CursorAddress = ScreenUp(CursorAddress); 75430015Sminshall break; 75530015Sminshall 75630015Sminshall case FCN_LEFT: 75730015Sminshall CursorAddress = ScreenDec(CursorAddress); 75830015Sminshall break; 75930015Sminshall 76030015Sminshall case FCN_RIGHT: 76130015Sminshall CursorAddress = ScreenInc(CursorAddress); 76230015Sminshall break; 76330015Sminshall 76430015Sminshall case FCN_DOWN: 76530015Sminshall CursorAddress = ScreenDown(CursorAddress); 76630015Sminshall break; 76730015Sminshall 76830015Sminshall case FCN_DELETE: 76930015Sminshall if (IsProtected(CursorAddress)) { 77030015Sminshall RingBell("Protected Field"); 77130015Sminshall } else { 77230015Sminshall Delete(CursorAddress, ScreenInc(CursorAddress)); 77330015Sminshall } 77430015Sminshall break; 77530015Sminshall 77630015Sminshall case FCN_INSRT: 77730015Sminshall InsertMode = !InsertMode; 77830015Sminshall break; 77930015Sminshall 78030015Sminshall case FCN_HOME: 78130015Sminshall Home(); 78230015Sminshall break; 78330015Sminshall 78430015Sminshall case FCN_NL: 78530015Sminshall /* The algorithm is to look for the first unprotected 78630015Sminshall * column after column 0 of the following line. Having 78730015Sminshall * found that unprotected column, we check whether the 78830015Sminshall * cursor-address-at-entry is at or to the right of the 78930015Sminshall * LeftMargin AND the LeftMargin column of the found line 79030015Sminshall * is unprotected. If this conjunction is true, then 79130015Sminshall * we set the found pointer to the address of the LeftMargin 79230015Sminshall * column in the found line. 79330015Sminshall * Then, we set the cursor address to the found address. 79430015Sminshall */ 79530015Sminshall i = SetBufferAddress(ScreenLine(ScreenDown(CursorAddress)), 0); 79630015Sminshall j = ScreenInc(WhereAttrByte(CursorAddress)); 79730015Sminshall do { 79830015Sminshall if (IsUnProtected(i)) { 79930015Sminshall break; 80030015Sminshall } 80130015Sminshall /* Again (see comment in Home()), this COULD be a problem 80230015Sminshall * with an unformatted screen. 80330015Sminshall */ 80430015Sminshall /* If there was a field with only an attribute byte, 80530015Sminshall * we may be pointing to the attribute byte of the NEXT 80630015Sminshall * field, so just look at the next byte. 80730015Sminshall */ 80830015Sminshall if (IsStartField(i)) { 80930015Sminshall i = ScreenInc(i); 81030015Sminshall } else { 81130015Sminshall i = ScreenInc(FieldInc(i)); 81230015Sminshall } 81330015Sminshall } while (i != j); 81430015Sminshall if (!IsUnProtected(i)) { /* couldn't find unprotected */ 81530015Sminshall i = SetBufferAddress(0,0); 81630015Sminshall } 81730015Sminshall if (OptLeftMargin <= ScreenLineOffset(CursorAddress)) { 81830015Sminshall if (IsUnProtected(SetBufferAddress(ScreenLine(i), 81930015Sminshall OptLeftMargin))) { 82030015Sminshall i = SetBufferAddress(ScreenLine(i), OptLeftMargin); 82130015Sminshall } 82230015Sminshall } 82330015Sminshall CursorAddress = i; 82430015Sminshall break; 82530015Sminshall 82630015Sminshall case FCN_EINP: 82730015Sminshall if (!FormattedScreen()) { 82830015Sminshall i = CursorAddress; 82930015Sminshall TurnOnMdt(i); 83030015Sminshall do { 83130015Sminshall AddHost(i, 0); 83230015Sminshall i = ScreenInc(i); 83330015Sminshall } while (i != CursorAddress); 83430015Sminshall } else { 83530015Sminshall /* 83630015Sminshall * The algorithm is: go through each unprotected 83730015Sminshall * field on the screen, clearing it out. When 83830015Sminshall * we are at the start of a field, skip that field 83930015Sminshall * if its contents are protected. 84030015Sminshall */ 84130015Sminshall i = j = FieldInc(CursorAddress); 84230015Sminshall do { 84330015Sminshall if (IsUnProtected(ScreenInc(i))) { 84430015Sminshall i = ScreenInc(i); 84530015Sminshall TurnOnMdt(i); 84630015Sminshall do { 84730015Sminshall AddHost(i, 0); 84830015Sminshall i = ScreenInc(i); 84930015Sminshall } while (!IsStartField(i)); 85030015Sminshall } else { 85130015Sminshall i = FieldInc(i); 85230015Sminshall } 85330015Sminshall } while (i != j); 85430015Sminshall } 85530015Sminshall Home(); 85630015Sminshall break; 85730015Sminshall 85830015Sminshall case FCN_EEOF: 85930015Sminshall EraseEndOfField(); 86030015Sminshall break; 86130015Sminshall 86230015Sminshall case FCN_SPACE: 86330015Sminshall OneCharacter(DISP_BLANK, InsertMode); /* Add cent */ 86430015Sminshall break; 86530015Sminshall 86630015Sminshall case FCN_CENTSIGN: 86730015Sminshall OneCharacter(DISP_CENTSIGN, InsertMode); /* Add cent */ 86830015Sminshall break; 86930015Sminshall 87030015Sminshall case FCN_FM: 87130015Sminshall OneCharacter(DISP_FM, InsertMode); /* Add field mark */ 87230015Sminshall break; 87330015Sminshall 87430015Sminshall case FCN_DP: 87530015Sminshall if (IsProtected(CursorAddress)) { 87630015Sminshall RingBell("Protected Field"); 87730015Sminshall } else { 87830015Sminshall OneCharacter(DISP_DUP, InsertMode);/* Add dup character */ 87930015Sminshall Tab(); 88030015Sminshall } 88130015Sminshall break; 88230015Sminshall 88330015Sminshall case FCN_TAB: 88430015Sminshall Tab(); 88530015Sminshall break; 88630015Sminshall 88730015Sminshall case FCN_BTAB: 88830015Sminshall BackTab(); 88930015Sminshall break; 89030015Sminshall 89130015Sminshall #ifdef NOTUSED /* Actually, this is superseded by unix flow 89230015Sminshall * control. 89330015Sminshall */ 89430015Sminshall case FCN_XOFF: 89530015Sminshall Flow = 0; /* stop output */ 89630015Sminshall break; 89730015Sminshall 89830015Sminshall case FCN_XON: 89930015Sminshall if (!Flow) { 90030015Sminshall Flow = 1; /* turn it back on */ 90130015Sminshall DoTerminalOutput(); 90230015Sminshall } 90330015Sminshall break; 90430015Sminshall #endif /* NOTUSED */ 90530015Sminshall 90630073Sminshall #if defined(FCN_ESCAPE) 90730015Sminshall case FCN_ESCAPE: 90830015Sminshall /* FlushChar(); do we want to flush characters from before? */ 90930015Sminshall StopScreen(1); 91030015Sminshall command(0); 91130015Sminshall ConnectScreen(); 91230015Sminshall break; 91330073Sminshall #endif /* defined(FCN_ESCAPE) 91430015Sminshall 91530073Sminshall #if defined(FCN_DISC) 91630015Sminshall case FCN_DISC: 91730015Sminshall StopScreen(1); 91830015Sminshall suspend(); 919*30319Sminshall setconnmode(); 92030015Sminshall ConnectScreen(); 92130015Sminshall break; 92230073Sminshall #endif /* defined(FCN_DISC) */ 92330015Sminshall 92430073Sminshall #if defined(FCN_RESHOW) 92530015Sminshall case FCN_RESHOW: 92630015Sminshall RefreshScreen(); 92730015Sminshall break; 92830073Sminshall #endif /* defined(FCN_RESHOW) */ 92930015Sminshall 93030073Sminshall #if defined(FCN_SETTAB) 93130015Sminshall case FCN_SETTAB: 93230015Sminshall OptColTabs[ScreenLineOffset(CursorAddress)] = 1; 93330015Sminshall break; 93430073Sminshall #endif /* defined(FCN_SETTAB) */ 93530015Sminshall 93630073Sminshall #if defined(FCN_DELTAB) 93730015Sminshall case FCN_DELTAB: 93830015Sminshall OptColTabs[ScreenLineOffset(CursorAddress)] = 0; 93930015Sminshall break; 94030073Sminshall #endif /* defined(FCN_DELTAB) */ 94130015Sminshall 94230073Sminshall #if defined(FCN_CLRTAB) 94330015Sminshall /* 94430015Sminshall * Clear all tabs, home line, and left margin. 94530015Sminshall */ 94630015Sminshall case FCN_CLRTAB: 94730015Sminshall for (i = 0; i < sizeof OptColTabs; i++) { 94830015Sminshall OptColTabs[i] = 0; 94930015Sminshall } 95030015Sminshall OptHome = 0; 95130015Sminshall OptLeftMargin = 0; 95230015Sminshall break; 95330073Sminshall #endif /* defined(FCN_CLRTAB) */ 95430015Sminshall 95530073Sminshall #if defined(FCN_COLTAB) 95630015Sminshall case FCN_COLTAB: 95730015Sminshall ColTab(); 95830015Sminshall break; 95930073Sminshall #endif /* defined(FCN_COLTAB) */ 96030015Sminshall 96130073Sminshall #if defined(FCN_COLBAK) 96230015Sminshall case FCN_COLBAK: 96330015Sminshall ColBak(); 96430015Sminshall break; 96530073Sminshall #endif /* defined(FCN_COLBAK) */ 96630015Sminshall 96730073Sminshall #if defined(FCN_INDENT) 96830015Sminshall case FCN_INDENT: 96930015Sminshall ColTab(); 97030015Sminshall OptLeftMargin = ScreenLineOffset(CursorAddress); 97130015Sminshall break; 97230073Sminshall #endif /* defined(FCN_INDENT) */ 97330015Sminshall 97430073Sminshall #if defined(FCN_UNDENT) 97530015Sminshall case FCN_UNDENT: 97630015Sminshall ColBak(); 97730015Sminshall OptLeftMargin = ScreenLineOffset(CursorAddress); 97830015Sminshall break; 97930073Sminshall #endif /* defined(FCN_UNDENT) */ 98030015Sminshall 98130073Sminshall #if defined(FCN_SETMRG) 98230015Sminshall case FCN_SETMRG: 98330015Sminshall OptLeftMargin = ScreenLineOffset(CursorAddress); 98430015Sminshall break; 98530073Sminshall #endif /* defined(FCN_SETMRG) */ 98630015Sminshall 98730073Sminshall #if defined(FCN_SETHOM) 98830015Sminshall case FCN_SETHOM: 98930015Sminshall OptHome = ScreenLine(CursorAddress); 99030015Sminshall break; 99130073Sminshall #endif /* defined(FCN_SETHOM) */ 99230015Sminshall 99330073Sminshall #if defined(FCN_WORDTAB) 99430015Sminshall /* 99530015Sminshall * Point to first character of next unprotected word on 99630015Sminshall * screen. 99730015Sminshall */ 99830015Sminshall case FCN_WORDTAB: 99930015Sminshall i = CursorAddress; 100030015Sminshall SetXIsProtected(); 100130015Sminshall while (!XIsProtected(i) && !Disspace(GetHost(i))) { 100230015Sminshall i = ScreenInc(i); 100330015Sminshall if (i == CursorAddress) { 100430015Sminshall break; 100530015Sminshall } 100630015Sminshall } 100730015Sminshall /* i is either protected, a space (blank or null), 100830015Sminshall * or wrapped 100930015Sminshall */ 101030015Sminshall while (XIsProtected(i) || Disspace(GetHost(i))) { 101130015Sminshall i = ScreenInc(i); 101230015Sminshall if (i == CursorAddress) { 101330015Sminshall break; 101430015Sminshall } 101530015Sminshall } 101630015Sminshall CursorAddress = i; 101730015Sminshall break; 101830073Sminshall #endif /* defined(FCN_WORDTAB) */ 101930015Sminshall 102030073Sminshall #if defined(FCN_WORDBACKTAB) 102130015Sminshall case FCN_WORDBACKTAB: 102230015Sminshall i = ScreenDec(CursorAddress); 102330015Sminshall SetXIsProtected(); 102430015Sminshall while (XIsProtected(i) || Disspace(GetHost(i))) { 102530015Sminshall i = ScreenDec(i); 102630015Sminshall if (i == CursorAddress) { 102730015Sminshall break; 102830015Sminshall } 102930015Sminshall } 103030015Sminshall /* i is pointing to a character IN an unprotected word 103130015Sminshall * (or i wrapped) 103230015Sminshall */ 103330015Sminshall while (!Disspace(GetHost(i))) { 103430015Sminshall i = ScreenDec(i); 103530015Sminshall if (i == CursorAddress) { 103630015Sminshall break; 103730015Sminshall } 103830015Sminshall } 103930015Sminshall CursorAddress = ScreenInc(i); 104030015Sminshall break; 104130073Sminshall #endif /* defined(FCN_WORDBACKTAB) */ 104230015Sminshall 104330073Sminshall #if defined(FCN_WORDEND) 104430015Sminshall /* Point to last non-blank character of this/next 104530015Sminshall * unprotected word. 104630015Sminshall */ 104730015Sminshall case FCN_WORDEND: 104830015Sminshall i = ScreenInc(CursorAddress); 104930015Sminshall SetXIsProtected(); 105030015Sminshall while (XIsProtected(i) || Disspace(GetHost(i))) { 105130015Sminshall i = ScreenInc(i); 105230015Sminshall if (i == CursorAddress) { 105330015Sminshall break; 105430015Sminshall } 105530015Sminshall } 105630015Sminshall /* we are pointing at a character IN an 105730015Sminshall * unprotected word (or we wrapped) 105830015Sminshall */ 105930015Sminshall while (!Disspace(GetHost(i))) { 106030015Sminshall i = ScreenInc(i); 106130015Sminshall if (i == CursorAddress) { 106230015Sminshall break; 106330015Sminshall } 106430015Sminshall } 106530015Sminshall CursorAddress = ScreenDec(i); 106630015Sminshall break; 106730073Sminshall #endif /* defined(WORDEND) */ 106830015Sminshall 106930073Sminshall #if defined(FCN_FIELDEND) 107030015Sminshall /* Get to last non-blank of this/next unprotected 107130015Sminshall * field. 107230015Sminshall */ 107330015Sminshall case FCN_FIELDEND: 107430015Sminshall i = LastOfField(CursorAddress); 107530015Sminshall if (i != CursorAddress) { 107630015Sminshall CursorAddress = i; /* We moved; take this */ 107730015Sminshall } else { 107830015Sminshall j = FieldInc(CursorAddress); /* Move to next field */ 107930015Sminshall i = LastOfField(j); 108030015Sminshall if (i != j) { 108130015Sminshall CursorAddress = i; /* We moved; take this */ 108230015Sminshall } 108330015Sminshall /* else - nowhere else on screen to be; stay here */ 108430015Sminshall } 108530015Sminshall break; 108630073Sminshall #endif /* defined(FCN_FIELDEND) */ 108730015Sminshall 108830015Sminshall default: 108930015Sminshall /* We don't handle this yet */ 109030015Sminshall RingBell("Function not implemented"); 109130015Sminshall } 109230015Sminshall } 109330015Sminshall } 109430015Sminshall return(origCount-count); 109530015Sminshall } 1096