Author: jmorlan Date: Fri Jun 4 20:26:22 2010 New Revision: 47572
URL: http://svn.reactos.org/svn/reactos?rev=47572&view=rev Log: [WIN32CSR] Console input simplification: - Put code for processing events for line input in one place, instead of duplicating it everywhere - Remove "Fake" and "NotChar" fields from ConsoleInput struct. ConioProcessKey didn't actually add Fake events; they were used for the \n when converting \r to \r\n, but this is better done by the line input code. - Build an input line completely on the server side; this will make it practical to add history and more sophisticated editing later
Modified: trunk/reactos/dll/win32/kernel32/misc/console.c trunk/reactos/include/reactos/subsys/csrss/csrss.h trunk/reactos/subsystems/win32/csrss/win32csr/coninput.c trunk/reactos/subsystems/win32/csrss/win32csr/conio.h trunk/reactos/subsystems/win32/csrss/win32csr/console.c
Modified: trunk/reactos/dll/win32/kernel32/misc/console.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/kernel32/misc/con... ============================================================================== --- trunk/reactos/dll/win32/kernel32/misc/console.c [iso-8859-1] (original) +++ trunk/reactos/dll/win32/kernel32/misc/console.c [iso-8859-1] Fri Jun 4 20:26:22 2010 @@ -1566,6 +1566,9 @@ }
Request->Status = STATUS_SUCCESS; + Request->Data.ReadConsoleRequest.ConsoleHandle = hConsoleInput; + Request->Data.ReadConsoleRequest.Unicode = bUnicode; + Request->Data.ReadConsoleRequest.FullReadSize = (WORD)nNumberOfCharsToRead; CsrRequest = MAKE_CSR_API(READ_CONSOLE, CSR_CONSOLE);
do @@ -1582,10 +1585,7 @@ } }
- Request->Data.ReadConsoleRequest.ConsoleHandle = hConsoleInput; - Request->Data.ReadConsoleRequest.Unicode = bUnicode; Request->Data.ReadConsoleRequest.NrCharactersToRead = (WORD)min(nNumberOfCharsToRead, CSRSS_MAX_READ_CONSOLE / CharSize); - Request->Data.ReadConsoleRequest.nCharsCanBeDeleted = (WORD)CharsRead;
Status = CsrClientCallServer(Request, NULL, @@ -1607,16 +1607,6 @@ Request->Data.ReadConsoleRequest.Buffer, Request->Data.ReadConsoleRequest.NrCharactersRead * CharSize); CharsRead += Request->Data.ReadConsoleRequest.NrCharactersRead; - - if (Request->Status == STATUS_NOTIFY_CLEANUP) - { - if(CharsRead > 0) - { - CharsRead--; - nNumberOfCharsToRead++; - } - Request->Status = STATUS_PENDING; - } } while (Request->Status == STATUS_PENDING && nNumberOfCharsToRead > 0);
Modified: trunk/reactos/include/reactos/subsys/csrss/csrss.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/include/reactos/subsys/csrs... ============================================================================== --- trunk/reactos/include/reactos/subsys/csrss/csrss.h [iso-8859-1] (original) +++ trunk/reactos/include/reactos/subsys/csrss/csrss.h [iso-8859-1] Fri Jun 4 20:26:22 2010 @@ -70,8 +70,8 @@ { HANDLE ConsoleHandle; BOOL Unicode; + WORD FullReadSize; WORD NrCharactersToRead; - WORD nCharsCanBeDeleted; /* number of chars already in buffer that can be backspaced */ HANDLE EventHandle; ULONG NrCharactersRead; BYTE Buffer[0];
Modified: trunk/reactos/subsystems/win32/csrss/win32csr/coninput.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/csrss/win3... ============================================================================== --- trunk/reactos/subsystems/win32/csrss/win32csr/coninput.c [iso-8859-1] (original) +++ trunk/reactos/subsystems/win32/csrss/win32csr/coninput.c [iso-8859-1] Fri Jun 4 20:26:22 2010 @@ -22,13 +22,62 @@
/* FUNCTIONS *****************************************************************/
+static VOID +ConioLineInputKeyDown(PCSRSS_CONSOLE Console, KEY_EVENT_RECORD *KeyEvent) +{ + if (KeyEvent->uChar.UnicodeChar == L'\b' && Console->Mode & ENABLE_PROCESSED_INPUT) + { + /* backspace handling - if we are in charge of echoing it then we handle it here + * otherwise we treat it like a normal char. + */ + if (Console->LineSize > 0) + { + Console->LineSize--; + if (Console->Mode & ENABLE_ECHO_INPUT) + ConioWriteConsole(Console, Console->ActiveBuffer, "\b", 1, TRUE); + } + } + else if (KeyEvent->uChar.UnicodeChar == L'\r') + { + /* TODO: add line to history */ + + Console->LineBuffer[Console->LineSize++] = L'\r'; + if (Console->Mode & ENABLE_ECHO_INPUT) + ConioWriteConsole(Console, Console->ActiveBuffer, "\r", 1, TRUE); + if (Console->Mode & ENABLE_PROCESSED_INPUT) + { + Console->LineBuffer[Console->LineSize++] = L'\n'; + if (Console->Mode & ENABLE_ECHO_INPUT) + ConioWriteConsole(Console, Console->ActiveBuffer, "\n", 1, TRUE); + } + Console->LineComplete = TRUE; + Console->LinePos = 0; + } + else if (KeyEvent->uChar.UnicodeChar != L'\0') + { + if (Console->LineSize + 2 < Console->LineMaxSize) + { + Console->LineBuffer[Console->LineSize++] = KeyEvent->uChar.UnicodeChar; + /* echo to screen if enabled */ + if (Console->Mode & ENABLE_ECHO_INPUT) + { + CHAR AsciiChar; + WideCharToMultiByte(Console->OutputCodePage, 0, + &KeyEvent->uChar.UnicodeChar, 1, + &AsciiChar, 1, NULL, NULL); + ConioWriteConsole(Console, Console->ActiveBuffer, &AsciiChar, 1, TRUE); + } + } + } +} + CSR_API(CsrReadConsole) { PLIST_ENTRY CurrentEntry; ConsoleInput *Input; PCHAR Buffer; PWCHAR UnicodeBuffer; - ULONG i; + ULONG i = 0; ULONG nNumberOfCharsToRead, CharSize; PCSRSS_CONSOLE Console; NTSTATUS Status; @@ -51,110 +100,94 @@ return Status; } Request->Data.ReadConsoleRequest.EventHandle = ProcessData->ConsoleEvent; - for (i = 0; i < nNumberOfCharsToRead && Console->InputEvents.Flink != &Console->InputEvents; i++) - { - /* remove input event from queue */ - CurrentEntry = RemoveHeadList(&Console->InputEvents); - if (IsListEmpty(&Console->InputEvents)) - { - ResetEvent(Console->ActiveEvent); - } - Input = CONTAINING_RECORD(CurrentEntry, ConsoleInput, ListEntry); - - /* only pay attention to valid ascii chars, on key down */ - if (KEY_EVENT == Input->InputEvent.EventType - && Input->InputEvent.Event.KeyEvent.bKeyDown - && Input->InputEvent.Event.KeyEvent.uChar.UnicodeChar != L'\0') - { - /* - * backspace handling - if we are in charge of echoing it then we handle it here - * otherwise we treat it like a normal char. - */ - if (L'\b' == Input->InputEvent.Event.KeyEvent.uChar.UnicodeChar && 0 - != (Console->Mode & ENABLE_ECHO_INPUT)) - { - /* echo if it has not already been done, and either we or the client has chars to be deleted */ - if (! Input->Echoed - && (0 != i || Request->Data.ReadConsoleRequest.nCharsCanBeDeleted)) - { - ConioWriteConsole(Console, Console->ActiveBuffer, "\b", 1, TRUE); - } - if (0 != i) - { - i -= 2; /* if we already have something to return, just back it up by 2 */ - } + + Status = STATUS_PENDING; /* we haven't read anything (yet) */ + if (Console->Mode & ENABLE_LINE_INPUT) + { + if (Console->LineBuffer == NULL) + { + /* Starting a new line */ + Console->LineMaxSize = max(256, Request->Data.ReadConsoleRequest.FullReadSize); + Console->LineBuffer = HeapAlloc(Win32CsrApiHeap, 0, Console->LineMaxSize * sizeof(WCHAR)); + if (Console->LineBuffer == NULL) + { + Status = STATUS_NO_MEMORY; + goto done; + } + Console->LineComplete = FALSE; + Console->LineSize = 0; + Console->LinePos = 0; + } + + /* If we don't have a complete line yet, process the pending input */ + while (!Console->LineComplete && !IsListEmpty(&Console->InputEvents)) + { + /* remove input event from queue */ + CurrentEntry = RemoveHeadList(&Console->InputEvents); + if (IsListEmpty(&Console->InputEvents)) + { + ResetEvent(Console->ActiveEvent); + } + Input = CONTAINING_RECORD(CurrentEntry, ConsoleInput, ListEntry); + + /* only pay attention to key down */ + if (KEY_EVENT == Input->InputEvent.EventType + && Input->InputEvent.Event.KeyEvent.bKeyDown) + { + ConioLineInputKeyDown(Console, &Input->InputEvent.Event.KeyEvent); + } + HeapFree(Win32CsrApiHeap, 0, Input); + } + + /* Check if we have a complete line to read from */ + if (Console->LineComplete) + { + while (i < nNumberOfCharsToRead && Console->LinePos != Console->LineSize) + { + WCHAR Char = Console->LineBuffer[Console->LinePos++]; + if (Request->Data.ReadConsoleRequest.Unicode) + UnicodeBuffer[i++] = Char; else - { - /* otherwise, return STATUS_NOTIFY_CLEANUP to tell client to back up its buffer */ - Console->WaitingChars--; - ConioUnlockConsole(Console); - HeapFree(Win32CsrApiHeap, 0, Input); - Request->Data.ReadConsoleRequest.NrCharactersRead = 0; - return STATUS_NOTIFY_CLEANUP; - - } - Request->Data.ReadConsoleRequest.nCharsCanBeDeleted--; - Input->Echoed = TRUE; /* mark as echoed so we don't echo it below */ - } - /* do not copy backspace to buffer */ - else - { - if(Request->Data.ReadConsoleRequest.Unicode) - UnicodeBuffer[i] = Input->InputEvent.Event.KeyEvent.uChar.UnicodeChar; + ConsoleInputUnicodeCharToAnsiChar(Console, &Buffer[i++], &Char); + } + if (Console->LinePos == Console->LineSize) + { + HeapFree(Win32CsrApiHeap, 0, Console->LineBuffer); + Console->LineBuffer = NULL; + Status = STATUS_SUCCESS; /* Entire line has been read */ + } + } + } + else + { + /* Character input */ + while (i < nNumberOfCharsToRead && !IsListEmpty(&Console->InputEvents)) + { + /* remove input event from queue */ + CurrentEntry = RemoveHeadList(&Console->InputEvents); + if (IsListEmpty(&Console->InputEvents)) + { + ResetEvent(Console->ActiveEvent); + } + Input = CONTAINING_RECORD(CurrentEntry, ConsoleInput, ListEntry); + + /* only pay attention to valid ascii chars, on key down */ + if (KEY_EVENT == Input->InputEvent.EventType + && Input->InputEvent.Event.KeyEvent.bKeyDown + && Input->InputEvent.Event.KeyEvent.uChar.UnicodeChar != L'\0') + { + WCHAR Char = Input->InputEvent.Event.KeyEvent.uChar.UnicodeChar; + if (Request->Data.ReadConsoleRequest.Unicode) + UnicodeBuffer[i++] = Char; else - ConsoleInputUnicodeCharToAnsiChar(Console, &Buffer[i], &Input->InputEvent.Event.KeyEvent.uChar.UnicodeChar); - } - /* echo to screen if enabled and we did not already echo the char */ - if (0 != (Console->Mode & ENABLE_ECHO_INPUT) - && ! Input->Echoed - && L'\r' != Input->InputEvent.Event.KeyEvent.uChar.UnicodeChar) - { - CHAR AsciiChar; - WideCharToMultiByte(Console->OutputCodePage, 0, - &Input->InputEvent.Event.KeyEvent.uChar.UnicodeChar, 1, - &AsciiChar, 1, NULL, NULL); - ConioWriteConsole(Console, Console->ActiveBuffer, &AsciiChar, 1, TRUE); - } - } - else - { - i--; - } - Console->WaitingChars--; - HeapFree(Win32CsrApiHeap, 0, Input); - } + ConsoleInputUnicodeCharToAnsiChar(Console, &Buffer[i++], &Char); + Status = STATUS_SUCCESS; /* did read something */ + } + HeapFree(Win32CsrApiHeap, 0, Input); + } + } +done: Request->Data.ReadConsoleRequest.NrCharactersRead = i; - if (0 == i) - { - Status = STATUS_PENDING; /* we didn't read anything */ - } - else if (0 != (Console->Mode & ENABLE_LINE_INPUT)) - { - if (0 == Console->WaitingLines || - (Request->Data.ReadConsoleRequest.Unicode ? (L'\n' != UnicodeBuffer[i - 1]) : ('\n' != Buffer[i - 1]))) - { - Status = STATUS_PENDING; /* line buffered, didn't get a complete line */ - } - else - { - Console->WaitingLines--; - Status = STATUS_SUCCESS; /* line buffered, did get a complete line */ - } - } - else - { - Status = STATUS_SUCCESS; /* not line buffered, did read something */ - } - - if (Status == STATUS_PENDING) - { - Console->EchoCount = nNumberOfCharsToRead - i; - } - else - { - Console->EchoCount = 0; /* if the client is no longer waiting on input, do not echo */ - } - ConioUnlockConsole(Console);
if (CSR_API_MESSAGE_HEADER_SIZE(CSRSS_READ_CONSOLE) + i * CharSize > sizeof(CSR_API_MESSAGE)) @@ -179,28 +212,24 @@ } }
-static VOID FASTCALL +static NTSTATUS FASTCALL ConioProcessChar(PCSRSS_CONSOLE Console, - ConsoleInput *KeyEventRecord) -{ - BOOL updown; - ConsoleInput *TempInput; - - if (KeyEventRecord->InputEvent.EventType == KEY_EVENT && - KeyEventRecord->InputEvent.Event.KeyEvent.bKeyDown) - { - WORD vk = KeyEventRecord->InputEvent.Event.KeyEvent.wVirtualKeyCode; + PINPUT_RECORD InputEvent) +{ + /* Check for pause or unpause */ + if (InputEvent->EventType == KEY_EVENT && InputEvent->Event.KeyEvent.bKeyDown) + { + WORD vk = InputEvent->Event.KeyEvent.wVirtualKeyCode; if (!(Console->PauseFlags & PAUSED_FROM_KEYBOARD)) { - DWORD cks = KeyEventRecord->InputEvent.Event.KeyEvent.dwControlKeyState; + DWORD cks = InputEvent->Event.KeyEvent.dwControlKeyState; if (Console->Mode & ENABLE_LINE_INPUT && (vk == VK_PAUSE || (vk == 'S' && (cks & (LEFT_CTRL_PRESSED | RIGHT_CTRL_PRESSED)) && !(cks & (LEFT_ALT_PRESSED | RIGHT_ALT_PRESSED))))) { ConioPause(Console, PAUSED_FROM_KEYBOARD); - HeapFree(Win32CsrApiHeap, 0, KeyEventRecord); - return; + return STATUS_SUCCESS; } } else @@ -209,110 +238,19 @@ vk != VK_RWIN && vk != VK_NUMLOCK && vk != VK_SCROLL) { ConioUnpause(Console, PAUSED_FROM_KEYBOARD); - HeapFree(Win32CsrApiHeap, 0, KeyEventRecord); - return; - } - } - } - - if (0 != (Console->Mode & (ENABLE_PROCESSED_INPUT | ENABLE_LINE_INPUT))) - { - switch(KeyEventRecord->InputEvent.Event.KeyEvent.uChar.UnicodeChar) - { - case L'\r': - /* first add the \r */ - KeyEventRecord->InputEvent.EventType = KEY_EVENT; - updown = KeyEventRecord->InputEvent.Event.KeyEvent.bKeyDown; - KeyEventRecord->Echoed = FALSE; - KeyEventRecord->InputEvent.Event.KeyEvent.wVirtualKeyCode = VK_RETURN; - KeyEventRecord->InputEvent.Event.KeyEvent.uChar.UnicodeChar = L'\r'; - InsertTailList(&Console->InputEvents, &KeyEventRecord->ListEntry); - Console->WaitingChars++; - KeyEventRecord = HeapAlloc(Win32CsrApiHeap, 0, sizeof(ConsoleInput)); - if (NULL == KeyEventRecord) - { - DPRINT1("Failed to allocate KeyEventRecord\n"); - return; - } - KeyEventRecord->InputEvent.EventType = KEY_EVENT; - KeyEventRecord->InputEvent.Event.KeyEvent.bKeyDown = updown; - KeyEventRecord->InputEvent.Event.KeyEvent.wVirtualKeyCode = 0; - KeyEventRecord->InputEvent.Event.KeyEvent.wVirtualScanCode = 0; - KeyEventRecord->InputEvent.Event.KeyEvent.uChar.UnicodeChar = L'\n'; - KeyEventRecord->Fake = TRUE; - break; - } - } + return STATUS_SUCCESS; + } + } + } + /* add event to the queue */ - InsertTailList(&Console->InputEvents, &KeyEventRecord->ListEntry); - Console->WaitingChars++; - /* if line input mode is enabled, only wake the client on enter key down */ - if (0 == (Console->Mode & ENABLE_LINE_INPUT) - || Console->EarlyReturn - || (L'\n' == KeyEventRecord->InputEvent.Event.KeyEvent.uChar.UnicodeChar - && KeyEventRecord->InputEvent.Event.KeyEvent.bKeyDown)) - { - if (L'\n' == KeyEventRecord->InputEvent.Event.KeyEvent.uChar.UnicodeChar) - { - Console->WaitingLines++; - } - } - KeyEventRecord->Echoed = FALSE; - if (0 != (Console->Mode & (ENABLE_PROCESSED_INPUT | ENABLE_LINE_INPUT)) - && L'\b' == KeyEventRecord->InputEvent.Event.KeyEvent.uChar.UnicodeChar - && KeyEventRecord->InputEvent.Event.KeyEvent.bKeyDown) - { - /* walk the input queue looking for a char to backspace */ - for (TempInput = (ConsoleInput *) Console->InputEvents.Blink; - TempInput != (ConsoleInput *) &Console->InputEvents - && (KEY_EVENT == TempInput->InputEvent.EventType - || ! TempInput->InputEvent.Event.KeyEvent.bKeyDown - || L'\b' == TempInput->InputEvent.Event.KeyEvent.uChar.UnicodeChar); - TempInput = (ConsoleInput *) TempInput->ListEntry.Blink) - { - /* NOP */; - } - /* if we found one, delete it, otherwise, wake the client */ - if (TempInput != (ConsoleInput *) &Console->InputEvents) - { - /* delete previous key in queue, maybe echo backspace to screen, and do not place backspace on queue */ - RemoveEntryList(&TempInput->ListEntry); - if (TempInput->Echoed) - { - CHAR AsciiChar; - WideCharToMultiByte(Console->OutputCodePage, 0, - &KeyEventRecord->InputEvent.Event.KeyEvent.uChar.UnicodeChar, 1, - &AsciiChar, 1, NULL, NULL); - ConioWriteConsole(Console, Console->ActiveBuffer, &AsciiChar, 1, TRUE); - } - HeapFree(Win32CsrApiHeap, 0, TempInput); - RemoveEntryList(&KeyEventRecord->ListEntry); - HeapFree(Win32CsrApiHeap, 0, KeyEventRecord); - Console->WaitingChars -= 2; - return; - } - } - else - { - /* echo chars if we are supposed to and client is waiting for some */ - if (0 != (Console->Mode & ENABLE_ECHO_INPUT) && Console->EchoCount - && KeyEventRecord->InputEvent.Event.KeyEvent.uChar.UnicodeChar - && KeyEventRecord->InputEvent.Event.KeyEvent.bKeyDown - && L'\r' != KeyEventRecord->InputEvent.Event.KeyEvent.uChar.UnicodeChar) - { - /* mark the char as already echoed */ - CHAR AsciiChar; - WideCharToMultiByte(Console->OutputCodePage, 0, - &KeyEventRecord->InputEvent.Event.KeyEvent.uChar.UnicodeChar, 1, - &AsciiChar, 1, NULL, NULL); - ConioWriteConsole(Console, Console->ActiveBuffer, &AsciiChar, 1, TRUE); - Console->EchoCount--; - KeyEventRecord->Echoed = TRUE; - } - } - - /* Console->WaitingChars++; */ + ConsoleInput *ConInRec = RtlAllocateHeap(Win32CsrApiHeap, 0, sizeof(ConsoleInput)); + if (ConInRec == NULL) + return STATUS_INSUFFICIENT_RESOURCES; + ConInRec->InputEvent = *InputEvent; + InsertTailList(&Console->InputEvents, &ConInRec->ListEntry); SetEvent(Console->ActiveEvent); + return STATUS_SUCCESS; }
static DWORD FASTCALL @@ -354,15 +292,14 @@ * or translated keys may be involved. */ static UINT LastVirtualKey = 0; DWORD ShiftState; - ConsoleInput *ConInRec; UINT RepeatCount; - CHAR AsciiChar; WCHAR UnicodeChar; UINT VirtualKeyCode; UINT VirtualScanCode; BOOL Down = FALSE; INPUT_RECORD er; - ULONG ResultSize = 0; + BOOLEAN Fake; // synthesized, not a real event + BOOLEAN NotChar; // message should not be used to return a character
RepeatCount = 1; VirtualScanCode = (msg->lParam >> 16) & 0xff; @@ -393,11 +330,6 @@ UnicodeChar = (1 == RetChars ? Chars[0] : 0); }
- if (0 == ResultSize) - { - AsciiChar = 0; - } - er.EventType = KEY_EVENT; er.Event.KeyEvent.bKeyDown = Down; er.Event.KeyEvent.wRepeatCount = RepeatCount; @@ -433,38 +365,26 @@ return; }
- ConInRec = HeapAlloc(Win32CsrApiHeap, 0, sizeof(ConsoleInput)); - - if (NULL == ConInRec) - { - return; - } - - ConInRec->InputEvent = er; - ConInRec->Fake = UnicodeChar && - (msg->message != WM_CHAR && msg->message != WM_SYSCHAR && - msg->message != WM_KEYUP && msg->message != WM_SYSKEYUP); - ConInRec->NotChar = (msg->message != WM_CHAR && msg->message != WM_SYSCHAR); - ConInRec->Echoed = FALSE; - if (ConInRec->NotChar) + Fake = UnicodeChar && + (msg->message != WM_CHAR && msg->message != WM_SYSCHAR && + msg->message != WM_KEYUP && msg->message != WM_SYSKEYUP); + NotChar = (msg->message != WM_CHAR && msg->message != WM_SYSCHAR); + if (NotChar) LastVirtualKey = msg->wParam;
- DPRINT ("csrss: %s %s %s %s %02x %02x '%c' %04x\n", + DPRINT ("csrss: %s %s %s %s %02x %02x '%lc' %04x\n", Down ? "down" : "up ", (msg->message == WM_CHAR || msg->message == WM_SYSCHAR) ? "char" : "key ", - ConInRec->Fake ? "fake" : "real", - ConInRec->NotChar ? "notc" : "char", + Fake ? "fake" : "real", + NotChar ? "notc" : "char", VirtualScanCode, VirtualKeyCode, - (AsciiChar >= ' ') ? AsciiChar : '.', + (UnicodeChar >= L' ') ? UnicodeChar : L'.', ShiftState);
- if (ConInRec->Fake && ConInRec->NotChar) - { - HeapFree(Win32CsrApiHeap, 0, ConInRec); + if (Fake) return; - }
/* process Ctrl-C and Ctrl-Break */ if (Console->Mode & ENABLE_PROCESSED_INPUT && @@ -483,7 +403,6 @@ current_entry = current_entry->Flink; ConioConsoleCtrlEvent((DWORD)CTRL_C_EVENT, current); } - HeapFree(Win32CsrApiHeap, 0, ConInRec); return; }
@@ -518,10 +437,9 @@ } ConioDrawConsole(Console); } - HeapFree(Win32CsrApiHeap, 0, ConInRec); return; } - ConioProcessChar(Console, ConInRec); + ConioProcessChar(Console, &er); }
CSR_API(CsrReadInputEvent) @@ -551,7 +469,7 @@ Input = CONTAINING_RECORD(CurrentEntry, ConsoleInput, ListEntry); CurrentEntry = CurrentEntry->Flink;
- if (Done && !Input->Fake) + if (Done) { Request->Data.ReadInputRequest.MoreEvents = TRUE; break; @@ -559,7 +477,7 @@
RemoveEntryList(&Input->ListEntry);
- if (!Done && !Input->Fake) + if (!Done) { Request->Data.ReadInputRequest.Input = Input->InputEvent; if (Request->Data.ReadInputRequest.Unicode == FALSE) @@ -569,29 +487,13 @@ Done = TRUE; }
- if (Input->InputEvent.EventType == KEY_EVENT) - { - if (0 != (Console->Mode & ENABLE_LINE_INPUT) - && Input->InputEvent.Event.KeyEvent.bKeyDown - && L'\r' == Input->InputEvent.Event.KeyEvent.uChar.UnicodeChar) - { - Console->WaitingLines--; - } - Console->WaitingChars--; - } HeapFree(Win32CsrApiHeap, 0, Input); }
if (Done) - { Status = STATUS_SUCCESS; - Console->EarlyReturn = FALSE; - } else - { Status = STATUS_PENDING; - Console->EarlyReturn = TRUE; /* mark for early return */ - }
if (IsListEmpty(&Console->InputEvents)) { @@ -632,7 +534,6 @@ HeapFree(Win32CsrApiHeap, 0, Input); } ResetEvent(Console->ActiveEvent); - Console->WaitingChars=0;
ConioUnlockConsole(Console);
@@ -645,7 +546,6 @@ PCSRSS_CONSOLE Console; PLIST_ENTRY CurrentItem; DWORD NumEvents; - ConsoleInput *Input;
DPRINT("CsrGetNumberOfConsoleInputEvents\n");
@@ -664,12 +564,8 @@ /* If there are any events ... */ while (CurrentItem != &Console->InputEvents) { - Input = CONTAINING_RECORD(CurrentItem, ConsoleInput, ListEntry); CurrentItem = CurrentItem->Flink; - if (!Input->Fake) - { - NumEvents++; - } + NumEvents++; }
ConioUnlockConsole(Console); @@ -719,16 +615,10 @@ { Item = CONTAINING_RECORD(CurrentItem, ConsoleInput, ListEntry);
- if (Item->Fake) - { - CurrentItem = CurrentItem->Flink; - continue; - } - ++NumItems; *InputRecord = Item->InputEvent;
- if (Request->Data.ReadInputRequest.Unicode == FALSE) + if (Request->Data.PeekConsoleInputRequest.Unicode == FALSE) { ConioInputEventToAnsi(Console, InputRecord); } @@ -752,7 +642,6 @@ NTSTATUS Status; DWORD Length; DWORD i; - ConsoleInput* Record;
DPRINT("CsrWriteConsoleInput\n");
@@ -774,35 +663,24 @@ return STATUS_ACCESS_VIOLATION; }
- for (i = 0; i < Length; i++) - { - Record = HeapAlloc(Win32CsrApiHeap, 0, sizeof(ConsoleInput)); - if (NULL == Record) - { - ConioUnlockConsole(Console); - return STATUS_INSUFFICIENT_RESOURCES; - } - - Record->Echoed = FALSE; - Record->Fake = FALSE; - //Record->InputEvent = *InputRecord++; - memcpy(&Record->InputEvent, &InputRecord[i], sizeof(INPUT_RECORD)); + for (i = 0; i < Length && NT_SUCCESS(Status); i++) + { if (!Request->Data.WriteConsoleInputRequest.Unicode && - Record->InputEvent.EventType == KEY_EVENT) - { - CHAR AsciiChar = Record->InputEvent.Event.KeyEvent.uChar.AsciiChar; + InputRecord->EventType == KEY_EVENT) + { + CHAR AsciiChar = InputRecord->Event.KeyEvent.uChar.AsciiChar; ConsoleInputAnsiCharToUnicodeChar(Console, - &Record->InputEvent.Event.KeyEvent.uChar.UnicodeChar, + &InputRecord->Event.KeyEvent.uChar.UnicodeChar, &AsciiChar); } - ConioProcessChar(Console, Record); + Status = ConioProcessChar(Console, InputRecord++); }
ConioUnlockConsole(Console);
Request->Data.WriteConsoleInputRequest.Length = i;
- return STATUS_SUCCESS; + return Status; }
/* EOF */
Modified: trunk/reactos/subsystems/win32/csrss/win32csr/conio.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/csrss/win3... ============================================================================== --- trunk/reactos/subsystems/win32/csrss/win32csr/conio.h [iso-8859-1] (original) +++ trunk/reactos/subsystems/win32/csrss/win32csr/conio.h [iso-8859-1] Fri Jun 4 20:26:22 2010 @@ -75,14 +75,15 @@ PCSRSS_CONSOLE Prev, Next; /* Next and Prev consoles in console wheel */ HANDLE ActiveEvent; LIST_ENTRY InputEvents; /* List head for input event queue */ - WORD WaitingChars; - WORD WaitingLines; /* number of chars and lines in input queue */ + PWCHAR LineBuffer; /* current line being input, in line buffered mode */ + WORD LineMaxSize; /* maximum size of line in characters (including CR+LF) */ + WORD LineSize; /* current size of line */ + WORD LinePos; /* current position within line */ + BOOLEAN LineComplete; /* user pressed enter, ready to send back to client */ LIST_ENTRY BufferList; /* List of all screen buffers for this console */ PCSRSS_SCREEN_BUFFER ActiveBuffer; /* Pointer to currently active screen buffer */ WORD Mode; /* Console mode flags */ - WORD EchoCount; /* count of chars to echo, in line buffered mode */ UNICODE_STRING Title; /* Title of console */ - BOOL EarlyReturn; /* wake client and return data, even if we are in line buffered mode, and we don't have a complete line */ DWORD HardwareState; /* _GDI_MANAGED, _DIRECT */ HWND hWindow; COORD Size; @@ -101,9 +102,6 @@ { LIST_ENTRY ListEntry; INPUT_RECORD InputEvent; - BOOLEAN Echoed; // already been echoed or not - BOOLEAN Fake; // synthesized, not a real event - BOOLEAN NotChar; // message should not be used to return a character } ConsoleInput;
/* CONSOLE_SELECTION_INFO dwFlags values */
Modified: trunk/reactos/subsystems/win32/csrss/win32csr/console.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/csrss/win3... ============================================================================== --- trunk/reactos/subsystems/win32/csrss/win32csr/console.c [iso-8859-1] (original) +++ trunk/reactos/subsystems/win32/csrss/win32csr/console.c [iso-8859-1] Fri Jun 4 20:26:22 2010 @@ -81,13 +81,10 @@ RtlCreateUnicodeString(&Console->Title, L"Command Prompt");
Console->ReferenceCount = 0; - Console->WaitingChars = 0; - Console->WaitingLines = 0; - Console->EchoCount = 0; + Console->LineBuffer = NULL; Console->Header.Type = CONIO_CONSOLE_MAGIC; Console->Header.Console = Console; Console->Mode = ENABLE_LINE_INPUT | ENABLE_ECHO_INPUT | ENABLE_PROCESSED_INPUT | ENABLE_MOUSE_INPUT; - Console->EarlyReturn = FALSE; InitializeListHead(&Console->BufferList); Console->ActiveBuffer = NULL; InitializeListHead(&Console->InputEvents); @@ -333,6 +330,8 @@ }
ConioCleanupConsole(Console); + if (Console->LineBuffer) + RtlFreeHeap(Win32CsrApiHeap, 0, Console->LineBuffer); ConioDeleteScreenBuffer(Console->ActiveBuffer); if (!IsListEmpty(&Console->BufferList)) {