130015Sminshall /* 2*31892Sminshall * 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*31892Sminshall static char sccsid[] = "@(#)inbound.c 1.18 (Berkeley) 07/17/87"; 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 14830015Sminshall 14930015Sminshall /* EraseEndOfField - erase all characters to the end of a field */ 15030015Sminshall 15130015Sminshall static void 15230015Sminshall EraseEndOfField() 15330015Sminshall { 15430015Sminshall register int i; 15530015Sminshall 15630015Sminshall if (IsProtected(CursorAddress)) { 15730015Sminshall RingBell("Protected Field"); 15830015Sminshall } else { 15930015Sminshall TurnOnMdt(CursorAddress); 16030015Sminshall if (FormattedScreen()) { 16130015Sminshall i = CursorAddress; 16230015Sminshall do { 16330015Sminshall AddHost(i, 0); 16430015Sminshall i = ScreenInc(i); 16530015Sminshall } while ((i != CursorAddress) && !IsStartField(i)); 16630015Sminshall } else { /* Screen is Unformatted */ 16730015Sminshall i = CursorAddress; 16830015Sminshall do { 16930015Sminshall AddHost(i, 0); 17030015Sminshall i = ScreenInc(i); 17130015Sminshall } while (i != HighestScreen()); 17230015Sminshall } 17330015Sminshall } 17430015Sminshall } 17530015Sminshall 17630015Sminshall /* Delete() - deletes a character from the screen 17730015Sminshall * 17830015Sminshall * What we want to do is delete the section 17930015Sminshall * [where, from-1] from the screen, 18030015Sminshall * filling in with what comes at from. 18130015Sminshall * 18230015Sminshall * The deleting continues to the end of the field (or 18330015Sminshall * until the cursor wraps). 18430015Sminshall * 18530015Sminshall * From can be a start of a field. We 18630015Sminshall * check for that. However, there can't be any 18730015Sminshall * fields that start between where and from. 18830015Sminshall * We don't check for that. 18930015Sminshall * 19030015Sminshall * Also, we assume that the protection status of 19130015Sminshall * everything has been checked by the caller. 19230015Sminshall * 19330015Sminshall */ 19430015Sminshall 19530015Sminshall static void 19630015Sminshall Delete(where, from) 19730015Sminshall register int where, /* Where to start deleting from */ 19830015Sminshall from; /* Where to pull back from */ 19930015Sminshall { 20030015Sminshall register int i; 20130015Sminshall 20230015Sminshall TurnOnMdt(where); /* Only do this once in this field */ 20330015Sminshall i = where; 20430015Sminshall do { 20530015Sminshall if (IsStartField(from)) { 20630015Sminshall AddHost(i, 0); /* Stick the edge at the start field */ 20730015Sminshall } else { 20830015Sminshall AddHost(i, GetHost(from)); 20930015Sminshall from = ScreenInc(from); /* Move the edge */ 21030015Sminshall } 21130015Sminshall i = ScreenInc(i); 21230015Sminshall } while ((!IsStartField(i)) && (i != where)); 21330015Sminshall } 21430015Sminshall 21530015Sminshall static void 21630015Sminshall ColBak() 21730015Sminshall { 21830015Sminshall register int i; 21930015Sminshall 22030015Sminshall i = ScreenLineOffset(CursorAddress); 22130015Sminshall for (i = i-1; i >= 0; i--) { 22230015Sminshall if (OptColTabs[i]) { 22330015Sminshall break; 22430015Sminshall } 22530015Sminshall } 22630015Sminshall if (i < 0) { 22730015Sminshall i = 0; 22830015Sminshall } 22930015Sminshall CursorAddress = SetBufferAddress(ScreenLine(CursorAddress), i); 23030015Sminshall } 23130015Sminshall 23230015Sminshall static void 23330015Sminshall ColTab() 23430015Sminshall { 23530015Sminshall register int i; 23630015Sminshall 23730015Sminshall i = ScreenLineOffset(CursorAddress); 23830015Sminshall for (i = i+1; i < NumberColumns; i++) { 23930015Sminshall if (OptColTabs[i]) { 24030015Sminshall break; 24130015Sminshall } 24230015Sminshall } 24330015Sminshall if (i >= NumberColumns) { 24430015Sminshall i = NumberColumns-1; 24530015Sminshall } 24630015Sminshall CursorAddress = SetBufferAddress(ScreenLine(CursorAddress), i); 24730015Sminshall } 24830015Sminshall 24930015Sminshall static void 25030015Sminshall Home() 25130015Sminshall { 25230015Sminshall register int i; 25330015Sminshall register int j; 25430015Sminshall 25530015Sminshall i = SetBufferAddress(OptHome, 0); 25630015Sminshall j = WhereLowByte(i); 25730015Sminshall do { 25830015Sminshall if (IsUnProtected(i)) { 25930015Sminshall CursorAddress = i; 26030015Sminshall return; 26130015Sminshall } 26230015Sminshall /* the following could be a problem if we got here with an 26330015Sminshall * unformatted screen. However, this is "impossible", since 26430015Sminshall * with an unformatted screen, the IsUnProtected(i) above 26530015Sminshall * should be true. 26630015Sminshall */ 26730015Sminshall i = ScreenInc(FieldInc(i)); 26830015Sminshall } while (i != j); 26930015Sminshall CursorAddress = LowestScreen(); 27030015Sminshall } 27130015Sminshall 27230015Sminshall static 27330015Sminshall LastOfField(i) 27430015Sminshall register int i; /* position to start from */ 27530015Sminshall { 27630015Sminshall register int j; 27730015Sminshall register int k; 27830015Sminshall 27930015Sminshall k = j = i; 28030015Sminshall SetXIsProtected(); 28130015Sminshall while (XIsProtected(i) || Disspace(GetHost(i))) { 28230015Sminshall i = ScreenInc(i); 28330015Sminshall if (i == j) { 28430015Sminshall break; 28530015Sminshall } 28630015Sminshall } 28730015Sminshall /* We are now IN a word IN an unprotected field (or wrapped) */ 28830015Sminshall while (!XIsProtected(i)) { 28930015Sminshall if (!Disspace(GetHost(i))) { 29030015Sminshall k = i; 29130015Sminshall } 29230015Sminshall i = ScreenInc(i); 29330015Sminshall if (i == j) { 29430015Sminshall break; 29530015Sminshall } 29630015Sminshall } 29730015Sminshall return(k); 29830015Sminshall } 29930015Sminshall 30030015Sminshall 30130015Sminshall static void 30230015Sminshall FlushChar() 30330015Sminshall { 30430015Sminshall ourPTail = ourPHead = ourBuffer; 30530015Sminshall } 30630015Sminshall 30730015Sminshall 30830015Sminshall /* 30930015Sminshall * Add one EBCDIC (NOT display code) character to the buffer. 31030015Sminshall */ 31130015Sminshall 31230015Sminshall static void 31330015Sminshall AddChar(character) 31430015Sminshall char character; 31530015Sminshall { 31630015Sminshall if (FullChar()) { 31730015Sminshall ourPTail += DataToNetwork(ourPTail, ourPHead-ourPTail, 0); 31830015Sminshall if (EmptyChar()) { 31930015Sminshall FlushChar(); 32030015Sminshall } else { 32130073Sminshall char buffer[100]; 32230073Sminshall 32330073Sminshall sprintf(buffer, "File %s, line %d: No room in network buffer!\n", 32430015Sminshall __FILE__, __LINE__); 32531085Sminshall ExitString(stderr, buffer, 1); 32630073Sminshall /*NOTREACHED*/ 32730015Sminshall } 32830015Sminshall } 32930015Sminshall *ourPHead++ = character; 33030015Sminshall } 33130015Sminshall 33230015Sminshall 33330015Sminshall static void 33430015Sminshall SendUnformatted() 33530015Sminshall { 33630015Sminshall register int i, j; 33730015Sminshall register int Nulls; 33830015Sminshall register int c; 33930015Sminshall 34030015Sminshall /* look for start of field */ 34130015Sminshall Nulls = 0; 34230015Sminshall i = j = LowestScreen(); 34330015Sminshall do { 34430015Sminshall c = GetHost(i); 34530015Sminshall if (c == 0) { 34630015Sminshall Nulls++; 34730015Sminshall } else { 34830015Sminshall while (Nulls) { 34930015Sminshall Nulls--; 35030015Sminshall AddChar(EBCDIC_BLANK); /* put in blanks */ 35130015Sminshall } 35230015Sminshall AddChar(disp_ebc[c]); 35330015Sminshall } 35430015Sminshall i = ScreenInc(i); 35530015Sminshall } while (i != j); 35630015Sminshall } 35730015Sminshall 35830015Sminshall static 35930015Sminshall SendField(i, command) 36030015Sminshall register int i; /* where we saw MDT bit */ 36130015Sminshall int command; /* The command code (type of read) */ 36230015Sminshall { 36330015Sminshall register int j; 36430015Sminshall register int k; 36530015Sminshall register int Nulls; 36630015Sminshall register int c; 36730015Sminshall 36830015Sminshall /* look for start of field */ 36930015Sminshall i = j = WhereLowByte(i); 37030015Sminshall 37130015Sminshall /* On a test_request_read, don't send sba and address */ 37230015Sminshall if ((AidByte != AID_TREQ) 37330015Sminshall || (command == CMD_SNA_READ_MODIFIED_ALL)) { 37430015Sminshall AddChar(ORDER_SBA); /* set start field */ 37530015Sminshall AddChar(BufferTo3270_0(j)); /* set address of this field */ 37630015Sminshall AddChar(BufferTo3270_1(j)); 37730015Sminshall } 37830015Sminshall /* 37930015Sminshall * Only on read_modified_all do we return the contents 38030015Sminshall * of the field when the attention was caused by a 38130015Sminshall * selector pen. 38230015Sminshall */ 38330015Sminshall if ((AidByte != AID_SELPEN) 38430015Sminshall || (command == CMD_SNA_READ_MODIFIED_ALL)) { 38530015Sminshall if (!IsStartField(j)) { 38630015Sminshall Nulls = 0; 38730015Sminshall k = ScreenInc(WhereHighByte(j)); 38830015Sminshall do { 38930015Sminshall c = GetHost(j); 39030015Sminshall if (c == 0) { 39130015Sminshall Nulls++; 39230015Sminshall } else { 39330015Sminshall while (Nulls) { 39430015Sminshall Nulls--; 39530015Sminshall AddChar(EBCDIC_BLANK); /* put in blanks */ 39630015Sminshall } 39730015Sminshall AddChar(disp_ebc[c]); 39830015Sminshall } 39930015Sminshall j = ScreenInc(j); 40030015Sminshall } while ((j != k) && (j != i)); 40130015Sminshall } 40230015Sminshall } else { 40330015Sminshall j = FieldInc(j); 40430015Sminshall } 40530015Sminshall return(j); 40630015Sminshall } 40730015Sminshall 40830015Sminshall /* Various types of reads... */ 40930015Sminshall void 41030015Sminshall DoReadModified(command) 41130015Sminshall int command; /* The command sent */ 41230015Sminshall { 41330015Sminshall register int i, j; 41430015Sminshall 41530015Sminshall if (AidByte) { 41630015Sminshall if (AidByte != AID_TREQ) { 41730015Sminshall AddChar(AidByte); 41830015Sminshall } else { 41930015Sminshall /* Test Request Read header */ 42030015Sminshall AddChar(EBCDIC_SOH); 42130015Sminshall AddChar(EBCDIC_PERCENT); 42230015Sminshall AddChar(EBCDIC_SLASH); 42330015Sminshall AddChar(EBCDIC_STX); 42430015Sminshall } 42530015Sminshall } else { 42630015Sminshall AddChar(AID_NONE); 42730015Sminshall } 42830015Sminshall if (((AidByte != AID_PA1) && (AidByte != AID_PA2) 42930015Sminshall && (AidByte != AID_PA3) && (AidByte != AID_CLEAR)) 43030015Sminshall || (command == CMD_SNA_READ_MODIFIED_ALL)) { 43130015Sminshall if ((AidByte != AID_TREQ) 43230015Sminshall || (command == CMD_SNA_READ_MODIFIED_ALL)) { 43330015Sminshall /* Test request read_modified doesn't give cursor address */ 43430015Sminshall AddChar(BufferTo3270_0(CursorAddress)); 43530015Sminshall AddChar(BufferTo3270_1(CursorAddress)); 43630015Sminshall } 43730015Sminshall i = j = WhereAttrByte(LowestScreen()); 43830015Sminshall /* Is this an unformatted screen? */ 43930015Sminshall if (!IsStartField(i)) { /* yes, handle separate */ 44030015Sminshall SendUnformatted(); 44130015Sminshall } else { 44230015Sminshall do { 44330015Sminshall if (HasMdt(i)) { 44430015Sminshall i = SendField(i, command); 44530015Sminshall } else { 44630015Sminshall i = FieldInc(i); 44730015Sminshall } 44830015Sminshall } while (i != j); 44930015Sminshall } 45030015Sminshall } 45130015Sminshall ourPTail += DataToNetwork(ourPTail, ourPHead-ourPTail, 1); 45230015Sminshall if (EmptyChar()) { 45330015Sminshall FlushChar(); 45430015Sminshall HadAid = 0; /* killed that buffer */ 45530015Sminshall } 45630015Sminshall } 45730015Sminshall 45830015Sminshall /* A read buffer operation... */ 45930015Sminshall 46030015Sminshall void 46130015Sminshall DoReadBuffer() 46230015Sminshall { 46330015Sminshall register int i, j; 46430015Sminshall 46530015Sminshall if (AidByte) { 46630015Sminshall AddChar(AidByte); 46730015Sminshall } else { 46830015Sminshall AddChar(AID_NONE); 46930015Sminshall } 47030015Sminshall AddChar(BufferTo3270_0(CursorAddress)); 47130015Sminshall AddChar(BufferTo3270_1(CursorAddress)); 47230015Sminshall i = j = LowestScreen(); 47330015Sminshall do { 47430015Sminshall if (IsStartField(i)) { 47530015Sminshall AddChar(ORDER_SF); 47630015Sminshall AddChar(BufferTo3270_1(FieldAttributes(i))); 47730015Sminshall } else { 47830015Sminshall AddChar(disp_ebc[GetHost(i)]); 47930015Sminshall } 48030015Sminshall i = ScreenInc(i); 48130015Sminshall } while (i != j); 48230015Sminshall ourPTail += DataToNetwork(ourPTail, ourPHead-ourPTail, 1); 48330015Sminshall if (EmptyChar()) { 48430015Sminshall FlushChar(); 48530015Sminshall HadAid = 0; /* killed that buffer */ 48630015Sminshall } 48730015Sminshall } 48831864Sminshall 48931864Sminshall /* Send some transparent data to the host */ 49031864Sminshall 49131864Sminshall void 49231864Sminshall SendTransparent(buffer, count) 49331864Sminshall char *buffer; 49431864Sminshall int count; 49531864Sminshall { 49631864Sminshall char stuff[3]; 49731864Sminshall 49831864Sminshall stuff[0] = AID_NONE_PRINTER; 49931864Sminshall stuff[1] = BufferTo3270_0(count); 50031864Sminshall stuff[2] = BufferTo3270_1(count); 50131864Sminshall DataToNetwork(stuff, sizeof stuff, 0); 50231864Sminshall DataToNetwork(buffer, count, 1); 50331864Sminshall } 50431864Sminshall 50531864Sminshall 50630015Sminshall /* Try to send some data to host */ 50730015Sminshall 50830015Sminshall void 50930015Sminshall SendToIBM() 51030015Sminshall { 51130076Sminshall #if !defined(PURE3274) 51231864Sminshall if (TransparentClock >= OutputClock) { 51330015Sminshall if (HadAid) { 51430015Sminshall AddChar(AidByte); 51530015Sminshall HadAid = 0; 51630015Sminshall } else { 51730015Sminshall AddChar(AID_NONE_PRINTER); 51830015Sminshall } 51930015Sminshall do { 52030015Sminshall ourPTail += DataToNetwork(ourPTail, ourPHead-ourPTail, 1); 52130015Sminshall } while (!EmptyChar()); 52230015Sminshall FlushChar(); 52330015Sminshall } else if (HadAid) { 52430015Sminshall DoReadModified(CMD_READ_MODIFIED); 52530015Sminshall } 52630076Sminshall #else /* !defined(PURE3274) */ 52730076Sminshall if (HadAid) { 52830076Sminshall DoReadModified(CMD_READ_MODIFIED); 52930076Sminshall } 53030076Sminshall #endif /* !defined(PURE3274) */ 53130015Sminshall } 53230015Sminshall 53330015Sminshall /* This takes in one character from the keyboard and places it on the 53430015Sminshall * screen. 53530015Sminshall */ 53630015Sminshall 53730015Sminshall static void 53830015Sminshall OneCharacter(c, insert) 53930015Sminshall int c; /* character (Ebcdic) to be shoved in */ 54030015Sminshall int insert; /* are we in insert mode? */ 54130015Sminshall { 54230015Sminshall register int i, j; 54330015Sminshall 54430015Sminshall if (IsProtected(CursorAddress)) { 54530015Sminshall RingBell("Protected Field"); 54630015Sminshall return; 54730015Sminshall } 54830015Sminshall if (insert) { 54930015Sminshall /* is the last character in the field a blank or null? */ 55030015Sminshall i = ScreenDec(FieldInc(CursorAddress)); 55130015Sminshall j = GetHost(i); 55230015Sminshall if (!Disspace(j)) { 55330015Sminshall RingBell("No more room for insert"); 55430015Sminshall return; 55530015Sminshall } else { 55630015Sminshall for (j = ScreenDec(i); i != CursorAddress; 55730015Sminshall j = ScreenDec(j), i = ScreenDec(i)) { 55830015Sminshall AddHost(i, GetHost(j)); 55930015Sminshall } 56030015Sminshall } 56130015Sminshall } 56230015Sminshall AddHost(CursorAddress, c); 56330015Sminshall TurnOnMdt(CursorAddress); 56430015Sminshall CursorAddress = ScreenInc(CursorAddress); 56530015Sminshall if (IsStartField(CursorAddress) && 56630015Sminshall ((FieldAttributes(CursorAddress)&ATTR_AUTO_SKIP_MASK) == 56730015Sminshall ATTR_AUTO_SKIP_VALUE)) { 56830015Sminshall Tab(); 56930015Sminshall } 57030015Sminshall } 57130015Sminshall 57231197Sminshall /* 57331197Sminshall * AcceptKeystroke() 57431197Sminshall * 57531197Sminshall * Processes one keystroke. 57631197Sminshall * 57731197Sminshall * Returns: 57831197Sminshall * 57931197Sminshall * 0 if this keystroke was NOT processed. 58031197Sminshall * 1 if everything went OK. 58131197Sminshall */ 58230015Sminshall 58330015Sminshall int 58431197Sminshall AcceptKeystroke(scancode, shiftstate) 58531197Sminshall int 58631197Sminshall scancode, /* 3270 scancode */ 58731197Sminshall shiftstate; /* The shift state */ 58830015Sminshall { 58930015Sminshall register int c; 59030015Sminshall register int i; 59130015Sminshall register int j; 59230076Sminshall enum ctlrfcn ctlrfcn; 59330015Sminshall 59431197Sminshall if (scancode >= numberof(hits)) { 59531085Sminshall ExitString(stderr, 59631197Sminshall "Unknown scancode encountered in AcceptKeystroke.\n", 1); 59730015Sminshall /*NOTREACHED*/ 59830015Sminshall } 59931197Sminshall ctlrfcn = hits[scancode].hit[HITNUM(shiftstate)].ctlrfcn; 60031197Sminshall c = hits[scancode].hit[HITNUM(shiftstate)].code; 60130015Sminshall 60230015Sminshall if (!UnLocked || HadAid) { 60330015Sminshall if (HadAid) { 60430015Sminshall SendToIBM(); 60530015Sminshall if (!EmptyChar()) { 60631197Sminshall return 0; /* nothing to do */ 60730015Sminshall } 60830015Sminshall } 60930327Sminshall #if !defined(PURE3274) 61030015Sminshall if (!HadAid && EmptyChar()) { 61130076Sminshall if ((ctlrfcn == FCN_RESET) || (ctlrfcn == FCN_MASTER_RESET)) { 61230015Sminshall UnLocked = 1; 61330015Sminshall } 61430015Sminshall } 61530327Sminshall #endif /* !defined(PURE3274) */ 61630015Sminshall if (!UnLocked) { 61731197Sminshall return 0; 61830015Sminshall } 61930015Sminshall } 62031864Sminshall 62130015Sminshall /* now, either empty, or haven't seen aid yet */ 62230015Sminshall 62330076Sminshall #if !defined(PURE3274) 62431864Sminshall /* 62531864Sminshall * If we are in transparent (output) mode, do something special 62631864Sminshall * with keystrokes. 62731864Sminshall */ 62830015Sminshall if (TransparentClock == OutputClock) { 62931197Sminshall if (ctlrfcn == FCN_AID) { 63031197Sminshall UnLocked = 0; 63131197Sminshall InsertMode = 0; 63231197Sminshall AidByte = (c); 63331197Sminshall HadAid = 1; 63431197Sminshall } else { 63531197Sminshall switch (ctlrfcn) { 63631197Sminshall case FCN_ESCAPE: 63731197Sminshall StopScreen(1); 63831197Sminshall command(0); 63931476Sminshall if (shell_active == 0) { 64031476Sminshall ConnectScreen(); 64131476Sminshall } 64231197Sminshall break; 64330015Sminshall 64431197Sminshall case FCN_RESET: 64531197Sminshall case FCN_MASTER_RESET: 64631197Sminshall UnLocked = 1; 64731197Sminshall break; 64830015Sminshall 64931197Sminshall default: 65031197Sminshall return 0; 65130015Sminshall } 65230015Sminshall } 65330015Sminshall } 65430076Sminshall #endif /* !defined(PURE3274) */ 65530015Sminshall 65631197Sminshall if (ctlrfcn == FCN_CHARACTER) { 65731197Sminshall /* Add the character to the buffer */ 65831197Sminshall OneCharacter(c, InsertMode); 65931197Sminshall } else if (ctlrfcn == FCN_AID) { /* got Aid */ 66031197Sminshall if (c == AID_CLEAR) { 66131197Sminshall LocalClearScreen(); /* Side effect is to clear 3270 */ 66230015Sminshall } 66331197Sminshall ResetOiaOnlineA(&OperatorInformationArea); 66431197Sminshall SetOiaTWait(&OperatorInformationArea); 66531197Sminshall ResetOiaInsert(&OperatorInformationArea); 66631197Sminshall InsertMode = 0; /* just like a 3278 */ 66731197Sminshall SetOiaSystemLocked(&OperatorInformationArea); 66831197Sminshall SetOiaModified(); 66931197Sminshall UnLocked = 0; 67031197Sminshall AidByte = c; 67131197Sminshall HadAid = 1; 67231197Sminshall SendToIBM(); 67331197Sminshall } else { 67431197Sminshall switch (ctlrfcn) { 67530015Sminshall 67631197Sminshall case FCN_CURSEL: 67731197Sminshall c = FieldAttributes(CursorAddress)&ATTR_DSPD_MASK; 67831197Sminshall if (!FormattedScreen() 67931197Sminshall || ((c != ATTR_DSPD_DSPD) && (c != ATTR_DSPD_HIGH))) { 68031197Sminshall RingBell("Cursor not in selectable field"); 68131197Sminshall } else { 68231197Sminshall i = ScreenInc(WhereAttrByte(CursorAddress)); 68331197Sminshall c = GetHost(i); 68431197Sminshall if (c == DISP_QUESTION) { 68531197Sminshall AddHost(i, DISP_GREATER_THAN); 68631197Sminshall TurnOnMdt(i); 68731197Sminshall } else if (c == DISP_GREATER_THAN) { 68831197Sminshall AddHost(i, DISP_QUESTION); 68931197Sminshall TurnOffMdt(i); 69031197Sminshall } else if (c == DISP_BLANK || c == DISP_NULL 69131197Sminshall || c == DISP_AMPERSAND) { 69231197Sminshall UnLocked = 0; 69331197Sminshall InsertMode = 0; 69431197Sminshall ResetOiaOnlineA(&OperatorInformationArea); 69531197Sminshall SetOiaTWait(&OperatorInformationArea); 69631197Sminshall SetOiaSystemLocked(&OperatorInformationArea); 69731197Sminshall ResetOiaInsert(&OperatorInformationArea); 69831197Sminshall SetOiaModified(); 69931197Sminshall if (c == DISP_AMPERSAND) { 70031197Sminshall TurnOnMdt(i); /* Only for & type */ 70131197Sminshall AidByte = AID_ENTER; 70230015Sminshall } else { 70331197Sminshall AidByte = AID_SELPEN; 70430015Sminshall } 70531197Sminshall HadAid = 1; 70631197Sminshall SendToIBM(); 70731197Sminshall } else { 70831197Sminshall RingBell( 70931197Sminshall "Cursor not in a selectable field (designator)"); 71030015Sminshall } 71131197Sminshall } 71231197Sminshall break; 71330015Sminshall 71430327Sminshall #if !defined(PURE3274) 71531197Sminshall case FCN_ERASE: 71631197Sminshall if (IsProtected(ScreenDec(CursorAddress))) { 71731197Sminshall RingBell("Protected Field"); 71831197Sminshall } else { 71931197Sminshall CursorAddress = ScreenDec(CursorAddress); 72031197Sminshall Delete(CursorAddress, ScreenInc(CursorAddress)); 72131197Sminshall } 72231197Sminshall break; 72331197Sminshall case FCN_WERASE: 72431197Sminshall j = CursorAddress; 72531197Sminshall i = ScreenDec(j); 72631197Sminshall if (IsProtected(i)) { 72731197Sminshall RingBell("Protected Field"); 72831197Sminshall } else { 72931197Sminshall SetXIsProtected(); 73031197Sminshall while ((!XIsProtected(i) && Disspace(GetHost(i))) 73131197Sminshall && (i != j)) { 73231197Sminshall i = ScreenDec(i); 73330015Sminshall } 73431197Sminshall /* we are pointing at a character in a word, or 73531197Sminshall * at a protected position 73631197Sminshall */ 73731197Sminshall while ((!XIsProtected(i) && !Disspace(GetHost(i))) 73831197Sminshall && (i != j)) { 73931197Sminshall i = ScreenDec(i); 74030015Sminshall } 74131197Sminshall /* we are pointing at a space, or at a protected 74231197Sminshall * position 74331197Sminshall */ 74431197Sminshall CursorAddress = ScreenInc(i); 74531197Sminshall Delete(CursorAddress, j); 74631197Sminshall } 74731197Sminshall break; 74830015Sminshall 74931197Sminshall case FCN_FERASE: 75031197Sminshall if (IsProtected(CursorAddress)) { 75131197Sminshall RingBell("Protected Field"); 75231197Sminshall } else { 75331197Sminshall CursorAddress = ScreenInc(CursorAddress); /* for btab */ 75431197Sminshall BackTab(); 75531197Sminshall EraseEndOfField(); 75631197Sminshall } 75731197Sminshall break; 75830015Sminshall 75931197Sminshall case FCN_RESET: 76031197Sminshall if (InsertMode) { 76131197Sminshall InsertMode = 0; 76231197Sminshall ResetOiaInsert(&OperatorInformationArea); 76331197Sminshall SetOiaModified(); 76431197Sminshall } 76531197Sminshall break; 76631197Sminshall case FCN_MASTER_RESET: 76731197Sminshall if (InsertMode) { 76831197Sminshall InsertMode = 0; 76931197Sminshall ResetOiaInsert(&OperatorInformationArea); 77031197Sminshall SetOiaModified(); 77131197Sminshall } 77231197Sminshall RefreshScreen(); 77331197Sminshall break; 77430327Sminshall #endif /* !defined(PURE3274) */ 77530015Sminshall 77631197Sminshall case FCN_UP: 77731197Sminshall CursorAddress = ScreenUp(CursorAddress); 77831197Sminshall break; 77930015Sminshall 78031197Sminshall case FCN_LEFT: 78131197Sminshall CursorAddress = ScreenDec(CursorAddress); 78231197Sminshall break; 78330015Sminshall 78431197Sminshall case FCN_RIGHT: 78531197Sminshall CursorAddress = ScreenInc(CursorAddress); 78631197Sminshall break; 78730015Sminshall 78831197Sminshall case FCN_DOWN: 78931197Sminshall CursorAddress = ScreenDown(CursorAddress); 79031197Sminshall break; 79130015Sminshall 79231197Sminshall case FCN_DELETE: 79331197Sminshall if (IsProtected(CursorAddress)) { 79431197Sminshall RingBell("Protected Field"); 79531197Sminshall } else { 79631197Sminshall Delete(CursorAddress, ScreenInc(CursorAddress)); 79731197Sminshall } 79831197Sminshall break; 79931197Sminshall 80031197Sminshall case FCN_INSRT: 80131197Sminshall InsertMode = !InsertMode; 80231197Sminshall if (InsertMode) { 80331197Sminshall SetOiaInsert(&OperatorInformationArea); 80431197Sminshall } else { 80531197Sminshall ResetOiaInsert(&OperatorInformationArea); 80631197Sminshall } 80731197Sminshall SetOiaModified(); 80831197Sminshall break; 80931197Sminshall 81031197Sminshall case FCN_HOME: 81131197Sminshall Home(); 81231197Sminshall break; 81331197Sminshall 81431197Sminshall case FCN_NL: 81531197Sminshall /* The algorithm is to look for the first unprotected 81631197Sminshall * column after column 0 of the following line. Having 81731197Sminshall * found that unprotected column, we check whether the 81831197Sminshall * cursor-address-at-entry is at or to the right of the 81931197Sminshall * LeftMargin AND the LeftMargin column of the found line 82031197Sminshall * is unprotected. If this conjunction is true, then 82131197Sminshall * we set the found pointer to the address of the LeftMargin 82231197Sminshall * column in the found line. 82331197Sminshall * Then, we set the cursor address to the found address. 82431197Sminshall */ 82531197Sminshall i = SetBufferAddress(ScreenLine(ScreenDown(CursorAddress)), 0); 82631197Sminshall j = ScreenInc(WhereAttrByte(CursorAddress)); 82731197Sminshall do { 82831197Sminshall if (IsUnProtected(i)) { 82931197Sminshall break; 83030015Sminshall } 83131197Sminshall /* Again (see comment in Home()), this COULD be a problem 83231197Sminshall * with an unformatted screen. 83331197Sminshall */ 83431197Sminshall /* If there was a field with only an attribute byte, 83531197Sminshall * we may be pointing to the attribute byte of the NEXT 83631197Sminshall * field, so just look at the next byte. 83731197Sminshall */ 83831197Sminshall if (IsStartField(i)) { 83931197Sminshall i = ScreenInc(i); 84031192Sminshall } else { 84131197Sminshall i = ScreenInc(FieldInc(i)); 84231192Sminshall } 84331197Sminshall } while (i != j); 84431197Sminshall if (!IsUnProtected(i)) { /* couldn't find unprotected */ 84531197Sminshall i = SetBufferAddress(0,0); 84631197Sminshall } 84731197Sminshall if (OptLeftMargin <= ScreenLineOffset(CursorAddress)) { 84831197Sminshall if (IsUnProtected(SetBufferAddress(ScreenLine(i), 84931197Sminshall OptLeftMargin))) { 85031197Sminshall i = SetBufferAddress(ScreenLine(i), OptLeftMargin); 85131197Sminshall } 85231197Sminshall } 85331197Sminshall CursorAddress = i; 85431197Sminshall break; 85530015Sminshall 85631197Sminshall case FCN_EINP: 85731197Sminshall if (!FormattedScreen()) { 85831197Sminshall i = CursorAddress; 85931197Sminshall TurnOffMdt(i); 86030015Sminshall do { 86131197Sminshall AddHost(i, 0); 86231197Sminshall i = ScreenInc(i); 86331197Sminshall } while (i != CursorAddress); 86431197Sminshall } else { 86531197Sminshall /* 86631197Sminshall * The algorithm is: go through each unprotected 86731197Sminshall * field on the screen, clearing it out. When 86831197Sminshall * we are at the start of a field, skip that field 86931197Sminshall * if its contents are protected. 87030015Sminshall */ 87131197Sminshall i = j = FieldInc(CursorAddress); 87231197Sminshall do { 87331197Sminshall if (IsUnProtected(ScreenInc(i))) { 87430015Sminshall i = ScreenInc(i); 87531197Sminshall TurnOffMdt(i); 87631197Sminshall do { 87731197Sminshall AddHost(i, 0); 87831197Sminshall i = ScreenInc(i); 87931197Sminshall } while (!IsStartField(i)); 88030015Sminshall } else { 88131197Sminshall i = FieldInc(i); 88230015Sminshall } 88330015Sminshall } while (i != j); 88431197Sminshall } 88531197Sminshall Home(); 88631197Sminshall break; 88730015Sminshall 88831197Sminshall case FCN_EEOF: 88931197Sminshall EraseEndOfField(); 89031197Sminshall break; 89130015Sminshall 89231197Sminshall case FCN_SPACE: 89331197Sminshall OneCharacter(DISP_BLANK, InsertMode); /* Add cent */ 89431197Sminshall break; 89530015Sminshall 89631197Sminshall case FCN_CENTSIGN: 89731197Sminshall OneCharacter(DISP_CENTSIGN, InsertMode); /* Add cent */ 89831197Sminshall break; 89930015Sminshall 90031197Sminshall case FCN_FM: 90131197Sminshall OneCharacter(DISP_FM, InsertMode); /* Add field mark */ 90231197Sminshall break; 90330015Sminshall 90431197Sminshall case FCN_DP: 90531197Sminshall if (IsProtected(CursorAddress)) { 90631197Sminshall RingBell("Protected Field"); 90731197Sminshall } else { 90831197Sminshall OneCharacter(DISP_DUP, InsertMode);/* Add dup character */ 90931197Sminshall Tab(); 91031197Sminshall } 91131197Sminshall break; 91230015Sminshall 91331197Sminshall case FCN_TAB: 91431197Sminshall Tab(); 91531197Sminshall break; 91630015Sminshall 91731197Sminshall case FCN_BTAB: 91831197Sminshall BackTab(); 91931197Sminshall break; 92030015Sminshall 92130015Sminshall #ifdef NOTUSED /* Actually, this is superseded by unix flow 92231197Sminshall * control. 92331197Sminshall */ 92431197Sminshall case FCN_XOFF: 92531197Sminshall Flow = 0; /* stop output */ 92631197Sminshall break; 92730015Sminshall 92831197Sminshall case FCN_XON: 92931197Sminshall if (!Flow) { 93031197Sminshall Flow = 1; /* turn it back on */ 93131197Sminshall DoTerminalOutput(); 93231197Sminshall } 93331197Sminshall break; 93430015Sminshall #endif /* NOTUSED */ 93530015Sminshall 93630327Sminshall #if !defined(PURE3274) 93731197Sminshall case FCN_ESCAPE: 93831197Sminshall /* FlushChar(); do we want to flush characters from before? */ 93931197Sminshall StopScreen(1); 94031197Sminshall command(0); 94131476Sminshall if (shell_active == 0) { 94231476Sminshall ConnectScreen(); 94331476Sminshall } 94431197Sminshall break; 94530015Sminshall 94631197Sminshall case FCN_DISC: 94731197Sminshall StopScreen(1); 94831197Sminshall suspend(); 94931197Sminshall setconnmode(); 95031197Sminshall ConnectScreen(); 95131197Sminshall break; 95230015Sminshall 95331197Sminshall case FCN_RESHOW: 95431197Sminshall RefreshScreen(); 95531197Sminshall break; 95630015Sminshall 95731197Sminshall case FCN_SETTAB: 95831197Sminshall OptColTabs[ScreenLineOffset(CursorAddress)] = 1; 95931197Sminshall break; 96030015Sminshall 96131197Sminshall case FCN_DELTAB: 96231197Sminshall OptColTabs[ScreenLineOffset(CursorAddress)] = 0; 96331197Sminshall break; 96430015Sminshall 96531197Sminshall /* 96631197Sminshall * Clear all tabs, home line, and left margin. 96731197Sminshall */ 96831197Sminshall case FCN_CLRTAB: 96931197Sminshall for (i = 0; i < sizeof OptColTabs; i++) { 97031197Sminshall OptColTabs[i] = 0; 97131197Sminshall } 97231197Sminshall OptHome = 0; 97331197Sminshall OptLeftMargin = 0; 97431197Sminshall break; 97530015Sminshall 97631197Sminshall case FCN_COLTAB: 97731197Sminshall ColTab(); 97831197Sminshall break; 97930015Sminshall 98031197Sminshall case FCN_COLBAK: 98131197Sminshall ColBak(); 98231197Sminshall break; 98330015Sminshall 98431197Sminshall case FCN_INDENT: 98531197Sminshall ColTab(); 98631197Sminshall OptLeftMargin = ScreenLineOffset(CursorAddress); 98731197Sminshall break; 98830015Sminshall 98931197Sminshall case FCN_UNDENT: 99031197Sminshall ColBak(); 99131197Sminshall OptLeftMargin = ScreenLineOffset(CursorAddress); 99231197Sminshall break; 99330015Sminshall 99431197Sminshall case FCN_SETMRG: 99531197Sminshall OptLeftMargin = ScreenLineOffset(CursorAddress); 99631197Sminshall break; 99730015Sminshall 99831197Sminshall case FCN_SETHOM: 99931197Sminshall OptHome = ScreenLine(CursorAddress); 100031197Sminshall break; 100130015Sminshall 100231197Sminshall /* 100331197Sminshall * Point to first character of next unprotected word on 100431197Sminshall * screen. 100531197Sminshall */ 100631197Sminshall case FCN_WORDTAB: 100731197Sminshall i = CursorAddress; 100831197Sminshall SetXIsProtected(); 100931197Sminshall while (!XIsProtected(i) && !Disspace(GetHost(i))) { 101031197Sminshall i = ScreenInc(i); 101131197Sminshall if (i == CursorAddress) { 101231197Sminshall break; 101330015Sminshall } 101431197Sminshall } 101531197Sminshall /* i is either protected, a space (blank or null), 101631197Sminshall * or wrapped 101731197Sminshall */ 101831197Sminshall while (XIsProtected(i) || Disspace(GetHost(i))) { 101931197Sminshall i = ScreenInc(i); 102031197Sminshall if (i == CursorAddress) { 102131197Sminshall break; 102230015Sminshall } 102331197Sminshall } 102431197Sminshall CursorAddress = i; 102531197Sminshall break; 102630015Sminshall 102731197Sminshall case FCN_WORDBACKTAB: 102831197Sminshall i = ScreenDec(CursorAddress); 102931197Sminshall SetXIsProtected(); 103031197Sminshall while (XIsProtected(i) || Disspace(GetHost(i))) { 103131197Sminshall i = ScreenDec(i); 103231197Sminshall if (i == CursorAddress) { 103331197Sminshall break; 103430015Sminshall } 103531197Sminshall } 103631197Sminshall /* i is pointing to a character IN an unprotected word 103731197Sminshall * (or i wrapped) 103831197Sminshall */ 103931197Sminshall while (!Disspace(GetHost(i))) { 104031197Sminshall i = ScreenDec(i); 104131197Sminshall if (i == CursorAddress) { 104231197Sminshall break; 104330015Sminshall } 104431197Sminshall } 104531197Sminshall CursorAddress = ScreenInc(i); 104631197Sminshall break; 104730015Sminshall 104831197Sminshall /* Point to last non-blank character of this/next 104931197Sminshall * unprotected word. 105031197Sminshall */ 105131197Sminshall case FCN_WORDEND: 105231197Sminshall i = ScreenInc(CursorAddress); 105331197Sminshall SetXIsProtected(); 105431197Sminshall while (XIsProtected(i) || Disspace(GetHost(i))) { 105531197Sminshall i = ScreenInc(i); 105631197Sminshall if (i == CursorAddress) { 105731197Sminshall break; 105830015Sminshall } 105931197Sminshall } 106031197Sminshall /* we are pointing at a character IN an 106131197Sminshall * unprotected word (or we wrapped) 106231197Sminshall */ 106331197Sminshall while (!Disspace(GetHost(i))) { 106431197Sminshall i = ScreenInc(i); 106531197Sminshall if (i == CursorAddress) { 106631197Sminshall break; 106730015Sminshall } 106831197Sminshall } 106931197Sminshall CursorAddress = ScreenDec(i); 107031197Sminshall break; 107130015Sminshall 107231197Sminshall /* Get to last non-blank of this/next unprotected 107331197Sminshall * field. 107431197Sminshall */ 107531197Sminshall case FCN_FIELDEND: 107631197Sminshall i = LastOfField(CursorAddress); 107731197Sminshall if (i != CursorAddress) { 107831197Sminshall CursorAddress = i; /* We moved; take this */ 107931197Sminshall } else { 108031197Sminshall j = FieldInc(CursorAddress); /* Move to next field */ 108131197Sminshall i = LastOfField(j); 108231197Sminshall if (i != j) { 108331197Sminshall CursorAddress = i; /* We moved; take this */ 108430015Sminshall } 108531197Sminshall /* else - nowhere else on screen to be; stay here */ 108631197Sminshall } 108731197Sminshall break; 108830327Sminshall #endif /* !defined(PURE3274) */ 108930015Sminshall 109031197Sminshall default: 109131197Sminshall /* We don't handle this yet */ 109231197Sminshall RingBell("Function not implemented"); 109331197Sminshall } 109431197Sminshall } 109531197Sminshall return 1; /* We did something! */ 109631197Sminshall } 109731197Sminshall 109831197Sminshall 109931197Sminshall /* 110031197Sminshall * We get data from the terminal. We keep track of the shift state 110131197Sminshall * (including ALT, CONTROL), and then call AcceptKeystroke to actually 110231197Sminshall * process any non-shift keys. 110331197Sminshall */ 110431197Sminshall 110531197Sminshall int 110631197Sminshall DataFrom3270(buffer, count) 110731197Sminshall unsigned char *buffer; /* where the data is */ 110831197Sminshall int count; /* how much data there is */ 110931197Sminshall { 111031197Sminshall int origCount; 111131197Sminshall 111231197Sminshall origCount = count; 111331197Sminshall 111431197Sminshall while (count) { 111531197Sminshall if (*buffer >= numberof(hits)) { 111631197Sminshall ExitString(stderr, 111731197Sminshall "Unknown scancode encountered in DataFrom3270.\n", 1); 111831197Sminshall /*NOTREACHED*/ 111931197Sminshall } 112031197Sminshall 112131197Sminshall switch (hits[*buffer].hit[HITNUM(rememberedshiftstate)].ctlrfcn) { 112231197Sminshall 112331197Sminshall case FCN_MAKE_SHIFT: 112431197Sminshall rememberedshiftstate |= (SHIFT_RIGHT|SHIFT_UPSHIFT); 112531197Sminshall break; 112631197Sminshall case FCN_BREAK_SHIFT: 112731197Sminshall rememberedshiftstate &= ~(SHIFT_RIGHT|SHIFT_UPSHIFT); 112831197Sminshall break; 112931197Sminshall case FCN_MAKE_ALT: 113031197Sminshall rememberedshiftstate |= SHIFT_ALT; 113131197Sminshall break; 113231197Sminshall case FCN_BREAK_ALT: 113331197Sminshall rememberedshiftstate &= ~SHIFT_ALT; 113431197Sminshall break; 113531197Sminshall default: 113631197Sminshall if (AcceptKeystroke(*buffer, rememberedshiftstate) == 0) { 113731197Sminshall return(origCount-count); 113830015Sminshall } 113931197Sminshall break; 114030015Sminshall } 114131197Sminshall buffer++; 114231197Sminshall count--; 114330015Sminshall } 114430015Sminshall return(origCount-count); 114530015Sminshall } 1146