Author: rharabien
Date: Sun Oct 16 11:39:47 2011
New Revision: 54159
URL:
http://svn.reactos.org/svn/reactos?rev=54159&view=rev
Log:
[WIN32K]
- Merge KeyboardInput thread and MouseInputThread into Raw Input Thread (RIT)
Modified:
trunk/reactos/subsystems/win32/csrss/win32csr/dllmain.c
trunk/reactos/subsystems/win32/win32k/ntuser/input.c
Modified: trunk/reactos/subsystems/win32/csrss/win32csr/dllmain.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/csrss/win…
==============================================================================
--- trunk/reactos/subsystems/win32/csrss/win32csr/dllmain.c [iso-8859-1] (original)
+++ trunk/reactos/subsystems/win32/csrss/win32csr/dllmain.c [iso-8859-1] Sun Oct 16
11:39:47 2011
@@ -182,7 +182,7 @@
WINAPI
CreateSystemThreads(PVOID pParam)
{
- NtUserCallOneParam((DWORD_PTR)pParam, ONEPARAM_ROUTINE_CREATESYSTEMTHREADS);
+ NtUserCallOneParam((DWORD)pParam, ONEPARAM_ROUTINE_CREATESYSTEMTHREADS);
DPRINT1("This thread should not terminate!\n");
return 0;
}
@@ -196,7 +196,6 @@
HANDLE ServerThread;
CLIENT_ID ClientId;
NTSTATUS Status;
- UINT i;
CsrExports = *Exports;
Win32CsrApiHeap = CsrssApiHeap;
@@ -215,18 +214,15 @@
RtlInitializeCriticalSection(&Win32CsrDefineDosDeviceCritSec);
InitializeListHead(&DosDeviceHistory);
- /* Start Keyboard, Mouse and Raw Input Threads */
- for (i = 0; i < 3; ++i)
- {
- Status = RtlCreateUserThread(NtCurrentProcess(), NULL, TRUE, 0, 0, 0,
(PTHREAD_START_ROUTINE)CreateSystemThreads, (PVOID)i, &ServerThread, &ClientId);
- if (NT_SUCCESS(Status))
- {
- NtResumeThread(ServerThread, NULL);
- NtClose(ServerThread);
- }
- else
- DPRINT1("Cannot start system thread: %u!\n", i);
- }
+ /* Start Raw Input Threads */
+ Status = RtlCreateUserThread(NtCurrentProcess(), NULL, TRUE, 0, 0, 0,
(PTHREAD_START_ROUTINE)CreateSystemThreads, (PVOID)0, &ServerThread, &ClientId);
+ if (NT_SUCCESS(Status))
+ {
+ NtResumeThread(ServerThread, NULL);
+ NtClose(ServerThread);
+ }
+ else
+ DPRINT1("Cannot start Raw Input Thread!\n");
return TRUE;
}
Modified: trunk/reactos/subsystems/win32/win32k/ntuser/input.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/nt…
==============================================================================
--- trunk/reactos/subsystems/win32/win32k/ntuser/input.c [iso-8859-1] (original)
+++ trunk/reactos/subsystems/win32/win32k/ntuser/input.c [iso-8859-1] Sun Oct 16 11:39:47
2011
@@ -23,12 +23,15 @@
HANDLE ghKeyboardDevice;
static DWORD LastInputTick = 0;
-static HANDLE MouseDeviceHandle;
-static KEVENT InputThreadsStart;
-static BOOLEAN InputThreadsRunning = FALSE;
+static HANDLE ghMouseDevice;
/* FUNCTIONS *****************************************************************/
+/*
+ * IntLastInputTick
+ *
+ * Updates or gets last input tick count
+ */
static DWORD FASTCALL
IntLastInputTick(BOOL bUpdate)
{
@@ -42,6 +45,11 @@
return LastInputTick;
}
+/*
+ * DoTheScreenSaver
+ *
+ * Check if scrensaver should be started and sends message to SAS window
+ */
VOID FASTCALL
DoTheScreenSaver(VOID)
{
@@ -78,210 +86,201 @@
}
}
-static VOID APIENTRY
-MouseThreadMain(PVOID StartContext)
-{
- UNICODE_STRING MouseDeviceName =
RTL_CONSTANT_STRING(L"\\Device\\PointerClass0");
- OBJECT_ATTRIBUTES MouseObjectAttributes;
+/*
+ * OpenInputDevice
+ *
+ * Opens input device for asynchronous access
+ */
+static
+NTAPI NTSTATUS
+OpenInputDevice(PHANDLE pHandle, PFILE_OBJECT *ppObject, CONST WCHAR *pszDeviceName)
+{
+ UNICODE_STRING DeviceName;
+ OBJECT_ATTRIBUTES ObjectAttributes;
+ NTSTATUS Status;
IO_STATUS_BLOCK Iosb;
- NTSTATUS Status;
- MOUSE_ATTRIBUTES MouseAttr;
-
- KeSetPriorityThread(&PsGetCurrentThread()->Tcb,
- LOW_REALTIME_PRIORITY + 3);
-
- InitializeObjectAttributes(&MouseObjectAttributes,
- &MouseDeviceName,
+
+ RtlInitUnicodeString(&DeviceName, pszDeviceName);
+
+ InitializeObjectAttributes(&ObjectAttributes,
+ &DeviceName,
0,
NULL,
NULL);
- do
- {
- LARGE_INTEGER DueTime;
+
+ Status = ZwOpenFile(pHandle,
+ FILE_ALL_ACCESS,
+ &ObjectAttributes,
+ &Iosb,
+ 0,
+ 0);
+ if (NT_SUCCESS(Status) && ppObject)
+ {
+ Status = ObReferenceObjectByHandle(*pHandle, SYNCHRONIZE, NULL, KernelMode,
(PVOID*)ppObject, NULL);
+ ASSERT(NT_SUCCESS(Status));
+ }
+
+ return Status;
+}
+
+/*
+ * RawInputThreadMain
+ *
+ * Reads data from input devices and supports win32 timers
+ */
+VOID NTAPI
+RawInputThreadMain()
+{
+ NTSTATUS MouStatus = STATUS_UNSUCCESSFUL, KbdStatus = STATUS_UNSUCCESSFUL, Status;
+ IO_STATUS_BLOCK MouIosb, KbdIosb;
+ PFILE_OBJECT pKbdDevice, pMouDevice;
+ LARGE_INTEGER WaitTimeout, ByteOffset;
+ PVOID WaitObjects[3], pSignaledObject = NULL;
+ ULONG cWaitObjects = 0, cMaxWaitObjects = 1;
+ MOUSE_INPUT_DATA MouseInput;
+ KEYBOARD_INPUT_DATA KeyInput;
+
+ ByteOffset.QuadPart = (LONGLONG)0;
+ WaitTimeout.QuadPart = (LONGLONG)(-10000000);
+
+ /*do
+ {
KEVENT Event;
- DueTime.QuadPart = (LONGLONG)(-10000000);
KeInitializeEvent(&Event, NotificationEvent, FALSE);
- Status = KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE,
&DueTime);
- Status = ZwOpenFile(&MouseDeviceHandle,
- FILE_ALL_ACCESS,
- &MouseObjectAttributes,
- &Iosb,
- 0,
- FILE_SYNCHRONOUS_IO_ALERT);
- } while (!NT_SUCCESS(Status));
-
- ptiMouse = PsGetCurrentThreadWin32Thread();
- ptiMouse->TIF_flags |= TIF_SYSTEMTHREAD;
- TRACE("Mouse Thread 0x%x \n", ptiMouse);
+ Status = KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE,
&WaitTimeout);
+ } while (!NT_SUCCESS(Status));*/
+
+ ptiRawInput = PsGetCurrentThreadWin32Thread();
+ ptiRawInput->TIF_flags |= TIF_SYSTEMTHREAD;
+ TRACE("Raw Input Thread 0x%x\n", ptiRawInput);
KeSetPriorityThread(&PsGetCurrentThread()->Tcb,
LOW_REALTIME_PRIORITY + 3);
+ UserEnterExclusive();
+ StartTheTimers();
+ UserLeave();
+
for(;;)
{
- /*
- * Wait to start input.
- */
- TRACE("Mouse Input Thread Waiting for start event\n");
- Status = KeWaitForSingleObject(&InputThreadsStart,
- 0,
- KernelMode,
- TRUE,
- NULL);
- TRACE("Mouse Input Thread Starting...\n");
-
- /*FIXME: Does mouse attributes need to be used for anything */
- Status = ZwDeviceIoControlFile(MouseDeviceHandle,
+ if (!ghMouseDevice)
+ {
+ /* Check if mouse device already exists */
+ Status = OpenInputDevice(&ghMouseDevice, &pMouDevice,
L"\\Device\\PointerClass0" );
+ if (NT_SUCCESS(Status))
+ {
+ ++cMaxWaitObjects;
+ TRACE("Mouse connected!\n");
+ }
+ }
+ if (!ghKeyboardDevice)
+ {
+ /* Check if keyboard device already exists */
+ Status = OpenInputDevice(&ghKeyboardDevice, &pKbdDevice,
L"\\Device\\KeyboardClass0");
+ if (NT_SUCCESS(Status))
+ {
+ ++cMaxWaitObjects;
+ TRACE("Keyboard connected!\n");
+ }
+ }
+
+ /* Reset WaitHandles array */
+ cWaitObjects = 0;
+ WaitObjects[cWaitObjects++] = MasterTimer;
+
+ if (ghMouseDevice)
+ {
+ /* Try to read from mouse if previous reading is not pending */
+ if (MouStatus != STATUS_PENDING)
+ {
+ MouStatus = ZwReadFile(ghMouseDevice,
NULL,
NULL,
NULL,
- &Iosb,
- IOCTL_MOUSE_QUERY_ATTRIBUTES,
- &MouseAttr, sizeof(MOUSE_ATTRIBUTES),
- NULL, 0);
- if(!NT_SUCCESS(Status))
- {
- TRACE("Failed to get mouse attributes\n");
- }
-
- /*
- * Receive and process mouse input.
- */
- while(InputThreadsRunning)
- {
- MOUSE_INPUT_DATA MouseInput;
- Status = ZwReadFile(MouseDeviceHandle,
- NULL,
- NULL,
- NULL,
- &Iosb,
- &MouseInput,
- sizeof(MOUSE_INPUT_DATA),
- NULL,
- NULL);
- if(Status == STATUS_ALERTED && !InputThreadsRunning)
- {
- break;
- }
- if(Status == STATUS_PENDING)
- {
- NtWaitForSingleObject(MouseDeviceHandle, FALSE, NULL);
- Status = Iosb.Status;
- }
- if(!NT_SUCCESS(Status))
- {
- ERR("Win32K: Failed to read from mouse.\n");
- return; //(Status);
- }
+ &MouIosb,
+ &MouseInput,
+ sizeof(MOUSE_INPUT_DATA),
+ &ByteOffset,
+ NULL);
+ }
+
+ if (MouStatus == STATUS_PENDING)
+ WaitObjects[cWaitObjects++] = &pMouDevice->Event;
+ }
+
+ if (ghKeyboardDevice)
+ {
+ /* Try to read from keyboard if previous reading is not pending */
+ if (KbdStatus != STATUS_PENDING)
+ {
+ KbdStatus = ZwReadFile(ghKeyboardDevice,
+ NULL,
+ NULL,
+ NULL,
+ &KbdIosb,
+ &KeyInput,
+ sizeof(KEYBOARD_INPUT_DATA),
+ &ByteOffset,
+ NULL);
+
+ }
+ if (KbdStatus == STATUS_PENDING)
+ WaitObjects[cWaitObjects++] = &pKbdDevice->Event;
+ }
+
+ /* If all objects are pending, wait for them */
+ if (cWaitObjects == cMaxWaitObjects)
+ {
+ Status = KeWaitForMultipleObjects(cWaitObjects,
+ WaitObjects,
+ WaitAny,
+ UserRequest,
+ KernelMode,
+ TRUE,
+ NULL,//&WaitTimeout,
+ NULL);
+
+ if (Status >= STATUS_WAIT_0 && Status < STATUS_WAIT_0 +
cWaitObjects)
+ {
+ /* Some device has finished reading */
+ pSignaledObject = WaitObjects[Status - STATUS_WAIT_0];
+
+ /* Check if it is mouse or keyboard and update status */
+ if (pSignaledObject == &pMouDevice->Event)
+ MouStatus = MouIosb.Status;
+ else if (pSignaledObject == &pKbdDevice->Event)
+ KbdStatus = KbdIosb.Status;
+ else if (pSignaledObject == MasterTimer)
+ {
+ /* FIXME: where it should go? */
+ ProcessTimers();
+ }
+ else ASSERT(FALSE);
+ }
+ }
+
+ /* Have we successed reading from mouse? */
+ if (NT_SUCCESS(MouStatus) && MouStatus != STATUS_PENDING)
+ {
TRACE("MouseEvent\n");
+
+ /* Set LastInputTick */
IntLastInputTick(TRUE);
+ /* Process data */
UserEnterExclusive();
-
- UserProcessMouseInput(&MouseInput, Iosb.Information /
sizeof(MOUSE_INPUT_DATA));
-
+ UserProcessMouseInput(&MouseInput, MouIosb.Information /
sizeof(MOUSE_INPUT_DATA));
UserLeave();
}
- TRACE("Mouse Input Thread Stopped...\n");
- }
-}
-
-VOID NTAPI
-KeyboardThreadMain(PVOID StartContext)
-{
- UNICODE_STRING KeyboardDeviceName =
RTL_CONSTANT_STRING(L"\\Device\\KeyboardClass0");
- OBJECT_ATTRIBUTES KeyboardObjectAttributes;
- IO_STATUS_BLOCK Iosb;
- NTSTATUS Status;
-
- InitializeObjectAttributes(&KeyboardObjectAttributes,
- &KeyboardDeviceName,
- 0,
- NULL,
- NULL);
- do
- {
- LARGE_INTEGER DueTime;
- KEVENT Event;
- DueTime.QuadPart = (LONGLONG)(-100000000);
- KeInitializeEvent(&Event, NotificationEvent, FALSE);
- Status = KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE,
&DueTime);
- Status = ZwOpenFile(&ghKeyboardDevice,
- FILE_READ_ACCESS,//FILE_ALL_ACCESS,
- &KeyboardObjectAttributes,
- &Iosb,
- 0,
- FILE_SYNCHRONOUS_IO_ALERT);
- } while (!NT_SUCCESS(Status));
-
- UserInitKeyboard(ghKeyboardDevice);
-
- ptiKeyboard = PsGetCurrentThreadWin32Thread();
- ptiKeyboard->TIF_flags |= TIF_SYSTEMTHREAD;
- TRACE("Keyboard Thread 0x%x \n", ptiKeyboard);
-
- KeSetPriorityThread(&PsGetCurrentThread()->Tcb,
- LOW_REALTIME_PRIORITY + 3);
-
- for (;;)
- {
- /*
- * Wait to start input.
- */
- TRACE("Keyboard Input Thread Waiting for start event\n");
- Status = KeWaitForSingleObject(&InputThreadsStart,
- 0,
- KernelMode,
- TRUE,
- NULL);
-
- TRACE("Keyboard Input Thread Starting...\n");
- /*
- * Receive and process keyboard input.
- */
- while (InputThreadsRunning)
- {
- KEYBOARD_INPUT_DATA KeyInput;
-
- TRACE("KeyInput @ %08x\n", &KeyInput);
-
- Status = ZwReadFile (ghKeyboardDevice,
- NULL,
- NULL,
- NULL,
- &Iosb,
- &KeyInput,
- sizeof(KEYBOARD_INPUT_DATA),
- NULL,
- NULL);
-
- if (Status == STATUS_ALERTED && !InputThreadsRunning)
- {
- break;
- }
- if (Status == STATUS_PENDING)
- {
- NtWaitForSingleObject(ghKeyboardDevice, FALSE, NULL);
- Status = Iosb.Status;
- }
- if (!NT_SUCCESS(Status))
- {
- ERR("Win32K: Failed to read from keyboard.\n");
- return; //(Status);
- }
-
- TRACE("KeyRaw: %s %04x\n",
+ else if (MouStatus != STATUS_PENDING)
+ ERR("Failed to read from mouse: %x.\n", MouStatus);
+
+ /* Have we successed reading from keyboard? */
+ if (NT_SUCCESS(KbdStatus) && KbdStatus != STATUS_PENDING)
+ {
+ TRACE("KeyboardEvent: %s %04x\n",
(KeyInput.Flags & KEY_BREAK) ? "up" : "down",
- KeyInput.MakeCode );
-
- if (Status == STATUS_ALERTED && !InputThreadsRunning)
- break;
-
- if (!NT_SUCCESS(Status))
- {
- ERR("Win32K: Failed to read from keyboard.\n");
- return; //(Status);
- }
+ KeyInput.MakeCode);
/* Set LastInputTick */
IntLastInputTick(TRUE);
@@ -291,68 +290,18 @@
UserProcessKeyboardInput(&KeyInput);
UserLeave();
}
-
- TRACE("KeyboardInput Thread Stopped...\n");
- }
-}
-
-
-static PVOID Objects[2];
-/*
- Raw Input Thread.
- Since this relies on InputThreadsStart, just fake it.
- */
-static VOID APIENTRY
-RawInputThreadMain(PVOID StartContext)
-{
- NTSTATUS Status;
- LARGE_INTEGER DueTime;
-
- DueTime.QuadPart = (LONGLONG)(-10000000);
-
- do
- {
- KEVENT Event;
- KeInitializeEvent(&Event, NotificationEvent, FALSE);
- Status = KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE,
&DueTime);
- } while (!NT_SUCCESS(Status));
-
- Objects[0] = &InputThreadsStart;
- Objects[1] = MasterTimer;
-
- ptiRawInput = PsGetCurrentThreadWin32Thread();
- ptiRawInput->TIF_flags |= TIF_SYSTEMTHREAD;
- TRACE("Raw Input Thread 0x%x \n", ptiRawInput);
-
- KeSetPriorityThread(&PsGetCurrentThread()->Tcb,
- LOW_REALTIME_PRIORITY + 3);
-
- UserEnterExclusive();
- StartTheTimers();
- UserLeave();
-
- //
- // ATM, we just have one job to handle, merge the other two later.
- //
- for(;;)
- {
- TRACE("Raw Input Thread Waiting for start event\n");
-
- Status = KeWaitForMultipleObjects( 2,
- Objects,
- WaitAll, //WaitAny,
- WrUserRequest,
- KernelMode,
- TRUE,
- NULL,
- NULL);
- TRACE("Raw Input Thread Starting...\n");
-
- ProcessTimers();
+ else if (KbdStatus != STATUS_PENDING)
+ ERR("Failed to read from keyboard: %x.\n", KbdStatus);
}
ERR("Raw Input Thread Exit!\n");
}
+/*
+ * CreateSystemThreads
+ *
+ * Called form dedicated thread in CSRSS. RIT is started in context of this
+ * thread because it needs valid Win32 process with TEB initialized
+ */
DWORD NTAPI
CreateSystemThreads(UINT Type)
{
@@ -360,9 +309,7 @@
switch (Type)
{
- case 0: KeyboardThreadMain(NULL); break;
- case 1: MouseThreadMain(NULL); break;
- case 2: RawInputThreadMain(NULL); break;
+ case 0: RawInputThreadMain(); break;
default: ERR("Wrong type: %x\n", Type);
}
@@ -371,38 +318,43 @@
return 0;
}
+/*
+ * InitInputImpl
+ *
+ * Inits input implementation
+ */
INIT_FUNCTION
NTSTATUS
NTAPI
InitInputImpl(VOID)
{
- KeInitializeEvent(&InputThreadsStart, NotificationEvent, FALSE);
-
MasterTimer = ExAllocatePoolWithTag(NonPagedPool, sizeof(KTIMER), USERTAG_SYSTEM);
if (!MasterTimer)
{
- ERR("Win32K: Failed making Raw Input thread a win32 thread.\n");
+ ERR("Failed to allocate memory\n");
ASSERT(FALSE);
return STATUS_UNSUCCESSFUL;
}
KeInitializeTimer(MasterTimer);
/* Initialize the default keyboard layout */
- if(!UserInitDefaultKeyboardLayout())
+ if (!UserInitDefaultKeyboardLayout())
{
ERR("Failed to initialize default keyboard layout!\n");
}
- InputThreadsRunning = TRUE;
- KeSetEvent(&InputThreadsStart, IO_NO_INCREMENT, FALSE);
-
return STATUS_SUCCESS;
}
+/*
+ * CleanupInputImp
+ *
+ * Cleans input implementation
+ */
NTSTATUS FASTCALL
CleanupInputImp(VOID)
{
- return(STATUS_SUCCESS);
+ return STATUS_SUCCESS;
}
BOOL FASTCALL
@@ -517,6 +469,11 @@
return TRUE;
}
+/*
+ * NtUserSendInput
+ *
+ * Generates input events from software
+ */
UINT
APIENTRY
NtUserSendInput(