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