[CONSRV]: Use an optional parameter for passing things to the "line discipline" funct...
[reactos.git] / win32ss / user / winsrv / consrv / condrv / coninput.c
index c19b601..1f4a34a 100644 (file)
 
 /* GLOBALS ********************************************************************/
 
-/*
- * From MSDN:
- * "The lpMultiByteStr and lpWideCharStr pointers must not be the same.
- *  If they are the same, the function fails, and GetLastError returns
- *  ERROR_INVALID_PARAMETER."
- */
-#define ConsoleInputUnicodeCharToAnsiChar(Console, dChar, sWChar) \
-    ASSERT((ULONG_PTR)dChar != (ULONG_PTR)sWChar); \
-    WideCharToMultiByte((Console)->InputCodePage, 0, (sWChar), 1, (dChar), 1, NULL, NULL)
-
-#define ConsoleInputAnsiCharToUnicodeChar(Console, dWChar, sChar) \
-    ASSERT((ULONG_PTR)dWChar != (ULONG_PTR)sChar); \
-    MultiByteToWideChar((Console)->InputCodePage, 0, (sChar), 1, (dWChar), 1)
-
 typedef struct ConsoleInput_t
 {
     LIST_ENTRY ListEntry;
@@ -39,117 +25,13 @@ typedef struct ConsoleInput_t
 
 /* PRIVATE FUNCTIONS **********************************************************/
 
-static VOID
-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);
-    }
-}
-
-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);
-    }
-}
-
-
-/*
- * This pre-processing code MUST be IN consrv ONLY
- */
-static ULONG
-PreprocessInput(PCONSOLE Console,
-                PINPUT_RECORD InputEvent,
-                ULONG NumEventsToWrite)
-{
-    ULONG NumEvents;
-
-    /*
-     * Loop each event, and for each, check for pause or unpause
-     * and perform adequate behaviour.
-     */
-    for (NumEvents = NumEventsToWrite; NumEvents > 0; --NumEvents)
-    {
-        /* 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);
-
-                    /* Skip the event */
-                    RtlMoveMemory(InputEvent,
-                                  InputEvent + 1,
-                                  (NumEvents - 1) * sizeof(INPUT_RECORD));
-                    --NumEventsToWrite;
-                    continue;
-                }
-            }
-            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);
-
-                    /* Skip the event */
-                    RtlMoveMemory(InputEvent,
-                                  InputEvent + 1,
-                                  (NumEvents - 1) * sizeof(INPUT_RECORD));
-                    --NumEventsToWrite;
-                    continue;
-                }
-            }
-        }
-
-        /* Go to the next event */
-        ++InputEvent;
-    }
-
-    return NumEventsToWrite;
-}
-
-/*
- * This post-processing code MUST be IN consrv ONLY
- */
-static VOID
-PostprocessInput(PCONSOLE Console)
-{
-    CsrNotifyWait(&Console->ReadWaitQueue,
-                  FALSE,
-                  NULL,
-                  NULL);
-    if (!IsListEmpty(&Console->ReadWaitQueue))
-    {
-        CsrDereferenceWait(&Console->ReadWaitQueue);
-    }
-}
-
-NTSTATUS
-ConioAddInputEvents(PCONSOLE Console,
-                    PINPUT_RECORD InputRecords, // InputEvent
-                    ULONG NumEventsToWrite,
-                    PULONG NumEventsWritten,
-                    BOOLEAN AppendToEnd)
+// ConDrvAddInputEvents
+static NTSTATUS
+AddInputEvents(PCONSOLE Console,
+               PINPUT_RECORD InputRecords, // InputEvent
+               ULONG NumEventsToWrite,
+               PULONG NumEventsWritten,
+               BOOLEAN AppendToEnd)
 {
     NTSTATUS Status = STATUS_SUCCESS;
     ULONG i = 0;
@@ -157,13 +39,6 @@ ConioAddInputEvents(PCONSOLE Console,
 
     if (NumEventsWritten) *NumEventsWritten = 0;
 
-    /*
-     * This pre-processing code MUST be IN consrv ONLY!!
-     */
-    NumEventsToWrite = PreprocessInput(Console, InputRecords, NumEventsToWrite);
-    if (NumEventsToWrite == 0) return STATUS_SUCCESS;
-
-
     /*
      * When adding many single events, in the case of repeated mouse move or
      * key down events, we try to coalesce them so that we do not saturate
@@ -295,35 +170,15 @@ ConioAddInputEvents(PCONSOLE Console,
         Status = STATUS_SUCCESS;
     }
 
-    if (SetWaitEvent) SetEvent(Console->InputBuffer.ActiveEvent);
+    if (SetWaitEvent) NtSetEvent(Console->InputBuffer.ActiveEvent, NULL);
 
 Done:
     if (NumEventsWritten) *NumEventsWritten = i;
 
-
-    /*
-     * This post-processing code MUST be IN consrv ONLY!!
-     */
-    // if (NT_SUCCESS(Status))
-    if (Status == STATUS_SUCCESS) PostprocessInput(Console);
-
-    return STATUS_SUCCESS;
-}
-
-NTSTATUS
-ConioProcessInputEvent(PCONSOLE Console,
-                       PINPUT_RECORD InputEvent)
-{
-    ULONG NumEventsWritten;
-    return ConioAddInputEvents(Console,
-                               InputEvent,
-                               1,
-                               &NumEventsWritten,
-                               TRUE);
+    return Status;
 }
 
-
-VOID
+static VOID
 PurgeInputBuffer(PCONSOLE Console)
 {
     PLIST_ENTRY CurrentEntry;
@@ -336,6 +191,44 @@ PurgeInputBuffer(PCONSOLE Console)
         ConsoleFreeHeap(Event);
     }
 
+    // CloseHandle(Console->InputBuffer.ActiveEvent);
+}
+
+NTSTATUS NTAPI
+ConDrvInitInputBuffer(IN PCONSOLE Console,
+                      IN ULONG InputBufferSize)
+{
+    NTSTATUS Status;
+    OBJECT_ATTRIBUTES ObjectAttributes;
+
+    ConSrvInitObject(&Console->InputBuffer.Header, INPUT_BUFFER, Console);
+
+    InitializeObjectAttributes(&ObjectAttributes,
+                               NULL,
+                               OBJ_INHERIT,
+                               NULL,
+                               NULL);
+
+    Status = NtCreateEvent(&Console->InputBuffer.ActiveEvent, EVENT_ALL_ACCESS,
+                           &ObjectAttributes, NotificationEvent, FALSE);
+    if (!NT_SUCCESS(Status))
+    {
+        return STATUS_UNSUCCESSFUL;
+        // return Status;
+    }
+
+    Console->InputBuffer.InputBufferSize = InputBufferSize;
+    InitializeListHead(&Console->InputBuffer.InputEvents);
+    Console->InputBuffer.Mode = ENABLE_PROCESSED_INPUT | ENABLE_LINE_INPUT |
+                                ENABLE_ECHO_INPUT      | ENABLE_MOUSE_INPUT;
+
+    return STATUS_SUCCESS;
+}
+
+VOID NTAPI
+ConDrvDeinitInputBuffer(IN PCONSOLE Console)
+{
+    PurgeInputBuffer(Console);
     CloseHandle(Console->InputBuffer.ActiveEvent);
 }
 
