130015Sminshall /* 2*33816Sbostic * Copyright (c) 1988 Regents of the University of California. 3*33816Sbostic * All rights reserved. 430015Sminshall * 5*33816Sbostic * Redistribution and use in source and binary forms are permitted 6*33816Sbostic * provided that this notice is preserved and that due credit is given 7*33816Sbostic * to the University of California at Berkeley. The name of the University 8*33816Sbostic * may not be used to endorse or promote products derived from this 9*33816Sbostic * software without specific prior written permission. This software 10*33816Sbostic * is provided ``as is'' without express or implied warranty. 1130015Sminshall */ 1230015Sminshall 13*33816Sbostic #ifndef lint 14*33816Sbostic static char sccsid[] = "@(#)inbound.c 3.3 (Berkeley) 03/28/88"; 15*33816Sbostic #endif /* not lint */ 1631085Sminshall #include <stdio.h> 1731085Sminshall 1831177Sminshall #include "../general/general.h" 1930015Sminshall #include "function.h" 2030015Sminshall #include "hostctlr.h" 2131192Sminshall #include "oia.h" 2230015Sminshall #include "scrnctlr.h" 2330015Sminshall #include "screen.h" 2430015Sminshall #include "options.h" 2531871Sminshall #include "../api/dctype.h" 2631871Sminshall #include "../api/ebc_disp.h" 2730015Sminshall 2831177Sminshall #include "../general/globals.h" 2930015Sminshall #include "inbound.ext" 3030015Sminshall #include "outbound.ext" 3130015Sminshall #include "../telnet.ext" 3230015Sminshall 3330015Sminshall #define EmptyChar() (ourPTail == ourPHead) 3430015Sminshall #define FullChar() (ourPHead == ourBuffer+sizeof ourBuffer) 3530015Sminshall 3630015Sminshall 3730015Sminshall /* 3830015Sminshall * We define something to allow us to to IsProtected() quickly 3930015Sminshall * on unformatted screens (with the current algorithm for fields, 4030015Sminshall * unprotected takes exponential time...). 4130015Sminshall * 4230015Sminshall * The idea is to call SetXIsProtected() BEFORE the 4330015Sminshall * loop, then use XIsProtected(). 4430015Sminshall */ 4530015Sminshall 4630361Sminshall #define SetXIsProtected() (XWasSF = 1) 4730361Sminshall #define XIsProtected(p) (IsStartField(p)? \ 4830361Sminshall XWasSF = 1 : \ 4930361Sminshall (XWasSF? \ 5030361Sminshall (XWasSF = 0, XProtected = IsProtected(p)) : \ 5130361Sminshall XProtected)) 5230015Sminshall 5330015Sminshall static char ourBuffer[400]; 5430015Sminshall 5530015Sminshall static char *ourPHead = ourBuffer, 5630015Sminshall *ourPTail = ourBuffer; 5730015Sminshall 5830327Sminshall static int HadAid; /* Had an AID haven't sent */ 5930015Sminshall 6030327Sminshall static int InsertMode; /* is the terminal in insert mode? */ 6130327Sminshall 6231197Sminshall static int rememberedshiftstate; /* Shift (alt) state of terminal */ 6331197Sminshall # define HITNUM(s) ((((s)&(SHIFT_CAPS|SHIFT_UPSHIFT))? 1:0) \ 6431197Sminshall + ((((s)&SHIFT_ALT)? 1:0)<<1)) 6531197Sminshall 6630361Sminshall static int XWasSF, XProtected; /* For optimizations */ 6730076Sminshall #if !defined(PURE3274) 6830076Sminshall extern int TransparentClock, OutputClock; 6930076Sminshall #endif /* !defined(PURE3274) */ 7030076Sminshall 7130327Sminshall #include "kbd.out" /* Get keyboard mapping function */ 7230015Sminshall 7330015Sminshall /* the following are global variables */ 7430015Sminshall 7530015Sminshall extern int UnLocked; /* keyboard is UnLocked? */ 7630015Sminshall 7730724Sminshall 7830724Sminshall /* 7930724Sminshall * init_inbound : 8030724Sminshall * 8130724Sminshall * Reset variables to initial state. 8230724Sminshall */ 8330724Sminshall 8430724Sminshall void 8530724Sminshall init_inbound() 8630724Sminshall { 8730724Sminshall ourPHead = ourPTail = ourBuffer; 8830724Sminshall HadAid = 0; 8931197Sminshall rememberedshiftstate = 0; 9030724Sminshall InsertMode = 0; 9130724Sminshall } 9230724Sminshall 9330724Sminshall 9430015Sminshall /* Tab() - sets cursor to the start of the next unprotected field */ 9530015Sminshall static void 9630015Sminshall Tab() 9730015Sminshall { 9830015Sminshall register int i, j; 9930015Sminshall 10030015Sminshall i = CursorAddress; 10130015Sminshall j = WhereAttrByte(CursorAddress); 10230015Sminshall do { 10330015Sminshall if (IsStartField(i) && IsUnProtected(ScreenInc(i))) { 10430015Sminshall break; 10530015Sminshall } 10630015Sminshall i = FieldInc(i); 10730015Sminshall } while (i != j); 10830015Sminshall if (IsStartField(i) && IsUnProtected(ScreenInc(i))) { 10930015Sminshall CursorAddress = ScreenInc(i); 11030015Sminshall } else { 11130015Sminshall CursorAddress = SetBufferAddress(0,0); 11230015Sminshall } 11330015Sminshall } 11430015Sminshall 11530015Sminshall 11630015Sminshall /* BackTab() - sets cursor to the start of the most recent field */ 11730015Sminshall 11830015Sminshall static void 11930015Sminshall BackTab() 12030015Sminshall { 12130015Sminshall register int i; 12230015Sminshall 12330015Sminshall i = ScreenDec(CursorAddress); 12430015Sminshall for (;;) { 12530015Sminshall if (IsStartField(ScreenDec(i)) && IsUnProtected(i)) { 12630015Sminshall CursorAddress = i; 12730015Sminshall break; 12830015Sminshall } 12930015Sminshall if (i == CursorAddress) { 13030015Sminshall CursorAddress = SetBufferAddress(0,0); 13130015Sminshall break; 13230015Sminshall } 13330015Sminshall i = ScreenDec(i); 13430015Sminshall } 13530015Sminshall } 13630015Sminshall 13733752Sminshall /* 13833752Sminshall * ModifyMdt() - Turn a modified data tag bit on or off (watch 13933752Sminshall * out for unformatted screens). 14033752Sminshall */ 14130015Sminshall 14233752Sminshall ModifyMdt(x,on) 14333752Sminshall int x; 14433752Sminshall int on; 14533752Sminshall { 14633752Sminshall int i = x; 14733752Sminshall 14833752Sminshall if (IsStartField(i)) { /* If we are at a start field position... */ 14933752Sminshall if (on) { 15033752Sminshall ModifyHost(i, |= ATTR_MDT); /* Turn it on */ 15133752Sminshall } else { 15233752Sminshall ModifyHost(i, &= ~ATTR_MDT); /* Turn it off */ 15333752Sminshall } 15433752Sminshall } else { 15533752Sminshall i = WhereAttrByte(i); /* Find beginning of field */ 15633752Sminshall if (IsStartField(i)) { /* Is there one? */ 15733752Sminshall if (on) { 15833752Sminshall ModifyHost(i, |= ATTR_MDT); /* Turn it on */ 15933752Sminshall } else { 16033752Sminshall ModifyHost(i, &= ~ATTR_MDT); /* Turn it off */ 16133752Sminshall } 16233752Sminshall } /* else, don't modify - this is an unformatted screen */ 16333752Sminshall } 16433752Sminshall } 16533752Sminshall 16633752Sminshall 16730015Sminshall /* EraseEndOfField - erase all characters to the end of a field */ 16830015Sminshall 16930015Sminshall static void 17030015Sminshall EraseEndOfField() 17130015Sminshall { 17230015Sminshall register int i; 17330015Sminshall 17430015Sminshall if (IsProtected(CursorAddress)) { 17530015Sminshall RingBell("Protected Field"); 17630015Sminshall } else { 17730015Sminshall TurnOnMdt(CursorAddress); 17830015Sminshall if (FormattedScreen()) { 17930015Sminshall i = CursorAddress; 18030015Sminshall do { 18130015Sminshall AddHost(i, 0); 18230015Sminshall i = ScreenInc(i); 18330015Sminshall } while ((i != CursorAddress) && !IsStartField(i)); 18430015Sminshall } else { /* Screen is Unformatted */ 18530015Sminshall i = CursorAddress; 18630015Sminshall do { 18730015Sminshall AddHost(i, 0); 18830015Sminshall i = ScreenInc(i); 18930015Sminshall } while (i != HighestScreen()); 19030015Sminshall } 19130015Sminshall } 19230015Sminshall } 19330015Sminshall 19430015Sminshall /* Delete() - deletes a character from the screen 19530015Sminshall * 19630015Sminshall * What we want to do is delete the section 19730015Sminshall * [where, from-1] from the screen, 19830015Sminshall * filling in with what comes at from. 19930015Sminshall * 20030015Sminshall * The deleting continues to the end of the field (or 20130015Sminshall * until the cursor wraps). 20230015Sminshall * 20330015Sminshall * From can be a start of a field. We 20430015Sminshall * check for that. However, there can't be any 20530015Sminshall * fields that start between where and from. 20630015Sminshall * We don't check for that. 20730015Sminshall * 20830015Sminshall * Also, we assume that the protection status of 20930015Sminshall * everything has been checked by the caller. 21030015Sminshall * 21130015Sminshall */ 21230015Sminshall 21330015Sminshall static void 21430015Sminshall Delete(where, from) 21530015Sminshall register int where, /* Where to start deleting from */ 21630015Sminshall from; /* Where to pull back from */ 21730015Sminshall { 21830015Sminshall register int i; 21930015Sminshall 22030015Sminshall TurnOnMdt(where); /* Only do this once in this field */ 22130015Sminshall i = where; 22230015Sminshall do { 22330015Sminshall if (IsStartField(from)) { 22430015Sminshall AddHost(i, 0); /* Stick the edge at the start field */ 22530015Sminshall } else { 22630015Sminshall AddHost(i, GetHost(from)); 22730015Sminshall from = ScreenInc(from); /* Move the edge */ 22830015Sminshall } 22930015Sminshall i = ScreenInc(i); 23030015Sminshall } while ((!IsStartField(i)) && (i != where)); 23130015Sminshall } 23230015Sminshall 23330015Sminshall static void 23430015Sminshall ColBak() 23530015Sminshall { 23630015Sminshall register int i; 23730015Sminshall 23830015Sminshall i = ScreenLineOffset(CursorAddress); 23930015Sminshall for (i = i-1; i >= 0; i--) { 24030015Sminshall if (OptColTabs[i]) { 24130015Sminshall break; 24230015Sminshall } 24330015Sminshall } 24430015Sminshall if (i < 0) { 24530015Sminshall i = 0; 24630015Sminshall } 24730015Sminshall CursorAddress = SetBufferAddress(ScreenLine(CursorAddress), i); 24830015Sminshall } 24930015Sminshall 25030015Sminshall static void 25130015Sminshall ColTab() 25230015Sminshall { 25330015Sminshall register int i; 25430015Sminshall 25530015Sminshall i = ScreenLineOffset(CursorAddress); 25630015Sminshall for (i = i+1; i < NumberColumns; i++) { 25730015Sminshall if (OptColTabs[i]) { 25830015Sminshall break; 25930015Sminshall } 26030015Sminshall } 26130015Sminshall if (i >= NumberColumns) { 26230015Sminshall i = NumberColumns-1; 26330015Sminshall } 26430015Sminshall CursorAddress = SetBufferAddress(ScreenLine(CursorAddress), i); 26530015Sminshall } 26630015Sminshall 26730015Sminshall static void 26830015Sminshall Home() 26930015Sminshall { 27030015Sminshall register int i; 27130015Sminshall register int j; 27230015Sminshall 27330015Sminshall i = SetBufferAddress(OptHome, 0); 27430015Sminshall j = WhereLowByte(i); 27530015Sminshall do { 27630015Sminshall if (IsUnProtected(i)) { 27730015Sminshall CursorAddress = i; 27830015Sminshall return; 27930015Sminshall } 28030015Sminshall /* the following could be a problem if we got here with an 28130015Sminshall * unformatted screen. However, this is "impossible", since 28230015Sminshall * with an unformatted screen, the IsUnProtected(i) above 28330015Sminshall * should be true. 28430015Sminshall */ 28530015Sminshall i = ScreenInc(FieldInc(i)); 28630015Sminshall } while (i != j); 28730015Sminshall CursorAddress = LowestScreen(); 28830015Sminshall } 28930015Sminshall 29030015Sminshall static 29130015Sminshall LastOfField(i) 29230015Sminshall register int i; /* position to start from */ 29330015Sminshall { 29430015Sminshall register int j; 29530015Sminshall register int k; 29630015Sminshall 29730015Sminshall k = j = i; 29830015Sminshall SetXIsProtected(); 29930015Sminshall while (XIsProtected(i) || Disspace(GetHost(i))) { 30030015Sminshall i = ScreenInc(i); 30130015Sminshall if (i == j) { 30230015Sminshall break; 30330015Sminshall } 30430015Sminshall } 30530015Sminshall /* We are now IN a word IN an unprotected field (or wrapped) */ 30630015Sminshall while (!XIsProtected(i)) { 30730015Sminshall if (!Disspace(GetHost(i))) { 30830015Sminshall k = i; 30930015Sminshall } 31030015Sminshall i = ScreenInc(i); 31130015Sminshall if (i == j) { 31230015Sminshall break; 31330015Sminshall } 31430015Sminshall } 31530015Sminshall return(k); 31630015Sminshall } 31730015Sminshall 31830015Sminshall 31930015Sminshall static void 32030015Sminshall FlushChar() 32130015Sminshall { 32230015Sminshall ourPTail = ourPHead = ourBuffer; 32330015Sminshall } 32430015Sminshall 32530015Sminshall 32630015Sminshall /* 32730015Sminshall * Add one EBCDIC (NOT display code) character to the buffer. 32830015Sminshall */ 32930015Sminshall 33030015Sminshall static void 33130015Sminshall AddChar(character) 33230015Sminshall char character; 33330015Sminshall { 33430015Sminshall if (FullChar()) { 33530015Sminshall ourPTail += DataToNetwork(ourPTail, ourPHead-ourPTail, 0); 33630015Sminshall if (EmptyChar()) { 33730015Sminshall FlushChar(); 33830015Sminshall } else { 33930073Sminshall char buffer[100]; 34030073Sminshall 34130073Sminshall sprintf(buffer, "File %s, line %d: No room in network buffer!\n", 34230015Sminshall __FILE__, __LINE__); 34331085Sminshall ExitString(stderr, buffer, 1); 34430073Sminshall /*NOTREACHED*/ 34530015Sminshall } 34630015Sminshall } 34730015Sminshall *ourPHead++ = character; 34830015Sminshall } 34930015Sminshall 35030015Sminshall 35130015Sminshall static void 35230015Sminshall SendUnformatted() 35330015Sminshall { 35430015Sminshall register int i, j; 35530015Sminshall register int Nulls; 35630015Sminshall register int c; 35730015Sminshall 35830015Sminshall /* look for start of field */ 35930015Sminshall Nulls = 0; 36030015Sminshall i = j = LowestScreen(); 36130015Sminshall do { 36230015Sminshall c = GetHost(i); 36330015Sminshall if (c == 0) { 36430015Sminshall Nulls++; 36530015Sminshall } else { 36630015Sminshall while (Nulls) { 36730015Sminshall Nulls--; 36830015Sminshall AddChar(EBCDIC_BLANK); /* put in blanks */ 36930015Sminshall } 37030015Sminshall AddChar(disp_ebc[c]); 37130015Sminshall } 37230015Sminshall i = ScreenInc(i); 37330015Sminshall } while (i != j); 37430015Sminshall } 37530015Sminshall 37630015Sminshall static 37730015Sminshall SendField(i, command) 37830015Sminshall register int i; /* where we saw MDT bit */ 37930015Sminshall int command; /* The command code (type of read) */ 38030015Sminshall { 38130015Sminshall register int j; 38230015Sminshall register int k; 38330015Sminshall register int Nulls; 38430015Sminshall register int c; 38530015Sminshall 38630015Sminshall /* look for start of field */ 38730015Sminshall i = j = WhereLowByte(i); 38830015Sminshall 38930015Sminshall /* On a test_request_read, don't send sba and address */ 39030015Sminshall if ((AidByte != AID_TREQ) 39130015Sminshall || (command == CMD_SNA_READ_MODIFIED_ALL)) { 39230015Sminshall AddChar(ORDER_SBA); /* set start field */ 39330015Sminshall AddChar(BufferTo3270_0(j)); /* set address of this field */ 39430015Sminshall AddChar(BufferTo3270_1(j)); 39530015Sminshall } 39630015Sminshall /* 39730015Sminshall * Only on read_modified_all do we return the contents 39830015Sminshall * of the field when the attention was caused by a 39930015Sminshall * selector pen. 40030015Sminshall */ 40130015Sminshall if ((AidByte != AID_SELPEN) 40230015Sminshall || (command == CMD_SNA_READ_MODIFIED_ALL)) { 40330015Sminshall if (!IsStartField(j)) { 40430015Sminshall Nulls = 0; 40530015Sminshall k = ScreenInc(WhereHighByte(j)); 40630015Sminshall do { 40730015Sminshall c = GetHost(j); 40830015Sminshall if (c == 0) { 40930015Sminshall Nulls++; 41030015Sminshall } else { 41130015Sminshall while (Nulls) { 41230015Sminshall Nulls--; 41330015Sminshall AddChar(EBCDIC_BLANK); /* put in blanks */ 41430015Sminshall } 41530015Sminshall AddChar(disp_ebc[c]); 41630015Sminshall } 41730015Sminshall j = ScreenInc(j); 41830015Sminshall } while ((j != k) && (j != i)); 41930015Sminshall } 42030015Sminshall } else { 42130015Sminshall j = FieldInc(j); 42230015Sminshall } 42330015Sminshall return(j); 42430015Sminshall } 42530015Sminshall 42630015Sminshall /* Various types of reads... */ 42730015Sminshall void 42830015Sminshall DoReadModified(command) 42930015Sminshall int command; /* The command sent */ 43030015Sminshall { 43130015Sminshall register int i, j; 43230015Sminshall 43330015Sminshall if (AidByte) { 43430015Sminshall if (AidByte != AID_TREQ) { 43530015Sminshall AddChar(AidByte); 43630015Sminshall } else { 43730015Sminshall /* Test Request Read header */ 43830015Sminshall AddChar(EBCDIC_SOH); 43930015Sminshall AddChar(EBCDIC_PERCENT); 44030015Sminshall AddChar(EBCDIC_SLASH); 44130015Sminshall AddChar(EBCDIC_STX); 44230015Sminshall } 44330015Sminshall } else { 44430015Sminshall AddChar(AID_NONE); 44530015Sminshall } 44630015Sminshall if (((AidByte != AID_PA1) && (AidByte != AID_PA2) 44730015Sminshall && (AidByte != AID_PA3) && (AidByte != AID_CLEAR)) 44830015Sminshall || (command == CMD_SNA_READ_MODIFIED_ALL)) { 44930015Sminshall if ((AidByte != AID_TREQ) 45030015Sminshall || (command == CMD_SNA_READ_MODIFIED_ALL)) { 45130015Sminshall /* Test request read_modified doesn't give cursor address */ 45230015Sminshall AddChar(BufferTo3270_0(CursorAddress)); 45330015Sminshall AddChar(BufferTo3270_1(CursorAddress)); 45430015Sminshall } 45530015Sminshall i = j = WhereAttrByte(LowestScreen()); 45630015Sminshall /* Is this an unformatted screen? */ 45730015Sminshall if (!IsStartField(i)) { /* yes, handle separate */ 45830015Sminshall SendUnformatted(); 45930015Sminshall } else { 46030015Sminshall do { 46130015Sminshall if (HasMdt(i)) { 46230015Sminshall i = SendField(i, command); 46330015Sminshall } else { 46430015Sminshall i = FieldInc(i); 46530015Sminshall } 46630015Sminshall } while (i != j); 46730015Sminshall } 46830015Sminshall } 46930015Sminshall ourPTail += DataToNetwork(ourPTail, ourPHead-ourPTail, 1); 47030015Sminshall if (EmptyChar()) { 47130015Sminshall FlushChar(); 47230015Sminshall HadAid = 0; /* killed that buffer */ 47330015Sminshall } 47430015Sminshall } 47530015Sminshall 47630015Sminshall /* A read buffer operation... */ 47730015Sminshall 47830015Sminshall void 47930015Sminshall DoReadBuffer() 48030015Sminshall { 48130015Sminshall register int i, j; 48230015Sminshall 48330015Sminshall if (AidByte) { 48430015Sminshall AddChar(AidByte); 48530015Sminshall } else { 48630015Sminshall AddChar(AID_NONE); 48730015Sminshall } 48830015Sminshall AddChar(BufferTo3270_0(CursorAddress)); 48930015Sminshall AddChar(BufferTo3270_1(CursorAddress)); 49030015Sminshall i = j = LowestScreen(); 49130015Sminshall do { 49230015Sminshall if (IsStartField(i)) { 49330015Sminshall AddChar(ORDER_SF); 49430015Sminshall AddChar(BufferTo3270_1(FieldAttributes(i))); 49530015Sminshall } else { 49630015Sminshall AddChar(disp_ebc[GetHost(i)]); 49730015Sminshall } 49830015Sminshall i = ScreenInc(i); 49930015Sminshall } while (i != j); 50030015Sminshall ourPTail += DataToNetwork(ourPTail, ourPHead-ourPTail, 1); 50130015Sminshall if (EmptyChar()) { 50230015Sminshall FlushChar(); 50330015Sminshall HadAid = 0; /* killed that buffer */ 50430015Sminshall } 50530015Sminshall } 50631864Sminshall 50731864Sminshall /* Send some transparent data to the host */ 50831864Sminshall 50931864Sminshall void 51031864Sminshall SendTransparent(buffer, count) 51131864Sminshall char *buffer; 51231864Sminshall int count; 51331864Sminshall { 51431864Sminshall char stuff[3]; 51531864Sminshall 51631864Sminshall stuff[0] = AID_NONE_PRINTER; 51731864Sminshall stuff[1] = BufferTo3270_0(count); 51831864Sminshall stuff[2] = BufferTo3270_1(count); 51931864Sminshall DataToNetwork(stuff, sizeof stuff, 0); 52031864Sminshall DataToNetwork(buffer, count, 1); 52131864Sminshall } 52231864Sminshall 52331864Sminshall 52430015Sminshall /* Try to send some data to host */ 52530015Sminshall 52630015Sminshall void 52730015Sminshall SendToIBM() 52830015Sminshall { 52930076Sminshall #if !defined(PURE3274) 53031864Sminshall if (TransparentClock >= OutputClock) { 53130015Sminshall if (HadAid) { 53230015Sminshall AddChar(AidByte); 53330015Sminshall HadAid = 0; 53430015Sminshall } else { 53530015Sminshall AddChar(AID_NONE_PRINTER); 53630015Sminshall } 53730015Sminshall do { 53830015Sminshall ourPTail += DataToNetwork(ourPTail, ourPHead-ourPTail, 1); 53930015Sminshall } while (!EmptyChar()); 54030015Sminshall FlushChar(); 54130015Sminshall } else if (HadAid) { 54230015Sminshall DoReadModified(CMD_READ_MODIFIED); 54330015Sminshall } 54430076Sminshall #else /* !defined(PURE3274) */ 54530076Sminshall if (HadAid) { 54630076Sminshall DoReadModified(CMD_READ_MODIFIED); 54730076Sminshall } 54830076Sminshall #endif /* !defined(PURE3274) */ 54930015Sminshall } 55030015Sminshall 55130015Sminshall /* This takes in one character from the keyboard and places it on the 55230015Sminshall * screen. 55330015Sminshall */ 55430015Sminshall 55530015Sminshall static void 55630015Sminshall OneCharacter(c, insert) 55730015Sminshall int c; /* character (Ebcdic) to be shoved in */ 55830015Sminshall int insert; /* are we in insert mode? */ 55930015Sminshall { 56030015Sminshall register int i, j; 56130015Sminshall 56230015Sminshall if (IsProtected(CursorAddress)) { 56330015Sminshall RingBell("Protected Field"); 56430015Sminshall return; 56530015Sminshall } 56630015Sminshall if (insert) { 56730015Sminshall /* is the last character in the field a blank or null? */ 56830015Sminshall i = ScreenDec(FieldInc(CursorAddress)); 56930015Sminshall j = GetHost(i); 57030015Sminshall if (!Disspace(j)) { 57130015Sminshall RingBell("No more room for insert"); 57230015Sminshall return; 57330015Sminshall } else { 57430015Sminshall for (j = ScreenDec(i); i != CursorAddress; 57530015Sminshall j = ScreenDec(j), i = ScreenDec(i)) { 57630015Sminshall AddHost(i, GetHost(j)); 57730015Sminshall } 57830015Sminshall } 57930015Sminshall } 58030015Sminshall AddHost(CursorAddress, c); 58130015Sminshall TurnOnMdt(CursorAddress); 58230015Sminshall CursorAddress = ScreenInc(CursorAddress); 58330015Sminshall if (IsStartField(CursorAddress) && 58430015Sminshall ((FieldAttributes(CursorAddress)&ATTR_AUTO_SKIP_MASK) == 58530015Sminshall ATTR_AUTO_SKIP_VALUE)) { 58630015Sminshall Tab(); 58730015Sminshall } 58830015Sminshall } 58930015Sminshall 59031197Sminshall /* 59131197Sminshall * AcceptKeystroke() 59231197Sminshall * 59331197Sminshall * Processes one keystroke. 59431197Sminshall * 59531197Sminshall * Returns: 59631197Sminshall * 59731197Sminshall * 0 if this keystroke was NOT processed. 59831197Sminshall * 1 if everything went OK. 59931197Sminshall */ 60030015Sminshall 60130015Sminshall int 60231197Sminshall AcceptKeystroke(scancode, shiftstate) 60331197Sminshall int 60431197Sminshall scancode, /* 3270 scancode */ 60531197Sminshall shiftstate; /* The shift state */ 60630015Sminshall { 60730015Sminshall register int c; 60830015Sminshall register int i; 60930015Sminshall register int j; 61030076Sminshall enum ctlrfcn ctlrfcn; 61130015Sminshall 61231197Sminshall if (scancode >= numberof(hits)) { 61331085Sminshall ExitString(stderr, 61431197Sminshall "Unknown scancode encountered in AcceptKeystroke.\n", 1); 61530015Sminshall /*NOTREACHED*/ 61630015Sminshall } 61731197Sminshall ctlrfcn = hits[scancode].hit[HITNUM(shiftstate)].ctlrfcn; 61831197Sminshall c = hits[scancode].hit[HITNUM(shiftstate)].code; 61930015Sminshall 62030015Sminshall if (!UnLocked || HadAid) { 62130015Sminshall if (HadAid) { 62230015Sminshall SendToIBM(); 62330015Sminshall if (!EmptyChar()) { 62431197Sminshall return 0; /* nothing to do */ 62530015Sminshall } 62630015Sminshall } 62730327Sminshall #if !defined(PURE3274) 62830015Sminshall if (!HadAid && EmptyChar()) { 62930076Sminshall if ((ctlrfcn == FCN_RESET) || (ctlrfcn == FCN_MASTER_RESET)) { 63030015Sminshall UnLocked = 1; 63130015Sminshall } 63230015Sminshall } 63330327Sminshall #endif /* !defined(PURE3274) */ 63430015Sminshall if (!UnLocked) { 63531197Sminshall return 0; 63630015Sminshall } 63730015Sminshall } 63831864Sminshall 63930015Sminshall /* now, either empty, or haven't seen aid yet */ 64030015Sminshall 64130076Sminshall #if !defined(PURE3274) 64231864Sminshall /* 64331864Sminshall * If we are in transparent (output) mode, do something special 64431864Sminshall * with keystrokes. 64531864Sminshall */ 64630015Sminshall if (TransparentClock == OutputClock) { 64731197Sminshall if (ctlrfcn == FCN_AID) { 64831197Sminshall UnLocked = 0; 64931197Sminshall InsertMode = 0; 65031197Sminshall AidByte = (c); 65131197Sminshall HadAid = 1; 65231197Sminshall } else { 65331197Sminshall switch (ctlrfcn) { 65431197Sminshall case FCN_ESCAPE: 65531197Sminshall StopScreen(1); 65631197Sminshall command(0); 65731476Sminshall if (shell_active == 0) { 65831476Sminshall ConnectScreen(); 65931476Sminshall } 66031197Sminshall break; 66130015Sminshall 66231197Sminshall case FCN_RESET: 66331197Sminshall case FCN_MASTER_RESET: 66431197Sminshall UnLocked = 1; 66531197Sminshall break; 66630015Sminshall 66731197Sminshall default: 66831197Sminshall return 0; 66930015Sminshall } 67030015Sminshall } 67130015Sminshall } 67230076Sminshall #endif /* !defined(PURE3274) */ 67330015Sminshall 67431197Sminshall if (ctlrfcn == FCN_CHARACTER) { 67531197Sminshall /* Add the character to the buffer */ 67631197Sminshall OneCharacter(c, InsertMode); 67731197Sminshall } else if (ctlrfcn == FCN_AID) { /* got Aid */ 67831197Sminshall if (c == AID_CLEAR) { 67931197Sminshall LocalClearScreen(); /* Side effect is to clear 3270 */ 68030015Sminshall } 68131197Sminshall ResetOiaOnlineA(&OperatorInformationArea); 68231197Sminshall SetOiaTWait(&OperatorInformationArea); 68331197Sminshall ResetOiaInsert(&OperatorInformationArea); 68431197Sminshall InsertMode = 0; /* just like a 3278 */ 68531197Sminshall SetOiaSystemLocked(&OperatorInformationArea); 68631197Sminshall SetOiaModified(); 68731197Sminshall UnLocked = 0; 68831197Sminshall AidByte = c; 68931197Sminshall HadAid = 1; 69031197Sminshall SendToIBM(); 69131197Sminshall } else { 69231197Sminshall switch (ctlrfcn) { 69330015Sminshall 69431197Sminshall case FCN_CURSEL: 69531197Sminshall c = FieldAttributes(CursorAddress)&ATTR_DSPD_MASK; 69631197Sminshall if (!FormattedScreen() 69731197Sminshall || ((c != ATTR_DSPD_DSPD) && (c != ATTR_DSPD_HIGH))) { 69831197Sminshall RingBell("Cursor not in selectable field"); 69931197Sminshall } else { 70031197Sminshall i = ScreenInc(WhereAttrByte(CursorAddress)); 70131197Sminshall c = GetHost(i); 70231197Sminshall if (c == DISP_QUESTION) { 70331197Sminshall AddHost(i, DISP_GREATER_THAN); 70431197Sminshall TurnOnMdt(i); 70531197Sminshall } else if (c == DISP_GREATER_THAN) { 70631197Sminshall AddHost(i, DISP_QUESTION); 70731197Sminshall TurnOffMdt(i); 70831197Sminshall } else if (c == DISP_BLANK || c == DISP_NULL 70931197Sminshall || c == DISP_AMPERSAND) { 71031197Sminshall UnLocked = 0; 71131197Sminshall InsertMode = 0; 71231197Sminshall ResetOiaOnlineA(&OperatorInformationArea); 71331197Sminshall SetOiaTWait(&OperatorInformationArea); 71431197Sminshall SetOiaSystemLocked(&OperatorInformationArea); 71531197Sminshall ResetOiaInsert(&OperatorInformationArea); 71631197Sminshall SetOiaModified(); 71731197Sminshall if (c == DISP_AMPERSAND) { 71831197Sminshall TurnOnMdt(i); /* Only for & type */ 71931197Sminshall AidByte = AID_ENTER; 72030015Sminshall } else { 72131197Sminshall AidByte = AID_SELPEN; 72230015Sminshall } 72331197Sminshall HadAid = 1; 72431197Sminshall SendToIBM(); 72531197Sminshall } else { 72631197Sminshall RingBell( 72731197Sminshall "Cursor not in a selectable field (designator)"); 72830015Sminshall } 72931197Sminshall } 73031197Sminshall break; 73130015Sminshall 73230327Sminshall #if !defined(PURE3274) 73331197Sminshall case FCN_ERASE: 73431197Sminshall if (IsProtected(ScreenDec(CursorAddress))) { 73531197Sminshall RingBell("Protected Field"); 73631197Sminshall } else { 73731197Sminshall CursorAddress = ScreenDec(CursorAddress); 73831197Sminshall Delete(CursorAddress, ScreenInc(CursorAddress)); 73931197Sminshall } 74031197Sminshall break; 74131197Sminshall case FCN_WERASE: 74231197Sminshall j = CursorAddress; 74331197Sminshall i = ScreenDec(j); 74431197Sminshall if (IsProtected(i)) { 74531197Sminshall RingBell("Protected Field"); 74631197Sminshall } else { 74731197Sminshall SetXIsProtected(); 74831197Sminshall while ((!XIsProtected(i) && Disspace(GetHost(i))) 74931197Sminshall && (i != j)) { 75031197Sminshall i = ScreenDec(i); 75130015Sminshall } 75231197Sminshall /* we are pointing at a character in a word, or 75331197Sminshall * at a protected position 75431197Sminshall */ 75531197Sminshall while ((!XIsProtected(i) && !Disspace(GetHost(i))) 75631197Sminshall && (i != j)) { 75731197Sminshall i = ScreenDec(i); 75830015Sminshall } 75931197Sminshall /* we are pointing at a space, or at a protected 76031197Sminshall * position 76131197Sminshall */ 76231197Sminshall CursorAddress = ScreenInc(i); 76331197Sminshall Delete(CursorAddress, j); 76431197Sminshall } 76531197Sminshall break; 76630015Sminshall 76731197Sminshall case FCN_FERASE: 76831197Sminshall if (IsProtected(CursorAddress)) { 76931197Sminshall RingBell("Protected Field"); 77031197Sminshall } else { 77131197Sminshall CursorAddress = ScreenInc(CursorAddress); /* for btab */ 77231197Sminshall BackTab(); 77331197Sminshall EraseEndOfField(); 77431197Sminshall } 77531197Sminshall break; 77630015Sminshall 77731197Sminshall case FCN_RESET: 77831197Sminshall if (InsertMode) { 77931197Sminshall InsertMode = 0; 78031197Sminshall ResetOiaInsert(&OperatorInformationArea); 78131197Sminshall SetOiaModified(); 78231197Sminshall } 78331197Sminshall break; 78431197Sminshall case FCN_MASTER_RESET: 78531197Sminshall if (InsertMode) { 78631197Sminshall InsertMode = 0; 78731197Sminshall ResetOiaInsert(&OperatorInformationArea); 78831197Sminshall SetOiaModified(); 78931197Sminshall } 79031197Sminshall RefreshScreen(); 79131197Sminshall break; 79230327Sminshall #endif /* !defined(PURE3274) */ 79330015Sminshall 79431197Sminshall case FCN_UP: 79531197Sminshall CursorAddress = ScreenUp(CursorAddress); 79631197Sminshall break; 79730015Sminshall 79831197Sminshall case FCN_LEFT: 79931197Sminshall CursorAddress = ScreenDec(CursorAddress); 80031197Sminshall break; 80130015Sminshall 80231197Sminshall case FCN_RIGHT: 80331197Sminshall CursorAddress = ScreenInc(CursorAddress); 80431197Sminshall break; 80530015Sminshall 80631197Sminshall case FCN_DOWN: 80731197Sminshall CursorAddress = ScreenDown(CursorAddress); 80831197Sminshall break; 80930015Sminshall 81031197Sminshall case FCN_DELETE: 81131197Sminshall if (IsProtected(CursorAddress)) { 81231197Sminshall RingBell("Protected Field"); 81331197Sminshall } else { 81431197Sminshall Delete(CursorAddress, ScreenInc(CursorAddress)); 81531197Sminshall } 81631197Sminshall break; 81731197Sminshall 81831197Sminshall case FCN_INSRT: 81931197Sminshall InsertMode = !InsertMode; 82031197Sminshall if (InsertMode) { 82131197Sminshall SetOiaInsert(&OperatorInformationArea); 82231197Sminshall } else { 82331197Sminshall ResetOiaInsert(&OperatorInformationArea); 82431197Sminshall } 82531197Sminshall SetOiaModified(); 82631197Sminshall break; 82731197Sminshall 82831197Sminshall case FCN_HOME: 82931197Sminshall Home(); 83031197Sminshall break; 83131197Sminshall 83231197Sminshall case FCN_NL: 83331197Sminshall /* The algorithm is to look for the first unprotected 83431197Sminshall * column after column 0 of the following line. Having 83531197Sminshall * found that unprotected column, we check whether the 83631197Sminshall * cursor-address-at-entry is at or to the right of the 83731197Sminshall * LeftMargin AND the LeftMargin column of the found line 83831197Sminshall * is unprotected. If this conjunction is true, then 83931197Sminshall * we set the found pointer to the address of the LeftMargin 84031197Sminshall * column in the found line. 84131197Sminshall * Then, we set the cursor address to the found address. 84231197Sminshall */ 84331197Sminshall i = SetBufferAddress(ScreenLine(ScreenDown(CursorAddress)), 0); 84431197Sminshall j = ScreenInc(WhereAttrByte(CursorAddress)); 84531197Sminshall do { 84631197Sminshall if (IsUnProtected(i)) { 84731197Sminshall break; 84830015Sminshall } 84931197Sminshall /* Again (see comment in Home()), this COULD be a problem 85031197Sminshall * with an unformatted screen. 85131197Sminshall */ 85231197Sminshall /* If there was a field with only an attribute byte, 85331197Sminshall * we may be pointing to the attribute byte of the NEXT 85431197Sminshall * field, so just look at the next byte. 85531197Sminshall */ 85631197Sminshall if (IsStartField(i)) { 85731197Sminshall i = ScreenInc(i); 85831192Sminshall } else { 85931197Sminshall i = ScreenInc(FieldInc(i)); 86031192Sminshall } 86131197Sminshall } while (i != j); 86231197Sminshall if (!IsUnProtected(i)) { /* couldn't find unprotected */ 86331197Sminshall i = SetBufferAddress(0,0); 86431197Sminshall } 86531197Sminshall if (OptLeftMargin <= ScreenLineOffset(CursorAddress)) { 86631197Sminshall if (IsUnProtected(SetBufferAddress(ScreenLine(i), 86731197Sminshall OptLeftMargin))) { 86831197Sminshall i = SetBufferAddress(ScreenLine(i), OptLeftMargin); 86931197Sminshall } 87031197Sminshall } 87131197Sminshall CursorAddress = i; 87231197Sminshall break; 87330015Sminshall 87431197Sminshall case FCN_EINP: 87531197Sminshall if (!FormattedScreen()) { 87631197Sminshall i = CursorAddress; 87731197Sminshall TurnOffMdt(i); 87830015Sminshall do { 87931197Sminshall AddHost(i, 0); 88031197Sminshall i = ScreenInc(i); 88131197Sminshall } while (i != CursorAddress); 88231197Sminshall } else { 88331197Sminshall /* 88431197Sminshall * The algorithm is: go through each unprotected 88531197Sminshall * field on the screen, clearing it out. When 88631197Sminshall * we are at the start of a field, skip that field 88731197Sminshall * if its contents are protected. 88830015Sminshall */ 88931197Sminshall i = j = FieldInc(CursorAddress); 89031197Sminshall do { 89131197Sminshall if (IsUnProtected(ScreenInc(i))) { 89230015Sminshall i = ScreenInc(i); 89331197Sminshall TurnOffMdt(i); 89431197Sminshall do { 89531197Sminshall AddHost(i, 0); 89631197Sminshall i = ScreenInc(i); 89731197Sminshall } while (!IsStartField(i)); 89830015Sminshall } else { 89931197Sminshall i = FieldInc(i); 90030015Sminshall } 90130015Sminshall } while (i != j); 90231197Sminshall } 90331197Sminshall Home(); 90431197Sminshall break; 90530015Sminshall 90631197Sminshall case FCN_EEOF: 90731197Sminshall EraseEndOfField(); 90831197Sminshall break; 90930015Sminshall 91031197Sminshall case FCN_SPACE: 91131197Sminshall OneCharacter(DISP_BLANK, InsertMode); /* Add cent */ 91231197Sminshall break; 91330015Sminshall 91431197Sminshall case FCN_CENTSIGN: 91531197Sminshall OneCharacter(DISP_CENTSIGN, InsertMode); /* Add cent */ 91631197Sminshall break; 91730015Sminshall 91831197Sminshall case FCN_FM: 91931197Sminshall OneCharacter(DISP_FM, InsertMode); /* Add field mark */ 92031197Sminshall break; 92130015Sminshall 92231197Sminshall case FCN_DP: 92331197Sminshall if (IsProtected(CursorAddress)) { 92431197Sminshall RingBell("Protected Field"); 92531197Sminshall } else { 92631197Sminshall OneCharacter(DISP_DUP, InsertMode);/* Add dup character */ 92731197Sminshall Tab(); 92831197Sminshall } 92931197Sminshall break; 93030015Sminshall 93131197Sminshall case FCN_TAB: 93231197Sminshall Tab(); 93331197Sminshall break; 93430015Sminshall 93531197Sminshall case FCN_BTAB: 93631197Sminshall BackTab(); 93731197Sminshall break; 93830015Sminshall 93930015Sminshall #ifdef NOTUSED /* Actually, this is superseded by unix flow 94031197Sminshall * control. 94131197Sminshall */ 94231197Sminshall case FCN_XOFF: 94331197Sminshall Flow = 0; /* stop output */ 94431197Sminshall break; 94530015Sminshall 94631197Sminshall case FCN_XON: 94731197Sminshall if (!Flow) { 94831197Sminshall Flow = 1; /* turn it back on */ 94931197Sminshall DoTerminalOutput(); 95031197Sminshall } 95131197Sminshall break; 95230015Sminshall #endif /* NOTUSED */ 95330015Sminshall 95430327Sminshall #if !defined(PURE3274) 95531197Sminshall case FCN_ESCAPE: 95631197Sminshall /* FlushChar(); do we want to flush characters from before? */ 95731197Sminshall StopScreen(1); 95831197Sminshall command(0); 95931476Sminshall if (shell_active == 0) { 96031476Sminshall ConnectScreen(); 96131476Sminshall } 96231197Sminshall break; 96330015Sminshall 96431197Sminshall case FCN_DISC: 96531197Sminshall StopScreen(1); 96631197Sminshall suspend(); 96731197Sminshall setconnmode(); 96831197Sminshall ConnectScreen(); 96931197Sminshall break; 97030015Sminshall 97131197Sminshall case FCN_RESHOW: 97231197Sminshall RefreshScreen(); 97331197Sminshall break; 97430015Sminshall 97531197Sminshall case FCN_SETTAB: 97631197Sminshall OptColTabs[ScreenLineOffset(CursorAddress)] = 1; 97731197Sminshall break; 97830015Sminshall 97931197Sminshall case FCN_DELTAB: 98031197Sminshall OptColTabs[ScreenLineOffset(CursorAddress)] = 0; 98131197Sminshall break; 98230015Sminshall 98331197Sminshall /* 98431197Sminshall * Clear all tabs, home line, and left margin. 98531197Sminshall */ 98631197Sminshall case FCN_CLRTAB: 98731197Sminshall for (i = 0; i < sizeof OptColTabs; i++) { 98831197Sminshall OptColTabs[i] = 0; 98931197Sminshall } 99031197Sminshall OptHome = 0; 99131197Sminshall OptLeftMargin = 0; 99231197Sminshall break; 99330015Sminshall 99431197Sminshall case FCN_COLTAB: 99531197Sminshall ColTab(); 99631197Sminshall break; 99730015Sminshall 99831197Sminshall case FCN_COLBAK: 99931197Sminshall ColBak(); 100031197Sminshall break; 100130015Sminshall 100231197Sminshall case FCN_INDENT: 100331197Sminshall ColTab(); 100431197Sminshall OptLeftMargin = ScreenLineOffset(CursorAddress); 100531197Sminshall break; 100630015Sminshall 100731197Sminshall case FCN_UNDENT: 100831197Sminshall ColBak(); 100931197Sminshall OptLeftMargin = ScreenLineOffset(CursorAddress); 101031197Sminshall break; 101130015Sminshall 101231197Sminshall case FCN_SETMRG: 101331197Sminshall OptLeftMargin = ScreenLineOffset(CursorAddress); 101431197Sminshall break; 101530015Sminshall 101631197Sminshall case FCN_SETHOM: 101731197Sminshall OptHome = ScreenLine(CursorAddress); 101831197Sminshall break; 101930015Sminshall 102031197Sminshall /* 102131197Sminshall * Point to first character of next unprotected word on 102231197Sminshall * screen. 102331197Sminshall */ 102431197Sminshall case FCN_WORDTAB: 102531197Sminshall i = CursorAddress; 102631197Sminshall SetXIsProtected(); 102731197Sminshall while (!XIsProtected(i) && !Disspace(GetHost(i))) { 102831197Sminshall i = ScreenInc(i); 102931197Sminshall if (i == CursorAddress) { 103031197Sminshall break; 103130015Sminshall } 103231197Sminshall } 103331197Sminshall /* i is either protected, a space (blank or null), 103431197Sminshall * or wrapped 103531197Sminshall */ 103631197Sminshall while (XIsProtected(i) || Disspace(GetHost(i))) { 103731197Sminshall i = ScreenInc(i); 103831197Sminshall if (i == CursorAddress) { 103931197Sminshall break; 104030015Sminshall } 104131197Sminshall } 104231197Sminshall CursorAddress = i; 104331197Sminshall break; 104430015Sminshall 104531197Sminshall case FCN_WORDBACKTAB: 104631197Sminshall i = ScreenDec(CursorAddress); 104731197Sminshall SetXIsProtected(); 104831197Sminshall while (XIsProtected(i) || Disspace(GetHost(i))) { 104931197Sminshall i = ScreenDec(i); 105031197Sminshall if (i == CursorAddress) { 105131197Sminshall break; 105230015Sminshall } 105331197Sminshall } 105431197Sminshall /* i is pointing to a character IN an unprotected word 105531197Sminshall * (or i wrapped) 105631197Sminshall */ 105731197Sminshall while (!Disspace(GetHost(i))) { 105831197Sminshall i = ScreenDec(i); 105931197Sminshall if (i == CursorAddress) { 106031197Sminshall break; 106130015Sminshall } 106231197Sminshall } 106331197Sminshall CursorAddress = ScreenInc(i); 106431197Sminshall break; 106530015Sminshall 106631197Sminshall /* Point to last non-blank character of this/next 106731197Sminshall * unprotected word. 106831197Sminshall */ 106931197Sminshall case FCN_WORDEND: 107031197Sminshall i = ScreenInc(CursorAddress); 107131197Sminshall SetXIsProtected(); 107231197Sminshall while (XIsProtected(i) || Disspace(GetHost(i))) { 107331197Sminshall i = ScreenInc(i); 107431197Sminshall if (i == CursorAddress) { 107531197Sminshall break; 107630015Sminshall } 107731197Sminshall } 107831197Sminshall /* we are pointing at a character IN an 107931197Sminshall * unprotected word (or we wrapped) 108031197Sminshall */ 108131197Sminshall while (!Disspace(GetHost(i))) { 108231197Sminshall i = ScreenInc(i); 108331197Sminshall if (i == CursorAddress) { 108431197Sminshall break; 108530015Sminshall } 108631197Sminshall } 108731197Sminshall CursorAddress = ScreenDec(i); 108831197Sminshall break; 108930015Sminshall 109031197Sminshall /* Get to last non-blank of this/next unprotected 109131197Sminshall * field. 109231197Sminshall */ 109331197Sminshall case FCN_FIELDEND: 109431197Sminshall i = LastOfField(CursorAddress); 109531197Sminshall if (i != CursorAddress) { 109631197Sminshall CursorAddress = i; /* We moved; take this */ 109731197Sminshall } else { 109831197Sminshall j = FieldInc(CursorAddress); /* Move to next field */ 109931197Sminshall i = LastOfField(j); 110031197Sminshall if (i != j) { 110131197Sminshall CursorAddress = i; /* We moved; take this */ 110230015Sminshall } 110331197Sminshall /* else - nowhere else on screen to be; stay here */ 110431197Sminshall } 110531197Sminshall break; 110630327Sminshall #endif /* !defined(PURE3274) */ 110730015Sminshall 110831197Sminshall default: 110931197Sminshall /* We don't handle this yet */ 111031197Sminshall RingBell("Function not implemented"); 111131197Sminshall } 111231197Sminshall } 111331197Sminshall return 1; /* We did something! */ 111431197Sminshall } 111531197Sminshall 111631197Sminshall 111731197Sminshall /* 111831197Sminshall * We get data from the terminal. We keep track of the shift state 111931197Sminshall * (including ALT, CONTROL), and then call AcceptKeystroke to actually 112031197Sminshall * process any non-shift keys. 112131197Sminshall */ 112231197Sminshall 112331197Sminshall int 112431197Sminshall DataFrom3270(buffer, count) 112531197Sminshall unsigned char *buffer; /* where the data is */ 112631197Sminshall int count; /* how much data there is */ 112731197Sminshall { 112831197Sminshall int origCount; 112931197Sminshall 113031197Sminshall origCount = count; 113131197Sminshall 113231197Sminshall while (count) { 113331197Sminshall if (*buffer >= numberof(hits)) { 113431197Sminshall ExitString(stderr, 113531197Sminshall "Unknown scancode encountered in DataFrom3270.\n", 1); 113631197Sminshall /*NOTREACHED*/ 113731197Sminshall } 113831197Sminshall 113931197Sminshall switch (hits[*buffer].hit[HITNUM(rememberedshiftstate)].ctlrfcn) { 114031197Sminshall 114131197Sminshall case FCN_MAKE_SHIFT: 114231197Sminshall rememberedshiftstate |= (SHIFT_RIGHT|SHIFT_UPSHIFT); 114331197Sminshall break; 114431197Sminshall case FCN_BREAK_SHIFT: 114531197Sminshall rememberedshiftstate &= ~(SHIFT_RIGHT|SHIFT_UPSHIFT); 114631197Sminshall break; 114731197Sminshall case FCN_MAKE_ALT: 114831197Sminshall rememberedshiftstate |= SHIFT_ALT; 114931197Sminshall break; 115031197Sminshall case FCN_BREAK_ALT: 115131197Sminshall rememberedshiftstate &= ~SHIFT_ALT; 115231197Sminshall break; 115331197Sminshall default: 115431197Sminshall if (AcceptKeystroke(*buffer, rememberedshiftstate) == 0) { 115531197Sminshall return(origCount-count); 115630015Sminshall } 115731197Sminshall break; 115830015Sminshall } 115931197Sminshall buffer++; 116031197Sminshall count--; 116130015Sminshall } 116230015Sminshall return(origCount-count); 116330015Sminshall } 1164