[KERNEL32][CONSRV]
[reactos.git] / win32ss / user / winsrv / consrv / condrv / coninput.c
index 3803130..3f36000 100644 (file)
@@ -9,33 +9,18 @@
 
 /* INCLUDES *******************************************************************/
 
-#include "consrv.h"
-#include "include/conio.h"
-#include "include/conio2.h"
-#include "handle.h"
-#include "lineinput.h"
+#include <consrv.h>
 
 #define NDEBUG
 #include <debug.h>
 
-
 /* 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)
+    WideCharToMultiByte((Console)->InputCodePage, 0, (sWChar), 1, (dChar), 1, NULL, NULL)
 
 #define ConsoleInputAnsiCharToUnicodeChar(Console, dWChar, sChar) \
-    MultiByteToWideChar((Console)->CodePage, 0, (sChar), 1, (dWChar), 1)
+    MultiByteToWideChar((Console)->InputCodePage, 0, (sChar), 1, (dWChar), 1)
 
 typedef struct ConsoleInput_t
 {
@@ -46,7 +31,7 @@ typedef struct ConsoleInput_t
 
 /* PRIVATE FUNCTIONS **********************************************************/
 
-static VOID FASTCALL
+static VOID
 ConioInputEventToAnsi(PCONSOLE Console, PINPUT_RECORD InputEvent)
 {
     if (InputEvent->EventType == KEY_EVENT)
@@ -59,9 +44,23 @@ ConioInputEventToAnsi(PCONSOLE Console, PINPUT_RECORD InputEvent)
     }
 }
 
