From 60f250a72df112d5a600aa25996f34d67e822b94 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Herm=C3=A8s=20B=C3=A9lusca-Ma=C3=AFto?= Date: Sun, 23 Jun 2013 23:19:42 +0000 Subject: [PATCH] [CONSRV] - Turn some BOOLs into BOOLEANs in condrv. - Move some coninput functions into condrv. svn path=/trunk/; revision=59326 --- reactos/win32ss/user/consrv/CMakeLists.txt | 1 + reactos/win32ss/user/consrv/condrv/coninput.c | 304 ++++++++++++++++++ .../win32ss/user/consrv/condrv/conoutput.c | 2 +- reactos/win32ss/user/consrv/condrv/console.c | 106 +++--- reactos/win32ss/user/consrv/condrv/text.c | 8 +- reactos/win32ss/user/consrv/coninput.c | 237 +++----------- reactos/win32ss/user/consrv/conoutput.c | 8 +- 7 files changed, 415 insertions(+), 251 deletions(-) create mode 100644 reactos/win32ss/user/consrv/condrv/coninput.c diff --git a/reactos/win32ss/user/consrv/CMakeLists.txt b/reactos/win32ss/user/consrv/CMakeLists.txt index 0ab14c1f2c2..a5024c3ea0a 100644 --- a/reactos/win32ss/user/consrv/CMakeLists.txt +++ b/reactos/win32ss/user/consrv/CMakeLists.txt @@ -18,6 +18,7 @@ list(APPEND SOURCE init.c lineinput.c settings.c + condrv/coninput.c condrv/conoutput.c condrv/console.c condrv/graphics.c diff --git a/reactos/win32ss/user/consrv/condrv/coninput.c b/reactos/win32ss/user/consrv/condrv/coninput.c new file mode 100644 index 00000000000..fb4347eb95d --- /dev/null +++ b/reactos/win32ss/user/consrv/condrv/coninput.c @@ -0,0 +1,304 @@ +/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS Console Server DLL + * FILE: win32ss/user/consrv/coninput.c + * PURPOSE: Console Input functions + * PROGRAMMERS: Jeffrey Morlan + * Hermes Belusca-Maito (hermes.belusca@sfr.fr) + */ + +/* INCLUDES *******************************************************************/ + +#include "consrv.h" +#include "include/conio.h" +#include "conio.h" +#include "handle.h" +#include "lineinput.h" + +#define NDEBUG +#include + + +/* GLOBALS ********************************************************************/ + +#define ConSrvGetInputBuffer(ProcessData, Handle, Ptr, Access, LockConsole) \ + ConSrvGetObject((ProcessData), (Handle), (PCONSOLE_IO_OBJECT*)(Ptr), NULL, \ + (Access), (LockConsole), INPUT_BUFFER) +#define ConSrvGetInputBufferAndHandleEntry(ProcessData, Handle, Ptr, Entry, Access, LockConsole) \ + ConSrvGetObject((ProcessData), (Handle), (PCONSOLE_IO_OBJECT*)(Ptr), (Entry), \ + (Access), (LockConsole), INPUT_BUFFER) +#define ConSrvReleaseInputBuffer(Buff, IsConsoleLocked) \ + ConSrvReleaseObject(&(Buff)->Header, (IsConsoleLocked)) + + +#define ConsoleInputUnicodeCharToAnsiChar(Console, dChar, sWChar) \ + WideCharToMultiByte((Console)->CodePage, 0, (sWChar), 1, (dChar), 1, NULL, NULL) + +#define ConsoleInputAnsiCharToUnicodeChar(Console, dWChar, sChar) \ + MultiByteToWideChar((Console)->CodePage, 0, (sChar), 1, (dWChar), 1) + +typedef struct ConsoleInput_t +{ + LIST_ENTRY ListEntry; + INPUT_RECORD InputEvent; +} ConsoleInput; + +typedef struct _GET_INPUT_INFO +{ + PCSR_THREAD CallingThread; // The thread which called the input API. + PVOID HandleEntry; // The handle data associated with the wait thread. + PCONSOLE_INPUT_BUFFER InputBuffer; // The input buffer corresponding to the handle. +} GET_INPUT_INFO, *PGET_INPUT_INFO; + + +/* PRIVATE FUNCTIONS **********************************************************/ + +#if 0 +static VOID FASTCALL +ConioInputEventToAnsi(PCONSOLE Console, PINPUT_RECORD InputEvent) +{ + if (InputEvent->EventType == KEY_EVENT) + { + WCHAR UnicodeChar = InputEvent->Event.KeyEvent.uChar.UnicodeChar; + InputEvent->Event.KeyEvent.uChar.UnicodeChar = 0; + ConsoleInputUnicodeCharToAnsiChar(Console, + &InputEvent->Event.KeyEvent.uChar.AsciiChar, + &UnicodeChar); + } +} +#endif + +NTSTATUS FASTCALL +ConioProcessInputEvent(PCONSOLE Console, + PINPUT_RECORD InputEvent) +{ + ConsoleInput *ConInRec; + + /* 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 = InputEvent->Event.KeyEvent.dwControlKeyState; + if (Console->InputBuffer.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); + return STATUS_SUCCESS; + } + } + else + { + if ((vk < VK_SHIFT || vk > VK_CAPITAL) && vk != VK_LWIN && + vk != VK_RWIN && vk != VK_NUMLOCK && vk != VK_SCROLL) + { + ConioUnpause(Console, PAUSED_FROM_KEYBOARD); + return STATUS_SUCCESS; + } + } + } + + /* Add event to the queue */ + ConInRec = ConsoleAllocHeap(0, sizeof(ConsoleInput)); + if (ConInRec == NULL) return STATUS_INSUFFICIENT_RESOURCES; + + ConInRec->InputEvent = *InputEvent; + InsertTailList(&Console->InputBuffer.InputEvents, &ConInRec->ListEntry); + + SetEvent(Console->InputBuffer.ActiveEvent); + CsrNotifyWait(&Console->InputBuffer.ReadWaitQueue, + WaitAny, + NULL, + NULL); + if (!IsListEmpty(&Console->InputBuffer.ReadWaitQueue)) + { + CsrDereferenceWait(&Console->InputBuffer.ReadWaitQueue); + } + + return STATUS_SUCCESS; +} + +VOID FASTCALL +PurgeInputBuffer(PCONSOLE Console) +{ + PLIST_ENTRY CurrentEntry; + ConsoleInput* Event; + + while (!IsListEmpty(&Console->InputBuffer.InputEvents)) + { + CurrentEntry = RemoveHeadList(&Console->InputBuffer.InputEvents); + Event = CONTAINING_RECORD(CurrentEntry, ConsoleInput, ListEntry); + ConsoleFreeHeap(Event); + } + + CloseHandle(Console->InputBuffer.ActiveEvent); +} + +VOID NTAPI +ConDrvProcessKey(IN PCONSOLE Console, + IN BOOLEAN Down, + IN UINT VirtualKeyCode, + IN UINT VirtualScanCode, + IN WCHAR UnicodeChar, + IN ULONG ShiftState, + IN BYTE KeyStateCtrl) +{ + INPUT_RECORD er; + + /* process Ctrl-C and Ctrl-Break */ + if ( Console->InputBuffer.Mode & ENABLE_PROCESSED_INPUT && + Down && (VirtualKeyCode == VK_PAUSE || VirtualKeyCode == 'C') && + (ShiftState & (LEFT_CTRL_PRESSED | RIGHT_CTRL_PRESSED) || KeyStateCtrl & 0x80) ) + { + DPRINT1("Console_Api Ctrl-C\n"); + ConDrvConsoleProcessCtrlEvent(Console, 0, CTRL_C_EVENT); + + if (Console->LineBuffer && !Console->LineComplete) + { + /* Line input is in progress; end it */ + Console->LinePos = Console->LineSize = 0; + Console->LineComplete = TRUE; + } + return; + } + + if ( (ShiftState & (RIGHT_ALT_PRESSED | LEFT_ALT_PRESSED)) != 0 && + (VK_UP == VirtualKeyCode || VK_DOWN == VirtualKeyCode) ) + { + if (!Down) return; + + /* scroll up or down */ + if (VK_UP == VirtualKeyCode) + { + /* only scroll up if there is room to scroll up into */ + if (Console->ActiveBuffer->CursorPosition.Y != Console->ActiveBuffer->ScreenBufferSize.Y - 1) + { + Console->ActiveBuffer->VirtualY = (Console->ActiveBuffer->VirtualY + + Console->ActiveBuffer->ScreenBufferSize.Y - 1) % + Console->ActiveBuffer->ScreenBufferSize.Y; + Console->ActiveBuffer->CursorPosition.Y++; + } + } + else + { + /* only scroll down if there is room to scroll down into */ + if (Console->ActiveBuffer->CursorPosition.Y != 0) + { + Console->ActiveBuffer->VirtualY = (Console->ActiveBuffer->VirtualY + 1) % + Console->ActiveBuffer->ScreenBufferSize.Y; + Console->ActiveBuffer->CursorPosition.Y--; + } + } + + ConioDrawConsole(Console); + return; + } + + er.EventType = KEY_EVENT; + er.Event.KeyEvent.bKeyDown = Down; + er.Event.KeyEvent.wRepeatCount = 1; + er.Event.KeyEvent.wVirtualKeyCode = VirtualKeyCode; + er.Event.KeyEvent.wVirtualScanCode = VirtualScanCode; + er.Event.KeyEvent.uChar.UnicodeChar = UnicodeChar; + er.Event.KeyEvent.dwControlKeyState = ShiftState; + + ConioProcessInputEvent(Console, &er); +} + + +/* PUBLIC SERVER APIS *********************************************************/ + +NTSTATUS NTAPI +ConDrvWriteConsoleInput(IN PCONSOLE Console, + IN PCONSOLE_INPUT_BUFFER InputBuffer, + IN BOOLEAN Unicode, + IN PINPUT_RECORD InputRecord, + IN ULONG NumEventsToWrite, + OUT PULONG NumEventsWritten) +{ + NTSTATUS Status = STATUS_SUCCESS; + ULONG i; + + if (Console == NULL || InputBuffer == NULL /* || InputRecord == NULL */) + return STATUS_INVALID_PARAMETER; + + /* Validity checks */ + ASSERT(Console == InputBuffer->Header.Console); + ASSERT( (InputRecord != NULL && NumEventsToWrite >= 0) || + (InputRecord == NULL && NumEventsToWrite == 0) ); + + if (NumEventsWritten) *NumEventsWritten = 0; + + for (i = 0; i < NumEventsToWrite && NT_SUCCESS(Status); ++i) + { + if (InputRecord->EventType == KEY_EVENT && !Unicode) + { + CHAR AsciiChar = InputRecord->Event.KeyEvent.uChar.AsciiChar; + ConsoleInputAnsiCharToUnicodeChar(Console, + &InputRecord->Event.KeyEvent.uChar.UnicodeChar, + &AsciiChar); + } + + Status = ConioProcessInputEvent(Console, InputRecord++); + } + + if (NumEventsWritten) *NumEventsWritten = i; + + return Status; +} + +NTSTATUS NTAPI +ConDrvFlushConsoleInputBuffer(IN PCONSOLE Console, + IN PCONSOLE_INPUT_BUFFER InputBuffer) +{ + PLIST_ENTRY CurrentEntry; + ConsoleInput* Event; + + if (Console == NULL || InputBuffer == NULL) + return STATUS_INVALID_PARAMETER; + + /* Validity check */ + ASSERT(Console == InputBuffer->Header.Console); + + /* Discard all entries in the input event queue */ + while (!IsListEmpty(&InputBuffer->InputEvents)) + { + CurrentEntry = RemoveHeadList(&InputBuffer->InputEvents); + Event = CONTAINING_RECORD(CurrentEntry, ConsoleInput, ListEntry); + ConsoleFreeHeap(Event); + } + ResetEvent(InputBuffer->ActiveEvent); + + return STATUS_SUCCESS; +} + +NTSTATUS NTAPI +ConDrvGetConsoleNumberOfInputEvents(IN PCONSOLE Console, + IN PCONSOLE_INPUT_BUFFER InputBuffer, + OUT PULONG NumEvents) +{ + PLIST_ENTRY CurrentInput; + + if (Console == NULL || InputBuffer == NULL || NumEvents == NULL) + return STATUS_INVALID_PARAMETER; + + /* Validity check */ + ASSERT(Console == InputBuffer->Header.Console); + + *NumEvents = 0; + + /* If there are any events ... */ + CurrentInput = InputBuffer->InputEvents.Flink; + while (CurrentInput != &InputBuffer->InputEvents) + { + CurrentInput = CurrentInput->Flink; + (*NumEvents)++; + } + + return STATUS_SUCCESS; +} + +/* EOF */ diff --git a/reactos/win32ss/user/consrv/condrv/conoutput.c b/reactos/win32ss/user/consrv/condrv/conoutput.c index e61b596775d..d505336cc4e 100644 --- a/reactos/win32ss/user/consrv/condrv/conoutput.c +++ b/reactos/win32ss/user/consrv/condrv/conoutput.c @@ -227,7 +227,7 @@ ConDrvSetConsoleCursorInfo(IN PCONSOLE Console, IN PCONSOLE_CURSOR_INFO CursorInfo) { ULONG Size; - BOOL Visible, Success = TRUE; + BOOLEAN Visible, Success = TRUE; if (Console == NULL || Buffer == NULL || CursorInfo == NULL) return STATUS_INVALID_PARAMETER; diff --git a/reactos/win32ss/user/consrv/condrv/console.c b/reactos/win32ss/user/consrv/condrv/console.c index 983ae3060c7..479249f7ef5 100644 --- a/reactos/win32ss/user/consrv/condrv/console.c +++ b/reactos/win32ss/user/consrv/condrv/console.c @@ -549,7 +549,7 @@ ConDrvRegisterFrontEnd(IN PCONSOLE Console, Console->TermIFace.Console = Console; /* Initialize the frontend AFTER having attached it to the console */ - DPRINT("Finish initialization of frontend\n"); + DPRINT1("Finish initialization of frontend\n"); Status = Console->TermIFace.Vtbl->InitFrontEnd(&Console->TermIFace, Console); if (!NT_SUCCESS(Status)) { @@ -565,9 +565,9 @@ ConDrvRegisterFrontEnd(IN PCONSOLE Console, /* Copy buffer contents to screen */ // FrontEnd.Draw(); // ConioDrawConsole(Console); - DPRINT("Console drawn\n"); + DPRINT1("Console drawn\n"); - DPRINT("Terminal FrontEnd initialization done\n"); + DPRINT1("Terminal FrontEnd initialization done\n"); return STATUS_SUCCESS; } @@ -584,7 +584,7 @@ ConDrvDeregisterFrontEnd(IN PCONSOLE Console) /* Detach the frontend from the console */ RtlZeroMemory(&Console->TermIFace, sizeof(Console->TermIFace)); - DPRINT("Terminal FrontEnd unregistered\n"); + DPRINT1("Terminal FrontEnd unregistered\n"); return STATUS_SUCCESS; } @@ -597,26 +597,28 @@ ConDrvDeleteConsole(IN PCONSOLE Console) * Forbid validation of any console by other threads * during the deletion of this console. */ - ConDrvLockConsoleListExclusive(); + // ConDrvLockConsoleListExclusive(); - /* Check the existence of the console, and if it's ok, continue */ - if (!ConDrvValidateConsolePointer(Console)) - { - /* Unlock the console list and return */ - ConDrvUnlockConsoleList(); - return; - } + // /* Check the existence of the console, and if it's ok, continue */ + // if (!ConDrvValidateConsolePointer(Console)) + // { + // /* Unlock the console list and return */ + // ConDrvUnlockConsoleList(); + // return; + // } - /* - * If the console is already being destroyed - * (thus not running), just return. - */ - if (!ConDrvValidateConsoleUnsafe(Console, CONSOLE_RUNNING, TRUE)) - { - /* Unlock the console list and return */ - ConDrvUnlockConsoleList(); - return; - } + // /* + // * If the console is already being destroyed + // * (thus not running), just return. + // */ + // if (!ConDrvValidateConsoleUnsafe(Console, CONSOLE_RUNNING, TRUE)) + // { + // /* Unlock the console list and return */ + // ConDrvUnlockConsoleList(); + // return; + // } + + if (!ConDrvValidateConsole(Console, CONSOLE_RUNNING, TRUE)) return; /* * We are about to be destroyed. Signal it to other people @@ -625,6 +627,9 @@ ConDrvDeleteConsole(IN PCONSOLE Console) */ Console->State = CONSOLE_TERMINATING; + /* We really delete the console. Reset the count to be sure. */ + Console->ReferenceCount = 0; + /* * Allow other threads to finish their job: basically, unlock * all other calls to EnterCriticalSection(&Console->Lock); by @@ -634,14 +639,25 @@ ConDrvDeleteConsole(IN PCONSOLE Console) * can see that we are in fact already deleting the console. */ LeaveCriticalSection(&Console->Lock); - ConDrvUnlockConsoleList(); + // ConDrvUnlockConsoleList(); /* FIXME: Send a terminate message to all the processes owning this console */ + /* Close all the applications which are linked to this console */ + /* + * FIXME: Windows will wait up to 5 seconds for the thread to exit. + * We shouldn't wait here, though, since the console lock is entered. + * A copy of the thread list probably needs to be made. + */ + // ConDrvConsoleProcessCtrlEvent(Console, 0, CTRL_CLOSE_EVENT); + // DPRINT1("Apps closed\n"); + // FIXME: Be sure that, starting from here, there is NO app running + // on this console anymore !!!!! + /* Cleanup the UI-oriented part */ - DPRINT("Deregister console\n"); + DPRINT1("Deregister console\n"); ConDrvDeregisterFrontEnd(Console); - DPRINT("Console deregistered\n"); + DPRINT1("Console deregistered\n"); /*** * Check that the console is in terminating state before continuing @@ -649,30 +665,36 @@ ConDrvDeleteConsole(IN PCONSOLE Console) * ...unless to cancel console deletion ?). ***/ - ConDrvLockConsoleListExclusive(); + // ConDrvLockConsoleListExclusive(); - /* Re-check the existence of the console, and if it's ok, continue */ - if (!ConDrvValidateConsolePointer(Console)) - { - /* Unlock the console list and return */ - ConDrvUnlockConsoleList(); - return; - } + // /* Re-check the existence of the console, and if it's ok, continue */ + // if (!ConDrvValidateConsolePointer(Console)) + // { + // /* Unlock the console list and return */ + // ConDrvUnlockConsoleList(); + // return; + // } - if (!ConDrvValidateConsoleUnsafe(Console, CONSOLE_TERMINATING, TRUE)) - { - ConDrvUnlockConsoleList(); - return; - } + // if (!ConDrvValidateConsoleUnsafe(Console, CONSOLE_TERMINATING, TRUE)) + // { + // ConDrvUnlockConsoleList(); + // return; + // } + + if (!ConDrvValidateConsole(Console, CONSOLE_TERMINATING, TRUE)) return; /* We are now in destruction */ Console->State = CONSOLE_IN_DESTRUCTION; + ///////////////////// + ConDrvLockConsoleListExclusive(); + ///////////////////// + /* Remove the console from the list */ RemoveEntryList(&Console->Entry); - /* We really delete the console. Reset the count to be sure. */ - Console->ReferenceCount = 0; + /* Unlock the console list */ + ConDrvUnlockConsoleList(); /* Discard all entries in the input event queue */ PurgeInputBuffer(Console); @@ -704,8 +726,8 @@ ConDrvDeleteConsole(IN PCONSOLE Console) ConsoleFreeHeap(Console); DPRINT("ConDrvDeleteConsole - Console destroyed\n"); - /* Unlock the console list and return */ - ConDrvUnlockConsoleList(); + // /* Unlock the console list and return */ + // ConDrvUnlockConsoleList(); } diff --git a/reactos/win32ss/user/consrv/condrv/text.c b/reactos/win32ss/user/consrv/condrv/text.c index 9ad477083ae..4f04c358761 100644 --- a/reactos/win32ss/user/consrv/condrv/text.c +++ b/reactos/win32ss/user/consrv/condrv/text.c @@ -606,7 +606,7 @@ ConioWriteConsole(PCONSOLE Console, NTSTATUS NTAPI ConDrvReadConsoleOutput(IN PCONSOLE Console, IN PTEXTMODE_SCREEN_BUFFER Buffer, - IN BOOL Unicode, + IN BOOLEAN Unicode, OUT PCHAR_INFO CharInfo/*Buffer*/, IN PCOORD BufferSize, IN PCOORD BufferCoord, @@ -680,7 +680,7 @@ ConDrvReadConsoleOutput(IN PCONSOLE Console, NTSTATUS NTAPI ConDrvWriteConsoleOutput(IN PCONSOLE Console, IN PTEXTMODE_SCREEN_BUFFER Buffer, - IN BOOL Unicode, + IN BOOLEAN Unicode, IN PCHAR_INFO CharInfo/*Buffer*/, IN PCOORD BufferSize, IN PCOORD BufferCoord, @@ -1161,9 +1161,9 @@ ConDrvSetConsoleScreenBufferSize(IN PCONSOLE Console, NTSTATUS NTAPI ConDrvScrollConsoleScreenBuffer(IN PCONSOLE Console, IN PTEXTMODE_SCREEN_BUFFER Buffer, - IN BOOL Unicode, + IN BOOLEAN Unicode, IN PSMALL_RECT ScrollRectangle, - IN BOOL UseClipRectangle, + IN BOOLEAN UseClipRectangle, IN PSMALL_RECT ClipRectangle OPTIONAL, IN PCOORD DestinationOrigin, IN CHAR_INFO FillChar) diff --git a/reactos/win32ss/user/consrv/coninput.c b/reactos/win32ss/user/consrv/coninput.c index e1f7b7ea949..4160132e092 100644 --- a/reactos/win32ss/user/consrv/coninput.c +++ b/reactos/win32ss/user/consrv/coninput.c @@ -34,9 +34,6 @@ #define ConsoleInputUnicodeCharToAnsiChar(Console, dChar, sWChar) \ WideCharToMultiByte((Console)->CodePage, 0, (sWChar), 1, (dChar), 1, NULL, NULL) -#define ConsoleInputAnsiCharToUnicodeChar(Console, dWChar, sChar) \ - MultiByteToWideChar((Console)->CodePage, 0, (sChar), 1, (dWChar), 1) - typedef struct ConsoleInput_t { LIST_ENTRY ListEntry; @@ -66,146 +63,6 @@ ConioInputEventToAnsi(PCONSOLE Console, PINPUT_RECORD InputEvent) } } -NTSTATUS FASTCALL -ConioProcessInputEvent(PCONSOLE Console, - PINPUT_RECORD InputEvent) -{ - ConsoleInput *ConInRec; - - /* 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 = InputEvent->Event.KeyEvent.dwControlKeyState; - if (Console->InputBuffer.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); - return STATUS_SUCCESS; - } - } - else - { - if ((vk < VK_SHIFT || vk > VK_CAPITAL) && vk != VK_LWIN && - vk != VK_RWIN && vk != VK_NUMLOCK && vk != VK_SCROLL) - { - ConioUnpause(Console, PAUSED_FROM_KEYBOARD); - return STATUS_SUCCESS; - } - } - } - - /* Add event to the queue */ - ConInRec = ConsoleAllocHeap(0, sizeof(ConsoleInput)); - if (ConInRec == NULL) return STATUS_INSUFFICIENT_RESOURCES; - - ConInRec->InputEvent = *InputEvent; - InsertTailList(&Console->InputBuffer.InputEvents, &ConInRec->ListEntry); - - SetEvent(Console->InputBuffer.ActiveEvent); - CsrNotifyWait(&Console->InputBuffer.ReadWaitQueue, - WaitAny, - NULL, - NULL); - if (!IsListEmpty(&Console->InputBuffer.ReadWaitQueue)) - { - CsrDereferenceWait(&Console->InputBuffer.ReadWaitQueue); - } - - return STATUS_SUCCESS; -} - -VOID FASTCALL -PurgeInputBuffer(PCONSOLE Console) -{ - PLIST_ENTRY CurrentEntry; - ConsoleInput* Event; - - while (!IsListEmpty(&Console->InputBuffer.InputEvents)) - { - CurrentEntry = RemoveHeadList(&Console->InputBuffer.InputEvents); - Event = CONTAINING_RECORD(CurrentEntry, ConsoleInput, ListEntry); - ConsoleFreeHeap(Event); - } - - CloseHandle(Console->InputBuffer.ActiveEvent); -} - -VOID NTAPI -ConDrvProcessKey(IN PCONSOLE Console, - IN BOOLEAN Down, - IN UINT VirtualKeyCode, - IN UINT VirtualScanCode, - IN WCHAR UnicodeChar, - IN ULONG ShiftState, - IN BYTE KeyStateCtrl) -{ - INPUT_RECORD er; - - /* process Ctrl-C and Ctrl-Break */ - if ( Console->InputBuffer.Mode & ENABLE_PROCESSED_INPUT && - Down && (VirtualKeyCode == VK_PAUSE || VirtualKeyCode == 'C') && - (ShiftState & (LEFT_CTRL_PRESSED | RIGHT_CTRL_PRESSED) || KeyStateCtrl & 0x80) ) - { - DPRINT1("Console_Api Ctrl-C\n"); - ConDrvConsoleProcessCtrlEvent(Console, 0, CTRL_C_EVENT); - - if (Console->LineBuffer && !Console->LineComplete) - { - /* Line input is in progress; end it */ - Console->LinePos = Console->LineSize = 0; - Console->LineComplete = TRUE; - } - return; - } - - if ( (ShiftState & (RIGHT_ALT_PRESSED | LEFT_ALT_PRESSED)) != 0 && - (VK_UP == VirtualKeyCode || VK_DOWN == VirtualKeyCode) ) - { - if (!Down) return; - - /* scroll up or down */ - if (VK_UP == VirtualKeyCode) - { - /* only scroll up if there is room to scroll up into */ - if (Console->ActiveBuffer->CursorPosition.Y != Console->ActiveBuffer->ScreenBufferSize.Y - 1) - { - Console->ActiveBuffer->VirtualY = (Console->ActiveBuffer->VirtualY + - Console->ActiveBuffer->ScreenBufferSize.Y - 1) % - Console->ActiveBuffer->ScreenBufferSize.Y; - Console->ActiveBuffer->CursorPosition.Y++; - } - } - else - { - /* only scroll down if there is room to scroll down into */ - if (Console->ActiveBuffer->CursorPosition.Y != 0) - { - Console->ActiveBuffer->VirtualY = (Console->ActiveBuffer->VirtualY + 1) % - Console->ActiveBuffer->ScreenBufferSize.Y; - Console->ActiveBuffer->CursorPosition.Y--; - } - } - - ConioDrawConsole(Console); - return; - } - - er.EventType = KEY_EVENT; - er.Event.KeyEvent.bKeyDown = Down; - er.Event.KeyEvent.wRepeatCount = 1; - er.Event.KeyEvent.wVirtualKeyCode = VirtualKeyCode; - er.Event.KeyEvent.wVirtualScanCode = VirtualScanCode; - er.Event.KeyEvent.uChar.UnicodeChar = UnicodeChar; - er.Event.KeyEvent.dwControlKeyState = ShiftState; - - ConioProcessInputEvent(Console, &er); -} - static NTSTATUS WaitBeforeReading(IN PGET_INPUT_INFO InputInfo, IN PCSR_API_MESSAGE ApiMessage, @@ -683,16 +540,19 @@ CSR_API(SrvGetConsoleInput) return Status; } +NTSTATUS NTAPI +ConDrvWriteConsoleInput(IN PCONSOLE Console, + IN PCONSOLE_INPUT_BUFFER InputBuffer, + IN BOOLEAN Unicode, + IN PINPUT_RECORD InputRecord, + IN ULONG NumEventsToWrite, + OUT PULONG NumEventsWritten); CSR_API(SrvWriteConsoleInput) { NTSTATUS Status; PCONSOLE_WRITEINPUT WriteInputRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.WriteInputRequest; - PINPUT_RECORD InputRecord; - PCONSOLE_PROCESS_DATA ProcessData = ConsoleGetPerProcessData(CsrGetClientThread()->Process); PCONSOLE_INPUT_BUFFER InputBuffer; - PCONSOLE Console; - DWORD Length; - DWORD i; + ULONG NumEventsWritten = 0; DPRINT("SrvWriteConsoleInput\n"); @@ -704,92 +564,69 @@ CSR_API(SrvWriteConsoleInput) return STATUS_INVALID_PARAMETER; } - Status = ConSrvGetInputBuffer(ProcessData, WriteInputRequest->InputHandle, &InputBuffer, GENERIC_WRITE, TRUE); + Status = ConSrvGetInputBuffer(ConsoleGetPerProcessData(CsrGetClientThread()->Process), + WriteInputRequest->InputHandle, + &InputBuffer, GENERIC_WRITE, TRUE); if (!NT_SUCCESS(Status)) return Status; - Console = InputBuffer->Header.Console; - InputRecord = WriteInputRequest->InputRecord; - Length = WriteInputRequest->Length; - - for (i = 0; i < Length && NT_SUCCESS(Status); i++) - { - if (!WriteInputRequest->Unicode && - InputRecord->EventType == KEY_EVENT) - { - CHAR AsciiChar = InputRecord->Event.KeyEvent.uChar.AsciiChar; - ConsoleInputAnsiCharToUnicodeChar(Console, - &InputRecord->Event.KeyEvent.uChar.UnicodeChar, - &AsciiChar); - } - - Status = ConioProcessInputEvent(Console, InputRecord++); - } + Status = ConDrvWriteConsoleInput(InputBuffer->Header.Console, + InputBuffer, + WriteInputRequest->Unicode, + WriteInputRequest->InputRecord, + WriteInputRequest->Length, + &NumEventsWritten); + WriteInputRequest->Length = NumEventsWritten; ConSrvReleaseInputBuffer(InputBuffer, TRUE); - - WriteInputRequest->Length = i; - return Status; } +NTSTATUS NTAPI +ConDrvFlushConsoleInputBuffer(IN PCONSOLE Console, + IN PCONSOLE_INPUT_BUFFER InputBuffer); CSR_API(SrvFlushConsoleInputBuffer) { NTSTATUS Status; PCONSOLE_FLUSHINPUTBUFFER FlushInputBufferRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.FlushInputBufferRequest; - PLIST_ENTRY CurrentEntry; PCONSOLE_INPUT_BUFFER InputBuffer; - ConsoleInput* Event; DPRINT("SrvFlushConsoleInputBuffer\n"); Status = ConSrvGetInputBuffer(ConsoleGetPerProcessData(CsrGetClientThread()->Process), - FlushInputBufferRequest->InputHandle, - &InputBuffer, - GENERIC_WRITE, - TRUE); + FlushInputBufferRequest->InputHandle, + &InputBuffer, GENERIC_WRITE, TRUE); if (!NT_SUCCESS(Status)) return Status; - /* Discard all entries in the input event queue */ - while (!IsListEmpty(&InputBuffer->InputEvents)) - { - CurrentEntry = RemoveHeadList(&InputBuffer->InputEvents); - Event = CONTAINING_RECORD(CurrentEntry, ConsoleInput, ListEntry); - ConsoleFreeHeap(Event); - } - ResetEvent(InputBuffer->ActiveEvent); + Status = ConDrvFlushConsoleInputBuffer(InputBuffer->Header.Console, + InputBuffer); ConSrvReleaseInputBuffer(InputBuffer, TRUE); - return STATUS_SUCCESS; + return Status; } +NTSTATUS NTAPI +ConDrvGetConsoleNumberOfInputEvents(IN PCONSOLE Console, + IN PCONSOLE_INPUT_BUFFER InputBuffer, + OUT PULONG NumEvents); CSR_API(SrvGetConsoleNumberOfInputEvents) { NTSTATUS Status; PCONSOLE_GETNUMINPUTEVENTS GetNumInputEventsRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.GetNumInputEventsRequest; PCONSOLE_INPUT_BUFFER InputBuffer; - PLIST_ENTRY CurrentInput; - DWORD NumEvents; DPRINT("SrvGetConsoleNumberOfInputEvents\n"); - Status = ConSrvGetInputBuffer(ConsoleGetPerProcessData(CsrGetClientThread()->Process), GetNumInputEventsRequest->InputHandle, &InputBuffer, GENERIC_READ, TRUE); + Status = ConSrvGetInputBuffer(ConsoleGetPerProcessData(CsrGetClientThread()->Process), + GetNumInputEventsRequest->InputHandle, + &InputBuffer, GENERIC_READ, TRUE); if (!NT_SUCCESS(Status)) return Status; - CurrentInput = InputBuffer->InputEvents.Flink; - /* GetNumInputEventsRequest->NumInputEvents = */ NumEvents = 0; - - /* If there are any events ... */ - while (CurrentInput != &InputBuffer->InputEvents) - { - CurrentInput = CurrentInput->Flink; - NumEvents++; - } + Status = ConDrvGetConsoleNumberOfInputEvents(InputBuffer->Header.Console, + InputBuffer, + &GetNumInputEventsRequest->NumInputEvents); ConSrvReleaseInputBuffer(InputBuffer, TRUE); - - GetNumInputEventsRequest->NumInputEvents = NumEvents; - - return STATUS_SUCCESS; + return Status; } /* EOF */ diff --git a/reactos/win32ss/user/consrv/conoutput.c b/reactos/win32ss/user/consrv/conoutput.c index 433f6b3f5dc..4aeaf25cc74 100644 --- a/reactos/win32ss/user/consrv/conoutput.c +++ b/reactos/win32ss/user/consrv/conoutput.c @@ -411,7 +411,7 @@ DoWriteConsole(IN PCSR_API_MESSAGE ApiMessage, NTSTATUS NTAPI ConDrvReadConsoleOutput(IN PCONSOLE Console, IN PTEXTMODE_SCREEN_BUFFER Buffer, - IN BOOL Unicode, + IN BOOLEAN Unicode, OUT PCHAR_INFO CharInfo/*Buffer*/, IN PCOORD BufferSize, IN PCOORD BufferCoord, @@ -452,7 +452,7 @@ CSR_API(SrvReadConsoleOutput) NTSTATUS NTAPI ConDrvWriteConsoleOutput(IN PCONSOLE Console, IN PTEXTMODE_SCREEN_BUFFER Buffer, - IN BOOL Unicode, + IN BOOLEAN Unicode, IN PCHAR_INFO CharInfo/*Buffer*/, IN PCOORD BufferSize, IN PCOORD BufferCoord, @@ -762,9 +762,9 @@ CSR_API(SrvSetConsoleScreenBufferSize) NTSTATUS NTAPI ConDrvScrollConsoleScreenBuffer(IN PCONSOLE Console, IN PTEXTMODE_SCREEN_BUFFER Buffer, - IN BOOL Unicode, + IN BOOLEAN Unicode, IN PSMALL_RECT ScrollRectangle, - IN BOOL UseClipRectangle, + IN BOOLEAN UseClipRectangle, IN PSMALL_RECT ClipRectangle OPTIONAL, IN PCOORD DestinationOrigin, IN CHAR_INFO FillChar);