@@ -345,18 +238,15 @@ PurgeInputBuffer(PCONSOLE Console)
 NTSTATUS NTAPI
 ConDrvReadConsole(IN PCONSOLE Console,
                   IN PCONSOLE_INPUT_BUFFER InputBuffer,
-                  /**/IN PUNICODE_STRING ExeName /**/OPTIONAL/**/,/**/
                   IN BOOLEAN Unicode,
                   OUT PVOID Buffer,
                   IN OUT PCONSOLE_READCONSOLE_CONTROL ReadControl,
+                  IN PVOID Parameter OPTIONAL,
                   IN ULONG NumCharsToRead,
                   OUT PULONG NumCharsRead OPTIONAL)
 {
     // STATUS_PENDING : Wait if more to read ; STATUS_SUCCESS : Don't wait.
-    NTSTATUS Status = STATUS_PENDING;
-    PLIST_ENTRY CurrentEntry;
-    ConsoleInput *Input;
-    ULONG i;
+    // NTSTATUS Status; = STATUS_PENDING;
 
     if (Console == NULL || InputBuffer == NULL || /* Buffer == NULL  || */
         ReadControl == NULL || ReadControl->nLength != sizeof(CONSOLE_READCONSOLE_CONTROL))
@@ -368,130 +258,14 @@ ConDrvReadConsole(IN PCONSOLE Console,
     ASSERT(Console == InputBuffer->Header.Console);
     ASSERT((Buffer != NULL) || (Buffer == NULL && NumCharsToRead == 0));
 
-    /* We haven't read anything (yet) */
-
-    i = ReadControl->nInitialChars;
-
-    if (InputBuffer->Mode & ENABLE_LINE_INPUT)
-    {
-        if (Console->LineBuffer == NULL)
-        {
-            /* Starting a new line */
-            Console->LineMaxSize = (WORD)max(256, NumCharsToRead);
-
-            Console->LineBuffer = ConsoleAllocHeap(0, Console->LineMaxSize * sizeof(WCHAR));
-            if (Console->LineBuffer == NULL) return STATUS_NO_MEMORY;
-
-            Console->LineComplete = FALSE;
-            Console->LineUpPressed = FALSE;
-            Console->LineInsertToggle = Console->InsertMode;
-            Console->LineWakeupMask = ReadControl->dwCtrlWakeupMask;
-            Console->LineSize = ReadControl->nInitialChars;
-            Console->LinePos = Console->LineSize;
-
-            /*
-             * Pre-filling the buffer is only allowed in the Unicode API,
-             * so we don't need to worry about ANSI <-> Unicode conversion.
-             */
-            memcpy(Console->LineBuffer, Buffer, Console->LineSize * sizeof(WCHAR));
-            if (Console->LineSize == Console->LineMaxSize)
-            {
-                Console->LineComplete = TRUE;
-                Console->LinePos = 0;
-            }
-        }
-
-        /* If we don't have a complete line yet, process the pending input */
-        while (!Console->LineComplete && !IsListEmpty(&InputBuffer->InputEvents))
-        {
-            /* Remove input event from queue */
-            CurrentEntry = RemoveHeadList(&InputBuffer->InputEvents);
-            if (IsListEmpty(&InputBuffer->InputEvents))
-            {
-                ResetEvent(InputBuffer->ActiveEvent);
-            }
-            Input = CONTAINING_RECORD(CurrentEntry, ConsoleInput, ListEntry);
-
-            /* Only pay attention to key down */
-            if (Input->InputEvent.EventType == KEY_EVENT &&
-                Input->InputEvent.Event.KeyEvent.bKeyDown)
-            {
-                LineInputKeyDown(Console, ExeName,
-                                 &Input->InputEvent.Event.KeyEvent);
-                ReadControl->dwControlKeyState = Input->InputEvent.Event.KeyEvent.dwControlKeyState;
-            }
-            ConsoleFreeHeap(Input);
-        }
-
-        /* Check if we have a complete line to read from */
-        if (Console->LineComplete)
-        {
-            while (i < NumCharsToRead && Console->LinePos != Console->LineSize)
-            {
-                WCHAR Char = Console->LineBuffer[Console->LinePos++];
-
-                if (Unicode)
-                {
-                    ((PWCHAR)Buffer)[i] = Char;
-                }
-                else
-                {
-                    ConsoleInputUnicodeCharToAnsiChar(Console, &((PCHAR)Buffer)[i], &Char);
-                }
-                ++i;
-            }
-
-            if (Console->LinePos == Console->LineSize)
-            {
-                /* Entire line has been read */
-                ConsoleFreeHeap(Console->LineBuffer);
-                Console->LineBuffer = NULL;
-            }
-
-            Status = STATUS_SUCCESS;
-        }
-    }
-    else
-    {
-        /* Character input */
-        while (i < NumCharsToRead && !IsListEmpty(&InputBuffer->InputEvents))
-        {
-            /* Remove input event from queue */
-            CurrentEntry = RemoveHeadList(&InputBuffer->InputEvents);
-            if (IsListEmpty(&InputBuffer->InputEvents))
-            {
-                ResetEvent(InputBuffer->ActiveEvent);
-            }
-            Input = CONTAINING_RECORD(CurrentEntry, ConsoleInput, ListEntry);
-
-            /* Only pay attention to valid ASCII chars, on key down */
-            if (Input->InputEvent.EventType == KEY_EVENT  &&
-                Input->InputEvent.Event.KeyEvent.bKeyDown &&
-                Input->InputEvent.Event.KeyEvent.uChar.UnicodeChar != L'\0')
-            {
-                WCHAR Char = Input->InputEvent.Event.KeyEvent.uChar.UnicodeChar;
-
-                if (Unicode)
-                {
-                    ((PWCHAR)Buffer)[i] = Char;
-                }
-                else
-                {
-                    ConsoleInputUnicodeCharToAnsiChar(Console, &((PCHAR)Buffer)[i], &Char);
-                }
-                ++i;
-
-                /* Did read something */
-                Status = STATUS_SUCCESS;
-            }
-            ConsoleFreeHeap(Input);
-        }
-    }
-
-    // FIXME: Only set if Status == STATUS_SUCCESS ???
-    if (NumCharsRead) *NumCharsRead = i;
-
-    return Status;
+    /* Call the line-discipline */
+    return TermReadStream(Console,
+                          Unicode,
+                          Buffer,
+                          ReadControl,
+                          Parameter,
+                          NumCharsToRead,
+                          NumCharsRead);
 }
 
 NTSTATUS NTAPI
@@ -499,7 +273,6 @@ ConDrvGetConsoleInput(IN PCONSOLE Console,
                       IN PCONSOLE_INPUT_BUFFER InputBuffer,
                       IN BOOLEAN KeepEvents,
                       IN BOOLEAN WaitForMoreEvents,
-                      IN BOOLEAN Unicode,
                       OUT PINPUT_RECORD InputRecord,
                       IN ULONG NumEventsToRead,
                       OUT PULONG NumEventsRead OPTIONAL)
@@ -549,20 +322,13 @@ ConDrvGetConsoleInput(IN PCONSOLE Console,
 
     if (NumEventsRead) *NumEventsRead = i;
 
-    /* Now translate everything to ANSI */
-    if (!Unicode)
-    {
-        for (; i > 0; --i)
-        {
-            ConioInputEventToAnsi(InputBuffer->Header.Console, --InputRecord);
-        }
-    }
-
     if (IsListEmpty(&InputBuffer->InputEvents))
     {
         ResetEvent(InputBuffer->ActiveEvent);
     }
 
+    // FIXME: If we add back UNICODE support, it's here that we need to do the translation.
+
     /* We read all the inputs available, we return success */
     return STATUS_SUCCESS;
 }
@@ -570,15 +336,11 @@ ConDrvGetConsoleInput(IN PCONSOLE Console,
 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)
 {
-    NTSTATUS Status = STATUS_SUCCESS;
-    ULONG i;
-
     if (Console == NULL || InputBuffer == NULL /* || InputRecord == NULL */)
         return STATUS_INVALID_PARAMETER;
 
@@ -586,25 +348,16 @@ ConDrvWriteConsoleInput(IN PCONSOLE Console,
     ASSERT(Console == InputBuffer->Header.Console);
     ASSERT((InputRecord != NULL) || (InputRecord == NULL && NumEventsToWrite == 0));
 
-    /* First translate everything to UNICODE */
-    if (!Unicode)
-    {
-        for (i = 0; i < NumEventsToWrite; ++i)
-        {
-            ConioInputEventToUnicode(Console, &InputRecord[i]);
-        }
-    }
-
     /* Now, add the events */
-    // if (NumEventsWritten) *NumEventsWritten = 0;
-    Status = ConioAddInputEvents(Console,
-                                 InputRecord,
-                                 NumEventsToWrite,
-                                 NumEventsWritten,
-                                 AppendToEnd);
-    // if (NumEventsWritten) *NumEventsWritten = i;
+    if (NumEventsWritten) *NumEventsWritten = 0;
 
-    return Status;
+    // FIXME: If we add back UNICODE support, it's here that we need to do the translation.
+
+    return AddInputEvents(Console,
+                          InputRecord,
+                          NumEventsToWrite,
+                          NumEventsWritten,
+                          AppendToEnd);
 }
 
 NTSTATUS NTAPI