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