-NTSTATUS FASTCALL
-ConioProcessInputEvent(PCONSOLE Console,
-                       PINPUT_RECORD InputEvent)
+static VOID
+ConioInputEventToUnicode(PCONSOLE Console, PINPUT_RECORD InputEvent)
+{
+    if (InputEvent->EventType == KEY_EVENT)
+    {
+        CHAR AsciiChar = InputEvent->Event.KeyEvent.uChar.AsciiChar;
+        InputEvent->Event.KeyEvent.uChar.AsciiChar = 0;
+        ConsoleInputAnsiCharToUnicodeChar(Console,
+                                          &InputEvent->Event.KeyEvent.uChar.UnicodeChar,
+                                          &AsciiChar);
+    }
+}
+
+NTSTATUS
+ConioAddInputEvent(PCONSOLE Console,
+                   PINPUT_RECORD InputEvent,
+                   BOOLEAN AppendToEnd)
 {
     ConsoleInput *ConInRec;
 
@@ -97,22 +96,39 @@ ConioProcessInputEvent(PCONSOLE Console,
     if (ConInRec == NULL) return STATUS_INSUFFICIENT_RESOURCES;
 
     ConInRec->InputEvent = *InputEvent;
-    InsertTailList(&Console->InputBuffer.InputEvents, &ConInRec->ListEntry);
+
+    if (AppendToEnd)
+    {
+        /* Append the event to the end of the queue */
+        InsertTailList(&Console->InputBuffer.InputEvents, &ConInRec->ListEntry);
+    }
+    else
+    {
+        /* Append the event to the beginning of the queue */
+        InsertHeadList(&Console->InputBuffer.InputEvents, &ConInRec->ListEntry);
+    }
 
     SetEvent(Console->InputBuffer.ActiveEvent);
-    CsrNotifyWait(&Console->InputBuffer.ReadWaitQueue,
-                  WaitAny,
+    CsrNotifyWait(&Console->ReadWaitQueue,
+                  FALSE,
                   NULL,
                   NULL);
-    if (!IsListEmpty(&Console->InputBuffer.ReadWaitQueue))
+    if (!IsListEmpty(&Console->ReadWaitQueue))
     {
-        CsrDereferenceWait(&Console->InputBuffer.ReadWaitQueue);
+        CsrDereferenceWait(&Console->ReadWaitQueue);
     }
 
     return STATUS_SUCCESS;
 }
 
-VOID FASTCALL
+NTSTATUS
+ConioProcessInputEvent(PCONSOLE Console,
+                       PINPUT_RECORD InputEvent)
+{
+    return ConioAddInputEvent(Console, InputEvent, TRUE);
+}
+
+VOID
 PurgeInputBuffer(PCONSOLE Console)
 {
     PLIST_ENTRY CurrentEntry;
@@ -128,77 +144,6 @@ PurgeInputBuffer(PCONSOLE Console)
     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 DRIVER APIS *********************************************************/
 
@@ -215,7 +160,7 @@ ConDrvReadConsole(IN PCONSOLE Console,
     NTSTATUS Status = STATUS_PENDING;
     PLIST_ENTRY CurrentEntry;
     ConsoleInput *Input;
-    ULONG i = ReadControl->nInitialChars;
+    ULONG i;
 
     if (Console == NULL || InputBuffer == NULL || /* Buffer == NULL  || */
         ReadControl == NULL || ReadControl->nLength != sizeof(CONSOLE_READCONSOLE_CONTROL))
@@ -225,11 +170,13 @@ ConDrvReadConsole(IN PCONSOLE Console,
 
     /* Validity checks */
     ASSERT(Console == InputBuffer->Header.Console);
-    ASSERT( (Buffer != NULL && NumCharsToRead >= 0) ||
+    ASSERT( (Buffer != NULL && NumCharsToRead >  0) ||
             (Buffer == NULL && NumCharsToRead == 0) );
 
     /* We haven't read anything (yet) */
 
+    i = ReadControl->nInitialChars;
+
     if (InputBuffer->Mode & ENABLE_LINE_INPUT)
     {
         if (Console->LineBuffer == NULL)
@@ -242,7 +189,7 @@ ConDrvReadConsole(IN PCONSOLE Console,
 
             Console->LineComplete = FALSE;
             Console->LineUpPressed = FALSE;
-            Console->LineInsertToggle = 0;
+            Console->LineInsertToggle = Console->InsertMode;
             Console->LineWakeupMask = ReadControl->dwCtrlWakeupMask;
             Console->LineSize = ReadControl->nInitialChars;
             Console->LinePos = Console->LineSize;
@@ -353,6 +300,7 @@ ConDrvReadConsole(IN PCONSOLE Console,
 NTSTATUS NTAPI
 ConDrvGetConsoleInput(IN PCONSOLE Console,
                       IN PCONSOLE_INPUT_BUFFER InputBuffer,
+                      IN BOOLEAN KeepEvents,
                       IN BOOLEAN WaitForMoreEvents,
                       IN BOOLEAN Unicode,
                       OUT PINPUT_RECORD InputRecord,
@@ -368,7 +316,7 @@ ConDrvGetConsoleInput(IN PCONSOLE Console,
 
     /* Validity checks */
     ASSERT(Console == InputBuffer->Header.Console);
-    ASSERT( (InputRecord != NULL && NumEventsToRead >= 0) ||
+    ASSERT( (InputRecord != NULL && NumEventsToRead >  0) ||
             (InputRecord == NULL && NumEventsToRead == 0) );
 
     // Do NOT do that !! Use the existing number of events already read, if any...
@@ -402,7 +350,8 @@ ConDrvGetConsoleInput(IN PCONSOLE Console,
         ++i;
         CurrentInput = CurrentInput->Flink;
 
-        if (WaitForMoreEvents) // TRUE --> Read, we remove inputs from the buffer ; FALSE --> Peek, we keep inputs.
+        /* Remove the events from the queue if needed */
+        if (!KeepEvents)
         {
             RemoveEntryList(&Input->ListEntry);
             ConsoleFreeHeap(Input);
@@ -424,6 +373,7 @@ NTSTATUS NTAPI
 ConDrvWriteConsoleInput(IN PCONSOLE Console,
                         IN PCONSOLE_INPUT_BUFFER InputBuffer,
                         IN BOOLEAN Unicode,
+                        IN BOOLEAN AppendToEnd,
                         IN PINPUT_RECORD InputRecord,
                         IN ULONG NumEventsToWrite,
                         OUT PULONG NumEventsWritten OPTIONAL)
@@ -436,23 +386,21 @@ ConDrvWriteConsoleInput(IN PCONSOLE Console,
 
     /* Validity checks */
     ASSERT(Console == InputBuffer->Header.Console);
-    ASSERT( (InputRecord != NULL && NumEventsToWrite >= 0) ||
+    ASSERT( (InputRecord != NULL && NumEventsToWrite >  0) ||
             (InputRecord == NULL && NumEventsToWrite == 0) );
 
-    // Do NOT do that !! Use the existing number of events already written, if any...
     // if (NumEventsWritten) *NumEventsWritten = 0;
 
-    for (i = (NumEventsWritten ? *NumEventsWritten : 0); i < NumEventsToWrite && NT_SUCCESS(Status); ++i)
+    /// Status = ConioAddInputEvents(Console, InputRecord, NumEventsToWrite, NumEventsWritten, AppendToEnd);
+
+    for (i = 0; i < NumEventsToWrite && NT_SUCCESS(Status); ++i)
     {
-        if (InputRecord->EventType == KEY_EVENT && !Unicode)
+        if (!Unicode)
         {
-            CHAR AsciiChar = InputRecord->Event.KeyEvent.uChar.AsciiChar;
-            ConsoleInputAnsiCharToUnicodeChar(Console,
-                                              &InputRecord->Event.KeyEvent.uChar.UnicodeChar,
-                                              &AsciiChar);
+            ConioInputEventToUnicode(Console, InputRecord);
         }
 
-        Status = ConioProcessInputEvent(Console, InputRecord++);
+        Status = ConioAddInputEvent(Console, InputRecord++, AppendToEnd);
     }
 
     if (NumEventsWritten) *NumEventsWritten = i;
@@ -488,24 +436,24 @@ ConDrvFlushConsoleInputBuffer(IN PCONSOLE Console,
 NTSTATUS NTAPI
 ConDrvGetConsoleNumberOfInputEvents(IN PCONSOLE Console,
                                     IN PCONSOLE_INPUT_BUFFER InputBuffer,
-                                    OUT PULONG NumEvents)
+                                    OUT PULONG NumberOfEvents)
 {
     PLIST_ENTRY CurrentInput;
 
-    if (Console == NULL || InputBuffer == NULL || NumEvents == NULL)
+    if (Console == NULL || InputBuffer == NULL || NumberOfEvents == NULL)
         return STATUS_INVALID_PARAMETER;
 
     /* Validity check */
     ASSERT(Console == InputBuffer->Header.Console);
 
-    *NumEvents = 0;
+    *NumberOfEvents = 0;
 
     /* If there are any events ... */
     CurrentInput = InputBuffer->InputEvents.Flink;
     while (CurrentInput != &InputBuffer->InputEvents)
     {
         CurrentInput = CurrentInput->Flink;
-        (*NumEvents)++;
+        (*NumberOfEvents)++;
     }
 
     return STATUS_SUCCESS;