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