130015Sminshall /* 231892Sminshall * Copyright (c) 1984-1987 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 #ifndef lint 23*33752Sminshall static char sccsid[] = "@(#)inbound.c 3.2 (Berkeley) 03/17/88"; 2430015Sminshall #endif /* ndef lint */ 2530015Sminshall 2630015Sminshall 2731085Sminshall #include <stdio.h> 2831085Sminshall 2931177Sminshall #include "../general/general.h" 3030015Sminshall #include "function.h" 3130015Sminshall #include "hostctlr.h" 3231192Sminshall #include "oia.h" 3330015Sminshall #include "scrnctlr.h" 3430015Sminshall #include "screen.h" 3530015Sminshall #include "options.h" 3631871Sminshall #include "../api/dctype.h" 3731871Sminshall #include "../api/ebc_disp.h" 3830015Sminshall 3931177Sminshall #include "../general/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 InsertMode; /* is the terminal in insert mode? */ 7230327Sminshall 7331197Sminshall static int rememberedshiftstate; /* Shift (alt) state of terminal */ 7431197Sminshall # define HITNUM(s) ((((s)&(SHIFT_CAPS|SHIFT_UPSHIFT))? 1:0) \ 7531197Sminshall + ((((s)&SHIFT_ALT)? 1:0)<<1)) 7631197Sminshall 7730361Sminshall static int XWasSF, XProtected; /* For optimizations */ 7830076Sminshall #if !defined(PURE3274) 7930076Sminshall extern int TransparentClock, OutputClock; 8030076Sminshall #endif /* !defined(PURE3274) */ 8130076Sminshall 8230327Sminshall #include "kbd.out" /* Get keyboard mapping function */ 8330015Sminshall 8430015Sminshall /* the following are global variables */ 8530015Sminshall 8630015Sminshall extern int UnLocked; /* keyboard is UnLocked? */ 8730015Sminshall 8830724Sminshall 8930724Sminshall /* 9030724Sminshall * init_inbound : 9130724Sminshall * 9230724Sminshall * Reset variables to initial state. 9330724Sminshall */ 9430724Sminshall 9530724Sminshall void 9630724Sminshall init_inbound() 9730724Sminshall { 9830724Sminshall ourPHead = ourPTail = ourBuffer; 9930724Sminshall HadAid = 0; 10031197Sminshall rememberedshiftstate = 0; 10130724Sminshall InsertMode = 0; 10230724Sminshall } 10330724Sminshall 10430724Sminshall 10530015Sminshall /* Tab() - sets cursor to the start of the next unprotected field */ 10630015Sminshall static void 10730015Sminshall Tab() 10830015Sminshall { 10930015Sminshall register int i, j; 11030015Sminshall 11130015Sminshall i = CursorAddress; 11230015Sminshall j = WhereAttrByte(CursorAddress); 11330015Sminshall do { 11430015Sminshall if (IsStartField(i) && IsUnProtected(ScreenInc(i))) { 11530015Sminshall break; 11630015Sminshall } 11730015Sminshall i = FieldInc(i); 11830015Sminshall } while (i != j); 11930015Sminshall if (IsStartField(i) && IsUnProtected(ScreenInc(i))) { 12030015Sminshall CursorAddress = ScreenInc(i); 12130015Sminshall } else { 12230015Sminshall CursorAddress = SetBufferAddress(0,0); 12330015Sminshall } 12430015Sminshall } 12530015Sminshall 12630015Sminshall 12730015Sminshall /* BackTab() - sets cursor to the start of the most recent field */ 12830015Sminshall 12930015Sminshall static void 13030015Sminshall BackTab() 13130015Sminshall { 13230015Sminshall register int i; 13330015Sminshall 13430015Sminshall i = ScreenDec(CursorAddress); 13530015Sminshall for (;;) { 13630015Sminshall if (IsStartField(ScreenDec(i)) && IsUnProtected(i)) { 13730015Sminshall CursorAddress = i; 13830015Sminshall break; 13930015Sminshall } 14030015Sminshall if (i == CursorAddress) { 14130015Sminshall CursorAddress = SetBufferAddress(0,0); 14230015Sminshall break; 14330015Sminshall } 14430015Sminshall i = ScreenDec(i); 14530015Sminshall } 14630015Sminshall } 14730015Sminshall 148*33752Sminshall /* 149*33752Sminshall * ModifyMdt() - Turn a modified data tag bit on or off (watch 150*33752Sminshall * out for unformatted screens). 151*33752Sminshall */ 15230015Sminshall 153*33752Sminshall ModifyMdt(x,on) 154*33752Sminshall int x; 155*33752Sminshall int on; 156*33752Sminshall { 157*33752Sminshall int i = x; 158*33752Sminshall 159*33752Sminshall if (IsStartField(i)) { /* If we are at a start field position... */ 160*33752Sminshall if (on) { 161*33752Sminshall ModifyHost(i, |= ATTR_MDT); /* Turn it on */ 162*33752Sminshall } else { 163*33752Sminshall ModifyHost(i, &= ~ATTR_MDT); /* Turn it off */ 164*33752Sminshall } 165*33752Sminshall } else { 166*33752Sminshall i = WhereAttrByte(i); /* Find beginning of field */ 167*33752Sminshall if (IsStartField(i)) { /* Is there one? */ 168*33752Sminshall if (on) { 169*33752Sminshall ModifyHost(i, |= ATTR_MDT); /* Turn it on */ 170*33752Sminshall } else { 171*33752Sminshall ModifyHost(i, &= ~ATTR_MDT); /* Turn it off */ 172*33752Sminshall } 173*33752Sminshall } /* else, don't modify - this is an unformatted screen */ 174*33752Sminshall } 175*33752Sminshall } 176*33752Sminshall 177*33752Sminshall 17830015Sminshall /* EraseEndOfField - erase all characters to the end of a field */ 17930015Sminshall 18030015Sminshall static void 18130015Sminshall EraseEndOfField() 18230015Sminshall { 18330015Sminshall register int i; 18430015Sminshall 18530015Sminshall if (IsProtected(CursorAddress)) { 18630015Sminshall RingBell("Protected Field"); 18730015Sminshall } else { 18830015Sminshall TurnOnMdt(CursorAddress); 18930015Sminshall if (FormattedScreen()) { 19030015Sminshall i = CursorAddress; 19130015Sminshall do { 19230015Sminshall AddHost(i, 0); 19330015Sminshall i = ScreenInc(i); 19430015Sminshall } while ((i != CursorAddress) && !IsStartField(i)); 19530015Sminshall } else { /* Screen is Unformatted */ 19630015Sminshall i = CursorAddress; 19730015Sminshall do { 19830015Sminshall AddHost(i, 0); 19930015Sminshall i = ScreenInc(i); 20030015Sminshall } while (i != HighestScreen()); 20130015Sminshall } 20230015Sminshall } 20330015Sminshall } 20430015Sminshall 20530015Sminshall /* Delete() - deletes a character from the screen 20630015Sminshall * 20730015Sminshall * What we want to do is delete the section 20830015Sminshall * [where, from-1] from the screen, 20930015Sminshall * filling in with what comes at from. 21030015Sminshall * 21130015Sminshall * The deleting continues to the end of the field (or 21230015Sminshall * until the cursor wraps). 21330015Sminshall * 21430015Sminshall * From can be a start of a field. We 21530015Sminshall * check for that. However, there can't be any 21630015Sminshall * fields that start between where and from. 21730015Sminshall * We don't check for that. 21830015Sminshall * 21930015Sminshall * Also, we assume that the protection status of 22030015Sminshall * everything has been checked by the caller. 22130015Sminshall * 22230015Sminshall */ 22330015Sminshall 22430015Sminshall static void 22530015Sminshall Delete(where, from) 22630015Sminshall register int where, /* Where to start deleting from */ 22730015Sminshall from; /* Where to pull back from */ 22830015Sminshall { 22930015Sminshall register int i; 23030015Sminshall 23130015Sminshall TurnOnMdt(where); /* Only do this once in this field */ 23230015Sminshall i = where; 23330015Sminshall do { 23430015Sminshall if (IsStartField(from)) { 23530015Sminshall AddHost(i, 0); /* Stick the edge at the start field */ 23630015Sminshall } else { 23730015Sminshall AddHost(i, GetHost(from)); 23830015Sminshall from = ScreenInc(from); /* Move the edge */ 23930015Sminshall } 24030015Sminshall i = ScreenInc(i); 24130015Sminshall } while ((!IsStartField(i)) && (i != where)); 24230015Sminshall } 24330015Sminshall 24430015Sminshall static void 24530015Sminshall ColBak() 24630015Sminshall { 24730015Sminshall register int i; 24830015Sminshall 24930015Sminshall i = ScreenLineOffset(CursorAddress); 25030015Sminshall for (i = i-1; i >= 0; i--) { 25130015Sminshall if (OptColTabs[i]) { 25230015Sminshall break; 25330015Sminshall } 25430015Sminshall } 25530015Sminshall if (i < 0) { 25630015Sminshall i = 0; 25730015Sminshall } 25830015Sminshall CursorAddress = SetBufferAddress(ScreenLine(CursorAddress), i); 25930015Sminshall } 26030015Sminshall 26130015Sminshall static void 26230015Sminshall ColTab() 26330015Sminshall { 26430015Sminshall register int i; 26530015Sminshall 26630015Sminshall i = ScreenLineOffset(CursorAddress); 26730015Sminshall for (i = i+1; i < NumberColumns; i++) { 26830015Sminshall if (OptColTabs[i]) { 26930015Sminshall break; 27030015Sminshall } 27130015Sminshall } 27230015Sminshall if (i >= NumberColumns) { 27330015Sminshall i = NumberColumns-1; 27430015Sminshall } 27530015Sminshall CursorAddress = SetBufferAddress(ScreenLine(CursorAddress), i); 27630015Sminshall } 27730015Sminshall 27830015Sminshall static void 27930015Sminshall Home() 28030015Sminshall { 28130015Sminshall register int i; 28230015Sminshall register int j; 28330015Sminshall 28430015Sminshall i = SetBufferAddress(OptHome, 0); 28530015Sminshall j = WhereLowByte(i); 28630015Sminshall do { 28730015Sminshall if (IsUnProtected(i)) { 28830015Sminshall CursorAddress = i; 28930015Sminshall return; 29030015Sminshall } 29130015Sminshall /* the following could be a problem if we got here with an 29230015Sminshall * unformatted screen. However, this is "impossible", since 29330015Sminshall * with an unformatted screen, the IsUnProtected(i) above 29430015Sminshall * should be true. 29530015Sminshall */ 29630015Sminshall i = ScreenInc(FieldInc(i)); 29730015Sminshall } while (i != j); 29830015Sminshall CursorAddress = LowestScreen(); 29930015Sminshall } 30030015Sminshall 30130015Sminshall static 30230015Sminshall LastOfField(i) 30330015Sminshall register int i; /* position to start from */ 30430015Sminshall { 30530015Sminshall register int j; 30630015Sminshall register int k; 30730015Sminshall 30830015Sminshall k = j = i; 30930015Sminshall SetXIsProtected(); 31030015Sminshall while (XIsProtected(i) || Disspace(GetHost(i))) { 31130015Sminshall i = ScreenInc(i); 31230015Sminshall if (i == j) { 31330015Sminshall break; 31430015Sminshall } 31530015Sminshall } 31630015Sminshall /* We are now IN a word IN an unprotected field (or wrapped) */ 31730015Sminshall while (!XIsProtected(i)) { 31830015Sminshall if (!Disspace(GetHost(i))) { 31930015Sminshall k = i; 32030015Sminshall } 32130015Sminshall i = ScreenInc(i); 32230015Sminshall if (i == j) { 32330015Sminshall break; 32430015Sminshall } 32530015Sminshall } 32630015Sminshall return(k); 32730015Sminshall } 32830015Sminshall 32930015Sminshall 33030015Sminshall static void 33130015Sminshall FlushChar() 33230015Sminshall { 33330015Sminshall ourPTail = ourPHead = ourBuffer; 33430015Sminshall } 33530015Sminshall 33630015Sminshall 33730015Sminshall /* 33830015Sminshall * Add one EBCDIC (NOT display code) character to the buffer. 33930015Sminshall */ 34030015Sminshall 34130015Sminshall static void 34230015Sminshall AddChar(character) 34330015Sminshall char character; 34430015Sminshall { 34530015Sminshall if (FullChar()) { 34630015Sminshall ourPTail += DataToNetwork(ourPTail, ourPHead-ourPTail, 0); 34730015Sminshall if (EmptyChar()) { 34830015Sminshall FlushChar(); 34930015Sminshall } else { 35030073Sminshall char buffer[100]; 35130073Sminshall 35230073Sminshall sprintf(buffer, "File %s, line %d: No room in network buffer!\n", 35330015Sminshall __FILE__, __LINE__); 35431085Sminshall ExitString(stderr, buffer, 1); 35530073Sminshall /*NOTREACHED*/ 35630015Sminshall } 35730015Sminshall } 35830015Sminshall *ourPHead++ = character; 35930015Sminshall } 36030015Sminshall 36130015Sminshall 36230015Sminshall static void 36330015Sminshall SendUnformatted() 36430015Sminshall { 36530015Sminshall register int i, j; 36630015Sminshall register int Nulls; 36730015Sminshall register int c; 36830015Sminshall 36930015Sminshall /* look for start of field */ 37030015Sminshall Nulls = 0; 37130015Sminshall i = j = LowestScreen(); 37230015Sminshall do { 37330015Sminshall c = GetHost(i); 37430015Sminshall if (c == 0) { 37530015Sminshall Nulls++; 37630015Sminshall } else { 37730015Sminshall while (Nulls) { 37830015Sminshall Nulls--; 37930015Sminshall AddChar(EBCDIC_BLANK); /* put in blanks */ 38030015Sminshall } 38130015Sminshall AddChar(disp_ebc[c]); 38230015Sminshall } 38330015Sminshall i = ScreenInc(i); 38430015Sminshall } while (i != j); 38530015Sminshall } 38630015Sminshall 38730015Sminshall static 38830015Sminshall SendField(i, command) 38930015Sminshall register int i; /* where we saw MDT bit */ 39030015Sminshall int command; /* The command code (type of read) */ 39130015Sminshall { 39230015Sminshall register int j; 39330015Sminshall register int k; 39430015Sminshall register int Nulls; 39530015Sminshall register int c; 39630015Sminshall 39730015Sminshall /* look for start of field */ 39830015Sminshall i = j = WhereLowByte(i); 39930015Sminshall 40030015Sminshall /* On a test_request_read, don't send sba and address */ 40130015Sminshall if ((AidByte != AID_TREQ) 40230015Sminshall || (command == CMD_SNA_READ_MODIFIED_ALL)) { 40330015Sminshall AddChar(ORDER_SBA); /* set start field */ 40430015Sminshall AddChar(BufferTo3270_0(j)); /* set address of this field */ 40530015Sminshall AddChar(BufferTo3270_1(j)); 40630015Sminshall } 40730015Sminshall /* 40830015Sminshall * Only on read_modified_all do we return the contents 40930015Sminshall * of the field when the attention was caused by a 41030015Sminshall * selector pen. 41130015Sminshall */ 41230015Sminshall if ((AidByte != AID_SELPEN) 41330015Sminshall || (command == CMD_SNA_READ_MODIFIED_ALL)) { 41430015Sminshall if (!IsStartField(j)) { 41530015Sminshall Nulls = 0; 41630015Sminshall k = ScreenInc(WhereHighByte(j)); 41730015Sminshall do { 41830015Sminshall c = GetHost(j); 41930015Sminshall if (c == 0) { 42030015Sminshall Nulls++; 42130015Sminshall } else { 42230015Sminshall while (Nulls) { 42330015Sminshall Nulls--; 42430015Sminshall AddChar(EBCDIC_BLANK); /* put in blanks */ 42530015Sminshall } 42630015Sminshall AddChar(disp_ebc[c]); 42730015Sminshall } 42830015Sminshall j = ScreenInc(j); 42930015Sminshall } while ((j != k) && (j != i)); 43030015Sminshall } 43130015Sminshall } else { 43230015Sminshall j = FieldInc(j); 43330015Sminshall } 43430015Sminshall return(j); 43530015Sminshall } 43630015Sminshall 43730015Sminshall /* Various types of reads... */ 43830015Sminshall void 43930015Sminshall DoReadModified(command) 44030015Sminshall int command; /* The command sent */ 44130015Sminshall { 44230015Sminshall register int i, j; 44330015Sminshall 44430015Sminshall if (AidByte) { 44530015Sminshall if (AidByte != AID_TREQ) { 44630015Sminshall AddChar(AidByte); 44730015Sminshall } else { 44830015Sminshall /* Test Request Read header */ 44930015Sminshall AddChar(EBCDIC_SOH); 45030015Sminshall AddChar(EBCDIC_PERCENT); 45130015Sminshall AddChar(EBCDIC_SLASH); 45230015Sminshall AddChar(EBCDIC_STX); 45330015Sminshall } 45430015Sminshall } else { 45530015Sminshall AddChar(AID_NONE); 45630015Sminshall } 45730015Sminshall if (((AidByte != AID_PA1) && (AidByte != AID_PA2) 45830015Sminshall && (AidByte != AID_PA3) && (AidByte != AID_CLEAR)) 45930015Sminshall || (command == CMD_SNA_READ_MODIFIED_ALL)) { 46030015Sminshall if ((AidByte != AID_TREQ) 46130015Sminshall || (command == CMD_SNA_READ_MODIFIED_ALL)) { 46230015Sminshall /* Test request read_modified doesn't give cursor address */ 46330015Sminshall AddChar(BufferTo3270_0(CursorAddress)); 46430015Sminshall AddChar(BufferTo3270_1(CursorAddress)); 46530015Sminshall } 46630015Sminshall i = j = WhereAttrByte(LowestScreen()); 46730015Sminshall /* Is this an unformatted screen? */ 46830015Sminshall if (!IsStartField(i)) { /* yes, handle separate */ 46930015Sminshall SendUnformatted(); 47030015Sminshall } else { 47130015Sminshall do { 47230015Sminshall if (HasMdt(i)) { 47330015Sminshall i = SendField(i, command); 47430015Sminshall } else { 47530015Sminshall i = FieldInc(i); 47630015Sminshall } 47730015Sminshall } while (i != j); 47830015Sminshall } 47930015Sminshall } 48030015Sminshall ourPTail += DataToNetwork(ourPTail, ourPHead-ourPTail, 1); 48130015Sminshall if (EmptyChar()) { 48230015Sminshall FlushChar(); 48330015Sminshall HadAid = 0; /* killed that buffer */ 48430015Sminshall } 48530015Sminshall } 48630015Sminshall 48730015Sminshall /* A read buffer operation... */ 48830015Sminshall 48930015Sminshall void 49030015Sminshall DoReadBuffer() 49130015Sminshall { 49230015Sminshall register int i, j; 49330015Sminshall 49430015Sminshall if (AidByte) { 49530015Sminshall AddChar(AidByte); 49630015Sminshall } else { 49730015Sminshall AddChar(AID_NONE); 49830015Sminshall } 49930015Sminshall AddChar(BufferTo3270_0(CursorAddress)); 50030015Sminshall AddChar(BufferTo3270_1(CursorAddress)); 50130015Sminshall i = j = LowestScreen(); 50230015Sminshall do { 50330015Sminshall if (IsStartField(i)) { 50430015Sminshall AddChar(ORDER_SF); 50530015Sminshall AddChar(BufferTo3270_1(FieldAttributes(i))); 50630015Sminshall } else { 50730015Sminshall AddChar(disp_ebc[GetHost(i)]); 50830015Sminshall } 50930015Sminshall i = ScreenInc(i); 51030015Sminshall } while (i != j); 51130015Sminshall ourPTail += DataToNetwork(ourPTail, ourPHead-ourPTail, 1); 51230015Sminshall if (EmptyChar()) { 51330015Sminshall FlushChar(); 51430015Sminshall HadAid = 0; /* killed that buffer */ 51530015Sminshall } 51630015Sminshall } 51731864Sminshall 51831864Sminshall /* Send some transparent data to the host */ 51931864Sminshall 52031864Sminshall void 52131864Sminshall SendTransparent(buffer, count) 52231864Sminshall char *buffer; 52331864Sminshall int count; 52431864Sminshall { 52531864Sminshall char stuff[3]; 52631864Sminshall 52731864Sminshall stuff[0] = AID_NONE_PRINTER; 52831864Sminshall stuff[1] = BufferTo3270_0(count); 52931864Sminshall stuff[2] = BufferTo3270_1(count); 53031864Sminshall DataToNetwork(stuff, sizeof stuff, 0); 53131864Sminshall DataToNetwork(buffer, count, 1); 53231864Sminshall } 53331864Sminshall 53431864Sminshall 53530015Sminshall /* Try to send some data to host */ 53630015Sminshall 53730015Sminshall void 53830015Sminshall SendToIBM() 53930015Sminshall { 54030076Sminshall #if !defined(PURE3274) 54131864Sminshall if (TransparentClock >= OutputClock) { 54230015Sminshall if (HadAid) { 54330015Sminshall AddChar(AidByte); 54430015Sminshall HadAid = 0; 54530015Sminshall } else { 54630015Sminshall AddChar(AID_NONE_PRINTER); 54730015Sminshall } 54830015Sminshall do { 54930015Sminshall ourPTail += DataToNetwork(ourPTail, ourPHead-ourPTail, 1); 55030015Sminshall } while (!EmptyChar()); 55130015Sminshall FlushChar(); 55230015Sminshall } else if (HadAid) { 55330015Sminshall DoReadModified(CMD_READ_MODIFIED); 55430015Sminshall } 55530076Sminshall #else /* !defined(PURE3274) */ 55630076Sminshall if (HadAid) { 55730076Sminshall DoReadModified(CMD_READ_MODIFIED); 55830076Sminshall } 55930076Sminshall #endif /* !defined(PURE3274) */ 56030015Sminshall } 56130015Sminshall 56230015Sminshall /* This takes in one character from the keyboard and places it on the 56330015Sminshall * screen. 56430015Sminshall */ 56530015Sminshall 56630015Sminshall static void 56730015Sminshall OneCharacter(c, insert) 56830015Sminshall int c; /* character (Ebcdic) to be shoved in */ 56930015Sminshall int insert; /* are we in insert mode? */ 57030015Sminshall { 57130015Sminshall register int i, j; 57230015Sminshall 57330015Sminshall if (IsProtected(CursorAddress)) { 57430015Sminshall RingBell("Protected Field"); 57530015Sminshall return; 57630015Sminshall } 57730015Sminshall if (insert) { 57830015Sminshall /* is the last character in the field a blank or null? */ 57930015Sminshall i = ScreenDec(FieldInc(CursorAddress)); 58030015Sminshall j = GetHost(i); 58130015Sminshall if (!Disspace(j)) { 58230015Sminshall RingBell("No more room for insert"); 58330015Sminshall return; 58430015Sminshall } else { 58530015Sminshall for (j = ScreenDec(i); i != CursorAddress; 58630015Sminshall j = ScreenDec(j), i = ScreenDec(i)) { 58730015Sminshall AddHost(i, GetHost(j)); 58830015Sminshall } 58930015Sminshall } 59030015Sminshall } 59130015Sminshall AddHost(CursorAddress, c); 59230015Sminshall TurnOnMdt(CursorAddress); 59330015Sminshall CursorAddress = ScreenInc(CursorAddress); 59430015Sminshall if (IsStartField(CursorAddress) && 59530015Sminshall ((FieldAttributes(CursorAddress)&ATTR_AUTO_SKIP_MASK) == 59630015Sminshall ATTR_AUTO_SKIP_VALUE)) { 59730015Sminshall Tab(); 59830015Sminshall } 59930015Sminshall } 60030015Sminshall 60131197Sminshall /* 60231197Sminshall * AcceptKeystroke() 60331197Sminshall * 60431197Sminshall * Processes one keystroke. 60531197Sminshall * 60631197Sminshall * Returns: 60731197Sminshall * 60831197Sminshall * 0 if this keystroke was NOT processed. 60931197Sminshall * 1 if everything went OK. 61031197Sminshall */ 61130015Sminshall 61230015Sminshall int 61331197Sminshall AcceptKeystroke(scancode, shiftstate) 61431197Sminshall int 61531197Sminshall scancode, /* 3270 scancode */ 61631197Sminshall shiftstate; /* The shift state */ 61730015Sminshall { 61830015Sminshall register int c; 61930015Sminshall register int i; 62030015Sminshall register int j; 62130076Sminshall enum ctlrfcn ctlrfcn; 62230015Sminshall 62331197Sminshall if (scancode >= numberof(hits)) { 62431085Sminshall ExitString(stderr, 62531197Sminshall "Unknown scancode encountered in AcceptKeystroke.\n", 1); 62630015Sminshall /*NOTREACHED*/ 62730015Sminshall } 62831197Sminshall ctlrfcn = hits[scancode].hit[HITNUM(shiftstate)].ctlrfcn; 62931197Sminshall c = hits[scancode].hit[HITNUM(shiftstate)].code; 63030015Sminshall 63130015Sminshall if (!UnLocked || HadAid) { 63230015Sminshall if (HadAid) { 63330015Sminshall SendToIBM(); 63430015Sminshall if (!EmptyChar()) { 63531197Sminshall return 0; /* nothing to do */ 63630015Sminshall } 63730015Sminshall } 63830327Sminshall #if !defined(PURE3274) 63930015Sminshall if (!HadAid && EmptyChar()) { 64030076Sminshall if ((ctlrfcn == FCN_RESET) || (ctlrfcn == FCN_MASTER_RESET)) { 64130015Sminshall UnLocked = 1; 64230015Sminshall } 64330015Sminshall } 64430327Sminshall #endif /* !defined(PURE3274) */ 64530015Sminshall if (!UnLocked) { 64631197Sminshall return 0; 64730015Sminshall } 64830015Sminshall } 64931864Sminshall 65030015Sminshall /* now, either empty, or haven't seen aid yet */ 65130015Sminshall 65230076Sminshall #if !defined(PURE3274) 65331864Sminshall /* 65431864Sminshall * If we are in transparent (output) mode, do something special 65531864Sminshall * with keystrokes. 65631864Sminshall */ 65730015Sminshall if (TransparentClock == OutputClock) { 65831197Sminshall if (ctlrfcn == FCN_AID) { 65931197Sminshall UnLocked = 0; 66031197Sminshall InsertMode = 0; 66131197Sminshall AidByte = (c); 66231197Sminshall HadAid = 1; 66331197Sminshall } else { 66431197Sminshall switch (ctlrfcn) { 66531197Sminshall case FCN_ESCAPE: 66631197Sminshall StopScreen(1); 66731197Sminshall command(0); 66831476Sminshall if (shell_active == 0) { 66931476Sminshall ConnectScreen(); 67031476Sminshall } 67131197Sminshall break; 67230015Sminshall 67331197Sminshall case FCN_RESET: 67431197Sminshall case FCN_MASTER_RESET: 67531197Sminshall UnLocked = 1; 67631197Sminshall break; 67730015Sminshall 67831197Sminshall default: 67931197Sminshall return 0; 68030015Sminshall } 68130015Sminshall } 68230015Sminshall } 68330076Sminshall #endif /* !defined(PURE3274) */ 68430015Sminshall 68531197Sminshall if (ctlrfcn == FCN_CHARACTER) { 68631197Sminshall /* Add the character to the buffer */ 68731197Sminshall OneCharacter(c, InsertMode); 68831197Sminshall } else if (ctlrfcn == FCN_AID) { /* got Aid */ 68931197Sminshall if (c == AID_CLEAR) { 69031197Sminshall LocalClearScreen(); /* Side effect is to clear 3270 */ 69130015Sminshall } 69231197Sminshall ResetOiaOnlineA(&OperatorInformationArea); 69331197Sminshall SetOiaTWait(&OperatorInformationArea); 69431197Sminshall ResetOiaInsert(&OperatorInformationArea); 69531197Sminshall InsertMode = 0; /* just like a 3278 */ 69631197Sminshall SetOiaSystemLocked(&OperatorInformationArea); 69731197Sminshall SetOiaModified(); 69831197Sminshall UnLocked = 0; 69931197Sminshall AidByte = c; 70031197Sminshall HadAid = 1; 70131197Sminshall SendToIBM(); 70231197Sminshall } else { 70331197Sminshall switch (ctlrfcn) { 70430015Sminshall 70531197Sminshall case FCN_CURSEL: 70631197Sminshall c = FieldAttributes(CursorAddress)&ATTR_DSPD_MASK; 70731197Sminshall if (!FormattedScreen() 70831197Sminshall || ((c != ATTR_DSPD_DSPD) && (c != ATTR_DSPD_HIGH))) { 70931197Sminshall RingBell("Cursor not in selectable field"); 71031197Sminshall } else { 71131197Sminshall i = ScreenInc(WhereAttrByte(CursorAddress)); 71231197Sminshall c = GetHost(i); 71331197Sminshall if (c == DISP_QUESTION) { 71431197Sminshall AddHost(i, DISP_GREATER_THAN); 71531197Sminshall TurnOnMdt(i); 71631197Sminshall } else if (c == DISP_GREATER_THAN) { 71731197Sminshall AddHost(i, DISP_QUESTION); 71831197Sminshall TurnOffMdt(i); 71931197Sminshall } else if (c == DISP_BLANK || c == DISP_NULL 72031197Sminshall || c == DISP_AMPERSAND) { 72131197Sminshall UnLocked = 0; 72231197Sminshall InsertMode = 0; 72331197Sminshall ResetOiaOnlineA(&OperatorInformationArea); 72431197Sminshall SetOiaTWait(&OperatorInformationArea); 72531197Sminshall SetOiaSystemLocked(&OperatorInformationArea); 72631197Sminshall ResetOiaInsert(&OperatorInformationArea); 72731197Sminshall SetOiaModified(); 72831197Sminshall if (c == DISP_AMPERSAND) { 72931197Sminshall TurnOnMdt(i); /* Only for & type */ 73031197Sminshall AidByte = AID_ENTER; 73130015Sminshall } else { 73231197Sminshall AidByte = AID_SELPEN; 73330015Sminshall } 73431197Sminshall HadAid = 1; 73531197Sminshall SendToIBM(); 73631197Sminshall } else { 73731197Sminshall RingBell( 73831197Sminshall "Cursor not in a selectable field (designator)"); 73930015Sminshall } 74031197Sminshall } 74131197Sminshall break; 74230015Sminshall 74330327Sminshall #if !defined(PURE3274) 74431197Sminshall case FCN_ERASE: 74531197Sminshall if (IsProtected(ScreenDec(CursorAddress))) { 74631197Sminshall RingBell("Protected Field"); 74731197Sminshall } else { 74831197Sminshall CursorAddress = ScreenDec(CursorAddress); 74931197Sminshall Delete(CursorAddress, ScreenInc(CursorAddress)); 75031197Sminshall } 75131197Sminshall break; 75231197Sminshall case FCN_WERASE: 75331197Sminshall j = CursorAddress; 75431197Sminshall i = ScreenDec(j); 75531197Sminshall if (IsProtected(i)) { 75631197Sminshall RingBell("Protected Field"); 75731197Sminshall } else { 75831197Sminshall SetXIsProtected(); 75931197Sminshall while ((!XIsProtected(i) && Disspace(GetHost(i))) 76031197Sminshall && (i != j)) { 76131197Sminshall i = ScreenDec(i); 76230015Sminshall } 76331197Sminshall /* we are pointing at a character in a word, or 76431197Sminshall * at a protected position 76531197Sminshall */ 76631197Sminshall while ((!XIsProtected(i) && !Disspace(GetHost(i))) 76731197Sminshall && (i != j)) { 76831197Sminshall i = ScreenDec(i); 76930015Sminshall } 77031197Sminshall /* we are pointing at a space, or at a protected 77131197Sminshall * position 77231197Sminshall */ 77331197Sminshall CursorAddress = ScreenInc(i); 77431197Sminshall Delete(CursorAddress, j); 77531197Sminshall } 77631197Sminshall break; 77730015Sminshall 77831197Sminshall case FCN_FERASE: 77931197Sminshall if (IsProtected(CursorAddress)) { 78031197Sminshall RingBell("Protected Field"); 78131197Sminshall } else { 78231197Sminshall CursorAddress = ScreenInc(CursorAddress); /* for btab */ 78331197Sminshall BackTab(); 78431197Sminshall EraseEndOfField(); 78531197Sminshall } 78631197Sminshall break; 78730015Sminshall 78831197Sminshall case FCN_RESET: 78931197Sminshall if (InsertMode) { 79031197Sminshall InsertMode = 0; 79131197Sminshall ResetOiaInsert(&OperatorInformationArea); 79231197Sminshall SetOiaModified(); 79331197Sminshall } 79431197Sminshall break; 79531197Sminshall case FCN_MASTER_RESET: 79631197Sminshall if (InsertMode) { 79731197Sminshall InsertMode = 0; 79831197Sminshall ResetOiaInsert(&OperatorInformationArea); 79931197Sminshall SetOiaModified(); 80031197Sminshall } 80131197Sminshall RefreshScreen(); 80231197Sminshall break; 80330327Sminshall #endif /* !defined(PURE3274) */ 80430015Sminshall 80531197Sminshall case FCN_UP: 80631197Sminshall CursorAddress = ScreenUp(CursorAddress); 80731197Sminshall break; 80830015Sminshall 80931197Sminshall case FCN_LEFT: 81031197Sminshall CursorAddress = ScreenDec(CursorAddress); 81131197Sminshall break; 81230015Sminshall 81331197Sminshall case FCN_RIGHT: 81431197Sminshall CursorAddress = ScreenInc(CursorAddress); 81531197Sminshall break; 81630015Sminshall 81731197Sminshall case FCN_DOWN: 81831197Sminshall CursorAddress = ScreenDown(CursorAddress); 81931197Sminshall break; 82030015Sminshall 82131197Sminshall case FCN_DELETE: 82231197Sminshall if (IsProtected(CursorAddress)) { 82331197Sminshall RingBell("Protected Field"); 82431197Sminshall } else { 82531197Sminshall Delete(CursorAddress, ScreenInc(CursorAddress)); 82631197Sminshall } 82731197Sminshall break; 82831197Sminshall 82931197Sminshall case FCN_INSRT: 83031197Sminshall InsertMode = !InsertMode; 83131197Sminshall if (InsertMode) { 83231197Sminshall SetOiaInsert(&OperatorInformationArea); 83331197Sminshall } else { 83431197Sminshall ResetOiaInsert(&OperatorInformationArea); 83531197Sminshall } 83631197Sminshall SetOiaModified(); 83731197Sminshall break; 83831197Sminshall 83931197Sminshall case FCN_HOME: 84031197Sminshall Home(); 84131197Sminshall break; 84231197Sminshall 84331197Sminshall case FCN_NL: 84431197Sminshall /* The algorithm is to look for the first unprotected 84531197Sminshall * column after column 0 of the following line. Having 84631197Sminshall * found that unprotected column, we check whether the 84731197Sminshall * cursor-address-at-entry is at or to the right of the 84831197Sminshall * LeftMargin AND the LeftMargin column of the found line 84931197Sminshall * is unprotected. If this conjunction is true, then 85031197Sminshall * we set the found pointer to the address of the LeftMargin 85131197Sminshall * column in the found line. 85231197Sminshall * Then, we set the cursor address to the found address. 85331197Sminshall */ 85431197Sminshall i = SetBufferAddress(ScreenLine(ScreenDown(CursorAddress)), 0); 85531197Sminshall j = ScreenInc(WhereAttrByte(CursorAddress)); 85631197Sminshall do { 85731197Sminshall if (IsUnProtected(i)) { 85831197Sminshall break; 85930015Sminshall } 86031197Sminshall /* Again (see comment in Home()), this COULD be a problem 86131197Sminshall * with an unformatted screen. 86231197Sminshall */ 86331197Sminshall /* If there was a field with only an attribute byte, 86431197Sminshall * we may be pointing to the attribute byte of the NEXT 86531197Sminshall * field, so just look at the next byte. 86631197Sminshall */ 86731197Sminshall if (IsStartField(i)) { 86831197Sminshall i = ScreenInc(i); 86931192Sminshall } else { 87031197Sminshall i = ScreenInc(FieldInc(i)); 87131192Sminshall } 87231197Sminshall } while (i != j); 87331197Sminshall if (!IsUnProtected(i)) { /* couldn't find unprotected */ 87431197Sminshall i = SetBufferAddress(0,0); 87531197Sminshall } 87631197Sminshall if (OptLeftMargin <= ScreenLineOffset(CursorAddress)) { 87731197Sminshall if (IsUnProtected(SetBufferAddress(ScreenLine(i), 87831197Sminshall OptLeftMargin))) { 87931197Sminshall i = SetBufferAddress(ScreenLine(i), OptLeftMargin); 88031197Sminshall } 88131197Sminshall } 88231197Sminshall CursorAddress = i; 88331197Sminshall break; 88430015Sminshall 88531197Sminshall case FCN_EINP: 88631197Sminshall if (!FormattedScreen()) { 88731197Sminshall i = CursorAddress; 88831197Sminshall TurnOffMdt(i); 88930015Sminshall do { 89031197Sminshall AddHost(i, 0); 89131197Sminshall i = ScreenInc(i); 89231197Sminshall } while (i != CursorAddress); 89331197Sminshall } else { 89431197Sminshall /* 89531197Sminshall * The algorithm is: go through each unprotected 89631197Sminshall * field on the screen, clearing it out. When 89731197Sminshall * we are at the start of a field, skip that field 89831197Sminshall * if its contents are protected. 89930015Sminshall */ 90031197Sminshall i = j = FieldInc(CursorAddress); 90131197Sminshall do { 90231197Sminshall if (IsUnProtected(ScreenInc(i))) { 90330015Sminshall i = ScreenInc(i); 90431197Sminshall TurnOffMdt(i); 90531197Sminshall do { 90631197Sminshall AddHost(i, 0); 90731197Sminshall i = ScreenInc(i); 90831197Sminshall } while (!IsStartField(i)); 90930015Sminshall } else { 91031197Sminshall i = FieldInc(i); 91130015Sminshall } 91230015Sminshall } while (i != j); 91331197Sminshall } 91431197Sminshall Home(); 91531197Sminshall break; 91630015Sminshall 91731197Sminshall case FCN_EEOF: 91831197Sminshall EraseEndOfField(); 91931197Sminshall break; 92030015Sminshall 92131197Sminshall case FCN_SPACE: 92231197Sminshall OneCharacter(DISP_BLANK, InsertMode); /* Add cent */ 92331197Sminshall break; 92430015Sminshall 92531197Sminshall case FCN_CENTSIGN: 92631197Sminshall OneCharacter(DISP_CENTSIGN, InsertMode); /* Add cent */ 92731197Sminshall break; 92830015Sminshall 92931197Sminshall case FCN_FM: 93031197Sminshall OneCharacter(DISP_FM, InsertMode); /* Add field mark */ 93131197Sminshall break; 93230015Sminshall 93331197Sminshall case FCN_DP: 93431197Sminshall if (IsProtected(CursorAddress)) { 93531197Sminshall RingBell("Protected Field"); 93631197Sminshall } else { 93731197Sminshall OneCharacter(DISP_DUP, InsertMode);/* Add dup character */ 93831197Sminshall Tab(); 93931197Sminshall } 94031197Sminshall break; 94130015Sminshall 94231197Sminshall case FCN_TAB: 94331197Sminshall Tab(); 94431197Sminshall break; 94530015Sminshall 94631197Sminshall case FCN_BTAB: 94731197Sminshall BackTab(); 94831197Sminshall break; 94930015Sminshall 95030015Sminshall #ifdef NOTUSED /* Actually, this is superseded by unix flow 95131197Sminshall * control. 95231197Sminshall */ 95331197Sminshall case FCN_XOFF: 95431197Sminshall Flow = 0; /* stop output */ 95531197Sminshall break; 95630015Sminshall 95731197Sminshall case FCN_XON: 95831197Sminshall if (!Flow) { 95931197Sminshall Flow = 1; /* turn it back on */ 96031197Sminshall DoTerminalOutput(); 96131197Sminshall } 96231197Sminshall break; 96330015Sminshall #endif /* NOTUSED */ 96430015Sminshall 96530327Sminshall #if !defined(PURE3274) 96631197Sminshall case FCN_ESCAPE: 96731197Sminshall /* FlushChar(); do we want to flush characters from before? */ 96831197Sminshall StopScreen(1); 96931197Sminshall command(0); 97031476Sminshall if (shell_active == 0) { 97131476Sminshall ConnectScreen(); 97231476Sminshall } 97331197Sminshall break; 97430015Sminshall 97531197Sminshall case FCN_DISC: 97631197Sminshall StopScreen(1); 97731197Sminshall suspend(); 97831197Sminshall setconnmode(); 97931197Sminshall ConnectScreen(); 98031197Sminshall break; 98130015Sminshall 98231197Sminshall case FCN_RESHOW: 98331197Sminshall RefreshScreen(); 98431197Sminshall break; 98530015Sminshall 98631197Sminshall case FCN_SETTAB: 98731197Sminshall OptColTabs[ScreenLineOffset(CursorAddress)] = 1; 98831197Sminshall break; 98930015Sminshall 99031197Sminshall case FCN_DELTAB: 99131197Sminshall OptColTabs[ScreenLineOffset(CursorAddress)] = 0; 99231197Sminshall break; 99330015Sminshall 99431197Sminshall /* 99531197Sminshall * Clear all tabs, home line, and left margin. 99631197Sminshall */ 99731197Sminshall case FCN_CLRTAB: 99831197Sminshall for (i = 0; i < sizeof OptColTabs; i++) { 99931197Sminshall OptColTabs[i] = 0; 100031197Sminshall } 100131197Sminshall OptHome = 0; 100231197Sminshall OptLeftMargin = 0; 100331197Sminshall break; 100430015Sminshall 100531197Sminshall case FCN_COLTAB: 100631197Sminshall ColTab(); 100731197Sminshall break; 100830015Sminshall 100931197Sminshall case FCN_COLBAK: 101031197Sminshall ColBak(); 101131197Sminshall break; 101230015Sminshall 101331197Sminshall case FCN_INDENT: 101431197Sminshall ColTab(); 101531197Sminshall OptLeftMargin = ScreenLineOffset(CursorAddress); 101631197Sminshall break; 101730015Sminshall 101831197Sminshall case FCN_UNDENT: 101931197Sminshall ColBak(); 102031197Sminshall OptLeftMargin = ScreenLineOffset(CursorAddress); 102131197Sminshall break; 102230015Sminshall 102331197Sminshall case FCN_SETMRG: 102431197Sminshall OptLeftMargin = ScreenLineOffset(CursorAddress); 102531197Sminshall break; 102630015Sminshall 102731197Sminshall case FCN_SETHOM: 102831197Sminshall OptHome = ScreenLine(CursorAddress); 102931197Sminshall break; 103030015Sminshall 103131197Sminshall /* 103231197Sminshall * Point to first character of next unprotected word on 103331197Sminshall * screen. 103431197Sminshall */ 103531197Sminshall case FCN_WORDTAB: 103631197Sminshall i = CursorAddress; 103731197Sminshall SetXIsProtected(); 103831197Sminshall while (!XIsProtected(i) && !Disspace(GetHost(i))) { 103931197Sminshall i = ScreenInc(i); 104031197Sminshall if (i == CursorAddress) { 104131197Sminshall break; 104230015Sminshall } 104331197Sminshall } 104431197Sminshall /* i is either protected, a space (blank or null), 104531197Sminshall * or wrapped 104631197Sminshall */ 104731197Sminshall while (XIsProtected(i) || Disspace(GetHost(i))) { 104831197Sminshall i = ScreenInc(i); 104931197Sminshall if (i == CursorAddress) { 105031197Sminshall break; 105130015Sminshall } 105231197Sminshall } 105331197Sminshall CursorAddress = i; 105431197Sminshall break; 105530015Sminshall 105631197Sminshall case FCN_WORDBACKTAB: 105731197Sminshall i = ScreenDec(CursorAddress); 105831197Sminshall SetXIsProtected(); 105931197Sminshall while (XIsProtected(i) || Disspace(GetHost(i))) { 106031197Sminshall i = ScreenDec(i); 106131197Sminshall if (i == CursorAddress) { 106231197Sminshall break; 106330015Sminshall } 106431197Sminshall } 106531197Sminshall /* i is pointing to a character IN an unprotected word 106631197Sminshall * (or i wrapped) 106731197Sminshall */ 106831197Sminshall while (!Disspace(GetHost(i))) { 106931197Sminshall i = ScreenDec(i); 107031197Sminshall if (i == CursorAddress) { 107131197Sminshall break; 107230015Sminshall } 107331197Sminshall } 107431197Sminshall CursorAddress = ScreenInc(i); 107531197Sminshall break; 107630015Sminshall 107731197Sminshall /* Point to last non-blank character of this/next 107831197Sminshall * unprotected word. 107931197Sminshall */ 108031197Sminshall case FCN_WORDEND: 108131197Sminshall i = ScreenInc(CursorAddress); 108231197Sminshall SetXIsProtected(); 108331197Sminshall while (XIsProtected(i) || Disspace(GetHost(i))) { 108431197Sminshall i = ScreenInc(i); 108531197Sminshall if (i == CursorAddress) { 108631197Sminshall break; 108730015Sminshall } 108831197Sminshall } 108931197Sminshall /* we are pointing at a character IN an 109031197Sminshall * unprotected word (or we wrapped) 109131197Sminshall */ 109231197Sminshall while (!Disspace(GetHost(i))) { 109331197Sminshall i = ScreenInc(i); 109431197Sminshall if (i == CursorAddress) { 109531197Sminshall break; 109630015Sminshall } 109731197Sminshall } 109831197Sminshall CursorAddress = ScreenDec(i); 109931197Sminshall break; 110030015Sminshall 110131197Sminshall /* Get to last non-blank of this/next unprotected 110231197Sminshall * field. 110331197Sminshall */ 110431197Sminshall case FCN_FIELDEND: 110531197Sminshall i = LastOfField(CursorAddress); 110631197Sminshall if (i != CursorAddress) { 110731197Sminshall CursorAddress = i; /* We moved; take this */ 110831197Sminshall } else { 110931197Sminshall j = FieldInc(CursorAddress); /* Move to next field */ 111031197Sminshall i = LastOfField(j); 111131197Sminshall if (i != j) { 111231197Sminshall CursorAddress = i; /* We moved; take this */ 111330015Sminshall } 111431197Sminshall /* else - nowhere else on screen to be; stay here */ 111531197Sminshall } 111631197Sminshall break; 111730327Sminshall #endif /* !defined(PURE3274) */ 111830015Sminshall 111931197Sminshall default: 112031197Sminshall /* We don't handle this yet */ 112131197Sminshall RingBell("Function not implemented"); 112231197Sminshall } 112331197Sminshall } 112431197Sminshall return 1; /* We did something! */ 112531197Sminshall } 112631197Sminshall 112731197Sminshall 112831197Sminshall /* 112931197Sminshall * We get data from the terminal. We keep track of the shift state 113031197Sminshall * (including ALT, CONTROL), and then call AcceptKeystroke to actually 113131197Sminshall * process any non-shift keys. 113231197Sminshall */ 113331197Sminshall 113431197Sminshall int 113531197Sminshall DataFrom3270(buffer, count) 113631197Sminshall unsigned char *buffer; /* where the data is */ 113731197Sminshall int count; /* how much data there is */ 113831197Sminshall { 113931197Sminshall int origCount; 114031197Sminshall 114131197Sminshall origCount = count; 114231197Sminshall 114331197Sminshall while (count) { 114431197Sminshall if (*buffer >= numberof(hits)) { 114531197Sminshall ExitString(stderr, 114631197Sminshall "Unknown scancode encountered in DataFrom3270.\n", 1); 114731197Sminshall /*NOTREACHED*/ 114831197Sminshall } 114931197Sminshall 115031197Sminshall switch (hits[*buffer].hit[HITNUM(rememberedshiftstate)].ctlrfcn) { 115131197Sminshall 115231197Sminshall case FCN_MAKE_SHIFT: 115331197Sminshall rememberedshiftstate |= (SHIFT_RIGHT|SHIFT_UPSHIFT); 115431197Sminshall break; 115531197Sminshall case FCN_BREAK_SHIFT: 115631197Sminshall rememberedshiftstate &= ~(SHIFT_RIGHT|SHIFT_UPSHIFT); 115731197Sminshall break; 115831197Sminshall case FCN_MAKE_ALT: 115931197Sminshall rememberedshiftstate |= SHIFT_ALT; 116031197Sminshall break; 116131197Sminshall case FCN_BREAK_ALT: 116231197Sminshall rememberedshiftstate &= ~SHIFT_ALT; 116331197Sminshall break; 116431197Sminshall default: 116531197Sminshall if (AcceptKeystroke(*buffer, rememberedshiftstate) == 0) { 116631197Sminshall return(origCount-count); 116730015Sminshall } 116831197Sminshall break; 116930015Sminshall } 117031197Sminshall buffer++; 117131197Sminshall count--; 117230015Sminshall } 117330015Sminshall return(origCount-count); 117430015Sminshall } 1175