summaryrefslogtreecommitdiffstats
path: root/private/os2/os2ses/kbdrqust.c
diff options
context:
space:
mode:
Diffstat (limited to 'private/os2/os2ses/kbdrqust.c')
-rw-r--r--private/os2/os2ses/kbdrqust.c4046
1 files changed, 4046 insertions, 0 deletions
diff --git a/private/os2/os2ses/kbdrqust.c b/private/os2/os2ses/kbdrqust.c
new file mode 100644
index 000000000..3c17e9332
--- /dev/null
+++ b/private/os2/os2ses/kbdrqust.c
@@ -0,0 +1,4046 @@
+/*++
+
+Copyright (c) 1989 Microsoft Corporation
+
+Module Name:
+
+ kbdrqust.c
+
+Abstract:
+
+ This module contains the Kbd requests thread and
+ the handler for Kbd requests.
+
+Author:
+
+ Michael Jarus (mjarus) 23-Oct-1991
+
+Environment:
+
+ User Mode Only
+
+Revision History:
+
+--*/
+
+#define WIN32_ONLY
+#include "os2ses.h"
+#include "trans.h"
+#include "event.h"
+#include "kbd.h"
+#include "os2win.h"
+#include <stdio.h>
+
+#define OS2_SCAN_INSERT_0 0x52
+#define OS2_SCAN_END_1 0x4F
+#define OS2_SCAN_CTRL_END_1 0x75
+#define OS2_SCAN_DOWN_2 0x50
+#define OS2_SCAN_LEFT_4 0x4B
+#define OS2_SCAN_CTRL_LEFT_4 0x73
+#define OS2_SCAN_RIGHT_6 0x4D
+#define OS2_SCAN_CTRL_RIGHT_6 0x74
+#define OS2_SCAN_HOME_7 0x47
+#define OS2_SCAN_CTRL_HOME_7 0x77
+#define OS2_SCAN_UP_8 0x48
+#define OS2_SCAN_DEL 0x53
+
+DWORD
+Ow2GetOs2KbdEventIntoQueue();
+
+DWORD
+Ow2VioUpdateCurPos(
+ IN COORD CurPos
+ );
+
+DWORD
+Ow2VioReadCurPos(
+ );
+
+DWORD
+Ow2VioReadCurType();
+
+VOID
+KbdSetTable(
+ IN ULONG KbdCP
+ );
+
+#if DBG
+BYTE KbdEchoCharToConsoleStr[] = "KbdEchoCharToConsole";
+BYTE KbdEchoCharStr[] = "KbdEchoChar";
+BYTE KbdEchoStringToConsoleStr[] = "KbdEchoStringToConsole";
+BYTE KbdEchoAStringStr[] = "KbdEchoAString";
+BYTE KbdEchoBSAndFillSpacesStr[] = "KbdEchoBSAndFillSpaces";
+BYTE KbdEchoESCStr[] = "KbdEchoESC";
+BYTE KbdCueMoveToRightStr[] = "KbdCueMoveToRight";
+#endif
+
+#define KEYBOARD_NEW_MASK (USHORT)(KEYBOARD_2B_TURNAROUND | KEYBOARD_SHIFT_REPORT)
+#define KEYBOARD_ECHO (USHORT)(KEYBOARD_ECHO_ON | KEYBOARD_ECHO_OFF)
+#define KEYBOARD_INPUT (USHORT)(KEYBOARD_ASCII_MODE | KEYBOARD_BINARY_MODE)
+
+#define KEYBOARD_BINARY_SHIFT (KEYBOARD_BINARY_MODE | KEYBOARD_SHIFT_REPORT)
+#define MODE_BINARY_SHIFT (SHIFT_REPORT_MODE | BINARY_MODE)
+
+#define KEYBOARD_SHIFT_ASCII_INPUT (USHORT)(KEYBOARD_ASCII_MODE | KEYBOARD_SHIFT_REPORT)
+#define KEYBOARD_INPUT_RESERVED \
+ ~( KEYBOARD_ECHO_ON | KEYBOARD_ECHO_OFF | KEYBOARD_BINARY_MODE | \
+ KEYBOARD_ASCII_MODE | KEYBOARD_MODIFY_STATE | KEYBOARD_MODIFY_INTERIM | \
+ KEYBOARD_MODIFY_TURNAROUND | KEYBOARD_2B_TURNAROUND | KEYBOARD_SHIFT_REPORT )
+
+#define KbdBuffSize 256
+#define KBD_BUFFER_ADDRESS ((PUCHAR)KbdAddress) // used for ECHO to console
+#define KBD_BUFFER_SIZE OS2_KBD_PORT_MSG_SIZE
+
+#define ALPHANUM_CHAR(BuffIndex) \
+ ((((Char = LineInputBuff[BuffIndex].Char) >= '0') && \
+ (Char <= '9')) || \
+ ((Char >= 'a') && (Char <= 'z')) || \
+ ((Char >= 'A') && (Char <= 'Z'))) \
+
+#define GET_CURRENT_COORD (SesGrp->WinCoord)
+
+typedef struct _LINE_EDIT_KBD
+{
+ UCHAR Char;
+ SHORT X_Pos; // Used as X Coordinate for edit
+ // Used as offset for CUE
+} LINE_EDIT_KBD;
+
+typedef enum
+{
+ CharMode,
+ AsciiMode,
+ BinaryMode
+} KBDMODE;
+
+//CONSOLE_SCREEN_BUFFER_INFO KbdConsoleInfo;
+KBDMODE KbdState; // state for HandleKeyboardInput
+ULONG KbdWaitFlag; // flags for KbdCheckPackage and
+ // arg to GetKeyboardInput
+/* (from event.h)
+ CharIn Peek String Read
+ ------ ---- ------ ----
+ WAIT_MASK 0x01 User NOWAIT User WAIT (0 IO_WAIT, 1 IO_NOWAIT)
+ ENABLE_SHIFT_KEY 0x02 <if SHIFT report>
+ ENABLE_NON_ASCII_KEY 0x04 + + <if BINARY>
+ ENABLE_LN_EDITOR_KEY 0x08 <if ASCII (for KEYS OFF)>
+ ENABLE_KEYS_ON_KEY 0x10 <if ASCII and KEYS ON>
+ */
+
+#define ENABLE_SHIFT_KEY 0x02 /* enable shift report keys (and break for them) */
+
+/*
+ * for Command line editing
+ */
+
+PUCHAR KbdCueBuffer = NULL; // 64K CUE buffer for KEYS ON
+ // This is a cyclic bufffer and all
+ // pointers are index of type USHORT.
+BOOL KbdLineWasEdited; // TRUE if user edited the current line
+USHORT KbdNextLinePointer; // where to put next input line
+USHORT KbdCurrentLine; // index of current line in KbdCueBuffer
+USHORT KbdIndexInLine; // index of current char in input line
+BOOL KbdCueUpRowIsCurrent; // flag set after CR to indicate UP arrow
+ // returns the current line
+
+/*
+ * for GetOs2KbdRead
+ */
+
+USHORT KbdBuffNextPtr; // when string typed was longer the size (ASCII read only)
+ // it points to the remain string
+USHORT KbdBuffNextLen; // remaining bytes in the string
+
+/*
+ * for for HandleKeyboardInput.CharMode:
+ */
+
+BOOL KbdPeekFlag; // called by CharIn (0) or Peek(1)
+
+/*
+ * for for HandleKeyboardInput.Ascii/BinaryMode:
+ */
+
+USHORT KbdInputLength; // the current string length (num of chars
+ // already in input buffer for the user)
+ULONG KbdMaxLength; // maximun input length (String.cb
+ // for StringIn, KbdBuffSize for Read)
+USHORT KbdLength; // On enter: the requested length,
+ // On exit: the returned string length
+USHORT KbdEndLength; // length of Turn Around string
+
+/*
+ * for for HandleKeyboardInput.AsciiMode:
+ */
+
+LINE_EDIT_KBD LineInputBuff[KbdBuffSize]; // the current input buffer
+UCHAR KbdLastBuff[KbdBuffSize]; // holds the previous "Buff"
+USHORT KbdLastBuffPtr; // points to the char in KbdLastBuff to take (if F1)
+USHORT LastStringLength; // length of the previous "Buff"
+USHORT KbdEditFlag; // support EDIT line (F1 .. F4, ->, <-, Ins, Del)
+USHORT KbdReadMode; // called by StringIn (0) or Read(1)
+USHORT KbdFxWaitForChar; // waiting for char after F2(1) or F4(2)
+BOOL KbdEchoFlag; // set if ECHO ON
+BOOL KbdInsertOn; // INSERT key current state (1 - ON)
+BOOL KbdEchoString; // copy string from last buffer (F2 and F3)
+USHORT KbdTurnAroundChar; // turn around char to look for
+BOOLEAN KbdTurnAroundCharTwo; // 2-byte turn around char (KEYBOARD_2B_TURNAROUND)
+USHORT KbdDelIndex;
+SHORT KbdFirstColumn; // first column for this input request
+SHORT KbdStartOfLine; // first column on this line
+
+BOOLEAN KbdSetupTurnAroundCharTwo; // KbsSetStatus of KbdTurnAroundCharTwo:
+ // before new read KbdTurnAroundCharTwo
+ // is updated from this.
+
+#ifdef JAPAN
+// MSKK May.07.1993 V-AkihiS
+/*
+ * for KBDGetKbdType
+ */
+extern USHORT KbdType, KbdSubType;
+extern BYTE OemId, OemSubType;
+#endif
+
+/*
+ * internal functions
+ */
+
+DWORD
+GetOs2KbdKey(
+ IN BOOL PeekFlag,
+ IN USHORT WaitFlag,
+ OUT PKBDKEYINFO KeyInfo,
+ IN PVOID pMsg,
+ OUT PULONG pReply
+ );
+
+DWORD
+GetOs2KbdString(
+ IN USHORT WaitFlag,
+ IN OUT PKBDREQUEST PReq,
+ IN PVOID pMsg,
+ OUT PULONG pReply
+ );
+
+DWORD
+GetOs2KbdRead(
+ IN PULONG Length,
+ IN PVOID pMsg,
+ OUT PULONG pReply
+ );
+
+VOID
+KbdNewSetup(
+ IN PKBDINFO LastSetup
+ );
+
+DWORD
+GetOs2KbdStringRead(
+ IN USHORT WaitFlag,
+ IN USHORT EditFlag,
+ IN USHORT ReadMode,
+ IN ULONG MaxLength,
+ IN OUT PUSHORT Length,
+ IN PVOID pMsg,
+ OUT PULONG pReply
+ );
+
+DWORD
+HandleKeyboardInput(
+ IN PKEYEVENTINFO pKbd
+ );
+
+DWORD
+Ow2KbdSetStatus(
+ IN PKBDREQUEST PReq
+ );
+
+BOOL
+KbdKeyIsTurnAround(
+ IN UCHAR Char,
+ IN UCHAR Scan
+ );
+
+/*
+ * Echo functions for KbdStringIn/Read (ASCII)
+ */
+
+DWORD
+KbdEchoNL(
+ IN ULONG Count
+ );
+
+DWORD
+KbdEchoESC(
+ IN ULONG Count,
+ IN ULONG HorzMove
+ );
+
+DWORD
+KbdEchoBSAndFillSpaces(
+ IN ULONG BSCount,
+ IN ULONG SpaceCount
+ );
+
+DWORD
+KbdEchoBeep(
+ IN ULONG Count
+ );
+
+DWORD
+KbdEchoChar(
+ IN UCHAR Char,
+ IN ULONG Count
+ );
+
+DWORD
+KbdEchoAString(
+ IN PUCHAR String,
+ IN ULONG Length
+ );
+
+/*
+ * CUE functions
+ */
+
+VOID
+KbdCueEraseAndDisplayLine(
+ IN ULONG NewLineIndex
+ );
+
+VOID
+KbdCueMoveToRight(
+ IN ULONG StartIndex,
+ IN ULONG StringLength,
+ IN ULONG UpdateLVB
+ );
+
+VOID
+KbdCueMoveToLeft(
+ IN ULONG StartIndex,
+ IN ULONG MoveLength
+ );
+
+VOID
+KbdCueUpdateBufferOffset(
+ IN ULONG StartIndex,
+ IN ULONG StringLength,
+ IN ULONG StartOffset
+ );
+
+VOID
+KbdCueDeleteCharAndShift(
+ IN ULONG StartIndex,
+ IN ULONG NumChar
+ );
+
+VOID
+KbdCueHandleChar(
+ IN UCHAR Char,
+ IN ULONG Count
+ );
+
+VOID
+KbdCueSetCurTypeToHalf();
+
+VOID
+KbdCueSetCurTypeToQuater();
+
+
+DWORD
+KbdInit(IN VOID)
+{
+ KBDINFO LastSetup;
+
+ if (InitQueue(&KbdQueue))
+ {
+ return(TRUE);
+ }
+
+ KbdMonQueue = PhyKbdQueue = KbdQueue;
+
+ KbdQueue->Setup.cb = sizeof(KBDINFO);
+ KbdQueue->Setup.fsMask = KEYBOARD_ECHO_ON | KEYBOARD_ASCII_MODE;
+ KbdQueue->Setup.chTurnAround = 0x0D; /* default: <ENTER>/<CR> */
+ KbdQueue->Setup.fsInterim = 0;
+ KbdQueue->Setup.fsState = 0;
+ KbdQueue->bNlsShift = 0;
+ KbdQueue->LastKeyFlag = FALSE;
+
+ LastSetup.fsMask = KEYBOARD_BINARY_MODE;
+ KbdNewSetup(&LastSetup);
+
+ KbdAddress = ((PCHAR)Os2SessionCtrlDataBaseAddress) + KBD_OFFSET;
+
+ Ow2KbdXlateVars.OtherFlags = InterruptTime;
+
+ return(FALSE);
+}
+
+
+DWORD
+KbdInitAfterSesGrp(IN VOID)
+{
+ if (SesGrp->KeysOnFlag)
+ {
+ KbdCueBuffer = HeapAlloc(HandleHeap, 0, 64 * 1024);
+ if ( KbdCueBuffer == NULL )
+ {
+#if DBG
+ KdPrint(("OS2SES(KbdRequset): unable to allocate Cue buffer\n"));
+#endif
+ return ERROR_KBD_NO_MORE_HANDLE;
+ }
+ }
+ return(FALSE);
+}
+
+
+BOOL
+ServeKbdRequest(IN PKBDREQUEST PReq,
+ OUT PVOID PStatus,
+ IN PVOID pMsg,
+ OUT PULONG pReply)
+{
+ DWORD Rc;
+ KBDINFO LastSetup;
+ PKEY_EVENT_QUEUE TempKbdQueue;
+ KEYEVENTINFO In;
+
+ Rc = 0;
+ TempKbdQueue = (PKEY_EVENT_QUEUE) PReq->hKbd;
+
+#if DBG
+ if (( PReq->Request != KBDNewFocus ) &&
+ ( PReq->Request != KBDNewCountry ) &&
+ ( PReq->Request != KBDOpen ) &&
+ (KbdQueue != TempKbdQueue))
+ {
+ KdPrint(("OS2SES(KbdRequest-%u): illegal handle\n",
+ PReq->Request));
+ }
+#endif
+
+ switch (PReq->Request)
+ {
+ case KBDOpen:
+ if((Rc = InitQueue(&TempKbdQueue)) == NO_ERROR)
+ {
+ PReq->hKbd = TempKbdQueue;
+ }
+ break;
+
+ case KBDClose:
+ if (( TempKbdQueue != PhyKbdQueue) && TempKbdQueue->Count )
+ {
+ if ( !--TempKbdQueue->Count )
+ {
+ HeapFree(HandleHeap, 0,
+ (LPSTR) TempKbdQueue->MonHdr.MemoryStartAddress);
+ }
+ }
+ break;
+
+ case KBDDupLogHandle:
+ if (TempKbdQueue != PhyKbdQueue)
+ {
+ TempKbdQueue->Count++ ;
+ }
+ break;
+
+ case KBDReadStdIn:
+ if (!hStdInConsoleType)
+ {
+#if DBG
+ KdPrint(("OS2SES(KbdRequest-KbdReadStdIn): illegal request\n"));
+#endif
+ Rc = ERROR_INVALID_HANDLE;
+ break;
+ }
+ // falls into KBDRead
+
+ case KBDRead:
+ Rc = GetOs2KbdRead(&PReq->Length,
+ pMsg,
+ pReply);
+ break;
+
+
+ case KBDCharIn:
+ Rc = GetOs2KbdKey(0, /* CharIn/Peek flag */
+ (USHORT)PReq->fWait,
+ &PReq->d.KeyInfo,
+ pMsg,
+ pReply);
+ break;
+
+ case KBDStringIn:
+ Rc = GetOs2KbdString((USHORT)PReq->fWait,
+ PReq,
+ pMsg,
+ pReply);
+ break;
+
+ case KBDPeek:
+ Rc = GetOs2KbdKey(1, /* CharIn/Peek flag */
+ IO_NOWAIT,
+ &PReq->d.KeyInfo,
+ pMsg,
+ pReply);
+ break;
+
+ case KBDFlushBuffer:
+ In.wRepeatCount = 0x7FFF;
+ while (TRUE)
+ {
+ KbdQueue->LastKeyFlag = FALSE;
+ KbdQueue->Out == KbdQueue->In;
+
+ Rc = GetKeyboardInput( IO_NOWAIT,
+ &In,
+ pMsg,
+ pReply);
+
+ if ( !Rc ) /* no char & NO_WAIT */
+ break;
+ }
+ break;
+
+ case KBDGetStatus:
+ if (PReq->d.KbdInfo.cb < 10 )
+ { Rc = ERROR_KBD_INVALID_LENGTH;
+ break;
+ }
+ Ow2GetOs2KbdEventIntoQueue();
+ PReq->d.KbdInfo = KbdQueue->Setup;
+#ifdef DBCS
+// MSKK May.18.1992 KazuM
+ GetNlsMode(&KbdQueue->Setup);
+#endif
+ PReq->d.KbdInfo.fsState &= KBDINFO_STATE_MASK;
+ break;
+
+ case KBDSetStatus:
+ Rc = Ow2KbdSetStatus(PReq);
+ break;
+
+ case KBDFreeFocus:
+ LastSetup = KbdQueue->Setup;
+ KbdQueue = PhyKbdQueue;
+ NewKbdQueue(KbdQueue);
+ KbdNewSetup(&LastSetup);
+ break;
+
+ case KBDNewFocus:
+ LastSetup = KbdQueue->Setup;
+ KbdQueue = TempKbdQueue;
+ NewKbdQueue(KbdQueue);
+ KbdNewSetup(&LastSetup);
+ break;
+
+// BUGBUG?? - do the following requests working on the current/last-focused
+// logical keyboard, on the physical keyboard or on a logical
+// keyboard passed as a parameter
+
+ case KBDGetInputMode:
+ switch (KbdQueue->Setup.fsMask & KEYBOARD_BINARY_SHIFT)
+ {
+ case KEYBOARD_BINARY_SHIFT:
+ PReq->d.InputMode = MODE_BINARY_SHIFT;
+ break;
+
+ case KEYBOARD_BINARY_MODE:
+ PReq->d.InputMode = BINARY_MODE;
+ break;
+
+ default:
+ PReq->d.InputMode = ASCII_MODE;
+ break;
+ }
+ break;
+
+ case KBDGetInterimFlag:
+#ifdef DBCS
+// MSKK May.18.1992 KazuM
+ GetNlsMode(&KbdQueue->Setup);
+#endif
+ PReq->d.Interim = (UCHAR)(KbdQueue->Setup.fsInterim &
+ (CONVERSION_REQUEST | INTERIM_CHAR));
+ break;
+
+ case KBDGetKbdType:
+#ifdef JAPAN
+// MSKK May.07.1993 V-AkihiS
+ if (KbdType == KBD_TYPE_JAPAN && OemId == SUB_KBD_TYPE_MICROSOFT)
+ {
+ switch(OemSubType)
+ {
+ case MICROSOFT_KBD_101_TYPE:
+ PReq->d.KbdType[0] = 0x0001;
+ PReq->d.KbdType[1] = 0x0000;
+ PReq->d.KbdType[2] = 0x0000;
+ break;
+ case MICROSOFT_KBD_AX_TYPE:
+ PReq->d.KbdType[0] = 0x0010;
+ PReq->d.KbdType[1] = 0x0000;
+ PReq->d.KbdType[2] = 0x0001;
+ break;
+ case MICROSOFT_KBD_106_TYPE:
+ PReq->d.KbdType[0] = 0x0001;
+ PReq->d.KbdType[1] = 0x82B3;
+ PReq->d.KbdType[2] = 0x0032;
+ break;
+ case MICROSOFT_KBD_002_TYPE:
+ PReq->d.KbdType[0] = 0x0006;
+ PReq->d.KbdType[1] = 0x82B3;
+ PReq->d.KbdType[2] = 0x0032;
+ break;
+ default:
+ PReq->d.KbdType[0] = 0x0001;
+ PReq->d.KbdType[1] = 0x0000;
+ PReq->d.KbdType[2] = 0x0000;
+#if DBG
+ KdPrint(("OS2SES(Kbd) This keyboard isn't supported yet.\n"));
+#endif
+ }
+ } else
+ {
+ PReq->d.KbdType[0] = 0x0001;
+ PReq->d.KbdType[1] = 0x0000;
+ PReq->d.KbdType[2] = 0x0000;
+#if DBG
+ KdPrint(("OS2SES(Kbd) This keyboard isn't supported yet.\n"));
+#endif
+ }
+#else
+ PReq->d.KbdType = 0x0001; // BUGBUG
+#endif
+ break;
+
+ case KBDGetHotKey:
+ // BUGBUG PReq->d.HotKey =
+ /*
+
+ if ((*pParm != HOTKEY_MAX_COUNT) &&
+ (*pParm != HOTKEY_CURRENT_COUNT))
+ {
+ }
+#define HOTKEY_MAX_COUNT 0x0000
+#define HOTKEY_CURRENT_COUNT 0x0001
+ */
+
+ break;
+
+ case KBDGetShiftState:
+#ifdef DBCS
+// MSKK Oct.20.1992 V-AkihiS
+ GetNlsMode(&KbdQueue->Setup);
+ PReq->d.Shift.fNLS = HIBYTE(KbdQueue->Setup.fsInterim);
+#else
+ PReq->d.Shift.fNLS = KbdQueue->bNlsShift;
+#endif
+ PReq->d.Shift.fsState = KbdQueue->Setup.fsState;
+ break;
+
+ case KBDSetInputMode:
+ LastSetup = KbdQueue->Setup;
+ KbdQueue->Setup.fsMask = (USHORT)
+ ((KbdQueue->Setup.fsMask & ~(KEYBOARD_INPUT | KEYBOARD_SHIFT_REPORT)) |
+ ((PReq->d.InputMode & SHIFT_REPORT_MODE) ? KEYBOARD_SHIFT_REPORT : 0) |
+ ((PReq->d.InputMode & BINARY_MODE ) ?
+ KEYBOARD_BINARY_MODE : KEYBOARD_ASCII_MODE));
+ KbdNewSetup(&LastSetup);
+ break;
+
+ case KBDSetShiftState:
+ LastSetup = KbdQueue->Setup;
+ KbdQueue->Setup.fsState = PReq->d.Shift.fsState;
+ // BUGBUG : SHIFTSTATE.fbNLS PReq->d.Shift.fNLS
+#ifdef DBCS
+// MSKK Oct.20.1992 V-AkihiS
+ KbdQueue->Setup.fsInterim = MAKEWORD(
+ KbdQueue->Setup.fsInterim,
+ PReq->d.Shift.fNLS
+ );
+ SetNlsMode(KbdQueue->Setup);
+#endif
+ KbdNewSetup(&LastSetup);
+ break;
+
+ case KBDSetTypamaticRate:
+ Rc = !SystemParametersInfo(
+ SPI_SETKEYBOARDDELAY,
+ PReq->d.RateDelay.usDelay,
+ NULL,
+ 0);
+ if (!Rc)
+ {
+ Rc = !SystemParametersInfo(
+ SPI_SETKEYBOARDSPEED,
+ PReq->d.RateDelay.usRate,
+ NULL,
+ 0
+ );
+ }
+ break;
+
+ case KBDSetInTerimFlag:
+ LastSetup = KbdQueue->Setup;
+#ifdef DBCS
+// MSKK Mar.03.1993 V-AkihiS
+ KbdQueue->Setup.fsInterim = MAKEWORD(
+ PReq->d.Interim,
+ HIBYTE(KbdQueue->Setup.fsInterim)
+ );
+ SetNlsMode(KbdQueue->Setup);
+#else
+ KbdQueue->Setup.fsInterim = (USHORT)PReq->d.Interim;
+#endif
+ KbdNewSetup(&LastSetup);
+ break;
+
+ case KBDGetCp:
+ PReq->d.CodePage = SesGrp->KbdCP;
+ break;
+
+ case KBDSetCp:
+ Rc = KbdNewCp(PReq->d.CodePage);
+ break;
+
+ case KBDNewCountry:
+ SesGrp->KeyboardCountry = PReq->d.CodePage; //Hack - Not Really CodePage
+ KbdSetTable(SesGrp->KbdCP);
+ *pReply = 0;
+
+ break;
+
+ case KBDXlate:
+ /*
+ {
+ KBD_XLATE_VARS XlateVars;
+ KBD_MON_PACKAGE KeyInfo[3];
+ PKBDTRANS pKbdXlate = &PReq->d.KbdTrans;
+
+ RtlZeroMemory(&XlateVars, sizeof(KBD_XLATE_VARS));
+ if (pKbdXlate->fsShift != 0)
+ {
+ // continue translation
+
+ //? = pKbdXlate->fsShift;
+ }
+
+ RtlZeroMemory(&Os2KeyInfo[0], 3 * sizeof(KBD_MON_PACKAGE));
+
+ //KeyInfo[0].MonitorFlag = pKbdXlate->...;
+ //KeyInfo[0].DeviceFlag = pKbdXlate->...;
+ KeyInfo[0].KeyInfo.chChar = pKbdXlate->chChar;
+ KeyInfo[0].KeyInfo.chScan = pKbdXlate->chScan;
+ KeyInfo[0].KeyInfo.fbStatus = pKbdXlate->fbStatus;
+ KeyInfo[0].KeyInfo.bNlsShift = pKbdXlate->bNlsShift;
+ KeyInfo[0].KeyInfo.fsState = pKbdXlate->fsState;
+ KeyInfo[0].KeyBoardFlag = pKbdXlate->fsDD;
+
+ KeyInfo[0].KeyInfo.fbStatus = 0x40;
+
+ //? XlateVars.XlateFlags |= SecPrefix; // Have seen E0 prefix
+
+ Rc = Ow2KbdXlate(
+ pKbdXlate->chScan, // ScanCode,
+ &XlateVars, // pFlagArea,
+ &KeyInfo[0], // pMonitorPack,
+ Ow2KbdScanTable // pTransTable
+ );
+
+ //? which packet - KeyInfo[?]
+ pKbdXlate->chChar = KeyInfo[0].KeyInfo.chChar;
+ pKbdXlate->chScan = KeyInfo[0].KeyInfo.chScan;
+ pKbdXlate->fbStatus = KeyInfo[0].KeyInfo.fbStatus;
+ pKbdXlate->bNlsShift = KeyInfo[0].KeyInfo.bNlsShift;
+ pKbdXlate->fsState = KeyInfo[0].KeyInfo.fsState;
+ pKbdXlate->fsDD = KeyInfo[0].KeyBoardFlag;
+ //? pKbdXlate->fsXlate = ;
+ //? pKbdXlate->fsShift = ;
+ }
+ */
+ case KBDSetCustXt:
+ /* from ??? */
+ default:
+ Rc = (DWORD)-1L; //STATUS_INVALID_PARAMETER;
+#if DBG
+ IF_OD2_DEBUG2( KBD, OS2_EXE )
+ KdPrint(("OS2SES(KbdRequest): Unknown Kbd request = %X\n", PReq->Request));
+#endif
+ }
+
+ if ( Rc == 1 )
+ {
+ Rc = GetLastError();
+ }
+
+ *(PDWORD) PStatus = Rc;
+ return(TRUE); // Continue
+}
+
+
+DWORD
+Ow2KbdSetStatus(IN PKBDREQUEST PReq)
+{
+ KBDINFO LastSetup, *pKbdSetup;
+ USHORT KbdMask, Mask;
+
+ /*
+ * check legalty of parameters:
+ *
+ * 1. sizeof structure
+ * 2. reserved bits
+ * 3. mutuex bits (ECHO_ON & ECHO_OFF, ASCII & BINARY, ASCII & SHIFT)
+ */
+
+ LastSetup = KbdQueue->Setup;
+ if (PReq->d.KbdInfo.cb != 10 )
+ {
+ return ERROR_KBD_INVALID_LENGTH;
+ }
+
+ KbdMask = PReq->d.KbdInfo.fsMask;
+ pKbdSetup = &KbdQueue->Setup;
+
+ if (KbdMask & KEYBOARD_INPUT_RESERVED)
+ {
+ return ERROR_KBD_INVALID_INPUT_MASK;
+ }
+
+ if ((KbdMask & KEYBOARD_ECHO ) == KEYBOARD_ECHO)
+ {
+ return ERROR_KBD_INVALID_ECHO_MASK;
+ }
+
+ if ((KbdMask & KEYBOARD_INPUT) == KEYBOARD_INPUT)
+ {
+ return ERROR_KBD_INVALID_INPUT_MASK;
+ }
+
+ if ((KbdMask & KEYBOARD_SHIFT_ASCII_INPUT) == KEYBOARD_SHIFT_ASCII_INPUT)
+ {
+ return ERROR_KBD_INVALID_INPUT_MASK;
+ }
+
+ /*
+ * check modified bits and set the flags according:
+ *
+ * 1. STATE - set fsState
+ * 2. INTERIM - set fsInterim
+ * 3. TURNAROUND - set chTurnAround
+ */
+
+#ifdef DBCS
+// MSKK Jul.1993 V-AKihiS
+ if (KbdMask & KEYBOARD_MODIFY_STATE)
+ {
+ pKbdSetup->fsState = PReq->d.KbdInfo.fsState;
+ pKbdSetup->fsInterim = MAKEWORD(
+ LOBYTE(pKbdSetup->fsInterim),
+ HIBYTE(PReq->d.KbdInfo.fsInterim)
+ );
+ SetNlsMode(*pKbdSetup);
+ }
+
+ if (KbdMask & KEYBOARD_MODIFY_INTERIM)
+ pKbdSetup->fsInterim = MAKEWORD(
+ LOBYTE(PReq->d.KbdInfo.fsInterim),
+ HIBYTE(pKbdSetup->fsInterim)
+ );
+#else
+ if (KbdMask & KEYBOARD_MODIFY_STATE)
+ pKbdSetup->fsState = PReq->d.KbdInfo.fsState;
+
+ if (KbdMask & KEYBOARD_MODIFY_INTERIM)
+ pKbdSetup->fsInterim = PReq->d.KbdInfo.fsInterim;
+#endif
+
+ if (KbdMask & KEYBOARD_MODIFY_TURNAROUND)
+ pKbdSetup->chTurnAround = PReq->d.KbdInfo.chTurnAround;
+
+ /*
+ * update mask:
+ *
+ * 1. update mask of new bits SHIFT_REPORT & 2B_TURNAROUND
+ * 2. if new mask includes new ECHO then update mask
+ * 3. if new mask includes new INPUT then update mask
+ */
+
+ Mask = KEYBOARD_NEW_MASK;
+
+ if (KbdMask & KEYBOARD_ECHO)
+ {
+ Mask |= KEYBOARD_ECHO;
+ }
+
+ if (KbdMask & KEYBOARD_INPUT)
+ {
+ Mask |= KEYBOARD_INPUT;
+ }
+
+ pKbdSetup->fsMask =
+ (pKbdSetup->fsMask & ~Mask) | (KbdMask & Mask);
+
+ KbdNewSetup(&LastSetup);
+
+ return (0L);
+}
+
+
+DWORD
+GetOs2KbdKey( IN BOOL PeekFlag,
+ IN USHORT WaitFlag,
+ OUT PKBDKEYINFO KeyInfo,
+ IN PVOID pMsg,
+ OUT PULONG pReply)
+/*++
+
+Routine Description:
+
+ This routine get kbd char for KbdCharIn and KbdPeek
+
+Arguments:
+
+ PeekFlag - TRUE if peek (0 - CharIn, 1 - Peek)
+
+ WaitFlag - Wait if no input (IO_WAIT or IO_NOWAIT)
+
+ KeyInfo - Where to return the key input record
+
+ pMsg - Pointer to the LPC message
+
+ pReply - Pointer to flag if return reply on LPC
+
+Return Value:
+
+
+Note:
+
+ If no event and IO_WAIT: save pMsg, put 0 into *pReply and
+ the reply is postponed.
+
+--*/
+{
+
+ DWORD Rc;
+ KEYEVENTINFO In;
+
+
+ RtlZeroMemory(KeyInfo, sizeof(KBDKEYINFO));
+ KeyInfo->fsState = 1;
+
+ if ( KbdQueue->Setup.fsMask & KEYBOARD_ASCII_MODE )
+ {
+ KbdAsciiMode = 1;
+ } else
+ {
+ KbdAsciiMode = 0;
+ if ((KbdQueue->Setup.fsMask & KEYBOARD_BINARY_SHIFT) == KEYBOARD_BINARY_SHIFT)
+ {
+ WaitFlag |= ENABLE_SHIFT_KEY;
+ }
+ }
+
+ WaitFlag |= ENABLE_NON_ASCII_KEY;
+
+ KbdState = CharMode;
+ KbdWaitFlag = (ULONG)WaitFlag;
+ KbdPeekFlag = PeekFlag;
+
+ for(;;)
+ {
+ if (KbdQueue->LastKeyFlag)
+ {
+ In = KbdQueue->LastKey;
+ KbdQueue->LastKeyFlag = FALSE;
+ } else
+ {
+ In.wRepeatCount = 0x7FFF;
+ Rc = GetKeyboardInput( KbdWaitFlag,
+ &In,
+ pMsg,
+ pReply);
+
+ if ( !Rc ) /* no char & (NO_WAIT or postponed reply) */
+ return(Rc);
+ }
+
+ if (( HandleKeyboardInput(
+ &In
+ )) == NO_ERROR )
+ {
+ *KeyInfo = In.KeyInfo[0].KeyInfo;
+ return(0L);
+ }
+ }
+}
+
+
+DWORD
+GetOs2KbdString( IN USHORT WaitFlag,
+ //IN OUT KBDRW *Length,
+ IN OUT PKBDREQUEST PReq,
+ IN PVOID pMsg,
+ OUT PULONG pReply)
+{
+
+ DWORD Rc;
+ USHORT EditFlag = 0;
+ STRINGINBUF String = PReq->d.String;
+
+ KbdAsciiMode = (BOOL)(( KbdQueue->Setup.fsMask & KEYBOARD_ASCII_MODE ) ? 1 : 0);
+
+ if ( String.cchIn && ( String.cchIn <= String.cb ) &&
+ ( KbdLastBuff[String.cchIn] == '\r' ))
+ {
+ EditFlag = 1;
+ }
+
+ String.cchIn = String.cb;
+
+ Rc = GetOs2KbdStringRead( WaitFlag,
+ EditFlag,
+ 0,
+ (ULONG)String.cb,
+ &String.cchIn,
+ pMsg,
+ pReply);
+ if ( pReply )
+ {
+ PReq->Length = (ULONG)KbdLength;
+ String.cchIn = KbdLength;
+ if ( String.cchIn != String.cb )
+ PReq->Length++ ; // ASCII mode - copy the CR
+ }
+
+ return(Rc);
+
+}
+
+
+DWORD
+GetOs2KbdRead(IN PULONG Length,
+ IN PVOID pMsg,
+ OUT PULONG pReply)
+{
+ DWORD Rc, i;
+
+ KbdAsciiMode = (BOOL)(( KbdQueue->Setup.fsMask & KEYBOARD_ASCII_MODE ) ? 1 : 0);
+
+ /*
+ * ignore previously-typed-but-not-returned character in binary mode
+ */
+
+ if ( !KbdAsciiMode || !KbdBuffNextLen)
+ {
+
+ Rc = GetOs2KbdStringRead( IO_WAIT,
+ TRUE,
+ 1,
+ KbdBuffSize - 2,
+ (PUSHORT)Length,
+ pMsg,
+ pReply);
+
+ return(Rc);
+
+ }
+
+ /*
+ *
+ * Copy from kbd buffer
+ *
+ */
+
+ if (*Length > (ULONG)KbdBuffNextLen)
+ *Length = KbdBuffNextLen;
+
+ for (i = 0 ; i < *Length ; i++ )
+ {
+ if ((KBD_BUFFER_ADDRESS[i] = KbdLastBuff[i + KbdBuffNextPtr]) == '\n')
+ {
+ *Length = i + 1;
+ break;
+ }
+ }
+
+ KbdBuffNextLen -= *((PUSHORT)Length);
+ KbdBuffNextPtr += (USHORT)*Length;
+
+ return(0L);
+}
+
+
+DWORD
+GetOs2KbdStringRead(IN USHORT WaitFlag,
+ IN USHORT EditFlag,
+ IN USHORT ReadMode,
+ IN ULONG MaxLength,
+ IN OUT PUSHORT Length,
+ IN PVOID pMsg,
+ OUT PULONG pReply)
+/*++
+
+Routine Description:
+
+ This routine get kbd string for KbdStringIn and Read("KBD$" or non-redirected
+ STD-IN).
+
+Arguments:
+
+ WaitFlag - Wait if no input (IO_WAIT or IO_NOWAIT)
+
+ EditFlag - TRUE if edit last line(0/1 according to cchIn - StringIn, 1 - Read)
+
+ ReadMode - Called by StringIn (0) or Read(1)
+
+ MaxLength - Maximun input length (String.cb for StringIn, KbdBuffSize
+ for Read)
+
+ Length - On enter: the requested length, on exit: the returned string
+ length (String.cchIn for StringIn, Length field in LPC for Read)
+
+ pMsg - Pointer to the LPC message
+
+ pReply - Pointer to flag if return reply on LPC
+
+Return Value:
+
+
+Note:
+
+ If no event and IO_WAIT: save pMsg, put 0 into *pReply and
+ the reply is postponed.
+
+--*/
+{
+ KEYEVENTINFO In;
+ DWORD Rc;
+
+ KbdLastBuffPtr = KbdInputLength = KbdFxWaitForChar = KbdDelIndex = 0;
+ KbdIndexInLine = 0;
+ KbdInsertOn = KbdEchoString = KbdLineWasEdited = FALSE;
+ //KbdSecondTurnAround = KbdEndFlag = FALSE;
+ KbdLength = *Length;
+
+ if ( KbdAsciiMode )
+ {
+ /*
+ * ASCII mode
+ */
+
+ KbdWaitFlag = (ULONG)(WaitFlag | ENABLE_LN_EDITOR_KEY);
+
+ /*
+ *
+ * Get Start Cursor-Position
+ *
+ */
+
+ // force SesGrp->WinCoord and CurType params to get updated
+
+ Ow2VioReadCurPos();
+ Ow2VioReadCurType();
+
+ if (SesGrp->KeysOnFlag)
+ {
+ KbdWaitFlag |= ENABLE_KEYS_ON_KEY;
+ KbdCueSetCurTypeToQuater();
+ }
+ KbdMaxLength = MaxLength - 1; /* leave space for the TurnAround char at the end */
+ KbdEndLength = 1;
+ KbdReadMode = ReadMode;
+
+ KbdEchoFlag = (BOOL)(( KbdQueue->Setup.fsMask & KEYBOARD_ECHO_ON ) ? 1 : 0);
+ KbdTurnAroundChar = KbdQueue->Setup.chTurnAround;
+ KbdTurnAroundCharTwo = KbdSetupTurnAroundCharTwo;
+
+ //if (KbdQueue->Setup.chTurnAround & 0x80)
+ if(KbdTurnAroundCharTwo)
+ { KbdMaxLength--; /* need another space for 2-byte-TurnAround */
+ KbdEndLength++;
+ }
+
+ KbdEditFlag = EditFlag;
+
+ LineInputBuff[KbdInputLength].X_Pos = KbdStartOfLine = KbdFirstColumn =
+ GET_CURRENT_COORD.X;
+
+ KbdState = AsciiMode;
+
+ } else
+ {
+ KbdWaitFlag = (ULONG)(WaitFlag | ENABLE_NON_ASCII_KEY);
+ KbdState = BinaryMode;
+ }
+
+ for(;;)
+ {
+ /*
+ *
+ * Restore saved Input Key if any
+ *
+ */
+
+ if (KbdQueue->LastKeyFlag)
+ {
+ In = KbdQueue->LastKey;
+ KbdQueue->LastKeyFlag = FALSE;
+ } else
+ {
+ /*
+ *
+ * Get Input Key if any
+ *
+ */
+
+ In.wRepeatCount = 0x7FFF;
+ Rc = GetKeyboardInput( KbdWaitFlag,
+ &In,
+ pMsg,
+ pReply);
+
+ if ( !Rc ) /* no char & NO_WAIT */
+ return(Rc);
+ }
+
+ if (( HandleKeyboardInput(
+ &In
+ )) == NO_ERROR )
+ {
+ *Length = KbdLength;
+ return(0L);
+ }
+ }
+}
+
+
+DWORD
+HandleKeyboardInput(IN PKEYEVENTINFO pKbd)
+{
+ DWORD NumChar = 0;
+ UCHAR Char, Scan, *puchLastString;
+ USHORT i, usIndex, StringLengthToEcho, NumBeep = 0;
+ SHORT X_Pos, Offset;
+
+ Scan = pKbd->KeyInfo[0].KeyInfo.chScan;
+ Char = pKbd->KeyInfo[0].KeyInfo.chChar;
+
+#if DBG
+ IF_OD2_DEBUG(KBD)
+ {
+ KdPrint(("HandleKeyboardInput: %s - Char %x, Scan %x, Status %x, State %x, Flag %x\n",
+ (KbdState == CharMode) ? "CharMode" :
+ (KbdState == AsciiMode) ? "AsciiMode" : "BinaryMode",
+ Char, Scan, pKbd->KeyInfo[0].KeyInfo.fbStatus,
+ pKbd->KeyInfo[0].KeyInfo.fsState, pKbd->KeyInfo[0].KeyboardFlag));
+ }
+#endif
+ switch (KbdState)
+ {
+ case CharMode:
+ if ( KbdPeekFlag || (pKbd->wRepeatCount > 1))
+ {
+ KbdQueue->LastKey = *pKbd;
+ KbdQueue->LastKeyFlag = TRUE;
+ if (!KbdPeekFlag)
+ {
+ KbdQueue->LastKey.wRepeatCount--;
+ }
+ }
+
+ return (NO_ERROR);
+ break;
+
+ case AsciiMode:
+
+ KbdQueue->LastKey = *pKbd; // prepare it in case we read only one copy of the char
+ KbdQueue->LastKey.wRepeatCount--;
+
+ /*
+ *
+ * Handle CR (TurnAround Char)
+ *
+ * 1. put in buffer (if there is a room), beep otherwise
+ * 2. echo if echo_on
+ * 3. (READ only) add LF to CR (if there is a place)
+ *
+ */
+
+ if ( !KbdFxWaitForChar && KbdKeyIsTurnAround(Char, Scan) )
+ {
+ if ( pKbd->wRepeatCount > 1 )
+ {
+ KbdQueue->LastKeyFlag = TRUE;
+ }
+
+ if (( KbdReadMode == 1 ) && KbdInputLength &&
+ ( LineInputBuff[0].Char == 0x1A )) // ^Z
+ {
+ NumChar = KbdInputLength = 0;
+ } else
+ {
+ NumChar = KbdInputLength;
+
+ /*
+ * Add the TurnAround char at the end of the buffer
+ */
+
+ LineInputBuff[KbdInputLength++].Char = Char;
+
+ if (KbdTurnAroundCharTwo)
+ {
+ if ( KbdReadMode == 1 )
+ {
+ LineInputBuff[KbdInputLength - 1].Char = '\r';
+ Scan = '\n';
+ }
+ LineInputBuff[KbdInputLength++].Char = Scan;
+ } else if (( KbdReadMode == 1 ) && ( Char == '\r' ) &&
+ ( KbdInputLength <= (USHORT)KbdMaxLength ))
+ {
+ LineInputBuff[KbdInputLength++].Char = '\n';
+ }
+
+ }
+
+ /*
+ * Echo the TurnAround char to console
+ */
+
+ if (KbdEchoFlag && !KbdTurnAroundCharTwo)
+ {
+ KbdEchoNL(1);
+ }
+
+ /*
+ *
+ * Save string length and data in buffer for editing keys
+ *
+ */
+
+ for ( i = 0 ; i < KbdInputLength ; i++ )
+ {
+ KbdLastBuff[i] = LineInputBuff[i].Char;
+ }
+
+ if (KbdReadMode == 0)
+ {
+ KbdInputLength = (USHORT)NumChar;
+ }
+ LastStringLength = (USHORT)NumChar; // not include the TurnAround char
+
+ /*
+ *
+ * Copy to application buffer
+ *
+ */
+
+ if ( KbdLength > KbdInputLength )
+ KbdLength = KbdInputLength;
+
+ RtlMoveMemory(KbdAddress, KbdLastBuff, KbdLength);
+
+ if ( KbdReadMode == 0 )
+ KBD_BUFFER_ADDRESS[KbdLength] = Char; // add the CR at the end
+
+ /*
+ *
+ * Keep info for Read in case we don't return all the string
+ *
+ */
+
+ KbdBuffNextPtr = KbdLength;
+ KbdBuffNextLen = KbdInputLength - KbdLength;
+
+ /*
+ *
+ * Copy string to CUE buffer if active
+ *
+ */
+
+ if ( SesGrp->KeysOnFlag )
+ {
+ if( KbdLineWasEdited && NumChar )
+ {
+ KbdCurrentLine = KbdNextLinePointer;
+
+ for ( i = 0, usIndex = KbdNextLinePointer ;
+ i < NumChar ; i++, usIndex++ )
+ {
+ KbdCueBuffer[usIndex] = KbdLastBuff[i];
+ }
+
+ KbdNextLinePointer = usIndex + 1;
+
+ while (KbdCueBuffer[usIndex])
+ {
+ // zero the end of the last string we copy the new
+ // one on (fill with NULL till start of next line)
+
+ KbdCueBuffer[usIndex++] = 0;
+ }
+ }
+
+ KbdCueUpRowIsCurrent = TRUE;
+ }
+
+ return(0L);
+ }
+
+ /*
+ *
+ * Check for Speciel Keys (PFx, enhanced ...)
+ *
+ */
+
+ if (( Char == 0 ) || ( Char == 0xE0 ))
+ {
+ if (SesGrp->KeysOnFlag)
+ {
+ if ( Scan == OS2_SCAN_RIGHT_6 ) // Right
+ {
+ if (( NumChar = KbdInputLength - KbdIndexInLine ) >
+ pKbd->wRepeatCount )
+ {
+ NumChar = pKbd->wRepeatCount;
+ }
+
+ KbdCueMoveToRight(
+ KbdIndexInLine,
+ (USHORT)NumChar,
+ FALSE
+ );
+
+ } else if ( Scan == OS2_SCAN_LEFT_4 ) // Left
+ {
+ NumChar = ( KbdIndexInLine < pKbd->wRepeatCount ) ?
+ KbdIndexInLine : pKbd->wRepeatCount;
+
+ KbdCueMoveToLeft(
+ KbdIndexInLine,
+ (USHORT)NumChar
+ );
+
+ } else if ( Scan == OS2_SCAN_UP_8 ) // Up
+ {
+ /*
+ * Find previous command in the command queue
+ */
+
+ if (KbdCueBuffer[KbdCurrentLine]) // if anything at the CUE buffer
+ {
+ if (KbdCueUpRowIsCurrent)
+ {
+ pKbd->wRepeatCount--;
+ KbdCueUpRowIsCurrent = FALSE;
+ }
+
+ usIndex = KbdCurrentLine;
+ for ( i = 0 ; i < pKbd->wRepeatCount ; i++ )
+ {
+ usIndex--;
+ while (!KbdCueBuffer[--usIndex]); // skip all null
+ while (KbdCueBuffer[--usIndex]); // go to start of command
+
+ usIndex++;
+ }
+ KbdCurrentLine = usIndex;
+ } else
+ {
+ usIndex = KbdCurrentLine;
+ }
+
+ KbdCueEraseAndDisplayLine(usIndex);
+ } else if ( Scan == OS2_SCAN_DOWN_2 ) // Down
+ {
+ /*
+ * Find next command in the command queue
+ */
+
+ if (KbdCueBuffer[KbdCurrentLine]) // if anything at the CUE buffer
+ {
+ usIndex = KbdCurrentLine;
+ KbdCueUpRowIsCurrent = FALSE;
+
+ for ( i = 0 ; i < pKbd->wRepeatCount ; i++ )
+ {
+ while (KbdCueBuffer[++usIndex]);
+ while (!KbdCueBuffer[++usIndex]);
+ }
+ KbdCurrentLine = usIndex;
+ } else
+ {
+ usIndex = KbdCurrentLine;
+ }
+
+ KbdCueEraseAndDisplayLine(usIndex);
+ } else if ( Scan == OS2_SCAN_HOME_7 ) // Home
+ {
+ KbdCueMoveToLeft(
+ KbdIndexInLine,
+ KbdIndexInLine
+ );
+ } else if ( Scan == OS2_SCAN_END_1 ) // End
+ {
+ KbdCueMoveToRight(
+ KbdIndexInLine,
+ (USHORT)(KbdInputLength - KbdIndexInLine),
+ FALSE
+ );
+
+ } else if ( Scan == OS2_SCAN_CTRL_LEFT_4 ) // ^Left
+ {
+ USHORT PrevIndex = KbdIndexInLine;
+
+ for ( i = 0;
+ (i < pKbd->wRepeatCount) && PrevIndex ;
+ i++ )
+ {
+ /* for each char:
+ * go one char left
+ * skip all non-alphanumeric chars
+ * akip all alphanumeric chars
+ * while points to alpha, which is not the original
+ */
+
+ usIndex = PrevIndex - 1;
+
+ while (usIndex && !ALPHANUM_CHAR(usIndex))
+ {
+ usIndex--;
+ }
+
+ while (usIndex && ALPHANUM_CHAR(usIndex))
+ {
+ usIndex--;
+ }
+
+ if (usIndex || !ALPHANUM_CHAR(usIndex))
+ {
+ usIndex++;
+ }
+
+ if (!ALPHANUM_CHAR(usIndex) ||
+ (PrevIndex == usIndex))
+ {
+ break;
+ }
+
+ PrevIndex = usIndex;
+ }
+ if (NumChar = KbdIndexInLine - PrevIndex)
+ {
+ KbdCueMoveToLeft(
+ KbdIndexInLine,
+ (USHORT)NumChar
+ );
+ }
+ } else if ( Scan == OS2_SCAN_CTRL_RIGHT_6 ) // ^Right
+ {
+ USHORT PrevIndex = KbdIndexInLine;
+
+ for ( i = 0;
+ (i < pKbd->wRepeatCount) && (PrevIndex < KbdInputLength);
+ i++ )
+ {
+ /* for each char:
+ * go one char right
+ * akip all alphanumeric chars
+ * skip all non-alphanumeric chars
+ * while points to alpha, which is not the original
+ */
+
+ usIndex = PrevIndex;
+
+ while ((usIndex < KbdInputLength) &&
+ ALPHANUM_CHAR(usIndex))
+ {
+ usIndex++;
+ }
+
+ while ((usIndex < KbdInputLength) &&
+ !ALPHANUM_CHAR(usIndex))
+ {
+ usIndex++;
+ }
+
+ if ((usIndex >= KbdInputLength) ||
+ !ALPHANUM_CHAR(usIndex))
+ {
+ break;
+ }
+
+ PrevIndex = usIndex;
+ }
+ if (NumChar = PrevIndex - KbdIndexInLine)
+ {
+ KbdCueMoveToRight(
+ KbdIndexInLine,
+ (USHORT)NumChar,
+ FALSE
+ );
+ }
+ } else if ( Scan == OS2_SCAN_CTRL_END_1 ) // ^End
+ {
+ KbdLineWasEdited = TRUE;
+ KbdEchoBSAndFillSpaces(0, LineInputBuff[KbdInputLength].X_Pos -
+ LineInputBuff[KbdIndexInLine].X_Pos);
+
+ KbdInputLength = KbdIndexInLine;
+ } else if ( Scan == OS2_SCAN_DEL ) // Del
+ {
+ KbdLineWasEdited = TRUE;
+ if (( NumChar = KbdInputLength - KbdIndexInLine ) >
+ pKbd->wRepeatCount )
+ {
+ NumChar = pKbd->wRepeatCount;
+ }
+
+ KbdCueDeleteCharAndShift(
+ KbdIndexInLine,
+ (USHORT)NumChar
+ );
+ } else if ( Scan == OS2_SCAN_CTRL_HOME_7 ) // ^Home
+ {
+ if (NumChar = KbdIndexInLine)
+ {
+ KbdLineWasEdited = TRUE;
+ KbdCueMoveToLeft(
+ KbdIndexInLine,
+ (USHORT)NumChar
+ );
+
+ KbdCueDeleteCharAndShift(
+ KbdIndexInLine,
+ (USHORT)NumChar
+ );
+ }
+ } else if ( Scan == OS2_SCAN_INSERT_0 ) // Ins
+ {
+ if ( pKbd->wRepeatCount % 2 )
+ {
+ if( KbdInsertOn = ~KbdInsertOn )
+ {
+ KbdCueSetCurTypeToHalf();
+ } else
+ {
+ KbdCueSetCurTypeToQuater();
+ }
+ }
+ }
+
+ break;
+ } else
+ {
+ if ( KbdFxWaitForChar )
+ {
+ KbdFxWaitForChar = 0;
+ if (--pKbd->wRepeatCount)
+ {
+ KbdQueue->LastKey.wRepeatCount--;
+ KbdQueue->LastKeyFlag = TRUE;
+ } else
+ {
+ break;
+ }
+ }
+
+ if ( Scan == 0x40 )
+ {
+ Char = 0x1A; // F6 => ^Z
+ } else if ( Scan == 0x41 )
+ {
+ Char = 0x00; // F7 => ^@
+ } else if (KbdEditFlag)
+ {
+ if (( Scan == 0x3B ) || // F1
+ ( Scan == OS2_SCAN_RIGHT_6 )) // Right
+ {
+ KbdInsertOn = FALSE;
+ if ((USHORT)(KbdDelIndex + KbdLastBuffPtr) < LastStringLength)
+ {
+ Char = KbdLastBuff[KbdDelIndex + KbdLastBuffPtr]; // => previous char
+ } else
+ break;
+
+ } else if ( Scan == 0x3C ) // F2
+ {
+ KbdInsertOn = FALSE;
+ if (pKbd->wRepeatCount % 2)
+ {
+ KbdFxWaitForChar = 1;
+ }
+ break;
+ } else if ( Scan == 0x3D ) // F3
+ {
+ KbdInsertOn = FALSE;
+ if ((USHORT)(KbdDelIndex + KbdLastBuffPtr) < LastStringLength)
+ {
+ StringLengthToEcho = LastStringLength - KbdDelIndex - KbdLastBuffPtr;
+ KbdEchoString = TRUE;
+ } else
+ break;
+
+ } else if ( Scan == 0x3E ) // F4
+ {
+ KbdInsertOn = FALSE;
+ if (pKbd->wRepeatCount % 2)
+ {
+ KbdFxWaitForChar = 2;
+ }
+ break;
+ } else if ( Scan == OS2_SCAN_DEL ) // Del
+ {
+ KbdDelIndex += pKbd->wRepeatCount;
+ if(KbdDelIndex > LastStringLength)
+ {
+ KbdDelIndex = LastStringLength;
+ }
+ break;
+ } else if ( Scan == OS2_SCAN_INSERT_0 ) // Ins
+ {
+ if (pKbd->wRepeatCount % 2)
+ {
+ KbdInsertOn = ~KbdInsertOn;
+ }
+
+ break;
+
+ } else if ( Scan == OS2_SCAN_LEFT_4 ) // Left
+ {
+ Char = '\b'; // => BS
+ KbdInsertOn = FALSE;
+ } else
+ break;
+ } else
+ break;
+ }
+ }
+
+ /*
+ *
+ * Search for char in KbdLastBuff (for F2 & F4)
+ *
+ */
+
+ if (KbdFxWaitForChar)
+ {
+ if (pKbd->wRepeatCount > 1)
+ {
+ KbdQueue->LastKeyFlag = TRUE;
+ }
+ for ( i = KbdDelIndex + KbdLastBuffPtr ;
+ (i < LastStringLength) && (KbdLastBuff[i] != Char) ; i++ );
+ if ((i == (USHORT)(KbdDelIndex + KbdLastBuffPtr)) ||
+ (KbdLastBuff[i] != Char))
+ {
+ KbdFxWaitForChar = 0;
+ break;
+ }
+
+ StringLengthToEcho = i - (KbdDelIndex + KbdLastBuffPtr);
+
+ if (KbdFxWaitForChar == 1) // F2
+ {
+ KbdFxWaitForChar = 0;
+ KbdEchoString = TRUE;
+ } else // F4
+ {
+ KbdDelIndex += i;
+ KbdFxWaitForChar = 0;
+ break;
+ }
+ }
+
+ /*
+ *
+ * Echo string from KbdLastBuff (for F2 & F3)
+ *
+ * StringLengthToEcho - is the string length
+ */
+
+ if (KbdEchoString)
+ {
+ X_Pos = GET_CURRENT_COORD.X;
+ NumChar = 0;
+
+ for ( i = KbdDelIndex + KbdLastBuffPtr, puchLastString = &KbdLastBuff[i] ;
+ StringLengthToEcho && (KbdInputLength < (USHORT)KbdMaxLength) ; StringLengthToEcho-- )
+ {
+ Char = KbdLastBuff[i++];
+ NumChar++ ;
+
+ LineInputBuff[KbdInputLength++].Char = Char;
+ if (Char == '\t') // TAB
+ {
+ X_Pos += 8 - (X_Pos % 8);
+ } else if (Char < ' ')
+ {
+ X_Pos += 2;
+ } else
+ {
+ X_Pos++;
+ }
+
+ if (X_Pos >= SesGrp->ScreenColNum)
+ {
+ X_Pos -= SesGrp->ScreenColNum;
+ KbdStartOfLine = 0;
+ }
+
+ LineInputBuff[KbdInputLength].X_Pos = X_Pos;
+ }
+
+ if (KbdEchoFlag && NumChar)
+ {
+ KbdEchoAString(puchLastString, NumChar);
+ }
+
+ KbdLastBuffPtr += (USHORT)NumChar;
+
+ if (StringLengthToEcho)
+ {
+ KbdEchoBeep(i);
+ }
+
+ KbdEchoString = FALSE;
+ break;
+ }
+
+ /*
+ *
+ * Handle BS
+ *
+ */
+
+ if (( Char == '\b' ) || ( Char == 0x7F ))
+ {
+ if (SesGrp->KeysOnFlag)
+ {
+ if ( NumChar = KbdIndexInLine )
+ {
+ if ( NumChar > pKbd->wRepeatCount )
+ {
+ NumChar = pKbd->wRepeatCount;
+ }
+
+ KbdCueMoveToLeft(
+ KbdIndexInLine,
+ (USHORT)NumChar
+ );
+
+ KbdCueDeleteCharAndShift(
+ KbdIndexInLine,
+ (USHORT)NumChar
+ );
+
+ KbdLineWasEdited = TRUE;
+ }
+
+ break;
+ } else
+ {
+ KbdInsertOn = FALSE;
+
+ for ( i = 0 ; (i < pKbd->wRepeatCount) && KbdInputLength &&
+ (LineInputBuff[KbdInputLength].X_Pos != KbdStartOfLine) ; i++ )
+ {
+ if (KbdLastBuffPtr)
+ {
+ KbdLastBuffPtr--;
+ } else if (KbdDelIndex)
+ {
+ KbdDelIndex--;
+ }
+
+ KbdInputLength--;
+ }
+
+ NumChar = GET_CURRENT_COORD.X - LineInputBuff[KbdInputLength].X_Pos;
+
+ if(KbdEchoFlag && NumChar)
+ {
+ KbdEchoBSAndFillSpaces(NumChar, NumChar);
+ }
+
+ break;
+ }
+ }
+
+ if (!SesGrp->KeysOnFlag)
+ {
+ /*
+ *
+ * Handle LF
+ *
+ */
+
+ if (Char == '\n')
+ {
+ if (KbdEchoFlag)
+ {
+ KbdEchoNL(pKbd->wRepeatCount);
+ }
+
+ LineInputBuff[KbdInputLength].X_Pos = 0;
+ KbdStartOfLine = 0;
+
+ break;
+ }
+
+ /*
+ *
+ * Handle ^W
+ *
+ */
+
+ if (Char == 0x17)
+ {
+ USHORT PrevIndex = KbdIndexInLine;
+
+ KbdInsertOn = FALSE;
+
+ for ( i = 0;
+ (i < pKbd->wRepeatCount) && ( PrevIndex > KbdStartOfLine ) ;
+ i++ )
+ {
+ /* for each char:
+ * go one char left
+ * skip all non-alphanumeric chars
+ * akip all alphanumeric chars
+ * while points to alpha, which is not the original
+ */
+
+ usIndex = PrevIndex - 1;
+
+ while (( usIndex > KbdStartOfLine ) &&
+ !ALPHANUM_CHAR(usIndex))
+ {
+ usIndex--;
+ }
+
+ while (( usIndex > KbdStartOfLine ) &&
+ ALPHANUM_CHAR(usIndex))
+ {
+ usIndex--;
+ }
+
+ if (( usIndex > KbdStartOfLine ) ||
+ !ALPHANUM_CHAR(usIndex))
+ {
+ usIndex++;
+ }
+
+ if (!ALPHANUM_CHAR(usIndex) ||
+ (PrevIndex == usIndex))
+ {
+ break;
+ }
+
+ PrevIndex = usIndex;
+ }
+
+ NumChar = LineInputBuff[KbdIndexInLine].X_Pos -
+ LineInputBuff[PrevIndex].X_Pos ;
+
+ if(KbdEchoFlag && NumChar)
+ {
+ KbdEchoBSAndFillSpaces(NumChar, NumChar);
+ }
+
+ KbdIndexInLine = KbdInputLength = PrevIndex;
+ //KbdLastBuffPtr = 0;
+ break;
+ }
+ }
+
+ /*
+ *
+ * Handle ESC
+ *
+ */
+
+ if (Char == 0x1B)
+ {
+ // ^[ => Write '\'<NL> & Clear Buff
+
+ KbdInsertOn = FALSE;
+
+ KbdLastBuffPtr = KbdDelIndex = 0;
+ if (SesGrp->KeysOnFlag)
+ {
+ if (KbdCueBuffer[KbdCurrentLine])
+ {
+ usIndex = KbdCurrentLine - 1;
+ } else
+ {
+ usIndex = KbdCurrentLine;
+ }
+
+ KbdCueEraseAndDisplayLine(usIndex); // don't display anything
+ } else if (KbdEchoFlag)
+ {
+ KbdEchoESC(pKbd->wRepeatCount, KbdFirstColumn);
+ }
+
+ KbdStartOfLine = LineInputBuff[0].X_Pos = KbdFirstColumn;
+ KbdInputLength = 0;
+ break;
+ }
+
+ /*
+ *
+ * Handle ^F
+ *
+ */
+
+ if (Char == 0x6)
+ {
+ break;
+ }
+
+ /*
+ *
+ * Handle char :
+ *
+ * 1. put in buffer (if there is a room), beep otherwise
+ * 2. save in buffer cursor position of next char
+ * 3. echo if echo_on
+ *
+ */
+
+ NumChar = 0;
+
+ if (SesGrp->KeysOnFlag)
+ {
+ KbdCueHandleChar(Char, pKbd->wRepeatCount);
+ } else
+ {
+ X_Pos = GET_CURRENT_COORD.X;
+
+ if (Char < ' ')
+ {
+ if (Char == '\t') // TAB
+ {
+ Offset = 8;
+ X_Pos &= ~7;
+ } else
+ {
+ Offset = 2;
+ }
+ } else
+ {
+ Offset = 1;
+ }
+
+ for ( i = 0 ; (i < pKbd->wRepeatCount) &&
+ (KbdInputLength < (USHORT)KbdMaxLength) ; i++ )
+ {
+ if (!KbdInsertOn)
+ {
+ KbdLastBuffPtr++;
+ }
+
+ LineInputBuff[KbdInputLength++].Char = Char;
+ X_Pos += Offset;
+
+ if (X_Pos >= SesGrp->ScreenColNum)
+ {
+ X_Pos -= SesGrp->ScreenColNum;
+ KbdStartOfLine = 0;
+ }
+ LineInputBuff[KbdInputLength].X_Pos = X_Pos;
+ }
+
+ if (KbdEchoFlag && i)
+ {
+ KbdEchoChar(Char, i);
+ }
+
+ if (i < pKbd->wRepeatCount)
+ {
+ KbdEchoBeep(pKbd->wRepeatCount - i);
+ }
+ }
+ break;
+
+ case BinaryMode:
+ /*
+ *
+ * Binary mode
+ *
+ */
+
+ /*
+ *
+ * Handle char :
+ *
+ * put in buffer (if a place exist)
+ * if enhanced - put also scan code
+ *
+ */
+
+ for ( i = 0 ; (i < pKbd->wRepeatCount) && (KbdInputLength < KbdLength); i++ )
+ {
+ KBD_BUFFER_ADDRESS[KbdInputLength++] = Char;
+
+ if ((Char == 0x0) && (KbdInputLength < KbdLength))
+ {
+ KBD_BUFFER_ADDRESS[KbdInputLength++] = Scan;
+ }
+ }
+
+ if ( KbdInputLength < KbdLength )
+ {
+ break;
+ } else if ( i < pKbd->wRepeatCount )
+ {
+ KbdQueue->LastKey = *pKbd; // prepare it in case we read only one copy of the char
+ KbdQueue->LastKey.wRepeatCount -= i;
+ KbdQueue->LastKeyFlag = TRUE;
+ }
+
+ /*
+ *
+ * Copy to application buffer
+ *
+ */
+
+ if ( KbdLength > KbdInputLength )
+ KbdLength = KbdInputLength;
+
+ /*
+ *
+ * Keep info for Read in case we don't return all the string
+ *
+ */
+
+ KbdBuffNextPtr = KbdLength;
+ KbdBuffNextLen = KbdInputLength - KbdLength;
+
+ /*
+ *
+ * No editing keys in binary mode
+ *
+ */
+
+ LastStringLength = 0;
+
+ return(0L);
+
+ default:
+ break;
+ }
+
+#if DBG
+ IF_OD2_DEBUG( KBD )
+ {
+ if ( KbdState == AsciiMode )
+ {
+ USHORT CurrentIdx;
+ CONSOLE_SCREEN_BUFFER_INFO ConsoleScreenBufferInfo;
+
+ CurrentIdx = (SesGrp->KeysOnFlag) ? KbdIndexInLine : KbdInputLength;
+
+ if (!GetConsoleScreenBufferInfo(
+ hConOut,
+ &ConsoleScreenBufferInfo
+ ))
+ {
+ ConsoleScreenBufferInfo.dwCursorPosition.X =
+ ConsoleScreenBufferInfo.dwCursorPosition.Y = 255;
+ KdPrint(("OS2SES(Ow2VioReadCurPos): Rc %lu\n", GetLastError()));
+ ASSERT( FALSE ); // should not happend
+ }
+ KdPrint(("HandleKeyboardInput: Len %u, CUE-Idx %u, Cur-Offset %u, Prev-Offset %u, Col %u, Pos %u:%u\n",
+ KbdInputLength, KbdIndexInLine,
+ LineInputBuff[CurrentIdx].X_Pos,
+ (CurrentIdx) ? LineInputBuff[CurrentIdx - 1].X_Pos : 255,
+ SesGrp->WinCoord.X,
+ ConsoleScreenBufferInfo.dwCursorPosition.Y,
+ ConsoleScreenBufferInfo.dwCursorPosition.X
+ ));
+ if (KbdEchoFlag)
+ {
+ ASSERT( ConsoleScreenBufferInfo.dwCursorPosition.X == SesGrp->WinCoord.X );
+ ASSERT( ConsoleScreenBufferInfo.dwCursorPosition.Y == SesGrp->WinCoord.Y );
+ ASSERT( (LineInputBuff[CurrentIdx].X_Pos % SesGrp->ScreenColNum) ==
+ SesGrp->WinCoord.X );
+ }
+ }
+ }
+#endif
+
+ return(1L);
+}
+
+
+DWORD
+KbdHandlePackage(IN PKEY_EVENT_QUEUE NextKbdMon,
+ IN PKBD_MON_PACKAGE KbdPackage)
+{
+ KEYEVENTINFO In;
+
+ if ( KbdCheckPackage( KbdPackage ))
+ {
+ return (0L); // ignore key
+ }
+
+#ifdef DBCS
+// MSKK Jul.23.1992 KazuM
+ In.wRepeatCount = NextKbdMon->In->wRepeatCount;
+#else
+ In.wRepeatCount = 1;
+#endif
+ In.KeyInfo[0] = *KbdPackage;
+
+ if ( HandleKeyboardInput( &In ))
+ {
+ return (0L); // not time to send reply yet
+ }
+
+ NextKbdMon->MonHdr.WaitForEvent = FALSE;
+
+#if DBG
+ IF_OD2_DEBUG( KBD )
+ {
+ KdPrint(("KbdHandlePackage: %s respond\n",
+ (KbdRequestSaveArea.Request == KBDCharIn) ? "KbdCharIn" :
+ (KbdRequestSaveArea.Request == KBDStringIn) ? "KbdStringIn" :
+ "KbdRead"));
+ }
+#endif
+ if ( KbdRequestSaveArea.Request == KBDCharIn )
+ {
+ KbdRequestSaveArea.d.KeyInfo = In.KeyInfo[0].KeyInfo;
+
+ SendKbdReply((PVOID)NextKbdMon->MonHdr.MemoryStartAddress,
+ (PVOID)&KbdRequestSaveArea,
+ KbdAddress,
+ 0);
+ } else
+ {
+ KbdRequestSaveArea.Length = (ULONG)KbdLength;
+
+ if ( KbdRequestSaveArea.Request == KBDStringIn )
+ {
+ KbdRequestSaveArea.d.String.cchIn = KbdLength;
+ if ( KbdRequestSaveArea.d.String.cchIn != KbdRequestSaveArea.d.String.cb )
+ KbdRequestSaveArea.Length++ ; // ASCII mode - copy the CR
+ }
+
+ SendKbdReply ((PVOID)NextKbdMon->MonHdr.MemoryStartAddress,
+ (PVOID)&KbdRequestSaveArea,
+ KbdAddress,
+ 0);
+ }
+
+ return (1L);
+}
+
+
+DWORD
+KbdCheckPackage(IN PKBD_MON_PACKAGE KbdPackage)
+{
+ BOOL IgnoreKey = FALSE;
+ UCHAR Scan, Char;
+
+ Char = KbdPackage->KeyInfo.chChar;
+ Scan = KbdPackage->KeyInfo.chScan;
+
+ if (( Char == 0 ) && ( Scan == 0 ))
+ {
+ if(!( ENABLE_SHIFT_KEY & KbdWaitFlag ))
+ {
+ /*
+ * Ignore shift keys if { in ASCII mode or shift report off }
+ */
+#if DBG
+ IF_OD2_DEBUG(KBD)
+ {
+ KdPrint((" - ignore since shift report disable\n"));
+ }
+#endif
+ IgnoreKey = TRUE; // ignore shift report
+ } else if(!( KbdPackage->KeyInfo.fbStatus & 1))
+ {
+ /*
+ * Ignore non-shift keys
+ */
+#if DBG
+ IF_OD2_DEBUG(KBD)
+ {
+ KdPrint((" - ignore since non-shift key\n"));
+ }
+#endif
+ IgnoreKey = TRUE;
+ }
+ } else if ( KbdPackage->KeyboardFlag & KBD_KEY_BREAK )
+ {
+ /*
+ * Ignore Break if non-shift
+ */
+
+#if DBG
+ IF_OD2_DEBUG( KBD )
+ {
+ KdPrint(("KbdCheckPackage: ignore key release\n"));
+ }
+#endif
+ IgnoreKey = TRUE; // ignore KEY_UP
+ } else if (( KbdWaitFlag & ENABLE_LN_EDITOR_KEY ) &&
+ KbdKeyIsTurnAround(Char, Scan) )
+ {
+ // don't ignore the turn around char in ASCII mode
+
+ } else if ( !( KbdWaitFlag & ENABLE_NON_ASCII_KEY ) &&
+ (( Char == 0 ) || ( Char == 0xE0 )))
+ {
+ IgnoreKey = TRUE; // ignore NON_ASCII
+
+ if ( KbdWaitFlag & ENABLE_KEYS_ON_KEY )
+ {
+ if (( Scan == OS2_SCAN_HOME_7 ) || // Home
+ ( Scan == OS2_SCAN_CTRL_HOME_7 ) || // ^Home
+ ( Scan == OS2_SCAN_END_1 ) || // End
+ ( Scan == OS2_SCAN_CTRL_END_1 ) || // ^End
+ ( Scan == OS2_SCAN_LEFT_4 ) || // Left
+ ( Scan == OS2_SCAN_CTRL_LEFT_4 ) || // ^Left
+ ( Scan == OS2_SCAN_RIGHT_6 ) || // Right
+ ( Scan == OS2_SCAN_CTRL_RIGHT_6 ) || // ^Right
+ ( Scan == OS2_SCAN_UP_8 ) || // Up
+ ( Scan == OS2_SCAN_DOWN_2 ) || // Down
+ ( Scan == OS2_SCAN_DEL ) || // Del
+ ( Scan == OS2_SCAN_INSERT_0 )) // Ins
+ {
+ IgnoreKey = FALSE; // don't ignore CUE keys
+ }
+ } else if ( KbdWaitFlag & ENABLE_LN_EDITOR_KEY )
+ {
+ if (( Scan == 0x3B ) || // F1
+ ( Scan == 0x3C ) || // F2
+ ( Scan == 0x3D ) || // F3
+ ( Scan == 0x3E ) || // F4
+ ( Scan == 0x40 ) || // F6
+ ( Scan == 0x41 ) || // F7
+ ( Scan == OS2_SCAN_LEFT_4 ) || // Left
+ ( Scan == OS2_SCAN_RIGHT_6 ) || // Right
+ ( Scan == OS2_SCAN_DEL ) || // Del
+ ( Scan == OS2_SCAN_INSERT_0 )) // Ins
+ {
+ IgnoreKey = FALSE; // don't ignore editing keys
+ }
+ }
+
+ if (IgnoreKey)
+ {
+#if DBG
+ IF_OD2_DEBUG( KBD )
+ {
+ KdPrint(("KbdCheckPackage: ignore non-ASCII key\n"));
+ }
+#endif
+ }
+ } else if ( KbdAsciiMode )
+ {
+ /*
+ *
+ * Ignore speciel CTRL-Keys in ASCII mode
+ *
+ */
+
+ if (( Char == 0x03 ) || // ^C
+ ( Char == 0x10 ) || // ^P
+ // ^Q: in non-US kbd(AZARTY) ^Q is passed
+ // and ^A not (mjarus 7/5/93)
+ (( Scan == 0x10 ) &&
+ ((KbdPackage->KeyInfo.fsState & (OS2_CONTROL | OS2_ALT)) == OS2_CONTROL)) ||
+ ( Char == 0x13 )) // ^S
+ {
+#if DBG
+ IF_OD2_DEBUG(KBD)
+ {
+ KdPrint((" - ignore Char %x in ASCII\n",
+ Char));
+ }
+#endif
+ IgnoreKey = TRUE; // ignore NON_ASCII
+ }
+ }
+
+ return ( (DWORD)IgnoreKey );
+}
+
+
+VOID
+KbdNewSetup(
+ IN PKBDINFO LastSetup
+ )
+{
+ PKBDINFO NewSetup = &KbdQueue->Setup;
+ USHORT Mask;
+
+// if (*LastSetup == *NewSetup)
+// return;
+
+ /* BUGBUG=> handle new setup */
+
+ SesGrp->ModeFlag = (USHORT)((NewSetup->fsMask & KEYBOARD_BINARY_MODE ) ? 1 : 0);
+
+ Mask = NewSetup->fsMask & (KEYBOARD_BINARY_MODE | KEYBOARD_SHIFT_REPORT);
+
+ Ow2KbdXlateVars.XInputMode = (Mask) ?
+ ((Mask & KEYBOARD_SHIFT_REPORT) ? (BINARY_MODE | SHIFT_REPORT_MODE) :
+ BINARY_MODE) : 0;
+
+ if ((NewSetup->fsMask & KEYBOARD_ASCII_MODE ) &&
+ (LastSetup->fsMask & KEYBOARD_BINARY_MODE ))
+ {
+ LastStringLength = 0;
+ KbdBuffNextPtr = 0;
+ KbdBuffNextLen = 0;
+ }
+
+ KbdAsciiMode = (BOOL)(( NewSetup->fsMask & KEYBOARD_ASCII_MODE ) ? 1 : 0);
+
+ if (NewSetup->fsMask & KEYBOARD_2B_TURNAROUND)
+ {
+ KbdSetupTurnAroundCharTwo = (BOOLEAN)TRUE;
+ } else
+ {
+ KbdSetupTurnAroundCharTwo = (BOOLEAN)FALSE;
+ }
+
+ return;
+}
+
+
+VOID
+KbdCueEraseAndDisplayLine(
+ IN ULONG NewLineIndex
+ )
+/*++
+
+Routine Description:
+
+ This routine erase the current input line and display new one.
+
+Arguments:
+
+ NewLineIndex - pointer in CUE buffer for new line (or to NULL
+ if nothing to diaply).
+
+Return Value:
+
+
+Note:
+
+ ASCII CUE string mode.
+
+ Used by UP-ARROW, DOWN-ARROW and ESC.
+
+ 1. Erase the active command line being displayed and
+ 2. Display the new command in the command queue.
+
+ Uses:
+
+ - KbdInputLength - active command line length.
+ - KbdIndexInLine - current index in command line.
+ - LineInputBuff[0, KbdIndexInLine, KbdInputLength].X_Pos
+ - KbdCueBuffer[NewLineIndex..]
+
+ Updates:
+
+ - KbdInputLength - new line length.
+ - KbdIndexInLine - 0.
+ - LineInputBuff[0..KbdInputLength].Char and .X_Pos
+ - console display
+ - LVB
+ - SesGrp->WinCoord - by other routines.
+
+ Calls:
+
+ - KbdEchoBSAndFillSpaces
+ - KbdCueUpdateBufferOffset
+ - KbdCueMoveToRight
+ - KbdCueMoveToLeft
+
+--*/
+{
+ /*
+ * Erase the active command line being displayed.
+ */
+
+ if ( KbdInputLength )
+ {
+ KbdEchoBSAndFillSpaces(
+ LineInputBuff[KbdIndexInLine].X_Pos - LineInputBuff[0].X_Pos,
+ LineInputBuff[KbdInputLength].X_Pos - LineInputBuff[0].X_Pos
+ );
+
+ KbdIndexInLine = 0;
+ KbdInputLength = 0;
+ }
+
+ /*
+ * Display the new command in the command queue
+ */
+
+ for ( KbdInputLength = 0 ;
+ LineInputBuff[KbdInputLength].Char = KbdCueBuffer[NewLineIndex + KbdInputLength] ;
+ KbdInputLength++ );
+
+ if (KbdInputLength)
+ {
+ KbdCueUpdateBufferOffset(
+ 0,
+ KbdInputLength,
+ LineInputBuff[0].X_Pos
+ );
+
+ KbdCueMoveToRight(
+ 0,
+ KbdInputLength,
+ TRUE
+ );
+
+ KbdCueMoveToLeft(
+ KbdInputLength,
+ KbdInputLength
+ );
+ }
+}
+
+
+VOID
+KbdCueMoveToRight(
+ IN ULONG StartIndex,
+ IN ULONG StringLength,
+ IN ULONG UpdateLVB
+ )
+/*++
+
+Routine Description:
+
+ This routine moves the console cursor position to the right
+ while sending the active command line to the console.
+
+Arguments:
+
+ StartIndex - index in LineInputBuff[] (the active command line) to start
+ moving right from.
+
+ StringLength - number of character to move right.
+
+ UpdateLVB - flag if to set LVB also (for new info)
+
+Return Value:
+
+
+Note:
+
+ ASCII CUE string mode.
+
+ Used by RIGHT-ARROW, END, ^RIGHT-ARROW, KbdCueEraseAndDisplayLine,
+ KbdCueDeleteCharAndShift and KbdCueHandleChar.
+
+ 1. Send to console
+ 2. Update Coord
+ 3. Update LVB
+ 4. Update position
+
+ Uses:
+
+ - LineInputBuff[0..KbdInputLength].Char and .X_Pos
+
+ Updates:
+
+ - KbdInputLength - NO.
+ - KbdIndexInLine - add StringLength.
+ - LineInputBuff[0..KbdInputLength].Char and .X_Pos - NO
+ - console display
+ - LVB (if UpdateLVB)
+ - SesGrp->WinCoord - add StringLength.
+
+ Calls:
+
+ - Or2WinWriteConsoleA
+ - Ow2VioUpdateCurPos
+ - VioLVBScrollBuff
+ - VioLVBCopyStr
+
+--*/
+{
+ UCHAR Char;
+ ULONG NumChar, NumBytes, NumWritten, NumLines = 0;
+ COORD OldCoord, Coord;
+
+ OldCoord = Coord = GET_CURRENT_COORD;
+
+ /*
+ * Copy to temp buffer
+ */
+
+ for ( NumBytes = 0, NumChar = 0 ; NumChar < StringLength ; NumChar++ )
+ {
+ if ((Char = LineInputBuff[StartIndex + NumChar].Char) < ' ')
+ {
+ KBD_BUFFER_ADDRESS[NumBytes++] = '^';
+ KBD_BUFFER_ADDRESS[NumBytes++] = (UCHAR)(Char + '@');
+ } else
+ {
+ KBD_BUFFER_ADDRESS[NumBytes++] = Char;
+ }
+ }
+
+ if (!NumBytes)
+ {
+ return ;
+ }
+
+ if ( KbdEchoFlag )
+ {
+ /*
+ * Send to console
+ */
+
+ if(!Or2WinWriteConsoleA(
+ #if DBG
+ KbdCueMoveToRightStr,
+ #endif
+ hConOut,
+ (LPSTR)KBD_BUFFER_ADDRESS,
+ NumBytes,
+ &NumWritten,
+ NULL
+ ))
+ {
+#if DBG
+ ASSERT1("OS2SES(KbdCueMoveToRight): failed on WriteConsoleA", FALSE);
+#endif
+ }
+
+#if DBG
+ if ( NumBytes != NumWritten )
+ {
+ KdPrint(("OS2SES(KbdCueMoveToRight): partial data WriteConsoleA (%u from %u)\n",
+ NumWritten, NumBytes));
+ ASSERT( FALSE );
+ }
+#endif
+
+ /*
+ * Update Coord
+ */
+
+ Coord.X += (SHORT)NumWritten;
+ while ( Coord.X >= SesGrp->ScreenColNum )
+ {
+ Coord.Y++;
+ Coord.X -= SesGrp->ScreenColNum;
+ }
+
+ if ( Coord.Y >= SesGrp->ScreenRowNum )
+ {
+ NumLines = Coord.Y - SesGrp->ScreenRowNum + 1;
+ Coord.Y = SesGrp->ScreenRowNum - 1;
+ }
+
+ Ow2VioUpdateCurPos(Coord);
+
+ /*
+ * Update LVB
+ */
+
+ if ( UpdateLVB )
+ {
+ if ( NumLines && ( SesGrp->ScreenSize < 512 ))
+ {
+ ULONG NumChar1 = SesGrp->ScreenRowNum - OldCoord.X;
+ UCHAR *Ptr = &KBD_BUFFER_ADDRESS[0];
+
+ while ( NumWritten )
+ {
+ VioLVBCopyStr(
+ Ptr,
+ OldCoord,
+ NumChar1
+ );
+
+ VioLVBFillAtt(
+ SesGrp->AnsiCellAttr,
+ OldCoord,
+ NumChar1
+ );
+
+ OldCoord.X = 0;
+
+ if ( ++OldCoord.Y >= SesGrp->ScreenRowNum )
+ {
+ OldCoord.Y--;
+ VioLVBScrollBuff(1);
+ NumLines--;
+ }
+
+ NumWritten -= NumChar1;
+
+ if (( NumChar1 = NumWritten ) > (ULONG)SesGrp->ScreenColNum )
+ {
+ NumChar1 = SesGrp->ScreenColNum;
+ }
+ }
+
+ ASSERT( NumLines == 0 );
+ } else
+ {
+ if ( NumLines )
+ {
+ OldCoord.Y -= (SHORT)NumLines;
+ VioLVBScrollBuff(NumLines);
+ }
+
+ VioLVBCopyStr(
+ KBD_BUFFER_ADDRESS,
+ OldCoord,
+ NumWritten
+ );
+
+ VioLVBFillAtt(
+ SesGrp->AnsiCellAttr,
+ OldCoord,
+ NumWritten
+ );
+ }
+ }
+ }
+
+ /*
+ * Update position index
+ */
+
+ KbdIndexInLine += (USHORT)StringLength;
+}
+
+
+VOID
+KbdCueMoveToLeft(
+ IN ULONG StartIndex,
+ IN ULONG MoveLength
+ )
+/*++
+
+Routine Description:
+
+ This routine moves the console cursor position to the left
+ using '\b'.
+
+Arguments:
+
+ StartIndex - index in LineInputBuff[] (the active command line) to start
+ moving left from.
+
+ MoveLength - number of character to move left.
+
+Return Value:
+
+
+Note:
+
+ ASCII CUE string mode.
+
+ Used by LEFT-ARROW, HOME, ^LEFT-ARROW, ^HOME, BS, KbdCueEraseAndDisplayLine,
+ KbdCueDeleteCharAndShift and KbdCueHandleChar.
+
+ 1. Send to console
+ 2. Update position
+
+ Uses:
+
+ - LineInputBuff[StartIndex - MoveLength,StartIndex].X_Pos
+ - LineInputBuff[StartIndex - MoveLength..StartIndex].Char
+
+ Updates:
+
+ - KbdInputLength - NO.
+ - KbdIndexInLine - sub MoveLength.
+ - LineInputBuff[0..KbdInputLength].Char and .X_Pos - NO
+ - console display - NO
+ - LVB - NO
+ - SesGrp->WinCoord - by other routines.
+
+ Calls:
+
+ - KbdEchoBSAndFillSpaces
+
+--*/
+{
+ ULONG NumBytes;
+
+ /*
+ * Calculate byte count
+ */
+
+ NumBytes = LineInputBuff[StartIndex].X_Pos - LineInputBuff[StartIndex - MoveLength].X_Pos;
+
+ if (!NumBytes)
+ {
+ return ;
+ }
+
+ if ( KbdEchoFlag )
+ {
+ if ( SesGrp->ScreenSize < 512 )
+ {
+ ULONG Row1, Row2;
+
+ Row1 = LineInputBuff[StartIndex - MoveLength].X_Pos / SesGrp->ScreenColNum;
+ Row2 = LineInputBuff[KbdInputLength].X_Pos / SesGrp->ScreenColNum;
+
+ if (( Row2 - Row1 + 1 ) > (ULONG)SesGrp->ScreenRowNum )
+ {
+ NumBytes += LineInputBuff[StartIndex - MoveLength].X_Pos % SesGrp->ScreenColNum;
+ NumBytes -= (Row2 - Row1 + 1 - SesGrp->ScreenRowNum) * SesGrp->ScreenColNum;
+ }
+ }
+
+ /*
+ * Send to console and update coord
+ */
+
+ KbdEchoBSAndFillSpaces(NumBytes, 0);
+ }
+
+ /*
+ * Update position index
+ */
+
+ KbdIndexInLine -= (USHORT)MoveLength;
+}
+
+
+VOID
+KbdCueUpdateBufferOffset(
+ IN ULONG StartIndex,
+ IN ULONG StringLength,
+ IN ULONG StartOffset
+ )
+/*++
+
+Routine Description:
+
+ This routine updates the offset in buffer for the active command line.
+ This is done from StartIndex for StringLength + 1 (to update the offset
+ of the next char according to the last char in string). The StartIndex
+ gets X_Pos of StartOffset and the following are updated according the
+ char type (char under 0x20 holds two columns for ^X).
+
+Arguments:
+
+ StartIndex - index in LineInputBuff[] (the active command line) to start
+ updaing the X_Pos field from.
+
+ StringLength - number of character to update X_Pos for.
+
+ StartOffset - X_Pos for the first character.
+
+Return Value:
+
+
+Note:
+
+ ASCII CUE string mode.
+
+ Used by KbdCueEraseAndDisplayLine, KbdCueDeleteCharAndShift and
+ KbdCueHandleChar.
+
+ 1. Updates the X_Pos field in LineInputBuff[].
+
+ Uses:
+
+ - KbdInputLength - active command line length.
+ - KbdIndexInLine - current index in command line.
+ - LineInputBuff[0, KbdIndexInLine, KbdInputLength].X_Pos
+ - KbdCueBuffer[NewLineIndex..]
+
+--*/
+{
+ ULONG NumChar, Index, Offset;
+
+ /*
+ * Update the offset in buffer. This is done for StringLength + 1
+ * to update the offset of the next char according to the last char
+ * in string.
+ */
+
+ for ( Index = StartIndex, Offset = StartOffset, NumChar = 0 ;
+ NumChar <= StringLength ; NumChar++ )
+ {
+ LineInputBuff[Index].X_Pos = (USHORT)Offset++;
+
+ if ( LineInputBuff[Index++].Char < ' ' )
+ {
+ Offset++;
+ }
+ }
+}
+
+
+VOID
+KbdCueDeleteCharAndShift(
+ IN ULONG StartIndex,
+ IN ULONG NumChar
+ )
+/*++
+
+Routine Description:
+
+ This routine delete character and shift the remaining command line
+ input to the left.
+
+Arguments:
+
+ StartIndex - index in LineInputBuff[] (the active command line) to start
+ deleting from.
+
+ NumChar - number of character to delete.
+
+Return Value:
+
+
+Note:
+
+ ASCII CUE string mode.
+
+ Used by DEL, ^HOME and BS.
+
+ 1 Shift buffer info (Char field)
+ 2 Update X_Pos (Offset) field in the shifted area
+ 3 Send the shifted string to console and LVB
+ 4 Clear remaining line
+ 5 Return to the cursor position
+
+ Uses:
+
+ - LineInputBuff[].X_Pos and Char
+
+ Updates:
+
+ - KbdInputLength - sub NumChar.
+ - KbdIndexInLine - NO
+ - LineInputBuff[0..KbdInputLength].Char and .X_Pos
+ - console display
+ - LVB
+ - SesGrp->WinCoord - by other routines.
+
+ Calls:
+
+ - KbdCueUpdateBufferOffset
+ - KbdCueMoveToRight
+ - KbdEchoBSAndFillSpaces
+ - KbdCueMoveToLeft
+
+--*/
+{
+ if (NumChar)
+ {
+ ULONG Offset = LineInputBuff[StartIndex].X_Pos;
+ ULONG Delta = LineInputBuff[StartIndex + NumChar].X_Pos - Offset;
+ ULONG NumShift = KbdInputLength - StartIndex - NumChar;
+
+ if ( NumShift )
+ {
+ /*
+ * Shift buffer info (Char field)
+ */
+
+ RtlMoveMemory(
+ &LineInputBuff[StartIndex].Char,
+ &LineInputBuff[StartIndex + NumChar].Char,
+ NumShift * sizeof(LINE_EDIT_KBD)
+ );
+
+ /*
+ * Update X_Pos (Offset) field in the shifted area
+ */
+
+ KbdCueUpdateBufferOffset(
+ StartIndex,
+ NumShift,
+ Offset
+ );
+
+ /*
+ * Send the shifted string to console and LVB
+ */
+
+ KbdCueMoveToRight(
+ StartIndex,
+ NumShift,
+ TRUE
+ );
+ }
+
+ /*
+ * Clear remaining line
+ */
+
+ KbdEchoBSAndFillSpaces(0, Delta);
+
+ /*
+ * Return to the cursor position
+ */
+
+ KbdCueMoveToLeft(
+ StartIndex + NumShift,
+ NumShift
+ );
+
+ KbdInputLength -= (USHORT)NumChar;
+ }
+}
+
+
+VOID
+KbdCueHandleChar(
+ IN UCHAR Char,
+ IN ULONG Count
+ )
+/*++
+
+Routine Description:
+
+ This routine handle new char at CUE mode.
+
+Arguments:
+
+ Char - char to handle.
+
+ NumChar - number of character.
+
+Return Value:
+
+
+Note:
+
+ ASCII CUE string mode.
+
+ Used by CHAR.
+
+ For INSERT:
+ 1 Shift buffer info (Char field)
+ 2 Fill new char
+ 3 Update X_Pos (Offset) field
+ 4 Send the new+old string to console and LVB
+ 5 Return to the cursor position
+ 6 Beep if no place
+ Else:
+ 1 Shift buffer info (Char field)
+ 2 Fill new char
+ 3 Update X_Pos (Offset) field
+ 4 Send the shifted string to console and LVB
+ 5 Clear remaining line
+ 6 Return to the cursor position
+ 7 Beep if no place
+
+ Uses:
+
+ - LineInputBuff[].X_Pos and Char
+ - KbdInsertOn
+ - KbdIndexInLine
+ - KbdMaxLength
+ - KbdInputLength
+
+ Updates:
+
+ - KbdInputLength
+ - KbdIndexInLine
+ - LineInputBuff[0..KbdInputLength].Char and .X_Pos
+ - console display
+ - LVB
+ - SesGrp->WinCoord - by other routines.
+
+ Calls:
+
+ - KbdCueUpdateBufferOffset
+ - KbdCueMoveToRight
+ - KbdCueMoveToLeft
+ - KbdEchoBSAndFillSpaces
+ - KbdEchoBeep
+ - RtlMoveMemory
+
+--*/
+{
+ ULONG NumChar, NumBeep = 0, NumShift, UpdateRight, i;
+ ULONG LastOffset = LineInputBuff[KbdInputLength].X_Pos;
+
+ if ( KbdInsertOn )
+ {
+ if (( NumChar = KbdMaxLength - KbdInputLength ) > Count )
+ {
+ NumChar = Count;
+ } else
+ {
+ NumBeep = Count - NumChar;
+ }
+
+ /*
+ * Shift buffer info (Char field) to free space for new char
+ */
+
+ NumShift = KbdInputLength - KbdIndexInLine;
+
+ RtlMoveMemory(
+ &LineInputBuff[KbdIndexInLine + NumChar].Char,
+ &LineInputBuff[KbdIndexInLine].Char,
+ NumShift * sizeof(LINE_EDIT_KBD)
+ );
+ /*
+ * Fill new char
+ */
+
+ for ( i = 0 ; i < NumChar ; i++ )
+ {
+ LineInputBuff[KbdIndexInLine + i].Char = Char;
+ }
+
+ /*
+ * Update X_Pos (Offset) field in the shifted and new areas
+ */
+
+ KbdCueUpdateBufferOffset(
+ KbdIndexInLine,
+ NumChar + NumShift,
+ LineInputBuff[KbdIndexInLine].X_Pos
+ );
+
+ /*
+ * Send the shifted string to console and LVB
+ */
+
+ KbdCueMoveToRight(
+ KbdIndexInLine,
+ NumChar + NumShift,
+ TRUE
+ );
+
+ /*
+ * Return to the cursor position
+ */
+
+ KbdCueMoveToLeft(
+ KbdIndexInLine,
+ NumShift
+ );
+
+ KbdInputLength += (USHORT)NumChar;
+ } else
+ {
+ if (( NumChar = KbdMaxLength - KbdIndexInLine ) > Count )
+ {
+ NumChar = Count;
+ } else
+ {
+ NumBeep = Count - NumChar;
+ }
+
+ UpdateRight = max(NumChar, (ULONG)(KbdInputLength - KbdIndexInLine));
+
+ /*
+ * Fill new char
+ */
+
+ for ( i = 0 ; i < NumChar ; i++ )
+ {
+ LineInputBuff[KbdIndexInLine + i].Char = Char;
+ }
+
+ /*
+ * Update X_Pos (Offset) field in the old and new areas
+ */
+
+ KbdCueUpdateBufferOffset(
+ KbdIndexInLine,
+ UpdateRight,
+ LineInputBuff[KbdIndexInLine].X_Pos
+ );
+
+ /*
+ * Send the shifted string to console and LVB
+ */
+
+ KbdCueMoveToRight(
+ KbdIndexInLine,
+ UpdateRight,
+ TRUE
+ );
+
+ if ( LastOffset > (ULONG)LineInputBuff[KbdIndexInLine].X_Pos )
+ {
+ /*
+ * Fill spaces at the EOL if needed
+ */
+
+ KbdEchoBSAndFillSpaces(
+ 0,
+ LastOffset - LineInputBuff[KbdIndexInLine].X_Pos
+ );
+ }
+
+ if ( UpdateRight != NumChar )
+ {
+ /*
+ * Return to the cursor position
+ */
+
+ KbdCueMoveToLeft(
+ KbdIndexInLine,
+ UpdateRight - NumChar
+ );
+ }
+
+ if ( KbdIndexInLine > KbdInputLength )
+ {
+ KbdInputLength = KbdIndexInLine;
+ }
+ }
+
+ if ( NumBeep != Count )
+ {
+ KbdLineWasEdited = TRUE;
+ }
+
+ if ( NumBeep )
+ {
+ KbdEchoBeep(NumBeep);
+ }
+}
+
+
+VOID
+KbdCueSetCurTypeToHalf()
+{
+ VIOCURSORINFO CurType;
+
+ //Ow2VioGetCurType((PVOID)&CurType);
+ //CurType = SesGrp->CursorInfo;
+
+ //CurType.cEnd = SesGrp->CellVSize;
+ CurType.cEnd = SesGrp->CursorInfo.cEnd;
+ CurType.yStart = (CurType.cEnd + 1 ) / 2;
+ CurType.cx = 1;
+ CurType.attr = 0;
+
+ Ow2VioSetCurType((PVOID)&CurType);
+}
+
+
+VOID
+KbdCueSetCurTypeToQuater()
+{
+ VIOCURSORINFO CurType;
+
+ //Ow2VioGetCurType((PVOID)&CurType);
+ //CurType = SesGrp->CursorInfo;
+
+ //CurType.cEnd = SesGrp->CellVSize;
+ CurType.cEnd = SesGrp->CursorInfo.cEnd;
+ CurType.yStart = (CurType.cEnd + 1 ) * 3 / 4;
+ CurType.cx = 1;
+ CurType.attr = 0;
+
+ Ow2VioSetCurType((PVOID)&CurType);
+}
+
+
+DWORD
+KbdEchoCharToConsole(
+ IN UCHAR Char,
+ IN ULONG Count
+ )
+/*++
+
+Routine Description:
+
+ This routine write <Char> to console <Count> times.
+
+Arguments:
+
+ Char - character to write.
+
+ Count - number of times to write char
+
+Return Value:
+
+
+Note:
+
+ ASCII CUE/EDIT string mode.
+
+ Used by KbdEchoNL, KbdEchoBSAndFillSpaces, KbdEchoBeep and KbdEchoChar.
+
+ Calls:
+
+ - Or2WinWriteConsoleA
+
+--*/
+{
+ ULONG NumChar, NumWritten, MaxCount = Count;
+
+ NumChar = (MaxCount > KBD_BUFFER_SIZE) ? KBD_BUFFER_SIZE : MaxCount;
+ memset(KBD_BUFFER_ADDRESS, Char, NumChar);
+
+ while (MaxCount)
+ {
+ if(!Or2WinWriteConsoleA(
+ #if DBG
+ KbdEchoCharToConsoleStr,
+ #endif
+ hConOut,
+ (LPSTR)KBD_BUFFER_ADDRESS,
+ NumChar,
+ &NumWritten,
+ NULL))
+ {
+#if DBG
+ ASSERT1("OS2SES(KbdEchoCharToConsole): failed on WriteConsoleA", FALSE);
+#endif
+ }
+
+#if DBG
+ if ( NumChar != NumWritten )
+ {
+ KdPrint(("OS2SES(KbdEchoCharToConsole): partial data WriteConsoleA %u from %u\n",
+ NumWritten, NumChar));
+ ASSERT( FALSE );
+ }
+#endif
+
+ MaxCount -= NumChar;
+ NumChar = (MaxCount > KBD_BUFFER_SIZE) ? KBD_BUFFER_SIZE : MaxCount;
+ }
+
+ return(NO_ERROR);
+}
+
+
+DWORD
+KbdEchoNL(
+ IN ULONG Count
+ )
+/*++
+
+Routine Description:
+
+ This routine write NL to console <Count> times and update LVB.
+
+Arguments:
+
+ Count - number of times to write char
+
+Return Value:
+
+
+Note:
+
+ ASCII CUE/EDIT string mode.
+
+ Used by LF (EDIT only) and CR.
+
+ Updates:
+
+ - SesGrp->WinCoord
+ - LVB
+
+ Calls:
+
+ - KbdEchoCharToConsole
+ - VioLVBScrollBuff
+
+--*/
+{
+ ULONG NumLines = 0;
+ COORD Coord = GET_CURRENT_COORD;
+
+ Coord.X = 0;
+ Coord.Y += (SHORT)Count;
+ if ( Coord.Y >= SesGrp->ScreenRowNum )
+ {
+ NumLines = Coord.Y - SesGrp->ScreenRowNum + 1;
+ Coord.Y = SesGrp->ScreenRowNum - 1;
+ }
+
+ KbdEchoCharToConsole('\n', Count);
+ Ow2VioUpdateCurPos(Coord);
+
+ if (NumLines)
+ {
+ VioLVBScrollBuff(NumLines);
+ }
+
+ return(NO_ERROR);
+}
+
+
+DWORD
+KbdEchoESC(
+ IN ULONG Count,
+ IN ULONG HorzMove
+ )
+/*++
+
+Routine Description:
+
+ This routine write <ESC> to console <Count> times with <HorzMove>
+ number of spaces on the next line. It also update LVB.
+
+Arguments:
+
+ Count - number of times to write char
+
+ HorzMove - number of spaces on the start of the new line.
+
+Return Value:
+
+
+Note:
+
+ ASCII EDIT string mode.
+
+ Used by ESC.
+
+ Updates:
+
+ - SesGrp->WinCoord
+ - LVB
+
+ Calls:
+
+ - Or2WinWriteConsoleA
+ - VioLVBScrollBuff
+
+--*/
+{
+ ULONG NumChar, NumWritten, MaxCount = Count, NumLines = 0, Length = HorzMove + 1;
+ COORD OldCoord, Coord;
+
+ OldCoord = Coord = GET_CURRENT_COORD;
+
+ KBD_BUFFER_ADDRESS[0] = '\\';
+ KBD_BUFFER_ADDRESS[1] = '\n';
+ memset(&KBD_BUFFER_ADDRESS[2], ' ', HorzMove);
+ KBD_BUFFER_ADDRESS[HorzMove + 2] = '\\';
+ NumChar = HorzMove + 2;
+
+ Coord.Y += (SHORT)Count;
+ Coord.X = (SHORT)HorzMove;
+
+ if ( Coord.Y >= SesGrp->ScreenRowNum )
+ {
+ NumLines = Coord.Y - SesGrp->ScreenRowNum + 1;
+ Coord.Y = SesGrp->ScreenRowNum - 1;
+ }
+
+ while ( MaxCount )
+ {
+ if(!Or2WinWriteConsoleA(
+ #if DBG
+ KbdEchoESCStr,
+ #endif
+ hConOut,
+ (LPSTR)KBD_BUFFER_ADDRESS,
+ NumChar,
+ &NumWritten,
+ NULL))
+ {
+#if DBG
+ ASSERT1("OS2SES(KbdEchoESC): failed on WriteConsoleA", FALSE);
+#endif
+ //return (1);
+ }
+
+#if DBG
+ if ( NumChar != NumWritten )
+ {
+ KdPrint(("OS2SES(KbdEchoESC): partial data WriteConsoleA %u from %u\n",
+ NumWritten, NumChar));
+ ASSERT( FALSE );
+ }
+#endif
+
+ MaxCount--;
+ }
+
+ Ow2VioUpdateCurPos(Coord);
+
+ VioLVBFillChar(
+#ifdef DBCS
+// MSKK Oct.14.1993 V-AkihiS
+ "\\",
+#else
+ '\\',
+#endif
+ OldCoord,
+ 1
+ );
+
+ VioLVBFillAtt(
+ SesGrp->AnsiCellAttr,
+ OldCoord,
+ 1
+ );
+
+ OldCoord.X = 0;
+
+ for ( NumChar = 0 ; NumChar < Count ; NumChar++ )
+ {
+ if ( ++OldCoord.Y >= SesGrp->ScreenRowNum )
+ {
+ OldCoord.Y--;
+ VioLVBScrollBuff(1);
+ NumLines--;
+ }
+
+ if ( NumChar == ( Count - 1 ))
+ {
+ Length--; // don't put the slash at the last line
+ }
+
+ VioLVBCopyStr(
+ &KBD_BUFFER_ADDRESS[2],
+ OldCoord,
+ Length
+ );
+
+ VioLVBFillAtt(
+ SesGrp->AnsiCellAttr,
+ OldCoord,
+ Length
+ );
+ }
+
+ ASSERT( NumLines == 0 );
+ return(NO_ERROR);
+}
+
+
+DWORD
+KbdEchoBSAndFillSpaces(
+ IN ULONG BSCount,
+ IN ULONG SpaceCount
+ )
+/*++
+
+Routine Description:
+
+ This routine write BS ('\b') to console <BSCount> times and fill
+ <SpaceCount> times spaces in console and LVB.
+
+Arguments:
+
+ BSCount - number of times to write \b char to console
+
+ SpaceCount - number of times to fill space char to console and LVB
+
+Return Value:
+
+
+Note:
+
+ ASCII EDIT/CUE string mode.
+
+ Used by ^END, BS (EDIT only), LF (EDIT only), KbdCueEraseAndDisplayLine,
+ KbdCueMoveToLeft, KbdCueDeleteCharAndShift and KbdCueHandleChar.
+
+ Updates:
+
+ - SesGrp->WinCoord (for BSCount only)
+ - LVB (for SpaceCount only)
+
+ Calls:
+
+ - KbdEchoCharToConsole
+ - Or2WinFillConsoleOutputCharacterA
+ - VioLVBFillChar
+
+--*/
+{
+ ULONG NumFilled;
+ COORD OldCoord, Coord;
+
+ if ( !KbdEchoFlag )
+ {
+ return (0L);
+ }
+
+ if (((long) BSCount < 0) || ((long) SpaceCount < 0)) {
+#if DBG
+ DbgPrint("KbdEchoBSAndFillSpaces: BSCount %d or SpaceCount %d are negative\n",
+ (long)BSCount, (long)SpaceCount);
+#endif
+ return ERROR_INVALID_PARAMETER;
+ }
+
+ OldCoord = Coord = GET_CURRENT_COORD;
+
+ Coord.X -= (SHORT)BSCount;
+ while ( Coord.X < 0 )
+ {
+ if ( Coord.Y )
+ {
+ Coord.Y--;
+ Coord.X += SesGrp->ScreenColNum;
+ } else
+ {
+ if ( SpaceCount )
+ {
+ if ( SpaceCount > (ULONG)abs(Coord.X) )
+ {
+ SpaceCount += (ULONG)Coord.X;
+ } else
+ {
+ SpaceCount = 0;
+ }
+ }
+
+ BSCount += (ULONG)Coord.X; // sub the negative value
+ Coord.X = 0;
+ }
+ }
+
+ KbdEchoCharToConsole('\b', BSCount);
+ Ow2VioUpdateCurPos(Coord);
+
+ if ( SpaceCount )
+ {
+ if (!Or2WinFillConsoleOutputCharacterA(
+ #if DBG
+ KbdEchoBSAndFillSpacesStr,
+ #endif
+ hConOut,
+ ' ',
+ SpaceCount,
+ Coord,
+ &NumFilled))
+ {
+#if DBG
+ ASSERT1("OS2SES(KbdEchoBSAndFillSpaces): failed on FillConsoleOutputCharacterA\n", FALSE);
+#endif
+ }
+
+#if DBG
+ if ( NumFilled != SpaceCount )
+ {
+ KdPrint(("OS2SES(KbdEchoBSAndFillSpaces): partial data %u from %u\n",
+ NumFilled, SpaceCount));
+ ASSERT( FALSE );
+ }
+#endif
+ VioLVBFillChar(
+#ifdef DBCS
+// MSKK Oct.14.1993 V-AkihiS
+ " ",
+#else
+ ' ',
+#endif
+ Coord,
+ SpaceCount
+ );
+
+ VioLVBFillAtt(
+ SesGrp->AnsiCellAttr,
+ Coord,
+ SpaceCount
+ );
+ }
+ return(NO_ERROR);
+}
+
+
+DWORD
+KbdEchoBeep(
+ IN ULONG Count
+ )
+/*++
+
+Routine Description:
+
+ This routine send BEPP ('\07') to console <Count> times.
+
+Arguments:
+
+ Count - number of times to write \g char to console
+
+Return Value:
+
+
+Note:
+
+ ASCII EDIT/CUE string mode.
+
+ Used when no place in the active command line by KbdEchoString,
+ Char and KbdCueHandleChar.
+
+ Calls:
+
+ - KbdEchoCharToConsole
+
+--*/
+{
+ KbdEchoCharToConsole('\07', Count);
+ return(NO_ERROR);
+}
+
+
+DWORD
+KbdEchoChar(
+ IN UCHAR Char,
+ IN ULONG Count
+ )
+/*++
+
+Routine Description:
+
+ This routine echo <Char> to console <Count> times and update LVB.
+
+Arguments:
+
+ Char - char to send to console
+
+ Count - number of times to send char to console
+
+Return Value:
+
+
+Note:
+
+ ASCII EDIT string mode.
+
+ Updates:
+
+ - SesGrp->WinCoord
+ - LVB
+
+ Calls:
+
+ - KbdEchoCharToConsole
+ - VioLVBScrollBuff
+
+--*/
+{
+ COORD OldCoord, Coord;
+ BOOL SendByLine = FALSE;
+ UCHAR FillChar;
+ ULONG Offset;
+
+ OldCoord = Coord = GET_CURRENT_COORD;
+ if (( Char >= ' ' ) || ( Char == '\t' ))
+ {
+ KbdEchoCharToConsole(Char, Count);
+
+ if ( Char == '\t' )
+ {
+ Offset = 8 * Count - (Coord.X & 7);
+ FillChar = ' ';
+ } else
+ {
+ FillChar = Char;
+ Offset = Count;
+ }
+
+ if ((ULONG)( Offset + 2 * SesGrp->ScreenColNum ) > SesGrp->ScreenSize )
+ {
+ SendByLine = TRUE;
+ } else
+ {
+ Coord.X += (SHORT)Offset;
+ while ( Coord.X >= SesGrp->ScreenColNum )
+ {
+ Coord.Y++;
+ Coord.X -= SesGrp->ScreenColNum;
+ }
+
+ if ( Coord.Y >= SesGrp->ScreenRowNum )
+ {
+ VioLVBScrollBuff(Coord.Y - SesGrp->ScreenRowNum + 1);
+ OldCoord.Y -= Coord.Y - SesGrp->ScreenRowNum + 1;
+ Coord.Y = SesGrp->ScreenRowNum - 1;
+ }
+
+ Ow2VioUpdateCurPos(Coord);
+
+ VioLVBFillChar(
+#ifdef DBCS
+// MSKK Oct.14.1993 V-AkihiS
+ &FillChar,
+#else
+ FillChar,
+#endif
+ OldCoord,
+ Offset
+ );
+
+ VioLVBFillAtt(
+ SesGrp->AnsiCellAttr,
+ OldCoord,
+ Offset
+ );
+ }
+ }
+
+ if ( SendByLine || (( Char < ' ' ) && ( Char != '\t' )))
+ {
+ ULONG NumChar, NumWritten, MaxCount, Pattern;
+
+ if ( SendByLine )
+ {
+ Pattern = (ULONG)((FillChar << 24) |
+ (FillChar << 16) |
+ (FillChar << 8) |
+ (FillChar));
+
+ MaxCount = 0;
+ } else
+ {
+ MaxCount = Offset = 2 * Count;
+ FillChar = (UCHAR)(Char + '@');
+
+ Pattern = (ULONG)((FillChar << 24) |
+ ('^' << 16) |
+ (FillChar << 8) |
+ ('^'));
+ }
+
+ NumChar = ( Offset > KBD_BUFFER_SIZE ) ? KBD_BUFFER_SIZE : Offset;
+
+ RtlFillMemoryUlong(
+ KBD_BUFFER_ADDRESS,
+ (NumChar + 3) & ~3,
+ Pattern
+ );
+
+ while ( MaxCount )
+ {
+ if(!Or2WinWriteConsoleA(
+ #if DBG
+ KbdEchoCharStr,
+ #endif
+ hConOut,
+ (LPSTR)KBD_BUFFER_ADDRESS,
+ NumChar,
+ &NumWritten,
+ NULL))
+ {
+#if DBG
+ ASSERT1("OS2SES(KbdEchoChar): failed on WriteConsoleA", FALSE);
+#endif
+ //return (1);
+ }
+
+#if DBG
+ if ( NumChar != NumWritten )
+ {
+ KdPrint(("OS2SES(KbdEchoChar): partial data WriteConsoleA %u from %u\n",
+ NumWritten, NumChar));
+ ASSERT( FALSE );
+ }
+#endif
+
+ MaxCount -= NumChar;
+ NumChar = ( MaxCount > KBD_BUFFER_SIZE ) ? KBD_BUFFER_SIZE : MaxCount;
+ }
+
+ if (( NumChar = SesGrp->ScreenColNum - Coord.X ) > Offset )
+ {
+ NumChar = Offset;
+ }
+
+ while ( Offset )
+ {
+ VioLVBCopyStr(
+ &KBD_BUFFER_ADDRESS[0],
+ Coord,
+ NumChar
+ );
+
+
+ VioLVBFillAtt(
+ SesGrp->AnsiCellAttr,
+ Coord,
+ NumChar
+ );
+ Coord.X += (SHORT)NumChar;
+ if ( Coord.X >= SesGrp->ScreenColNum )
+ {
+ Coord.X -= SesGrp->ScreenColNum;
+ if ( ++Coord.Y >= SesGrp->ScreenRowNum )
+ {
+ VioLVBScrollBuff(1);
+ Coord.Y--;
+ }
+ }
+
+ Offset -= NumChar;
+ if (( NumChar = SesGrp->ScreenColNum - Coord.X ) > Offset )
+ {
+ NumChar = Offset;
+ }
+ }
+
+ Ow2VioUpdateCurPos(Coord);
+ }
+
+ return(NO_ERROR);
+}
+
+
+DWORD
+KbdEchoAString(
+ IN PUCHAR String,
+ IN ULONG Length
+ )
+/*++
+
+Routine Description:
+
+ This routine echo <String>, which size is <Lenght> to console and update LVB.
+
+Arguments:
+
+ String - char string to send to console
+
+ Length - string length
+
+Return Value:
+
+
+Note:
+
+ ASCII EDIT string mode.
+
+ Updates:
+
+ - SesGrp->WinCoord
+ - LVB
+
+ Calls:
+
+ - Or2WinWriteConsoleA
+
+--*/
+{
+ ULONG NumWritten, NumChar, NumBytes, Num;
+ COORD OldCoord, Coord;
+ UCHAR Char;
+
+ OldCoord = Coord = GET_CURRENT_COORD;
+
+ for ( NumChar = 0, NumBytes = 0 ; NumChar < Length ; NumChar++ )
+ {
+ Char = String[NumChar];
+ if ( Char >= ' ' )
+ {
+ KBD_BUFFER_ADDRESS[NumBytes++] = Char;
+ } else if ( Char = '\t' )
+ {
+ Num = 8 - ((Coord.X + NumBytes) & 7);
+ memset(&KBD_BUFFER_ADDRESS[NumBytes], ' ', Num);
+ NumBytes += Num;
+ } else
+ {
+ KBD_BUFFER_ADDRESS[NumBytes++] = '^';
+ KBD_BUFFER_ADDRESS[NumBytes++] = (UCHAR)(Char + '@');
+ }
+
+ if (((ULONG)( Coord.X + NumBytes ) >= (ULONG)SesGrp->ScreenColNum ) ||
+ ( NumChar == ( Length - 1 )))
+ {
+ if(!Or2WinWriteConsoleA(
+ #if DBG
+ KbdEchoAStringStr,
+ #endif
+ hConOut,
+ (LPSTR)KBD_BUFFER_ADDRESS,
+ NumBytes,
+ &NumWritten,
+ NULL))
+ {
+#if DBG
+ ASSERT1("OS2SES(KbdEchoAString): failed on WriteConsoleA", FALSE);
+#endif
+ }
+
+#if DBG
+ if ( NumBytes != NumWritten )
+ {
+ KdPrint(("OS2SES(KbdEchoAString): partial data WriteConsoleA %u from %u\n",
+ NumWritten, NumBytes));
+ ASSERT( FALSE );
+ }
+#endif
+ OldCoord = Coord;
+ Coord.X += (SHORT)NumBytes;
+ if ( Coord.X >= SesGrp->ScreenColNum )
+ {
+ Coord.Y++;
+ Coord.X -= SesGrp->ScreenColNum;
+
+ if ( Coord.Y >= SesGrp->ScreenRowNum )
+ {
+ Coord.Y = SesGrp->ScreenRowNum - 1;
+ OldCoord.Y--;
+ }
+ }
+
+ Ow2VioUpdateCurPos(Coord);
+
+ VioLVBCopyStr(
+ &KBD_BUFFER_ADDRESS[0],
+ OldCoord,
+ NumBytes
+ );
+
+ VioLVBFillAtt(
+ SesGrp->AnsiCellAttr,
+ OldCoord,
+ NumBytes
+ );
+ NumBytes = 0;
+ }
+ }
+ return(NO_ERROR);
+}
+
+
+BOOL
+KbdKeyIsTurnAround(
+ IN UCHAR Char,
+ IN UCHAR Scan
+ )
+{
+ if ( KbdTurnAroundCharTwo )
+ {
+ if ( Scan == (UCHAR)KbdTurnAroundChar )
+ {
+ if ((( KbdReadMode == 0 ) &&
+ (( Char == 0 ) || ( Char == 0xE0 ))) ||
+ (( KbdReadMode == 1 ) && ( Char == HIBYTE(KbdTurnAroundChar) )))
+ {
+ return(TRUE);
+ }
+ }
+ } else
+ {
+ if ( Char == (UCHAR)KbdTurnAroundChar )
+ {
+ return(TRUE);
+ }
+ }
+
+ return(FALSE);
+}
+