DWORD IntLastInputTick(BOOL LastInputTickSetGet)
{
- if (LastInputTickSetGet == TRUE)
- {
- LARGE_INTEGER TickCount;
- KeQueryTickCount(&TickCount);
- LastInputTick = MsqCalculateMessageTime(&TickCount);
- if (gpsi) gpsi->dwLastRITEventTickCount = LastInputTick;
- }
- return LastInputTick;
+ if (LastInputTickSetGet == TRUE)
+ {
+ LARGE_INTEGER TickCount;
+ KeQueryTickCount(&TickCount);
+ LastInputTick = MsqCalculateMessageTime(&TickCount);
+ if (gpsi) gpsi->dwLastRITEventTickCount = LastInputTick;
+ }
+ return LastInputTick;
}
VOID FASTCALL DoTheScreenSaver(VOID)
{
- LARGE_INTEGER TickCount;
- DWORD Test, TO;
-
- if (gspv.iScrSaverTimeout > 0) // Zero means Off.
- {
- KeQueryTickCount(&TickCount);
- Test = MsqCalculateMessageTime(&TickCount);
- Test = Test - LastInputTick;
- TO = 1000 * gspv.iScrSaverTimeout;
- if (Test > TO)
- {
- TRACE("Screensaver Message Start! Tick %d Timeout %d \n", Test, gspv.iScrSaverTimeout);
-
- if (ppiScrnSaver) // We are or we are not the screensaver, prevent reentry...
- {
- if (!(ppiScrnSaver->W32PF_flags & W32PF_IDLESCREENSAVER))
+ LARGE_INTEGER TickCount;
+ DWORD Test, TO;
+
+ if (gspv.iScrSaverTimeout > 0) // Zero means Off.
+ {
+ KeQueryTickCount(&TickCount);
+ Test = MsqCalculateMessageTime(&TickCount);
+ Test = Test - LastInputTick;
+ TO = 1000 * gspv.iScrSaverTimeout;
+ if (Test > TO)
+ {
+ TRACE("Screensaver Message Start! Tick %d Timeout %d \n", Test, gspv.iScrSaverTimeout);
+
+ if (ppiScrnSaver) // We are or we are not the screensaver, prevent reentry...
{
- ppiScrnSaver->W32PF_flags |= W32PF_IDLESCREENSAVER;
- ERR("Screensaver is Idle\n");
+ if (!(ppiScrnSaver->W32PF_flags & W32PF_IDLESCREENSAVER))
+ {
+ ppiScrnSaver->W32PF_flags |= W32PF_IDLESCREENSAVER;
+ ERR("Screensaver is Idle\n");
+ }
}
- }
- else
- {
- PUSER_MESSAGE_QUEUE ForegroundQueue = IntGetFocusMessageQueue();
- if (ForegroundQueue && ForegroundQueue->ActiveWindow)
- UserPostMessage(hwndSAS, WM_LOGONNOTIFY, LN_START_SCREENSAVE, 1); // lParam 1 == Secure
else
- UserPostMessage(hwndSAS, WM_LOGONNOTIFY, LN_START_SCREENSAVE, 0);
- }
- }
- }
+ {
+ PUSER_MESSAGE_QUEUE ForegroundQueue = IntGetFocusMessageQueue();
+ if (ForegroundQueue && ForegroundQueue->ActiveWindow)
+ UserPostMessage(hwndSAS, WM_LOGONNOTIFY, LN_START_SCREENSAVE, 1); // lParam 1 == Secure
+ else
+ UserPostMessage(hwndSAS, WM_LOGONNOTIFY, LN_START_SCREENSAVE, 0);
+ }
+ }
+ }
}
VOID FASTCALL
ProcessMouseInputData(PMOUSE_INPUT_DATA Data, ULONG InputCount)
{
- PMOUSE_INPUT_DATA mid;
- MOUSEINPUT mi;
- ULONG i;
-
- ClearMouseInput(mi);
- mi.time = 0;
- mi.dwExtraInfo = 0;
- for(i = 0; i < InputCount; i++)
- {
- mid = (Data + i);
- mi.dx += mid->LastX;
- mi.dy += mid->LastY;
-
- /* Check if the mouse move is absolute */
- if (mid->Flags == MOUSE_MOVE_ABSOLUTE)
- {
- /* Set flag to convert to screen location */
- mi.dwFlags |= MOUSEEVENTF_ABSOLUTE;
- }
-
- if(mid->ButtonFlags)
- {
- if(mid->ButtonFlags & MOUSE_LEFT_BUTTON_DOWN)
- {
- mi.dwFlags |= MOUSEEVENTF_LEFTDOWN;
- SendMouseEvent(mi);
- }
- if(mid->ButtonFlags & MOUSE_LEFT_BUTTON_UP)
- {
- mi.dwFlags |= MOUSEEVENTF_LEFTUP;
- SendMouseEvent(mi);
- }
- if(mid->ButtonFlags & MOUSE_MIDDLE_BUTTON_DOWN)
- {
- mi.dwFlags |= MOUSEEVENTF_MIDDLEDOWN;
- SendMouseEvent(mi);
- }
- if(mid->ButtonFlags & MOUSE_MIDDLE_BUTTON_UP)
- {
- mi.dwFlags |= MOUSEEVENTF_MIDDLEUP;
- SendMouseEvent(mi);
- }
- if(mid->ButtonFlags & MOUSE_RIGHT_BUTTON_DOWN)
- {
- mi.dwFlags |= MOUSEEVENTF_RIGHTDOWN;
- SendMouseEvent(mi);
- }
- if(mid->ButtonFlags & MOUSE_RIGHT_BUTTON_UP)
- {
- mi.dwFlags |= MOUSEEVENTF_RIGHTUP;
- SendMouseEvent(mi);
- }
- if(mid->ButtonFlags & MOUSE_BUTTON_4_DOWN)
- {
- mi.mouseData |= XBUTTON1;
- mi.dwFlags |= MOUSEEVENTF_XDOWN;
- SendMouseEvent(mi);
- }
- if(mid->ButtonFlags & MOUSE_BUTTON_4_UP)
- {
- mi.mouseData |= XBUTTON1;
- mi.dwFlags |= MOUSEEVENTF_XUP;
- SendMouseEvent(mi);
- }
- if(mid->ButtonFlags & MOUSE_BUTTON_5_DOWN)
- {
- mi.mouseData |= XBUTTON2;
- mi.dwFlags |= MOUSEEVENTF_XDOWN;
- SendMouseEvent(mi);
- }
- if(mid->ButtonFlags & MOUSE_BUTTON_5_UP)
- {
- mi.mouseData |= XBUTTON2;
- mi.dwFlags |= MOUSEEVENTF_XUP;
- SendMouseEvent(mi);
- }
- if(mid->ButtonFlags & MOUSE_WHEEL)
- {
- mi.mouseData = mid->ButtonData;
- mi.dwFlags |= MOUSEEVENTF_WHEEL;
- SendMouseEvent(mi);
- }
- }
- }
-
- SendMouseEvent(mi);
+ PMOUSE_INPUT_DATA mid;
+ MOUSEINPUT mi;
+ ULONG i;
+
+ ClearMouseInput(mi);
+ mi.time = 0;
+ mi.dwExtraInfo = 0;
+ for(i = 0; i < InputCount; i++)
+ {
+ mid = (Data + i);
+ mi.dx += mid->LastX;
+ mi.dy += mid->LastY;
+
+ /* Check if the mouse move is absolute */
+ if (mid->Flags == MOUSE_MOVE_ABSOLUTE)
+ {
+ /* Set flag to convert to screen location */
+ mi.dwFlags |= MOUSEEVENTF_ABSOLUTE;
+ }
+
+ if(mid->ButtonFlags)
+ {
+ if(mid->ButtonFlags & MOUSE_LEFT_BUTTON_DOWN)
+ {
+ mi.dwFlags |= MOUSEEVENTF_LEFTDOWN;
+ SendMouseEvent(mi);
+ }
+ if(mid->ButtonFlags & MOUSE_LEFT_BUTTON_UP)
+ {
+ mi.dwFlags |= MOUSEEVENTF_LEFTUP;
+ SendMouseEvent(mi);
+ }
+ if(mid->ButtonFlags & MOUSE_MIDDLE_BUTTON_DOWN)
+ {
+ mi.dwFlags |= MOUSEEVENTF_MIDDLEDOWN;
+ SendMouseEvent(mi);
+ }
+ if(mid->ButtonFlags & MOUSE_MIDDLE_BUTTON_UP)
+ {
+ mi.dwFlags |= MOUSEEVENTF_MIDDLEUP;
+ SendMouseEvent(mi);
+ }
+ if(mid->ButtonFlags & MOUSE_RIGHT_BUTTON_DOWN)
+ {
+ mi.dwFlags |= MOUSEEVENTF_RIGHTDOWN;
+ SendMouseEvent(mi);
+ }
+ if(mid->ButtonFlags & MOUSE_RIGHT_BUTTON_UP)
+ {
+ mi.dwFlags |= MOUSEEVENTF_RIGHTUP;
+ SendMouseEvent(mi);
+ }
+ if(mid->ButtonFlags & MOUSE_BUTTON_4_DOWN)
+ {
+ mi.mouseData |= XBUTTON1;
+ mi.dwFlags |= MOUSEEVENTF_XDOWN;
+ SendMouseEvent(mi);
+ }
+ if(mid->ButtonFlags & MOUSE_BUTTON_4_UP)
+ {
+ mi.mouseData |= XBUTTON1;
+ mi.dwFlags |= MOUSEEVENTF_XUP;
+ SendMouseEvent(mi);
+ }
+ if(mid->ButtonFlags & MOUSE_BUTTON_5_DOWN)
+ {
+ mi.mouseData |= XBUTTON2;
+ mi.dwFlags |= MOUSEEVENTF_XDOWN;
+ SendMouseEvent(mi);
+ }
+ if(mid->ButtonFlags & MOUSE_BUTTON_5_UP)
+ {
+ mi.mouseData |= XBUTTON2;
+ mi.dwFlags |= MOUSEEVENTF_XUP;
+ SendMouseEvent(mi);
+ }
+ if(mid->ButtonFlags & MOUSE_WHEEL)
+ {
+ mi.mouseData = mid->ButtonData;
+ mi.dwFlags |= MOUSEEVENTF_WHEEL;
+ SendMouseEvent(mi);
+ }
+ }
+ }
+
+ SendMouseEvent(mi);
}
VOID APIENTRY
MouseThreadMain(PVOID StartContext)
{
- UNICODE_STRING MouseDeviceName = RTL_CONSTANT_STRING(L"\\Device\\PointerClass0");
- OBJECT_ATTRIBUTES MouseObjectAttributes;
- IO_STATUS_BLOCK Iosb;
- NTSTATUS Status;
- MOUSE_ATTRIBUTES MouseAttr;
-
- KeSetPriorityThread(&PsGetCurrentThread()->Tcb,
- LOW_REALTIME_PRIORITY + 3);
-
- InitializeObjectAttributes(&MouseObjectAttributes,
- &MouseDeviceName,
- 0,
- NULL,
- NULL);
- do
- {
- LARGE_INTEGER DueTime;
- KEVENT Event;
- DueTime.QuadPart = (LONGLONG)(-10000000);
- KeInitializeEvent(&Event, NotificationEvent, FALSE);
- Status = KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, &DueTime);
- Status = NtOpenFile(&MouseDeviceHandle,
- FILE_ALL_ACCESS,
- &MouseObjectAttributes,
- &Iosb,
- 0,
- FILE_SYNCHRONOUS_IO_ALERT);
- } while (!NT_SUCCESS(Status));
-
- /* Need to setup basic win32k for this thread to process WH_MOUSE_LL messages. */
- Status = Win32kInitWin32Thread(PsGetCurrentThread());
- if (!NT_SUCCESS(Status))
- {
- ERR("Win32K: Failed making mouse thread a win32 thread.\n");
- return; //(Status);
- }
-
- ptiMouse = PsGetCurrentThreadWin32Thread();
- ptiMouse->TIF_flags |= TIF_SYSTEMTHREAD;
- TRACE("Mouse Thread 0x%x \n", ptiMouse);
-
- KeSetPriorityThread(&PsGetCurrentThread()->Tcb,
- LOW_REALTIME_PRIORITY + 3);
-
- 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 = NtDeviceIoControlFile(MouseDeviceHandle,
- 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 = NtReadFile(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);
- }
- TRACE("MouseEvent\n");
- IntLastInputTick(TRUE);
-
- UserEnterExclusive();
-
- ProcessMouseInputData(&MouseInput, Iosb.Information / sizeof(MOUSE_INPUT_DATA));
-
- UserLeave();
- }
- TRACE("Mouse Input Thread Stopped...\n");
- }
+ UNICODE_STRING MouseDeviceName = RTL_CONSTANT_STRING(L"\\Device\\PointerClass0");
+ OBJECT_ATTRIBUTES MouseObjectAttributes;
+ IO_STATUS_BLOCK Iosb;
+ NTSTATUS Status;
+ MOUSE_ATTRIBUTES MouseAttr;
+
+ KeSetPriorityThread(&PsGetCurrentThread()->Tcb,
+ LOW_REALTIME_PRIORITY + 3);
+
+ InitializeObjectAttributes(&MouseObjectAttributes,
+ &MouseDeviceName,
+ 0,
+ NULL,
+ NULL);
+ do
+ {
+ LARGE_INTEGER DueTime;
+ KEVENT Event;
+ DueTime.QuadPart = (LONGLONG)(-10000000);
+ KeInitializeEvent(&Event, NotificationEvent, FALSE);
+ Status = KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, &DueTime);
+ Status = NtOpenFile(&MouseDeviceHandle,
+ FILE_ALL_ACCESS,
+ &MouseObjectAttributes,
+ &Iosb,
+ 0,
+ FILE_SYNCHRONOUS_IO_ALERT);
+ } while (!NT_SUCCESS(Status));
+
+ /* Need to setup basic win32k for this thread to process WH_MOUSE_LL messages. */
+ Status = Win32kInitWin32Thread(PsGetCurrentThread());
+ if (!NT_SUCCESS(Status))
+ {
+ ERR("Win32K: Failed making mouse thread a win32 thread.\n");
+ return; //(Status);
+ }
+
+ ptiMouse = PsGetCurrentThreadWin32Thread();
+ ptiMouse->TIF_flags |= TIF_SYSTEMTHREAD;
+ TRACE("Mouse Thread 0x%x \n", ptiMouse);
+
+ KeSetPriorityThread(&PsGetCurrentThread()->Tcb,
+ LOW_REALTIME_PRIORITY + 3);
+
+ 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 = NtDeviceIoControlFile(MouseDeviceHandle,
+ 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 = NtReadFile(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);
+ }
+ TRACE("MouseEvent\n");
+ IntLastInputTick(TRUE);
+
+ UserEnterExclusive();
+
+ ProcessMouseInputData(&MouseInput, Iosb.Information / sizeof(MOUSE_INPUT_DATA));
+
+ UserLeave();
+ }
+ TRACE("Mouse Input Thread Stopped...\n");
+ }
}
/* Returns a value that indicates if the key is a modifier key, and
static UINT APIENTRY
IntKeyboardGetModifiers(KEYBOARD_INPUT_DATA *InputData)
{
- if (InputData->Flags & KEY_E1)
- return 0;
-
- if (!(InputData->Flags & KEY_E0))
- {
- switch (InputData->MakeCode)
- {
- case 0x2a: /* left shift */
- case 0x36: /* right shift */
- return MOD_SHIFT;
-
- case 0x1d: /* left control */
- return MOD_CONTROL;
-
- case 0x38: /* left alt */
- return MOD_ALT;
-
- default:
- return 0;
- }
- }
- else
- {
- switch (InputData->MakeCode)
- {
- case 0x1d: /* right control */
- return MOD_CONTROL;
-
- case 0x38: /* right alt */
- return MOD_ALT;
-
- case 0x5b: /* left gui (windows) */
- case 0x5c: /* right gui (windows) */
- return MOD_WIN;
-
- default:
- return 0;
- }
- }
+ if (InputData->Flags & KEY_E1)
+ return 0;
+
+ if (!(InputData->Flags & KEY_E0))
+ {
+ switch (InputData->MakeCode)
+ {
+ case 0x2a: /* left shift */
+ case 0x36: /* right shift */
+ return MOD_SHIFT;
+
+ case 0x1d: /* left control */
+ return MOD_CONTROL;
+
+ case 0x38: /* left alt */
+ return MOD_ALT;
+
+ default:
+ return 0;
+ }
+ }
+ else
+ {
+ switch (InputData->MakeCode)
+ {
+ case 0x1d: /* right control */
+ return MOD_CONTROL;
+
+ case 0x38: /* right alt */
+ return MOD_ALT;
+
+ case 0x5b: /* left gui (windows) */
+ case 0x5c: /* right gui (windows) */
+ return MOD_WIN;
+
+ default:
+ return 0;
+ }
+ }
}
/* Asks the keyboard driver to send a small table that shows which
IntKeyboardGetIndicatorTrans(HANDLE KeyboardDeviceHandle,
PKEYBOARD_INDICATOR_TRANSLATION *IndicatorTrans)
{
- NTSTATUS Status;
- DWORD Size = 0;
- IO_STATUS_BLOCK Block;
- PKEYBOARD_INDICATOR_TRANSLATION Ret;
-
- Size = sizeof(KEYBOARD_INDICATOR_TRANSLATION);
-
- Ret = ExAllocatePoolWithTag(PagedPool,
- Size,
- USERTAG_KBDTABLE);
-
- while (Ret)
- {
- Status = NtDeviceIoControlFile(KeyboardDeviceHandle,
- NULL,
- NULL,
- NULL,
- &Block,
- IOCTL_KEYBOARD_QUERY_INDICATOR_TRANSLATION,
- NULL, 0,
- Ret, Size);
-
- if (Status != STATUS_BUFFER_TOO_SMALL)
- break;
-
- ExFreePoolWithTag(Ret, USERTAG_KBDTABLE);
-
- Size += sizeof(KEYBOARD_INDICATOR_TRANSLATION);
-
- Ret = ExAllocatePoolWithTag(PagedPool,
- Size,
- USERTAG_KBDTABLE);
- }
-
- if (!Ret)
- return STATUS_INSUFFICIENT_RESOURCES;
-
- if (Status != STATUS_SUCCESS)
- {
- ExFreePoolWithTag(Ret, USERTAG_KBDTABLE);
- return Status;
- }
-
- *IndicatorTrans = Ret;
- return Status;
+ NTSTATUS Status;
+ DWORD Size = 0;
+ IO_STATUS_BLOCK Block;
+ PKEYBOARD_INDICATOR_TRANSLATION Ret;
+
+ Size = sizeof(KEYBOARD_INDICATOR_TRANSLATION);
+
+ Ret = ExAllocatePoolWithTag(PagedPool,
+ Size,
+ USERTAG_KBDTABLE);
+
+ while (Ret)
+ {
+ Status = NtDeviceIoControlFile(KeyboardDeviceHandle,
+ NULL,
+ NULL,
+ NULL,
+ &Block,
+ IOCTL_KEYBOARD_QUERY_INDICATOR_TRANSLATION,
+ NULL, 0,
+ Ret, Size);
+
+ if (Status != STATUS_BUFFER_TOO_SMALL)
+ break;
+
+ ExFreePoolWithTag(Ret, USERTAG_KBDTABLE);
+
+ Size += sizeof(KEYBOARD_INDICATOR_TRANSLATION);
+
+ Ret = ExAllocatePoolWithTag(PagedPool,
+ Size,
+ USERTAG_KBDTABLE);
+ }
+
+ if (!Ret)
+ return STATUS_INSUFFICIENT_RESOURCES;
+
+ if (Status != STATUS_SUCCESS)
+ {
+ ExFreePoolWithTag(Ret, USERTAG_KBDTABLE);
+ return Status;
+ }
+
+ *IndicatorTrans = Ret;
+ return Status;
}
/* Sends the keyboard commands to turn on/off the lights.
PKEYBOARD_INPUT_DATA KeyInput,
PKEYBOARD_INDICATOR_TRANSLATION IndicatorTrans)
{
- NTSTATUS Status;
- UINT Count;
- static KEYBOARD_INDICATOR_PARAMETERS Indicators;
- IO_STATUS_BLOCK Block;
-
- if (!IndicatorTrans)
- return STATUS_NOT_SUPPORTED;
-
- if (KeyInput->Flags & (KEY_E0 | KEY_E1 | KEY_BREAK))
- return STATUS_SUCCESS;
-
- for (Count = 0; Count < IndicatorTrans->NumberOfIndicatorKeys; Count++)
- {
- if (KeyInput->MakeCode == IndicatorTrans->IndicatorList[Count].MakeCode)
- {
- Indicators.LedFlags ^=
- IndicatorTrans->IndicatorList[Count].IndicatorFlags;
-
- /* Update the lights on the hardware */
-
- Status = NtDeviceIoControlFile(KeyboardDeviceHandle,
- NULL,
- NULL,
- NULL,
- &Block,
- IOCTL_KEYBOARD_SET_INDICATORS,
- &Indicators, sizeof(Indicators),
- NULL, 0);
-
- return Status;
- }
- }
-
- return STATUS_SUCCESS;
+ NTSTATUS Status;
+ UINT Count;
+ static KEYBOARD_INDICATOR_PARAMETERS Indicators;
+ IO_STATUS_BLOCK Block;
+
+ if (!IndicatorTrans)
+ return STATUS_NOT_SUPPORTED;
+
+ if (KeyInput->Flags & (KEY_E0 | KEY_E1 | KEY_BREAK))
+ return STATUS_SUCCESS;
+
+ for (Count = 0; Count < IndicatorTrans->NumberOfIndicatorKeys; Count++)
+ {
+ if (KeyInput->MakeCode == IndicatorTrans->IndicatorList[Count].MakeCode)
+ {
+ Indicators.LedFlags ^=
+ IndicatorTrans->IndicatorList[Count].IndicatorFlags;
+
+ /* Update the lights on the hardware */
+
+ Status = NtDeviceIoControlFile(KeyboardDeviceHandle,
+ NULL,
+ NULL,
+ NULL,
+ &Block,
+ IOCTL_KEYBOARD_SET_INDICATORS,
+ &Indicators, sizeof(Indicators),
+ NULL, 0);
+
+ return Status;
+ }
+ }
+
+ return STATUS_SUCCESS;
}
static VOID APIENTRY
IntKeyboardSendWinKeyMsg()
{
- PWND Window;
- MSG Mesg;
-
- if (!(Window = UserGetWindowObject(InputWindowStation->ShellWindow)))
- {
- ERR("Couldn't find window to send Windows key message!\n");
- return;
- }
-
- Mesg.hwnd = InputWindowStation->ShellWindow;
- Mesg.message = WM_SYSCOMMAND;
- Mesg.wParam = SC_TASKLIST;
- Mesg.lParam = 0;
-
- /* The QS_HOTKEY is just a guess */
- MsqPostMessage(Window->head.pti->MessageQueue, &Mesg, FALSE, QS_HOTKEY);
+ PWND Window;
+ MSG Mesg;
+
+ if (!(Window = UserGetWindowObject(InputWindowStation->ShellWindow)))
+ {
+ ERR("Couldn't find window to send Windows key message!\n");
+ return;
+ }
+
+ Mesg.hwnd = InputWindowStation->ShellWindow;
+ Mesg.message = WM_SYSCOMMAND;
+ Mesg.wParam = SC_TASKLIST;
+ Mesg.lParam = 0;
+
+ /* The QS_HOTKEY is just a guess */
+ MsqPostMessage(Window->head.pti->MessageQueue, &Mesg, FALSE, QS_HOTKEY);
}
static VOID APIENTRY
co_IntKeyboardSendAltKeyMsg()
{
- ERR("co_IntKeyboardSendAltKeyMsg\n");
+ ERR("co_IntKeyboardSendAltKeyMsg\n");
// co_MsqPostKeyboardMessage(WM_SYSCOMMAND,SC_KEYMENU,0); // This sends everything into a msg loop!
}
static VOID APIENTRY
KeyboardThreadMain(PVOID StartContext)
{
- UNICODE_STRING KeyboardDeviceName = RTL_CONSTANT_STRING(L"\\Device\\KeyboardClass0");
- OBJECT_ATTRIBUTES KeyboardObjectAttributes;
- IO_STATUS_BLOCK Iosb;
- NTSTATUS Status;
- MSG msg;
- PUSER_MESSAGE_QUEUE FocusQueue;
- struct _ETHREAD *FocusThread;
-
- PKEYBOARD_INDICATOR_TRANSLATION IndicatorTrans = NULL;
- UINT ModifierState = 0;
- USHORT LastMakeCode = 0;
- USHORT LastFlags = 0;
- UINT RepeatCount = 0;
-
- InitializeObjectAttributes(&KeyboardObjectAttributes,
- &KeyboardDeviceName,
- 0,
- NULL,
- NULL);
- do
- {
- LARGE_INTEGER DueTime;
- KEVENT Event;
- DueTime.QuadPart = (LONGLONG)(-10000000);
- KeInitializeEvent(&Event, NotificationEvent, FALSE);
- Status = KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, &DueTime);
- Status = NtOpenFile(&KeyboardDeviceHandle,
- FILE_ALL_ACCESS,
- &KeyboardObjectAttributes,
- &Iosb,
- 0,
- FILE_SYNCHRONOUS_IO_ALERT);
- } while (!NT_SUCCESS(Status));
-
- /* Not sure if converting this thread to a win32 thread is such
- a great idea. Since we're posting keyboard messages to the focus
- window message queue, we'll be (indirectly) doing sendmessage
- stuff from this thread (for WH_KEYBOARD_LL processing), which
- means we need our own message queue. If keyboard messages were
- instead queued to the system message queue, the thread removing
- the message from the system message queue would be responsible
- for WH_KEYBOARD_LL processing and we wouldn't need this thread
- to be a win32 thread. */
- Status = Win32kInitWin32Thread(PsGetCurrentThread());
- if (!NT_SUCCESS(Status))
- {
- ERR("Win32K: Failed making keyboard thread a win32 thread.\n");
- return; //(Status);
- }
-
- ptiKeyboard = PsGetCurrentThreadWin32Thread();
- ptiKeyboard->TIF_flags |= TIF_SYSTEMTHREAD;
- TRACE("Keyboard Thread 0x%x \n", ptiKeyboard);
-
- KeSetPriorityThread(&PsGetCurrentThread()->Tcb,
- LOW_REALTIME_PRIORITY + 3);
-
- IntKeyboardGetIndicatorTrans(KeyboardDeviceHandle,
- &IndicatorTrans);
-
- 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)
- {
- BOOLEAN NumKeys = 1;
- BOOLEAN bLeftAlt;
- KEYBOARD_INPUT_DATA KeyInput;
- KEYBOARD_INPUT_DATA NextKeyInput;
- LPARAM lParam = 0;
- UINT fsModifiers, fsNextModifiers;
- struct _ETHREAD *Thread;
- HWND hWnd;
- int id;
-
- TRACE("KeyInput @ %08x\n", &KeyInput);
-
- Status = NtReadFile (KeyboardDeviceHandle,
- NULL,
- NULL,
- NULL,
- &Iosb,
- &KeyInput,
- sizeof(KEYBOARD_INPUT_DATA),
- NULL,
- NULL);
-
- if(Status == STATUS_ALERTED && !InputThreadsRunning)
- {
- break;
- }
- if(Status == STATUS_PENDING)
- {
- NtWaitForSingleObject(KeyboardDeviceHandle, FALSE, NULL);
- Status = Iosb.Status;
- }
- if(!NT_SUCCESS(Status))
- {
- ERR("Win32K: Failed to read from keyboard.\n");
- return; //(Status);
- }
-
- TRACE("KeyRaw: %s %04x\n",
- (KeyInput.Flags & KEY_BREAK) ? "up" : "down",
- KeyInput.MakeCode );
-
- if (Status == STATUS_ALERTED && !InputThreadsRunning)
- break;
+ UNICODE_STRING KeyboardDeviceName = RTL_CONSTANT_STRING(L"\\Device\\KeyboardClass0");
+ OBJECT_ATTRIBUTES KeyboardObjectAttributes;
+ IO_STATUS_BLOCK Iosb;
+ NTSTATUS Status;
+ MSG msg;
+ PUSER_MESSAGE_QUEUE FocusQueue;
+ struct _ETHREAD *FocusThread;
+
+ PKEYBOARD_INDICATOR_TRANSLATION IndicatorTrans = NULL;
+ UINT ModifierState = 0;
+ USHORT LastMakeCode = 0;
+ USHORT LastFlags = 0;
+ UINT RepeatCount = 0;
+
+ InitializeObjectAttributes(&KeyboardObjectAttributes,
+ &KeyboardDeviceName,
+ 0,
+ NULL,
+ NULL);
+ do
+ {
+ LARGE_INTEGER DueTime;
+ KEVENT Event;
+ DueTime.QuadPart = (LONGLONG)(-10000000);
+ KeInitializeEvent(&Event, NotificationEvent, FALSE);
+ Status = KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, &DueTime);
+ Status = NtOpenFile(&KeyboardDeviceHandle,
+ FILE_ALL_ACCESS,
+ &KeyboardObjectAttributes,
+ &Iosb,
+ 0,
+ FILE_SYNCHRONOUS_IO_ALERT);
+ } while (!NT_SUCCESS(Status));
+
+ /* Not sure if converting this thread to a win32 thread is such
+ a great idea. Since we're posting keyboard messages to the focus
+ window message queue, we'll be (indirectly) doing sendmessage
+ stuff from this thread (for WH_KEYBOARD_LL processing), which
+ means we need our own message queue. If keyboard messages were
+ instead queued to the system message queue, the thread removing
+ the message from the system message queue would be responsible
+ for WH_KEYBOARD_LL processing and we wouldn't need this thread
+ to be a win32 thread. */
+ Status = Win32kInitWin32Thread(PsGetCurrentThread());
+ if (!NT_SUCCESS(Status))
+ {
+ ERR("Win32K: Failed making keyboard thread a win32 thread.\n");
+ return; //(Status);
+ }
+
+ ptiKeyboard = PsGetCurrentThreadWin32Thread();
+ ptiKeyboard->TIF_flags |= TIF_SYSTEMTHREAD;
+ TRACE("Keyboard Thread 0x%x \n", ptiKeyboard);
+
+ KeSetPriorityThread(&PsGetCurrentThread()->Tcb,
+ LOW_REALTIME_PRIORITY + 3);
+
+ IntKeyboardGetIndicatorTrans(KeyboardDeviceHandle,
+ &IndicatorTrans);
+
+ 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)
+ {
+ BOOLEAN NumKeys = 1;
+ BOOLEAN bLeftAlt;
+ KEYBOARD_INPUT_DATA KeyInput;
+ KEYBOARD_INPUT_DATA NextKeyInput;
+ LPARAM lParam = 0;
+ UINT fsModifiers, fsNextModifiers;
+ struct _ETHREAD *Thread;
+ HWND hWnd;
+ int id;
+
+ TRACE("KeyInput @ %08x\n", &KeyInput);
+
+ Status = NtReadFile (KeyboardDeviceHandle,
+ NULL,
+ NULL,
+ NULL,
+ &Iosb,
+ &KeyInput,
+ sizeof(KEYBOARD_INPUT_DATA),
+ NULL,
+ NULL);
- if (!NT_SUCCESS(Status))
- {
- ERR("Win32K: Failed to read from keyboard.\n");
- return; //(Status);
- }
+ if(Status == STATUS_ALERTED && !InputThreadsRunning)
+ {
+ break;
+ }
+ if(Status == STATUS_PENDING)
+ {
+ NtWaitForSingleObject(KeyboardDeviceHandle, FALSE, NULL);
+ Status = Iosb.Status;
+ }
+ if(!NT_SUCCESS(Status))
+ {
+ ERR("Win32K: Failed to read from keyboard.\n");
+ return; //(Status);
+ }
- /* Set LastInputTick */
- IntLastInputTick(TRUE);
+ TRACE("KeyRaw: %s %04x\n",
+ (KeyInput.Flags & KEY_BREAK) ? "up" : "down",
+ KeyInput.MakeCode );
- /* Update modifier state */
- fsModifiers = IntKeyboardGetModifiers(&KeyInput);
+ if (Status == STATUS_ALERTED && !InputThreadsRunning)
+ break;
- if (fsModifiers)
- {
- if (KeyInput.Flags & KEY_BREAK)
+ if (!NT_SUCCESS(Status))
{
- ModifierState &= ~fsModifiers;
- if(fsModifiers == MOD_ALT)
- {
- if(KeyInput.Flags & KEY_E0)
- {
- gKeyStateTable[VK_RMENU] = 0;
- }
- else
- {
- gKeyStateTable[VK_LMENU] = 0;
- }
- if (gKeyStateTable[VK_RMENU] == 0 &&
- gKeyStateTable[VK_LMENU] == 0)
- {
- gKeyStateTable[VK_MENU] = 0;
- }
- }
+ ERR("Win32K: Failed to read from keyboard.\n");
+ return; //(Status);
}
- else
+
+ /* Set LastInputTick */
+ IntLastInputTick(TRUE);
+
+ /* Update modifier state */
+ fsModifiers = IntKeyboardGetModifiers(&KeyInput);
+
+ if (fsModifiers)
{
- ModifierState |= fsModifiers;
-
- if (ModifierState == fsModifiers &&
- (fsModifiers == MOD_ALT || fsModifiers == MOD_WIN))
- {
- /* First send out special notifications
- * (For alt, the message that turns on accelerator
- * display, not sure what for win. Both TODO though.)
- */
- bLeftAlt = FALSE;
- if(fsModifiers == MOD_ALT)
- {
- if(KeyInput.Flags & KEY_E0)
- {
- gKeyStateTable[VK_RMENU] = KS_DOWN_BIT;
- }
- else
- {
- gKeyStateTable[VK_LMENU] = KS_DOWN_BIT;
- bLeftAlt = TRUE;
- }
-
- gKeyStateTable[VK_MENU] = KS_DOWN_BIT;
- }
-
- /* Read the next key before sending this one */
- do
- {
- Status = NtReadFile (KeyboardDeviceHandle,
- NULL,
- NULL,
- NULL,
- &Iosb,
- &NextKeyInput,
- sizeof(KEYBOARD_INPUT_DATA),
- NULL,
- NULL);
- TRACE("KeyRaw: %s %04x\n",
- (NextKeyInput.Flags & KEY_BREAK) ? "up":"down",
- NextKeyInput.MakeCode );
-
- if (Status == STATUS_ALERTED && !InputThreadsRunning)
- goto KeyboardEscape;
-
- }
- while ((!(NextKeyInput.Flags & KEY_BREAK)) &&
- NextKeyInput.MakeCode == KeyInput.MakeCode);
- /* ^ Ignore repeats, they'll be KEY_MAKE and the same
- * code. I'm not caring about the counting, not sure
- * if that matters. I think not.
- */
-
- /* If the ModifierState is now empty again, send a
- * special notification and eat both keypresses
- */
-
- fsNextModifiers = IntKeyboardGetModifiers(&NextKeyInput);
-
- if (fsNextModifiers)
- ModifierState ^= fsNextModifiers;
-
- if (ModifierState == 0)
- {
- UserEnterExclusive();
- if (fsModifiers == MOD_WIN)
- IntKeyboardSendWinKeyMsg();
- else if (fsModifiers == MOD_ALT)
- {
- gKeyStateTable[VK_MENU] = 0;
- if(bLeftAlt)
+ if (KeyInput.Flags & KEY_BREAK)
+ {
+ ModifierState &= ~fsModifiers;
+ if(fsModifiers == MOD_ALT)
+ {
+ if(KeyInput.Flags & KEY_E0)
{
- gKeyStateTable[VK_LMENU] = 0;
+ gKeyStateTable[VK_RMENU] = 0;
}
else
{
- gKeyStateTable[VK_RMENU] = 0;
+ gKeyStateTable[VK_LMENU] = 0;
+ }
+ if (gKeyStateTable[VK_RMENU] == 0 &&
+ gKeyStateTable[VK_LMENU] == 0)
+ {
+ gKeyStateTable[VK_MENU] = 0;
+ }
+ }
+ }
+ else
+ {
+ ModifierState |= fsModifiers;
+
+ if (ModifierState == fsModifiers &&
+ (fsModifiers == MOD_ALT || fsModifiers == MOD_WIN))
+ {
+ /* First send out special notifications
+ * (For alt, the message that turns on accelerator
+ * display, not sure what for win. Both TODO though.)
+ */
+ bLeftAlt = FALSE;
+ if(fsModifiers == MOD_ALT)
+ {
+ if(KeyInput.Flags & KEY_E0)
+ {
+ gKeyStateTable[VK_RMENU] = KS_DOWN_BIT;
+ }
+ else
+ {
+ gKeyStateTable[VK_LMENU] = KS_DOWN_BIT;
+ bLeftAlt = TRUE;
+ }
+
+ gKeyStateTable[VK_MENU] = KS_DOWN_BIT;
}
- co_IntKeyboardSendAltKeyMsg();
- }
- UserLeave();
- continue;
- }
-
- NumKeys = 2;
- }
- }
- }
-
- UserEnterExclusive();
-
- for (;NumKeys;memcpy(&KeyInput, &NextKeyInput, sizeof(KeyInput)),
- NumKeys--)
- {
- PKBL keyboardLayout = NULL;
- lParam = 0;
-
- IntKeyboardUpdateLeds(KeyboardDeviceHandle,
- &KeyInput,
- IndicatorTrans);
-
- /* While we are working, we set up lParam. The format is:
- * 0-15: The number of times this key has autorepeated
- * 16-23: The keyboard scancode
- * 24: Set if it's and extended key (I assume KEY_E0 | KEY_E1)
- * Note that E1 is only used for PAUSE (E1-1D-45) and
- * E0-45 happens not to be anything.
- * 29: Alt is pressed ('Context code')
- * 30: Previous state, if the key was down before this message
- * This is a cheap way to ignore autorepeat keys
- * 31: 1 if the key is being pressed
- */
-
- /* If it's a KEY_MAKE (which is 0, so test using !KEY_BREAK)
- * and it's the same key as the last one, increase the repeat
- * count.
- */
-
- if (!(KeyInput.Flags & KEY_BREAK))
- {
- if (((KeyInput.Flags & (KEY_E0 | KEY_E1)) == LastFlags) &&
- (KeyInput.MakeCode == LastMakeCode))
- {
- RepeatCount++;
- lParam |= (KF_REPEAT << 16);
- }
- else
- {
- RepeatCount = 1;
- LastFlags = KeyInput.Flags & (KEY_E0 | KEY_E1);
- LastMakeCode = KeyInput.MakeCode;
- }
- }
- else
- {
- LastFlags = 0;
- LastMakeCode = 0; /* Should never match */
- lParam |= (KF_UP << 16) | (KF_REPEAT << 16);
- }
- lParam |= RepeatCount;
+ /* Read the next key before sending this one */
+ do
+ {
+ Status = NtReadFile (KeyboardDeviceHandle,
+ NULL,
+ NULL,
+ NULL,
+ &Iosb,
+ &NextKeyInput,
+ sizeof(KEYBOARD_INPUT_DATA),
+ NULL,
+ NULL);
+ TRACE("KeyRaw: %s %04x\n",
+ (NextKeyInput.Flags & KEY_BREAK) ? "up" : "down",
+ NextKeyInput.MakeCode );
+
+ if (Status == STATUS_ALERTED && !InputThreadsRunning)
+ goto KeyboardEscape;
- lParam |= (KeyInput.MakeCode & 0xff) << 16;
+ }
+ while ((!(NextKeyInput.Flags & KEY_BREAK)) &&
+ NextKeyInput.MakeCode == KeyInput.MakeCode);
+ /* ^ Ignore repeats, they'll be KEY_MAKE and the same
+ * code. I'm not caring about the counting, not sure
+ * if that matters. I think not.
+ */
- if (KeyInput.Flags & KEY_E0)
- lParam |= (KF_EXTENDED << 16);
+ /* If the ModifierState is now empty again, send a
+ * special notification and eat both keypresses
+ */
- if (ModifierState & MOD_ALT)
- {
- lParam |= (KF_ALTDOWN << 16);
+ fsNextModifiers = IntKeyboardGetModifiers(&NextKeyInput);
- if (!(KeyInput.Flags & KEY_BREAK))
- msg.message = WM_SYSKEYDOWN;
- else
- msg.message = WM_SYSKEYUP;
- }
- else
- {
- if (!(KeyInput.Flags & KEY_BREAK))
- msg.message = WM_KEYDOWN;
- else
- msg.message = WM_KEYUP;
+ if (fsNextModifiers)
+ ModifierState ^= fsNextModifiers;
+
+ if (ModifierState == 0)
+ {
+ UserEnterExclusive();
+ if (fsModifiers == MOD_WIN)
+ IntKeyboardSendWinKeyMsg();
+ else if (fsModifiers == MOD_ALT)
+ {
+ gKeyStateTable[VK_MENU] = 0;
+ if(bLeftAlt)
+ {
+ gKeyStateTable[VK_LMENU] = 0;
+ }
+ else
+ {
+ gKeyStateTable[VK_RMENU] = 0;
+ }
+ co_IntKeyboardSendAltKeyMsg();
+ }
+ UserLeave();
+ continue;
+ }
+
+ NumKeys = 2;
+ }
+ }
}
- /* Find the target thread whose locale is in effect */
- FocusQueue = IntGetFocusMessageQueue();
+ UserEnterExclusive();
- if (FocusQueue)
+ for (; NumKeys; memcpy(&KeyInput, &NextKeyInput, sizeof(KeyInput)),
+ NumKeys--)
{
- msg.hwnd = FocusQueue->FocusWindow;
+ PKBL keyboardLayout = NULL;
+ lParam = 0;
+
+ IntKeyboardUpdateLeds(KeyboardDeviceHandle,
+ &KeyInput,
+ IndicatorTrans);
+
+ /* While we are working, we set up lParam. The format is:
+ * 0-15: The number of times this key has autorepeated
+ * 16-23: The keyboard scancode
+ * 24: Set if it's and extended key (I assume KEY_E0 | KEY_E1)
+ * Note that E1 is only used for PAUSE (E1-1D-45) and
+ * E0-45 happens not to be anything.
+ * 29: Alt is pressed ('Context code')
+ * 30: Previous state, if the key was down before this message
+ * This is a cheap way to ignore autorepeat keys
+ * 31: 1 if the key is being pressed
+ */
+
+ /* If it's a KEY_MAKE (which is 0, so test using !KEY_BREAK)
+ * and it's the same key as the last one, increase the repeat
+ * count.
+ */
+
+ if (!(KeyInput.Flags & KEY_BREAK))
+ {
+ if (((KeyInput.Flags & (KEY_E0 | KEY_E1)) == LastFlags) &&
+ (KeyInput.MakeCode == LastMakeCode))
+ {
+ RepeatCount++;
+ lParam |= (KF_REPEAT << 16);
+ }
+ else
+ {
+ RepeatCount = 1;
+ LastFlags = KeyInput.Flags & (KEY_E0 | KEY_E1);
+ LastMakeCode = KeyInput.MakeCode;
+ }
+ }
+ else
+ {
+ LastFlags = 0;
+ LastMakeCode = 0; /* Should never match */
+ lParam |= (KF_UP << 16) | (KF_REPEAT << 16);
+ }
+
+ lParam |= RepeatCount;
+
+ lParam |= (KeyInput.MakeCode & 0xff) << 16;
- FocusThread = FocusQueue->Thread;
- if (FocusThread && FocusThread->Tcb.Win32Thread)
+ if (KeyInput.Flags & KEY_E0)
+ lParam |= (KF_EXTENDED << 16);
+
+ if (ModifierState & MOD_ALT)
{
- keyboardLayout = ((PTHREADINFO)FocusThread->Tcb.Win32Thread)->KeyboardLayout;
+ lParam |= (KF_ALTDOWN << 16);
+
+ if (!(KeyInput.Flags & KEY_BREAK))
+ msg.message = WM_SYSKEYDOWN;
+ else
+ msg.message = WM_SYSKEYUP;
+ }
+ else
+ {
+ if (!(KeyInput.Flags & KEY_BREAK))
+ msg.message = WM_KEYDOWN;
+ else
+ msg.message = WM_KEYUP;
}
- if ( FocusQueue->QF_flags & QF_DIALOGACTIVE )
- lParam |= (KF_DLGMODE << 16);
- if ( FocusQueue->MenuOwner )//FocusQueue->MenuState ) // MenuState needs a start flag...
- lParam |= (KF_MENUMODE << 16);
- }
- if (!keyboardLayout)
- {
- keyboardLayout = W32kGetDefaultKeyLayout();
- }
- msg.lParam = lParam;
-
- /* This function uses lParam to fill wParam according to the
- * keyboard layout in use.
- */
- W32kKeyProcessMessage(&msg,
- keyboardLayout->KBTables,
- KeyInput.Flags & KEY_E0 ? 0xE0 :
- (KeyInput.Flags & KEY_E1 ? 0xE1 : 0));
-
- if (GetHotKey(ModifierState,
- msg.wParam,
- &Thread,
- &hWnd,
- &id))
- {
- if (!(KeyInput.Flags & KEY_BREAK))
- {
- TRACE("Hot key pressed (hWnd %lx, id %d)\n", hWnd, id);
- MsqPostHotKeyMessage (Thread,
- hWnd,
- (WPARAM)id,
- MAKELPARAM((WORD)ModifierState,
- (WORD)msg.wParam));
- }
- continue; /* Eat key up motion too */
- }
+ /* Find the target thread whose locale is in effect */
+ FocusQueue = IntGetFocusMessageQueue();
- if (!FocusQueue)
- {
- /* There is no focused window to receive a keyboard message */
- continue;
- }
- if ( msg.wParam == VK_F10 ) // Bypass this key before it is in the queue.
- {
- if (msg.message == WM_KEYUP) msg.message = WM_SYSKEYUP;
- if (msg.message == WM_KEYDOWN) msg.message = WM_SYSKEYDOWN;
+ if (FocusQueue)
+ {
+ msg.hwnd = FocusQueue->FocusWindow;
+
+ FocusThread = FocusQueue->Thread;
+ if (FocusThread && FocusThread->Tcb.Win32Thread)
+ {
+ keyboardLayout = ((PTHREADINFO)FocusThread->Tcb.Win32Thread)->KeyboardLayout;
+ }
+ if ( FocusQueue->QF_flags & QF_DIALOGACTIVE )
+ lParam |= (KF_DLGMODE << 16);
+ if ( FocusQueue->MenuOwner )//FocusQueue->MenuState ) // MenuState needs a start flag...
+ lParam |= (KF_MENUMODE << 16);
+ }
+ if (!keyboardLayout)
+ {
+ keyboardLayout = W32kGetDefaultKeyLayout();
+ }
+
+ msg.lParam = lParam;
+
+ /* This function uses lParam to fill wParam according to the
+ * keyboard layout in use.
+ */
+ W32kKeyProcessMessage(&msg,
+ keyboardLayout->KBTables,
+ KeyInput.Flags & KEY_E0 ? 0xE0 :
+ (KeyInput.Flags & KEY_E1 ? 0xE1 : 0));
+
+ if (GetHotKey(ModifierState,
+ msg.wParam,
+ &Thread,
+ &hWnd,
+ &id))
+ {
+ if (!(KeyInput.Flags & KEY_BREAK))
+ {
+ TRACE("Hot key pressed (hWnd %lx, id %d)\n", hWnd, id);
+ MsqPostHotKeyMessage (Thread,
+ hWnd,
+ (WPARAM)id,
+ MAKELPARAM((WORD)ModifierState,
+ (WORD)msg.wParam));
+ }
+ continue; /* Eat key up motion too */
+ }
+
+ if (!FocusQueue)
+ {
+ /* There is no focused window to receive a keyboard message */
+ continue;
+ }
+ if ( msg.wParam == VK_F10 ) // Bypass this key before it is in the queue.
+ {
+ if (msg.message == WM_KEYUP) msg.message = WM_SYSKEYUP;
+ if (msg.message == WM_KEYDOWN) msg.message = WM_SYSKEYDOWN;
+ }
+ /*
+ * Post a keyboard message.
+ */
+ co_MsqPostKeyboardMessage(msg.message, msg.wParam, msg.lParam);
}
- /*
- * Post a keyboard message.
- */
- co_MsqPostKeyboardMessage(msg.message,msg.wParam,msg.lParam);
- }
- UserLeave();
- }
+ UserLeave();
+ }
KeyboardEscape:
- TRACE( "KeyboardInput Thread Stopped...\n" );
- }
+ TRACE( "KeyboardInput Thread Stopped...\n" );
+ }
}
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;
-
- // This thread requires win32k!
- Status = Win32kInitWin32Thread(PsGetCurrentThread());
- if (!NT_SUCCESS(Status))
- {
- ERR("Win32K: Failed making Raw Input thread a win32 thread.\n");
- return; //(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();
-
- //
- // 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();
- }
- ERR("Raw Input Thread Exit!\n");
+ 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;
+
+ // This thread requires win32k!
+ Status = Win32kInitWin32Thread(PsGetCurrentThread());
+ if (!NT_SUCCESS(Status))
+ {
+ ERR("Win32K: Failed making Raw Input thread a win32 thread.\n");
+ return; //(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();
+
+ //
+ // 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();
+ }
+ ERR("Raw Input Thread Exit!\n");
}
INIT_FUNCTION
NTAPI
InitInputImpl(VOID)
{
- NTSTATUS Status;
-
- KeInitializeEvent(&InputThreadsStart, NotificationEvent, FALSE);
-
- MasterTimer = ExAllocatePoolWithTag(NonPagedPool, sizeof(KTIMER), USERTAG_SYSTEM);
- if (!MasterTimer)
- {
- ERR("Win32K: Failed making Raw Input thread a win32 thread.\n");
- ASSERT(FALSE);
- return STATUS_UNSUCCESSFUL;
- }
- KeInitializeTimer(MasterTimer);
-
- /* Initialize the default keyboard layout */
- if(!UserInitDefaultKeyboardLayout())
- {
- ERR("Failed to initialize default keyboard layout!\n");
- }
-
- Status = PsCreateSystemThread(&RawInputThreadHandle,
- THREAD_ALL_ACCESS,
- NULL,
- NULL,
- &RawInputThreadId,
- RawInputThreadMain,
- NULL);
- if (!NT_SUCCESS(Status))
- {
- ERR("Win32K: Failed to create raw thread.\n");
- }
-
- Status = PsCreateSystemThread(&KeyboardThreadHandle,
- THREAD_ALL_ACCESS,
- NULL,
- NULL,
- &KeyboardThreadId,
- KeyboardThreadMain,
- NULL);
- if (!NT_SUCCESS(Status))
- {
- ERR("Win32K: Failed to create keyboard thread.\n");
- }
-
- Status = PsCreateSystemThread(&MouseThreadHandle,
- THREAD_ALL_ACCESS,
- NULL,
- NULL,
- &MouseThreadId,
- MouseThreadMain,
- NULL);
- if (!NT_SUCCESS(Status))
- {
- ERR("Win32K: Failed to create mouse thread.\n");
- }
-
- InputThreadsRunning = TRUE;
- KeSetEvent(&InputThreadsStart, IO_NO_INCREMENT, FALSE);
-
- return STATUS_SUCCESS;
+ NTSTATUS Status;
+
+ KeInitializeEvent(&InputThreadsStart, NotificationEvent, FALSE);
+
+ MasterTimer = ExAllocatePoolWithTag(NonPagedPool, sizeof(KTIMER), USERTAG_SYSTEM);
+ if (!MasterTimer)
+ {
+ ERR("Win32K: Failed making Raw Input thread a win32 thread.\n");
+ ASSERT(FALSE);
+ return STATUS_UNSUCCESSFUL;
+ }
+ KeInitializeTimer(MasterTimer);
+
+ /* Initialize the default keyboard layout */
+ if(!UserInitDefaultKeyboardLayout())
+ {
+ ERR("Failed to initialize default keyboard layout!\n");
+ }
+
+ Status = PsCreateSystemThread(&RawInputThreadHandle,
+ THREAD_ALL_ACCESS,
+ NULL,
+ NULL,
+ &RawInputThreadId,
+ RawInputThreadMain,
+ NULL);
+ if (!NT_SUCCESS(Status))
+ {
+ ERR("Win32K: Failed to create raw thread.\n");
+ }
+
+ Status = PsCreateSystemThread(&KeyboardThreadHandle,
+ THREAD_ALL_ACCESS,
+ NULL,
+ NULL,
+ &KeyboardThreadId,
+ KeyboardThreadMain,
+ NULL);
+ if (!NT_SUCCESS(Status))
+ {
+ ERR("Win32K: Failed to create keyboard thread.\n");
+ }
+
+ Status = PsCreateSystemThread(&MouseThreadHandle,
+ THREAD_ALL_ACCESS,
+ NULL,
+ NULL,
+ &MouseThreadId,
+ MouseThreadMain,
+ NULL);
+ if (!NT_SUCCESS(Status))
+ {
+ ERR("Win32K: Failed to create mouse thread.\n");
+ }
+
+ InputThreadsRunning = TRUE;
+ KeSetEvent(&InputThreadsStart, IO_NO_INCREMENT, FALSE);
+
+ return STATUS_SUCCESS;
}
NTSTATUS FASTCALL
CleanupInputImp(VOID)
{
- return(STATUS_SUCCESS);
+ return(STATUS_SUCCESS);
}
BOOL FASTCALL
IntBlockInput(PTHREADINFO W32Thread, BOOL BlockIt)
{
- PTHREADINFO OldBlock;
- ASSERT(W32Thread);
-
- if(!W32Thread->rpdesk || ((W32Thread->TIF_flags & TIF_INCLEANUP) && BlockIt))
- {
- /*
- * fail blocking if exiting the thread
- */
-
- return FALSE;
- }
-
- /*
- * FIXME - check access rights of the window station
- * e.g. services running in the service window station cannot block input
- */
- if(!ThreadHasInputAccess(W32Thread) ||
- !IntIsActiveDesktop(W32Thread->rpdesk))
- {
- EngSetLastError(ERROR_ACCESS_DENIED);
- return FALSE;
- }
-
- ASSERT(W32Thread->rpdesk);
- OldBlock = W32Thread->rpdesk->BlockInputThread;
- if(OldBlock)
- {
- if(OldBlock != W32Thread)
- {
- EngSetLastError(ERROR_ACCESS_DENIED);
- return FALSE;
- }
- W32Thread->rpdesk->BlockInputThread = (BlockIt ? W32Thread : NULL);
- return OldBlock == NULL;
- }
-
- W32Thread->rpdesk->BlockInputThread = (BlockIt ? W32Thread : NULL);
- return OldBlock == NULL;
+ PTHREADINFO OldBlock;
+ ASSERT(W32Thread);
+
+ if(!W32Thread->rpdesk || ((W32Thread->TIF_flags & TIF_INCLEANUP) && BlockIt))
+ {
+ /*
+ * fail blocking if exiting the thread
+ */
+
+ return FALSE;
+ }
+
+ /*
+ * FIXME - check access rights of the window station
+ * e.g. services running in the service window station cannot block input
+ */
+ if(!ThreadHasInputAccess(W32Thread) ||
+ !IntIsActiveDesktop(W32Thread->rpdesk))
+ {
+ EngSetLastError(ERROR_ACCESS_DENIED);
+ return FALSE;
+ }
+
+ ASSERT(W32Thread->rpdesk);
+ OldBlock = W32Thread->rpdesk->BlockInputThread;
+ if(OldBlock)
+ {
+ if(OldBlock != W32Thread)
+ {
+ EngSetLastError(ERROR_ACCESS_DENIED);
+ return FALSE;
+ }
+ W32Thread->rpdesk->BlockInputThread = (BlockIt ? W32Thread : NULL);
+ return OldBlock == NULL;
+ }
+
+ W32Thread->rpdesk->BlockInputThread = (BlockIt ? W32Thread : NULL);
+ return OldBlock == NULL;
}
BOOL
APIENTRY
NtUserBlockInput(
- BOOL BlockIt)
+ BOOL BlockIt)
{
- DECLARE_RETURN(BOOLEAN);
+ DECLARE_RETURN(BOOLEAN);
- TRACE("Enter NtUserBlockInput\n");
- UserEnterExclusive();
+ TRACE("Enter NtUserBlockInput\n");
+ UserEnterExclusive();
- RETURN( IntBlockInput(PsGetCurrentThreadWin32Thread(), BlockIt));
+ RETURN( IntBlockInput(PsGetCurrentThreadWin32Thread(), BlockIt));
CLEANUP:
- TRACE("Leave NtUserBlockInput, ret=%i\n",_ret_);
- UserLeave();
- END_CLEANUP;
+ TRACE("Leave NtUserBlockInput, ret=%i\n", _ret_);
+ UserLeave();
+ END_CLEANUP;
}
BOOL FASTCALL
IntMouseInput(MOUSEINPUT *mi, BOOL Injected)
{
- const UINT SwapBtnMsg[2][2] =
- {
- {WM_LBUTTONDOWN, WM_RBUTTONDOWN},
- {WM_LBUTTONUP, WM_RBUTTONUP}
- };
- const WPARAM SwapBtn[2] =
- {
- MK_LBUTTON, MK_RBUTTON
- };
- POINT MousePos;
- PSYSTEM_CURSORINFO CurInfo;
- BOOL SwapButtons;
- MSG Msg;
-
- ASSERT(mi);
-
- CurInfo = IntGetSysCursorInfo();
-
- if(!mi->time)
- {
- LARGE_INTEGER LargeTickCount;
- KeQueryTickCount(&LargeTickCount);
- mi->time = MsqCalculateMessageTime(&LargeTickCount);
- }
-
- SwapButtons = gspv.bMouseBtnSwap;
-
- MousePos = gpsi->ptCursor;
-
- if(mi->dwFlags & MOUSEEVENTF_MOVE)
- {
- if(mi->dwFlags & MOUSEEVENTF_ABSOLUTE)
- {
- MousePos.x = mi->dx * UserGetSystemMetrics(SM_CXVIRTUALSCREEN) >> 16;
- MousePos.y = mi->dy * UserGetSystemMetrics(SM_CYVIRTUALSCREEN) >> 16;
- }
- else
- {
- MousePos.x += mi->dx;
- MousePos.y += mi->dy;
- }
- }
-
- /*
- * Insert the messages into the system queue
- */
- Msg.wParam = 0;
- Msg.lParam = MAKELPARAM(MousePos.x, MousePos.y);
- Msg.pt = MousePos;
-
- if (gKeyStateTable[VK_SHIFT] & KS_DOWN_BIT)
- {
- Msg.wParam |= MK_SHIFT;
- }
-
- if (gKeyStateTable[VK_CONTROL] & KS_DOWN_BIT)
- {
- Msg.wParam |= MK_CONTROL;
- }
-
- if(mi->dwFlags & MOUSEEVENTF_MOVE)
- {
- UserSetCursorPos(MousePos.x, MousePos.y, Injected, mi->dwExtraInfo, TRUE);
- }
- if(mi->dwFlags & MOUSEEVENTF_LEFTDOWN)
- {
- gKeyStateTable[VK_LBUTTON] |= KS_DOWN_BIT;
- Msg.message = SwapBtnMsg[0][SwapButtons];
- CurInfo->ButtonsDown |= SwapBtn[SwapButtons];
- Msg.wParam |= CurInfo->ButtonsDown;
- co_MsqInsertMouseMessage(&Msg, Injected, mi->dwExtraInfo, TRUE);
- }
- else if(mi->dwFlags & MOUSEEVENTF_LEFTUP)
- {
- gKeyStateTable[VK_LBUTTON] &= ~KS_DOWN_BIT;
- Msg.message = SwapBtnMsg[1][SwapButtons];
- CurInfo->ButtonsDown &= ~SwapBtn[SwapButtons];
- Msg.wParam |= CurInfo->ButtonsDown;
- co_MsqInsertMouseMessage(&Msg, Injected, mi->dwExtraInfo, TRUE);
- }
- if(mi->dwFlags & MOUSEEVENTF_MIDDLEDOWN)
- {
- gKeyStateTable[VK_MBUTTON] |= KS_DOWN_BIT;
- Msg.message = WM_MBUTTONDOWN;
- CurInfo->ButtonsDown |= MK_MBUTTON;
- Msg.wParam |= CurInfo->ButtonsDown;
- co_MsqInsertMouseMessage(&Msg, Injected, mi->dwExtraInfo, TRUE);
- }
- else if(mi->dwFlags & MOUSEEVENTF_MIDDLEUP)
- {
- gKeyStateTable[VK_MBUTTON] &= ~KS_DOWN_BIT;
- Msg.message = WM_MBUTTONUP;
- CurInfo->ButtonsDown &= ~MK_MBUTTON;
- Msg.wParam |= CurInfo->ButtonsDown;
- co_MsqInsertMouseMessage(&Msg, Injected, mi->dwExtraInfo, TRUE);
- }
- if(mi->dwFlags & MOUSEEVENTF_RIGHTDOWN)
- {
- gKeyStateTable[VK_RBUTTON] |= KS_DOWN_BIT;
- Msg.message = SwapBtnMsg[0][!SwapButtons];
- CurInfo->ButtonsDown |= SwapBtn[!SwapButtons];
- Msg.wParam |= CurInfo->ButtonsDown;
- co_MsqInsertMouseMessage(&Msg, Injected, mi->dwExtraInfo, TRUE);
- }
- else if(mi->dwFlags & MOUSEEVENTF_RIGHTUP)
- {
- gKeyStateTable[VK_RBUTTON] &= ~KS_DOWN_BIT;
- Msg.message = SwapBtnMsg[1][!SwapButtons];
- CurInfo->ButtonsDown &= ~SwapBtn[!SwapButtons];
- Msg.wParam |= CurInfo->ButtonsDown;
- co_MsqInsertMouseMessage(&Msg, Injected, mi->dwExtraInfo, TRUE);
- }
-
- if((mi->dwFlags & (MOUSEEVENTF_XDOWN | MOUSEEVENTF_XUP)) &&
- (mi->dwFlags & MOUSEEVENTF_WHEEL))
- {
- /* fail because both types of events use the mouseData field */
- return FALSE;
- }
-
- if(mi->dwFlags & MOUSEEVENTF_XDOWN)
- {
- Msg.message = WM_XBUTTONDOWN;
- if(mi->mouseData & XBUTTON1)
- {
- gKeyStateTable[VK_XBUTTON1] |= KS_DOWN_BIT;
- CurInfo->ButtonsDown |= MK_XBUTTON1;
- Msg.wParam = MAKEWPARAM(CurInfo->ButtonsDown, XBUTTON1);
- co_MsqInsertMouseMessage(&Msg, Injected, mi->dwExtraInfo, TRUE);
- }
- if(mi->mouseData & XBUTTON2)
- {
- gKeyStateTable[VK_XBUTTON2] |= KS_DOWN_BIT;
- CurInfo->ButtonsDown |= MK_XBUTTON2;
- Msg.wParam = MAKEWPARAM(CurInfo->ButtonsDown, XBUTTON2);
- co_MsqInsertMouseMessage(&Msg, Injected, mi->dwExtraInfo, TRUE);
- }
- }
- else if(mi->dwFlags & MOUSEEVENTF_XUP)
- {
- Msg.message = WM_XBUTTONUP;
- if(mi->mouseData & XBUTTON1)
- {
- gKeyStateTable[VK_XBUTTON1] &= ~KS_DOWN_BIT;
- CurInfo->ButtonsDown &= ~MK_XBUTTON1;
- Msg.wParam = MAKEWPARAM(CurInfo->ButtonsDown, XBUTTON1);
- co_MsqInsertMouseMessage(&Msg, Injected, mi->dwExtraInfo, TRUE);
- }
- if(mi->mouseData & XBUTTON2)
- {
- gKeyStateTable[VK_XBUTTON2] &= ~KS_DOWN_BIT;
- CurInfo->ButtonsDown &= ~MK_XBUTTON2;
- Msg.wParam = MAKEWPARAM(CurInfo->ButtonsDown, XBUTTON2);
- co_MsqInsertMouseMessage(&Msg, Injected, mi->dwExtraInfo, TRUE);
- }
- }
- if(mi->dwFlags & MOUSEEVENTF_WHEEL)
- {
- Msg.message = WM_MOUSEWHEEL;
- Msg.wParam = MAKEWPARAM(CurInfo->ButtonsDown, mi->mouseData);
- co_MsqInsertMouseMessage(&Msg, Injected, mi->dwExtraInfo, TRUE);
- }
-
- return TRUE;
+ const UINT SwapBtnMsg[2][2] =
+ {
+ {WM_LBUTTONDOWN, WM_RBUTTONDOWN},
+ {WM_LBUTTONUP, WM_RBUTTONUP}
+ };
+ const WPARAM SwapBtn[2] =
+ {
+ MK_LBUTTON, MK_RBUTTON
+ };
+ POINT MousePos;
+ PSYSTEM_CURSORINFO CurInfo;
+ BOOL SwapButtons;
+ MSG Msg;
+
+ ASSERT(mi);
+
+ CurInfo = IntGetSysCursorInfo();
+
+ if(!mi->time)
+ {
+ LARGE_INTEGER LargeTickCount;
+ KeQueryTickCount(&LargeTickCount);
+ mi->time = MsqCalculateMessageTime(&LargeTickCount);
+ }
+
+ SwapButtons = gspv.bMouseBtnSwap;
+
+ MousePos = gpsi->ptCursor;
+
+ if(mi->dwFlags & MOUSEEVENTF_MOVE)
+ {
+ if(mi->dwFlags & MOUSEEVENTF_ABSOLUTE)
+ {
+ MousePos.x = mi->dx * UserGetSystemMetrics(SM_CXVIRTUALSCREEN) >> 16;
+ MousePos.y = mi->dy * UserGetSystemMetrics(SM_CYVIRTUALSCREEN) >> 16;
+ }
+ else
+ {
+ MousePos.x += mi->dx;
+ MousePos.y += mi->dy;
+ }
+ }
+
+ /*
+ * Insert the messages into the system queue
+ */
+ Msg.wParam = 0;
+ Msg.lParam = MAKELPARAM(MousePos.x, MousePos.y);
+ Msg.pt = MousePos;
+
+ if (gKeyStateTable[VK_SHIFT] & KS_DOWN_BIT)
+ {
+ Msg.wParam |= MK_SHIFT;
+ }
+
+ if (gKeyStateTable[VK_CONTROL] & KS_DOWN_BIT)
+ {
+ Msg.wParam |= MK_CONTROL;
+ }
+
+ if(mi->dwFlags & MOUSEEVENTF_MOVE)
+ {
+ UserSetCursorPos(MousePos.x, MousePos.y, Injected, mi->dwExtraInfo, TRUE);
+ }
+ if(mi->dwFlags & MOUSEEVENTF_LEFTDOWN)
+ {
+ gKeyStateTable[VK_LBUTTON] |= KS_DOWN_BIT;
+ Msg.message = SwapBtnMsg[0][SwapButtons];
+ CurInfo->ButtonsDown |= SwapBtn[SwapButtons];
+ Msg.wParam |= CurInfo->ButtonsDown;
+ co_MsqInsertMouseMessage(&Msg, Injected, mi->dwExtraInfo, TRUE);
+ }
+ else if(mi->dwFlags & MOUSEEVENTF_LEFTUP)
+ {
+ gKeyStateTable[VK_LBUTTON] &= ~KS_DOWN_BIT;
+ Msg.message = SwapBtnMsg[1][SwapButtons];
+ CurInfo->ButtonsDown &= ~SwapBtn[SwapButtons];
+ Msg.wParam |= CurInfo->ButtonsDown;
+ co_MsqInsertMouseMessage(&Msg, Injected, mi->dwExtraInfo, TRUE);
+ }
+ if(mi->dwFlags & MOUSEEVENTF_MIDDLEDOWN)
+ {
+ gKeyStateTable[VK_MBUTTON] |= KS_DOWN_BIT;
+ Msg.message = WM_MBUTTONDOWN;
+ CurInfo->ButtonsDown |= MK_MBUTTON;
+ Msg.wParam |= CurInfo->ButtonsDown;
+ co_MsqInsertMouseMessage(&Msg, Injected, mi->dwExtraInfo, TRUE);
+ }
+ else if(mi->dwFlags & MOUSEEVENTF_MIDDLEUP)
+ {
+ gKeyStateTable[VK_MBUTTON] &= ~KS_DOWN_BIT;
+ Msg.message = WM_MBUTTONUP;
+ CurInfo->ButtonsDown &= ~MK_MBUTTON;
+ Msg.wParam |= CurInfo->ButtonsDown;
+ co_MsqInsertMouseMessage(&Msg, Injected, mi->dwExtraInfo, TRUE);
+ }
+ if(mi->dwFlags & MOUSEEVENTF_RIGHTDOWN)
+ {
+ gKeyStateTable[VK_RBUTTON] |= KS_DOWN_BIT;
+ Msg.message = SwapBtnMsg[0][!SwapButtons];
+ CurInfo->ButtonsDown |= SwapBtn[!SwapButtons];
+ Msg.wParam |= CurInfo->ButtonsDown;
+ co_MsqInsertMouseMessage(&Msg, Injected, mi->dwExtraInfo, TRUE);
+ }
+ else if(mi->dwFlags & MOUSEEVENTF_RIGHTUP)
+ {
+ gKeyStateTable[VK_RBUTTON] &= ~KS_DOWN_BIT;
+ Msg.message = SwapBtnMsg[1][!SwapButtons];
+ CurInfo->ButtonsDown &= ~SwapBtn[!SwapButtons];
+ Msg.wParam |= CurInfo->ButtonsDown;
+ co_MsqInsertMouseMessage(&Msg, Injected, mi->dwExtraInfo, TRUE);
+ }
+
+ if((mi->dwFlags & (MOUSEEVENTF_XDOWN | MOUSEEVENTF_XUP)) &&
+ (mi->dwFlags & MOUSEEVENTF_WHEEL))
+ {
+ /* fail because both types of events use the mouseData field */
+ return FALSE;
+ }
+
+ if(mi->dwFlags & MOUSEEVENTF_XDOWN)
+ {
+ Msg.message = WM_XBUTTONDOWN;
+ if(mi->mouseData & XBUTTON1)
+ {
+ gKeyStateTable[VK_XBUTTON1] |= KS_DOWN_BIT;
+ CurInfo->ButtonsDown |= MK_XBUTTON1;
+ Msg.wParam = MAKEWPARAM(CurInfo->ButtonsDown, XBUTTON1);
+ co_MsqInsertMouseMessage(&Msg, Injected, mi->dwExtraInfo, TRUE);
+ }
+ if(mi->mouseData & XBUTTON2)
+ {
+ gKeyStateTable[VK_XBUTTON2] |= KS_DOWN_BIT;
+ CurInfo->ButtonsDown |= MK_XBUTTON2;
+ Msg.wParam = MAKEWPARAM(CurInfo->ButtonsDown, XBUTTON2);
+ co_MsqInsertMouseMessage(&Msg, Injected, mi->dwExtraInfo, TRUE);
+ }
+ }
+ else if(mi->dwFlags & MOUSEEVENTF_XUP)
+ {
+ Msg.message = WM_XBUTTONUP;
+ if(mi->mouseData & XBUTTON1)
+ {
+ gKeyStateTable[VK_XBUTTON1] &= ~KS_DOWN_BIT;
+ CurInfo->ButtonsDown &= ~MK_XBUTTON1;
+ Msg.wParam = MAKEWPARAM(CurInfo->ButtonsDown, XBUTTON1);
+ co_MsqInsertMouseMessage(&Msg, Injected, mi->dwExtraInfo, TRUE);
+ }
+ if(mi->mouseData & XBUTTON2)
+ {
+ gKeyStateTable[VK_XBUTTON2] &= ~KS_DOWN_BIT;
+ CurInfo->ButtonsDown &= ~MK_XBUTTON2;
+ Msg.wParam = MAKEWPARAM(CurInfo->ButtonsDown, XBUTTON2);
+ co_MsqInsertMouseMessage(&Msg, Injected, mi->dwExtraInfo, TRUE);
+ }
+ }
+ if(mi->dwFlags & MOUSEEVENTF_WHEEL)
+ {
+ Msg.message = WM_MOUSEWHEEL;
+ Msg.wParam = MAKEWPARAM(CurInfo->ButtonsDown, mi->mouseData);
+ co_MsqInsertMouseMessage(&Msg, Injected, mi->dwExtraInfo, TRUE);
+ }
+
+ return TRUE;
}
BOOL FASTCALL
IntKeyboardInput(KEYBDINPUT *ki, BOOL Injected)
{
- PUSER_MESSAGE_QUEUE FocusMessageQueue;
- MSG Msg;
- LARGE_INTEGER LargeTickCount;
- KBDLLHOOKSTRUCT KbdHookData;
- WORD flags, wVkStripped, wVkL, wVkR, wVk = ki->wVk, vk_hook = ki->wVk;
-
- Msg.lParam = 0;
-
- // Condition may arise when calling MsqPostMessage and waiting for an event.
- ASSERT (UserIsEntered());
-
- wVk = LOBYTE(wVk);
- Msg.wParam = wVk;
- flags = LOBYTE(ki->wScan);
-
- FocusMessageQueue = IntGetFocusMessageQueue();
-
- if (ki->dwFlags & KEYEVENTF_EXTENDEDKEY) flags |= KF_EXTENDED;
- /* FIXME: set KF_DLGMODE and KF_MENUMODE when needed */
- if ( FocusMessageQueue && FocusMessageQueue->QF_flags & QF_DIALOGACTIVE )
- flags |= KF_DLGMODE;
- if ( FocusMessageQueue && FocusMessageQueue->MenuOwner )//FocusMessageQueue->MenuState ) // MenuState needs a start flag...
- flags |= KF_MENUMODE;
-
- /* strip left/right for menu, control, shift */
- switch (wVk)
- {
- case VK_MENU:
- case VK_LMENU:
- case VK_RMENU:
- wVk = (ki->dwFlags & KEYEVENTF_EXTENDEDKEY) ? VK_RMENU : VK_LMENU;
- wVkStripped = VK_MENU;
- wVkL = VK_LMENU;
- wVkR = VK_RMENU;
- break;
- case VK_CONTROL:
- case VK_LCONTROL:
- case VK_RCONTROL:
- wVk = (ki->dwFlags & KEYEVENTF_EXTENDEDKEY) ? VK_RCONTROL : VK_LCONTROL;
- wVkStripped = VK_CONTROL;
- wVkL = VK_LCONTROL;
- wVkR = VK_RCONTROL;
- break;
- case VK_SHIFT:
- case VK_LSHIFT:
- case VK_RSHIFT:
- wVk = (ki->dwFlags & KEYEVENTF_EXTENDEDKEY) ? VK_RSHIFT : VK_LSHIFT;
- wVkStripped = VK_SHIFT;
- wVkL = VK_LSHIFT;
- wVkR = VK_RSHIFT;
- break;
- default:
- wVkStripped = wVkL = wVkR = wVk;
- }
-
- if (ki->dwFlags & KEYEVENTF_KEYUP)
- {
- Msg.message = WM_KEYUP;
- if (((gKeyStateTable[VK_MENU] & KS_DOWN_BIT) &&
- ((wVkStripped == VK_MENU) || (wVkStripped == VK_CONTROL)
- || !(gKeyStateTable[VK_CONTROL] & KS_DOWN_BIT)))
- || (wVkStripped == VK_F10))
- {
- if( TrackSysKey == VK_MENU || /* <ALT>-down/<ALT>-up sequence */
- (wVkStripped != VK_MENU)) /* <ALT>-down...<something else>-up */
- Msg.message = WM_SYSKEYUP;
- TrackSysKey = 0;
- }
- flags |= KF_REPEAT | KF_UP;
- }
- else
- {
- Msg.message = WM_KEYDOWN;
- if (((gKeyStateTable[VK_MENU] & KS_DOWN_BIT || wVkStripped == VK_MENU) &&
- !(gKeyStateTable[VK_CONTROL] & KS_DOWN_BIT || wVkStripped == VK_CONTROL))
- || (wVkStripped == VK_F10))
- {
- Msg.message = WM_SYSKEYDOWN;
- TrackSysKey = wVkStripped;
- }
- if (!(ki->dwFlags & KEYEVENTF_UNICODE) && gKeyStateTable[wVk] & KS_DOWN_BIT) flags |= KF_REPEAT;
- }
-
- if (ki->dwFlags & KEYEVENTF_UNICODE)
- {
- vk_hook = Msg.wParam = wVk = VK_PACKET;
- Msg.lParam = MAKELPARAM(1 /* repeat count */, ki->wScan);
- }
-
- if (!(ki->dwFlags & KEYEVENTF_UNICODE))
- {
- if (ki->dwFlags & KEYEVENTF_KEYUP)
- {
- gKeyStateTable[wVk] &= ~KS_DOWN_BIT;
- gKeyStateTable[wVkStripped] = gKeyStateTable[wVkL] | gKeyStateTable[wVkR];
- }
- else
- {
- if (!(gKeyStateTable[wVk] & KS_DOWN_BIT)) gKeyStateTable[wVk] ^= KS_LOCK_BIT;
- gKeyStateTable[wVk] |= KS_DOWN_BIT;
- gKeyStateTable[wVkStripped] = gKeyStateTable[wVkL] | gKeyStateTable[wVkR];
- }
-
- if (gKeyStateTable[VK_MENU] & KS_DOWN_BIT) flags |= KF_ALTDOWN;
-
- if (wVkStripped == VK_SHIFT) flags &= ~KF_EXTENDED;
-
- Msg.lParam = MAKELPARAM(1 /* repeat count */, flags);
- }
-
- Msg.hwnd = 0;
-
- if (FocusMessageQueue && (FocusMessageQueue->FocusWindow != (HWND)0))
- Msg.hwnd = FocusMessageQueue->FocusWindow;
-
- if (!ki->time)
- {
- KeQueryTickCount(&LargeTickCount);
- Msg.time = MsqCalculateMessageTime(&LargeTickCount);
- }
- else
- Msg.time = ki->time;
-
- /* All messages have to contain the cursor point. */
- Msg.pt = gpsi->ptCursor;
-
- KbdHookData.vkCode = vk_hook;
- KbdHookData.scanCode = ki->wScan;
- KbdHookData.flags = (flags & (KF_EXTENDED | KF_ALTDOWN | KF_UP)) >> 8;
- if (Injected) KbdHookData.flags |= LLKHF_INJECTED;
- KbdHookData.time = Msg.time;
- KbdHookData.dwExtraInfo = ki->dwExtraInfo;
- if (co_HOOK_CallHooks(WH_KEYBOARD_LL, HC_ACTION, Msg.message, (LPARAM) &KbdHookData))
- {
- ERR("Kbd msg %d wParam %d lParam 0x%08x dropped by WH_KEYBOARD_LL hook\n",
- Msg.message, vk_hook, Msg.lParam);
-
- return FALSE;
- }
-
- if (FocusMessageQueue == NULL)
- {
- TRACE("No focus message queue\n");
-
- return FALSE;
- }
-
- if (FocusMessageQueue->FocusWindow != (HWND)0)
- {
- Msg.hwnd = FocusMessageQueue->FocusWindow;
- TRACE("Msg.hwnd = %x\n", Msg.hwnd);
-
- FocusMessageQueue->Desktop->pDeskInfo->LastInputWasKbd = TRUE;
-
- // Post to hardware queue, based on the first part of wine "some GetMessage tests"
- // in test_PeekMessage()
- MsqPostMessage(FocusMessageQueue, &Msg, TRUE, QS_KEY);
- }
- else
- {
- TRACE("Invalid focus window handle\n");
- }
-
- return TRUE;
-}
+ PUSER_MESSAGE_QUEUE FocusMessageQueue;
+ MSG Msg;
+ LARGE_INTEGER LargeTickCount;
+ KBDLLHOOKSTRUCT KbdHookData;
+ WORD flags, wVkStripped, wVkL, wVkR, wVk = ki->wVk, vk_hook = ki->wVk;
+
+ Msg.lParam = 0;
+
+ // Condition may arise when calling MsqPostMessage and waiting for an event.
+ ASSERT (UserIsEntered());
+
+ wVk = LOBYTE(wVk);
+ Msg.wParam = wVk;
+ flags = LOBYTE(ki->wScan);
+
+ FocusMessageQueue = IntGetFocusMessageQueue();
+
+ if (ki->dwFlags & KEYEVENTF_EXTENDEDKEY) flags |= KF_EXTENDED;
+ /* FIXME: set KF_DLGMODE and KF_MENUMODE when needed */
+ if ( FocusMessageQueue && FocusMessageQueue->QF_flags & QF_DIALOGACTIVE )
+ flags |= KF_DLGMODE;
+ if ( FocusMessageQueue && FocusMessageQueue->MenuOwner )//FocusMessageQueue->MenuState ) // MenuState needs a start flag...
+ flags |= KF_MENUMODE;
+
+ /* strip left/right for menu, control, shift */
+ switch (wVk)
+ {
+ case VK_MENU:
+ case VK_LMENU:
+ case VK_RMENU:
+ wVk = (ki->dwFlags & KEYEVENTF_EXTENDEDKEY) ? VK_RMENU : VK_LMENU;
+ wVkStripped = VK_MENU;
+ wVkL = VK_LMENU;
+ wVkR = VK_RMENU;
+ break;
+ case VK_CONTROL:
+ case VK_LCONTROL:
+ case VK_RCONTROL:
+ wVk = (ki->dwFlags & KEYEVENTF_EXTENDEDKEY) ? VK_RCONTROL : VK_LCONTROL;
+ wVkStripped = VK_CONTROL;
+ wVkL = VK_LCONTROL;
+ wVkR = VK_RCONTROL;
+ break;
+ case VK_SHIFT:
+ case VK_LSHIFT:
+ case VK_RSHIFT:
+ wVk = (ki->dwFlags & KEYEVENTF_EXTENDEDKEY) ? VK_RSHIFT : VK_LSHIFT;
+ wVkStripped = VK_SHIFT;
+ wVkL = VK_LSHIFT;
+ wVkR = VK_RSHIFT;
+ break;
+ default:
+ wVkStripped = wVkL = wVkR = wVk;
+ }
+
+ if (ki->dwFlags & KEYEVENTF_KEYUP)
+ {
+ Msg.message = WM_KEYUP;
+ if (((gKeyStateTable[VK_MENU] & KS_DOWN_BIT) &&
+ ((wVkStripped == VK_MENU) || (wVkStripped == VK_CONTROL)
+ || !(gKeyStateTable[VK_CONTROL] & KS_DOWN_BIT)))
+ || (wVkStripped == VK_F10))
+ {
+ if( TrackSysKey == VK_MENU || /* <ALT>-down/<ALT>-up sequence */
+ (wVkStripped != VK_MENU)) /* <ALT>-down...<something else>-up */
+ Msg.message = WM_SYSKEYUP;
+ TrackSysKey = 0;
+ }
+ flags |= KF_REPEAT | KF_UP;
+ }
+ else
+ {
+ Msg.message = WM_KEYDOWN;
+ if (((gKeyStateTable[VK_MENU] & KS_DOWN_BIT || wVkStripped == VK_MENU) &&
+ !(gKeyStateTable[VK_CONTROL] & KS_DOWN_BIT || wVkStripped == VK_CONTROL))
+ || (wVkStripped == VK_F10))
+ {
+ Msg.message = WM_SYSKEYDOWN;
+ TrackSysKey = wVkStripped;
+ }
+ if (!(ki->dwFlags & KEYEVENTF_UNICODE) && gKeyStateTable[wVk] & KS_DOWN_BIT) flags |= KF_REPEAT;
+ }
+
+ if (ki->dwFlags & KEYEVENTF_UNICODE)
+ {
+ vk_hook = Msg.wParam = wVk = VK_PACKET;
+ Msg.lParam = MAKELPARAM(1 /* repeat count */, ki->wScan);
+ }
+
+ if (!(ki->dwFlags & KEYEVENTF_UNICODE))
+ {
+ if (ki->dwFlags & KEYEVENTF_KEYUP)
+ {
+ gKeyStateTable[wVk] &= ~KS_DOWN_BIT;
+ gKeyStateTable[wVkStripped] = gKeyStateTable[wVkL] | gKeyStateTable[wVkR];
+ }
+ else
+ {
+ if (!(gKeyStateTable[wVk] & KS_DOWN_BIT)) gKeyStateTable[wVk] ^= KS_LOCK_BIT;
+ gKeyStateTable[wVk] |= KS_DOWN_BIT;
+ gKeyStateTable[wVkStripped] = gKeyStateTable[wVkL] | gKeyStateTable[wVkR];
+ }
-BOOL FASTCALL
-UserAttachThreadInput( PTHREADINFO pti, PTHREADINFO ptiTo, BOOL fAttach)
-{
- PATTACHINFO pai;
+ if (gKeyStateTable[VK_MENU] & KS_DOWN_BIT) flags |= KF_ALTDOWN;
+
+ if (wVkStripped == VK_SHIFT) flags &= ~KF_EXTENDED;
+
+ Msg.lParam = MAKELPARAM(1 /* repeat count */, flags);
+ }
- /* Can not be the same thread.*/
- if (pti == ptiTo) return FALSE;
+ Msg.hwnd = 0;
- /* Do not attach to system threads or between different desktops. */
- if ( pti->TIF_flags & TIF_DONTATTACHQUEUE ||
- ptiTo->TIF_flags & TIF_DONTATTACHQUEUE ||
- pti->rpdesk != ptiTo->rpdesk )
- return FALSE;
+ if (FocusMessageQueue && (FocusMessageQueue->FocusWindow != (HWND)0))
+ Msg.hwnd = FocusMessageQueue->FocusWindow;
- /* If Attach set, allocate and link. */
- if ( fAttach )
- {
- pai = ExAllocatePoolWithTag(PagedPool, sizeof(ATTACHINFO), USERTAG_ATTACHINFO);
- if ( !pai ) return FALSE;
+ if (!ki->time)
+ {
+ KeQueryTickCount(&LargeTickCount);
+ Msg.time = MsqCalculateMessageTime(&LargeTickCount);
+ }
+ else
+ Msg.time = ki->time;
- pai->paiNext = gpai;
- pai->pti1 = pti;
- pai->pti2 = ptiTo;
- gpai = pai;
- }
- else /* If clear, unlink and free it. */
- {
- PATTACHINFO paiprev = NULL;
+ /* All messages have to contain the cursor point. */
+ Msg.pt = gpsi->ptCursor;
- if ( !gpai ) return FALSE;
+ KbdHookData.vkCode = vk_hook;
+ KbdHookData.scanCode = ki->wScan;
+ KbdHookData.flags = (flags & (KF_EXTENDED | KF_ALTDOWN | KF_UP)) >> 8;
+ if (Injected) KbdHookData.flags |= LLKHF_INJECTED;
+ KbdHookData.time = Msg.time;
+ KbdHookData.dwExtraInfo = ki->dwExtraInfo;
+ if (co_HOOK_CallHooks(WH_KEYBOARD_LL, HC_ACTION, Msg.message, (LPARAM) &KbdHookData))
+ {
+ ERR("Kbd msg %d wParam %d lParam 0x%08x dropped by WH_KEYBOARD_LL hook\n",
+ Msg.message, vk_hook, Msg.lParam);
- pai = gpai;
+ return FALSE;
+ }
- /* Search list and free if found or return false. */
- do
- {
- if ( pai->pti2 == ptiTo && pai->pti1 == pti ) break;
- paiprev = pai;
- pai = pai->paiNext;
- } while (pai);
+ if (FocusMessageQueue == NULL)
+ {
+ TRACE("No focus message queue\n");
- if ( !pai ) return FALSE;
+ return FALSE;
+ }
- if (paiprev) paiprev->paiNext = pai->paiNext;
+ if (FocusMessageQueue->FocusWindow != (HWND)0)
+ {
+ Msg.hwnd = FocusMessageQueue->FocusWindow;
+ TRACE("Msg.hwnd = %x\n", Msg.hwnd);
- ExFreePoolWithTag(pai, USERTAG_ATTACHINFO);
- }
+ FocusMessageQueue->Desktop->pDeskInfo->LastInputWasKbd = TRUE;
- return TRUE;
+ // Post to hardware queue, based on the first part of wine "some GetMessage tests"
+ // in test_PeekMessage()
+ MsqPostMessage(FocusMessageQueue, &Msg, TRUE, QS_KEY);
+ }
+ else
+ {
+ TRACE("Invalid focus window handle\n");
+ }
+
+ return TRUE;
+}
+
+BOOL FASTCALL
+UserAttachThreadInput( PTHREADINFO pti, PTHREADINFO ptiTo, BOOL fAttach)
+{
+ PATTACHINFO pai;
+
+ /* Can not be the same thread.*/
+ if (pti == ptiTo) return FALSE;
+
+ /* Do not attach to system threads or between different desktops. */
+ if ( pti->TIF_flags & TIF_DONTATTACHQUEUE ||
+ ptiTo->TIF_flags & TIF_DONTATTACHQUEUE ||
+ pti->rpdesk != ptiTo->rpdesk )
+ return FALSE;
+
+ /* If Attach set, allocate and link. */
+ if ( fAttach )
+ {
+ pai = ExAllocatePoolWithTag(PagedPool, sizeof(ATTACHINFO), USERTAG_ATTACHINFO);
+ if ( !pai ) return FALSE;
+
+ pai->paiNext = gpai;
+ pai->pti1 = pti;
+ pai->pti2 = ptiTo;
+ gpai = pai;
+ }
+ else /* If clear, unlink and free it. */
+ {
+ PATTACHINFO paiprev = NULL;
+
+ if ( !gpai ) return FALSE;
+
+ pai = gpai;
+
+ /* Search list and free if found or return false. */
+ do
+ {
+ if ( pai->pti2 == ptiTo && pai->pti1 == pti ) break;
+ paiprev = pai;
+ pai = pai->paiNext;
+ } while (pai);
+
+ if ( !pai ) return FALSE;
+
+ if (paiprev) paiprev->paiNext = pai->paiNext;
+
+ ExFreePoolWithTag(pai, USERTAG_ATTACHINFO);
+ }
+
+ return TRUE;
}
UINT
APIENTRY
NtUserSendInput(
- UINT nInputs,
- LPINPUT pInput,
- INT cbSize)
+ UINT nInputs,
+ LPINPUT pInput,
+ INT cbSize)
{
- PTHREADINFO W32Thread;
- UINT cnt;
- DECLARE_RETURN(UINT);
-
- TRACE("Enter NtUserSendInput\n");
- UserEnterExclusive();
-
- W32Thread = PsGetCurrentThreadWin32Thread();
- ASSERT(W32Thread);
-
- if(!W32Thread->rpdesk)
- {
- RETURN( 0);
- }
-
- if(!nInputs || !pInput || (cbSize != sizeof(INPUT)))
- {
- EngSetLastError(ERROR_INVALID_PARAMETER);
- RETURN( 0);
- }
-
- /*
- * FIXME - check access rights of the window station
- * e.g. services running in the service window station cannot block input
- */
- if(!ThreadHasInputAccess(W32Thread) ||
- !IntIsActiveDesktop(W32Thread->rpdesk))
- {
- EngSetLastError(ERROR_ACCESS_DENIED);
- RETURN( 0);
- }
-
- cnt = 0;
- while(nInputs--)
- {
- INPUT SafeInput;
- NTSTATUS Status;
-
- Status = MmCopyFromCaller(&SafeInput, pInput++, sizeof(INPUT));
- if(!NT_SUCCESS(Status))
- {
- SetLastNtError(Status);
- RETURN( cnt);
- }
-
- switch(SafeInput.type)
- {
- case INPUT_MOUSE:
- if(IntMouseInput(&SafeInput.mi, TRUE))
- {
- cnt++;
- }
- break;
- case INPUT_KEYBOARD:
- if(IntKeyboardInput(&SafeInput.ki, TRUE))
- {
- cnt++;
- }
- break;
- case INPUT_HARDWARE:
- break;
+ PTHREADINFO W32Thread;
+ UINT cnt;
+ DECLARE_RETURN(UINT);
+
+ TRACE("Enter NtUserSendInput\n");
+ UserEnterExclusive();
+
+ W32Thread = PsGetCurrentThreadWin32Thread();
+ ASSERT(W32Thread);
+
+ if(!W32Thread->rpdesk)
+ {
+ RETURN( 0);
+ }
+
+ if(!nInputs || !pInput || (cbSize != sizeof(INPUT)))
+ {
+ EngSetLastError(ERROR_INVALID_PARAMETER);
+ RETURN( 0);
+ }
+
+ /*
+ * FIXME - check access rights of the window station
+ * e.g. services running in the service window station cannot block input
+ */
+ if(!ThreadHasInputAccess(W32Thread) ||
+ !IntIsActiveDesktop(W32Thread->rpdesk))
+ {
+ EngSetLastError(ERROR_ACCESS_DENIED);
+ RETURN( 0);
+ }
+
+ cnt = 0;
+ while(nInputs--)
+ {
+ INPUT SafeInput;
+ NTSTATUS Status;
+
+ Status = MmCopyFromCaller(&SafeInput, pInput++, sizeof(INPUT));
+ if(!NT_SUCCESS(Status))
+ {
+ SetLastNtError(Status);
+ RETURN( cnt);
+ }
+
+ switch(SafeInput.type)
+ {
+ case INPUT_MOUSE:
+ if(IntMouseInput(&SafeInput.mi, TRUE))
+ {
+ cnt++;
+ }
+ break;
+ case INPUT_KEYBOARD:
+ if(IntKeyboardInput(&SafeInput.ki, TRUE))
+ {
+ cnt++;
+ }
+ break;
+ case INPUT_HARDWARE:
+ break;
#ifndef NDEBUG
- default:
- ERR("SendInput(): Invalid input type: 0x%x\n", SafeInput.type);
- break;
+ default:
+ ERR("SendInput(): Invalid input type: 0x%x\n", SafeInput.type);
+ break;
#endif
- }
- }
+ }
+ }
- RETURN( cnt);
+ RETURN( cnt);
CLEANUP:
- TRACE("Leave NtUserSendInput, ret=%i\n",_ret_);
- UserLeave();
- END_CLEANUP;
+ TRACE("Leave NtUserSendInput, ret=%i\n", _ret_);
+ UserLeave();
+ END_CLEANUP;
}
BOOL
FASTCALL
IntQueryTrackMouseEvent(
- LPTRACKMOUSEEVENT lpEventTrack)
+ LPTRACKMOUSEEVENT lpEventTrack)
{
- PDESKTOP pDesk;
- PTHREADINFO pti;
-
- pti = PsGetCurrentThreadWin32Thread();
- pDesk = pti->rpdesk;
-
- /* Always cleared with size set and return true. */
- RtlZeroMemory(lpEventTrack ,sizeof(TRACKMOUSEEVENT));
- lpEventTrack->cbSize = sizeof(TRACKMOUSEEVENT);
-
- if ( pDesk->dwDTFlags & (DF_TME_LEAVE|DF_TME_HOVER) &&
- pDesk->spwndTrack &&
- pti->MessageQueue == pDesk->spwndTrack->head.pti->MessageQueue )
- {
- if ( pDesk->htEx != HTCLIENT )
- lpEventTrack->dwFlags |= TME_NONCLIENT;
-
- if ( pDesk->dwDTFlags & DF_TME_LEAVE )
- lpEventTrack->dwFlags |= TME_LEAVE;
-
- if ( pDesk->dwDTFlags & DF_TME_HOVER )
- {
- lpEventTrack->dwFlags |= TME_HOVER;
- lpEventTrack->dwHoverTime = pDesk->dwMouseHoverTime;
- }
- lpEventTrack->hwndTrack = UserHMGetHandle(pDesk->spwndTrack);
- }
- return TRUE;
+ PDESKTOP pDesk;
+ PTHREADINFO pti;
+
+ pti = PsGetCurrentThreadWin32Thread();
+ pDesk = pti->rpdesk;
+
+ /* Always cleared with size set and return true. */
+ RtlZeroMemory(lpEventTrack , sizeof(TRACKMOUSEEVENT));
+ lpEventTrack->cbSize = sizeof(TRACKMOUSEEVENT);
+
+ if ( pDesk->dwDTFlags & (DF_TME_LEAVE | DF_TME_HOVER) &&
+ pDesk->spwndTrack &&
+ pti->MessageQueue == pDesk->spwndTrack->head.pti->MessageQueue )
+ {
+ if ( pDesk->htEx != HTCLIENT )
+ lpEventTrack->dwFlags |= TME_NONCLIENT;
+
+ if ( pDesk->dwDTFlags & DF_TME_LEAVE )
+ lpEventTrack->dwFlags |= TME_LEAVE;
+
+ if ( pDesk->dwDTFlags & DF_TME_HOVER )
+ {
+ lpEventTrack->dwFlags |= TME_HOVER;
+ lpEventTrack->dwHoverTime = pDesk->dwMouseHoverTime;
+ }
+ lpEventTrack->hwndTrack = UserHMGetHandle(pDesk->spwndTrack);
+ }
+ return TRUE;
}
BOOL
FASTCALL
IntTrackMouseEvent(
- LPTRACKMOUSEEVENT lpEventTrack)
+ LPTRACKMOUSEEVENT lpEventTrack)
{
- PDESKTOP pDesk;
- PTHREADINFO pti;
- PWND pWnd;
- POINT point;
-
- pti = PsGetCurrentThreadWin32Thread();
- pDesk = pti->rpdesk;
-
- if (!(pWnd = UserGetWindowObject(lpEventTrack->hwndTrack)))
- return FALSE;
-
- if ( pDesk->spwndTrack != pWnd ||
- (pDesk->htEx != HTCLIENT) ^ !!(lpEventTrack->dwFlags & TME_NONCLIENT) )
- {
- if ( lpEventTrack->dwFlags & TME_LEAVE && !(lpEventTrack->dwFlags & TME_CANCEL) )
- {
- UserPostMessage( lpEventTrack->hwndTrack,
- lpEventTrack->dwFlags & TME_NONCLIENT ? WM_NCMOUSELEAVE : WM_MOUSELEAVE,
- 0, 0);
- }
- TRACE("IntTrackMouseEvent spwndTrack 0x%x pwnd 0x%x\n", pDesk->spwndTrack,pWnd);
- return TRUE;
- }
-
- /* Tracking spwndTrack same as pWnd */
- if ( lpEventTrack->dwFlags & TME_CANCEL ) // Canceled mode.
- {
- if ( lpEventTrack->dwFlags & TME_LEAVE )
- pDesk->dwDTFlags &= ~DF_TME_LEAVE;
-
- if ( lpEventTrack->dwFlags & TME_HOVER )
- {
- if ( pDesk->dwDTFlags & DF_TME_HOVER )
- { // Kill hover timer.
- IntKillTimer(pWnd, ID_EVENT_SYSTIMER_MOUSEHOVER, TRUE);
- pDesk->dwDTFlags &= ~DF_TME_HOVER;
- }
- }
- }
- else // Not Canceled.
- {
- if ( lpEventTrack->dwFlags & TME_LEAVE )
- pDesk->dwDTFlags |= DF_TME_LEAVE;
-
- if ( lpEventTrack->dwFlags & TME_HOVER )
- {
- pDesk->dwDTFlags |= DF_TME_HOVER;
-
- if ( !lpEventTrack->dwHoverTime || lpEventTrack->dwHoverTime == HOVER_DEFAULT )
- pDesk->dwMouseHoverTime = gspv.iMouseHoverTime; // use the system default hover time-out.
- else
- pDesk->dwMouseHoverTime = lpEventTrack->dwHoverTime;
- // Start timer for the hover period.
- IntSetTimer( pWnd, ID_EVENT_SYSTIMER_MOUSEHOVER, pDesk->dwMouseHoverTime, SystemTimerProc, TMRF_SYSTEM);
- // Get windows thread message points.
- point = pWnd->head.pti->ptLast;
- // Set desktop mouse hover from the system default hover rectangle.
- RECTL_vSetRect(&pDesk->rcMouseHover,
- point.x - gspv.iMouseHoverWidth / 2,
- point.y - gspv.iMouseHoverHeight / 2,
- point.x + gspv.iMouseHoverWidth / 2,
- point.y + gspv.iMouseHoverHeight / 2);
- }
- }
- return TRUE;
+ PDESKTOP pDesk;
+ PTHREADINFO pti;
+ PWND pWnd;
+ POINT point;
+
+ pti = PsGetCurrentThreadWin32Thread();
+ pDesk = pti->rpdesk;
+
+ if (!(pWnd = UserGetWindowObject(lpEventTrack->hwndTrack)))
+ return FALSE;
+
+ if ( pDesk->spwndTrack != pWnd ||
+ (pDesk->htEx != HTCLIENT) ^ !!(lpEventTrack->dwFlags & TME_NONCLIENT) )
+ {
+ if ( lpEventTrack->dwFlags & TME_LEAVE && !(lpEventTrack->dwFlags & TME_CANCEL) )
+ {
+ UserPostMessage( lpEventTrack->hwndTrack,
+ lpEventTrack->dwFlags & TME_NONCLIENT ? WM_NCMOUSELEAVE : WM_MOUSELEAVE,
+ 0, 0);
+ }
+ TRACE("IntTrackMouseEvent spwndTrack 0x%x pwnd 0x%x\n", pDesk->spwndTrack, pWnd);
+ return TRUE;
+ }
+
+ /* Tracking spwndTrack same as pWnd */
+ if ( lpEventTrack->dwFlags & TME_CANCEL ) // Canceled mode.
+ {
+ if ( lpEventTrack->dwFlags & TME_LEAVE )
+ pDesk->dwDTFlags &= ~DF_TME_LEAVE;
+
+ if ( lpEventTrack->dwFlags & TME_HOVER )
+ {
+ if ( pDesk->dwDTFlags & DF_TME_HOVER )
+ { // Kill hover timer.
+ IntKillTimer(pWnd, ID_EVENT_SYSTIMER_MOUSEHOVER, TRUE);
+ pDesk->dwDTFlags &= ~DF_TME_HOVER;
+ }
+ }
+ }
+ else // Not Canceled.
+ {
+ if ( lpEventTrack->dwFlags & TME_LEAVE )
+ pDesk->dwDTFlags |= DF_TME_LEAVE;
+
+ if ( lpEventTrack->dwFlags & TME_HOVER )
+ {
+ pDesk->dwDTFlags |= DF_TME_HOVER;
+
+ if ( !lpEventTrack->dwHoverTime || lpEventTrack->dwHoverTime == HOVER_DEFAULT )
+ pDesk->dwMouseHoverTime = gspv.iMouseHoverTime; // use the system default hover time-out.
+ else
+ pDesk->dwMouseHoverTime = lpEventTrack->dwHoverTime;
+ // Start timer for the hover period.
+ IntSetTimer( pWnd, ID_EVENT_SYSTIMER_MOUSEHOVER, pDesk->dwMouseHoverTime, SystemTimerProc, TMRF_SYSTEM);
+ // Get windows thread message points.
+ point = pWnd->head.pti->ptLast;
+ // Set desktop mouse hover from the system default hover rectangle.
+ RECTL_vSetRect(&pDesk->rcMouseHover,
+ point.x - gspv.iMouseHoverWidth / 2,
+ point.y - gspv.iMouseHoverHeight / 2,
+ point.x + gspv.iMouseHoverWidth / 2,
+ point.y + gspv.iMouseHoverHeight / 2);
+ }
+ }
+ return TRUE;
}
BOOL
APIENTRY
NtUserTrackMouseEvent(
- LPTRACKMOUSEEVENT lpEventTrack)
+ LPTRACKMOUSEEVENT lpEventTrack)
{
- TRACKMOUSEEVENT saveTME;
- BOOL Ret = FALSE;
-
- TRACE("Enter NtUserTrackMouseEvent\n");
- UserEnterExclusive();
-
- _SEH2_TRY
- {
- ProbeForRead(lpEventTrack, sizeof(TRACKMOUSEEVENT), 1);
- RtlCopyMemory(&saveTME, lpEventTrack, sizeof(TRACKMOUSEEVENT));
- }
- _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
- {
- SetLastNtError(_SEH2_GetExceptionCode());
- _SEH2_YIELD(goto Exit;)
- }
- _SEH2_END;
-
- if ( saveTME.cbSize != sizeof(TRACKMOUSEEVENT) )
- {
- EngSetLastError(ERROR_INVALID_PARAMETER);
- goto Exit;
- }
-
- if (saveTME.dwFlags & ~(TME_CANCEL|TME_QUERY|TME_NONCLIENT|TME_LEAVE|TME_HOVER) )
- {
- EngSetLastError(ERROR_INVALID_FLAGS);
- goto Exit;
- }
-
- if ( saveTME.dwFlags & TME_QUERY )
- {
- Ret = IntQueryTrackMouseEvent(&saveTME);
- _SEH2_TRY
- {
- ProbeForWrite(lpEventTrack, sizeof(TRACKMOUSEEVENT), 1);
- RtlCopyMemory(lpEventTrack, &saveTME, sizeof(TRACKMOUSEEVENT));
- }
- _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
- {
- SetLastNtError(_SEH2_GetExceptionCode());
- Ret = FALSE;
- }
- _SEH2_END;
- }
- else
- {
- Ret = IntTrackMouseEvent(&saveTME);
- }
-
+ TRACKMOUSEEVENT saveTME;
+ BOOL Ret = FALSE;
+
+ TRACE("Enter NtUserTrackMouseEvent\n");
+ UserEnterExclusive();
+
+ _SEH2_TRY
+ {
+ ProbeForRead(lpEventTrack, sizeof(TRACKMOUSEEVENT), 1);
+ RtlCopyMemory(&saveTME, lpEventTrack, sizeof(TRACKMOUSEEVENT));
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ SetLastNtError(_SEH2_GetExceptionCode());
+ _SEH2_YIELD(goto Exit;)
+ }
+ _SEH2_END;
+
+ if ( saveTME.cbSize != sizeof(TRACKMOUSEEVENT) )
+ {
+ EngSetLastError(ERROR_INVALID_PARAMETER);
+ goto Exit;
+ }
+
+ if (saveTME.dwFlags & ~(TME_CANCEL | TME_QUERY | TME_NONCLIENT | TME_LEAVE | TME_HOVER) )
+ {
+ EngSetLastError(ERROR_INVALID_FLAGS);
+ goto Exit;
+ }
+
+ if ( saveTME.dwFlags & TME_QUERY )
+ {
+ Ret = IntQueryTrackMouseEvent(&saveTME);
+ _SEH2_TRY
+ {
+ ProbeForWrite(lpEventTrack, sizeof(TRACKMOUSEEVENT), 1);
+ RtlCopyMemory(lpEventTrack, &saveTME, sizeof(TRACKMOUSEEVENT));
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ SetLastNtError(_SEH2_GetExceptionCode());
+ Ret = FALSE;
+ }
+ _SEH2_END;
+ }
+ else
+ {
+ Ret = IntTrackMouseEvent(&saveTME);
+ }
+
Exit:
- TRACE("Leave NtUserTrackMouseEvent, ret=%i\n",Ret);
- UserLeave();
- return Ret;
+ TRACE("Leave NtUserTrackMouseEvent, ret=%i\n", Ret);
+ UserLeave();
+ return Ret;
}
extern MOUSEMOVEPOINT MouseHistoryOfMoves[];
-extern INT gcur_count;
+extern INT gcur_count;
DWORD
APIENTRY
NtUserGetMouseMovePointsEx(
- UINT cbSize,
- LPMOUSEMOVEPOINT lpptIn,
- LPMOUSEMOVEPOINT lpptOut,
- int nBufPoints,
- DWORD resolution)
+ UINT cbSize,
+ LPMOUSEMOVEPOINT lpptIn,
+ LPMOUSEMOVEPOINT lpptOut,
+ int nBufPoints,
+ DWORD resolution)
{
- MOUSEMOVEPOINT Safeppt;
- BOOL Hit;
- INT Count = -1;
- DECLARE_RETURN(DWORD);
-
- TRACE("Enter NtUserGetMouseMovePointsEx\n");
- UserEnterExclusive();
-
- if ((cbSize != sizeof(MOUSEMOVEPOINT)) || (nBufPoints < 0) || (nBufPoints > 64))
- {
- EngSetLastError(ERROR_INVALID_PARAMETER);
- RETURN( -1);
- }
-
- if (!lpptIn || (!lpptOut && nBufPoints))
- {
- EngSetLastError(ERROR_NOACCESS);
- RETURN( -1);
- }
-
- _SEH2_TRY
- {
- ProbeForRead( lpptIn, cbSize, 1);
- RtlCopyMemory(&Safeppt, lpptIn, cbSize);
- }
- _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
- {
- SetLastNtError(_SEH2_GetExceptionCode());
- _SEH2_YIELD(RETURN( -1))
- }
- _SEH2_END;
-
- // http://msdn.microsoft.com/en-us/library/ms646259(v=vs.85).aspx
- // This explains the math issues in transforming points.
- Count = gcur_count; // FIFO is forward so retrieve backward.
- Hit = FALSE;
- do
- {
- if (Safeppt.x == 0 && Safeppt.y == 0)
- break; // No test.
- // Finds the point, it returns the last nBufPoints prior to and including the supplied point.
- if (MouseHistoryOfMoves[Count].x == Safeppt.x && MouseHistoryOfMoves[Count].y == Safeppt.y)
- {
- if ( Safeppt.time ) // Now test time and it seems to be absolute.
- {
- if (Safeppt.time == MouseHistoryOfMoves[Count].time)
- {
- Hit = TRUE;
- break;
- }
- else
- {
- if (--Count < 0) Count = 63;
- continue;
- }
- }
- Hit = TRUE;
- break;
- }
- if (--Count < 0) Count = 63;
- }
- while ( Count != gcur_count);
-
- switch(resolution)
- {
- case GMMP_USE_DISPLAY_POINTS:
- if (nBufPoints)
+ MOUSEMOVEPOINT Safeppt;
+ BOOL Hit;
+ INT Count = -1;
+ DECLARE_RETURN(DWORD);
+
+ TRACE("Enter NtUserGetMouseMovePointsEx\n");
+ UserEnterExclusive();
+
+ if ((cbSize != sizeof(MOUSEMOVEPOINT)) || (nBufPoints < 0) || (nBufPoints > 64))
+ {
+ EngSetLastError(ERROR_INVALID_PARAMETER);
+ RETURN( -1);
+ }
+
+ if (!lpptIn || (!lpptOut && nBufPoints))
+ {
+ EngSetLastError(ERROR_NOACCESS);
+ RETURN( -1);
+ }
+
+ _SEH2_TRY
+ {
+ ProbeForRead( lpptIn, cbSize, 1);
+ RtlCopyMemory(&Safeppt, lpptIn, cbSize);
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ SetLastNtError(_SEH2_GetExceptionCode());
+ _SEH2_YIELD(RETURN( -1))
+ }
+ _SEH2_END;
+
+ // http://msdn.microsoft.com/en-us/library/ms646259(v=vs.85).aspx
+ // This explains the math issues in transforming points.
+ Count = gcur_count; // FIFO is forward so retrieve backward.
+ Hit = FALSE;
+ do
+ {
+ if (Safeppt.x == 0 && Safeppt.y == 0)
+ break; // No test.
+ // Finds the point, it returns the last nBufPoints prior to and including the supplied point.
+ if (MouseHistoryOfMoves[Count].x == Safeppt.x && MouseHistoryOfMoves[Count].y == Safeppt.y)
{
- _SEH2_TRY
- {
- ProbeForWrite(lpptOut, cbSize, 1);
- }
- _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
- {
- SetLastNtError(_SEH2_GetExceptionCode());
- _SEH2_YIELD(RETURN( -1))
- }
- _SEH2_END;
+ if ( Safeppt.time ) // Now test time and it seems to be absolute.
+ {
+ if (Safeppt.time == MouseHistoryOfMoves[Count].time)
+ {
+ Hit = TRUE;
+ break;
+ }
+ else
+ {
+ if (--Count < 0) Count = 63;
+ continue;
+ }
+ }
+ Hit = TRUE;
+ break;
}
- Count = nBufPoints;
- break;
- case GMMP_USE_HIGH_RESOLUTION_POINTS:
- break;
- default:
- EngSetLastError(ERROR_POINT_NOT_FOUND);
- RETURN( -1);
- }
+ if (--Count < 0) Count = 63;
+ }
+ while ( Count != gcur_count);
+
+ switch(resolution)
+ {
+ case GMMP_USE_DISPLAY_POINTS:
+ if (nBufPoints)
+ {
+ _SEH2_TRY
+ {
+ ProbeForWrite(lpptOut, cbSize, 1);
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ SetLastNtError(_SEH2_GetExceptionCode());
+ _SEH2_YIELD(RETURN( -1))
+ }
+ _SEH2_END;
+ }
+ Count = nBufPoints;
+ break;
+ case GMMP_USE_HIGH_RESOLUTION_POINTS:
+ break;
+ default:
+ EngSetLastError(ERROR_POINT_NOT_FOUND);
+ RETURN( -1);
+ }
- RETURN( Count);
+ RETURN( Count);
CLEANUP:
- TRACE("Leave NtUserGetMouseMovePointsEx, ret=%i\n",_ret_);
- UserLeave();
- END_CLEANUP;
+ TRACE("Leave NtUserGetMouseMovePointsEx, ret=%i\n", _ret_);
+ UserLeave();
+ END_CLEANUP;
}
/* EOF */
NTAPI
InitKeyboardImpl(VOID)
{
- RtlZeroMemory(&gKeyStateTable, 0x100);
- return STATUS_SUCCESS;
+ RtlZeroMemory(&gKeyStateTable, 0x100);
+ return STATUS_SUCCESS;
}
/*** Statics used by TranslateMessage ***/
static UINT DontDistinguishShifts( UINT ret )
{
- if( ret == VK_LSHIFT || ret == VK_RSHIFT )
- ret = VK_SHIFT;
- if( ret == VK_LCONTROL || ret == VK_RCONTROL )
- ret = VK_CONTROL;
- if( ret == VK_LMENU || ret == VK_RMENU )
- ret = VK_MENU;
- return ret;
+ if( ret == VK_LSHIFT || ret == VK_RSHIFT )
+ ret = VK_SHIFT;
+ if( ret == VK_LCONTROL || ret == VK_RCONTROL )
+ ret = VK_CONTROL;
+ if( ret == VK_LMENU || ret == VK_RMENU )
+ ret = VK_MENU;
+ return ret;
}
static VOID APIENTRY SetKeyState(DWORD key, DWORD vk, DWORD ext, BOOL down)
{
- ASSERT(vk <= 0xff);
-
- /* Special handling for toggles like numpad and caps lock */
- if (vk == VK_CAPITAL || vk == VK_NUMLOCK)
- {
- if (down)
- gKeyStateTable[vk] ^= KS_LOCK_BIT;
- }
-
- if (vk == VK_SHIFT)
- vk = ext ? VK_RSHIFT : VK_LSHIFT;
- if (vk == VK_CONTROL)
- vk = ext ? VK_RCONTROL : VK_LCONTROL;
- if (vk == VK_MENU)
- vk = ext ? VK_RMENU : VK_LMENU;
-
- if (down)
- gKeyStateTable[vk] |= KS_DOWN_BIT;
- else
- gKeyStateTable[vk] &= ~KS_DOWN_BIT;
-
- if (vk == VK_LSHIFT || vk == VK_RSHIFT)
- {
- if ((gKeyStateTable[VK_LSHIFT] & KS_DOWN_BIT) ||
- (gKeyStateTable[VK_RSHIFT] & KS_DOWN_BIT))
- {
- gKeyStateTable[VK_SHIFT] |= KS_DOWN_BIT;
- }
- else
- {
- gKeyStateTable[VK_SHIFT] &= ~KS_DOWN_BIT;
- }
- }
-
- if (vk == VK_LCONTROL || vk == VK_RCONTROL)
- {
- if ((gKeyStateTable[VK_LCONTROL] & KS_DOWN_BIT) ||
- (gKeyStateTable[VK_RCONTROL] & KS_DOWN_BIT))
- {
- gKeyStateTable[VK_CONTROL] |= KS_DOWN_BIT;
- }
- else
- {
- gKeyStateTable[VK_CONTROL] &= ~KS_DOWN_BIT;
- }
- }
-
- if (vk == VK_LMENU || vk == VK_RMENU)
- {
- if ((gKeyStateTable[VK_LMENU] & KS_DOWN_BIT) ||
- (gKeyStateTable[VK_RMENU] & KS_DOWN_BIT))
- {
- gKeyStateTable[VK_MENU] |= KS_DOWN_BIT;
- }
- else
- {
- gKeyStateTable[VK_MENU] &= ~KS_DOWN_BIT;
- }
- }
+ ASSERT(vk <= 0xff);
+
+ /* Special handling for toggles like numpad and caps lock */
+ if (vk == VK_CAPITAL || vk == VK_NUMLOCK)
+ {
+ if (down)
+ gKeyStateTable[vk] ^= KS_LOCK_BIT;
+ }
+
+ if (vk == VK_SHIFT)
+ vk = ext ? VK_RSHIFT : VK_LSHIFT;
+ if (vk == VK_CONTROL)
+ vk = ext ? VK_RCONTROL : VK_LCONTROL;
+ if (vk == VK_MENU)
+ vk = ext ? VK_RMENU : VK_LMENU;
+
+ if (down)
+ gKeyStateTable[vk] |= KS_DOWN_BIT;
+ else
+ gKeyStateTable[vk] &= ~KS_DOWN_BIT;
+
+ if (vk == VK_LSHIFT || vk == VK_RSHIFT)
+ {
+ if ((gKeyStateTable[VK_LSHIFT] & KS_DOWN_BIT) ||
+ (gKeyStateTable[VK_RSHIFT] & KS_DOWN_BIT))
+ {
+ gKeyStateTable[VK_SHIFT] |= KS_DOWN_BIT;
+ }
+ else
+ {
+ gKeyStateTable[VK_SHIFT] &= ~KS_DOWN_BIT;
+ }
+ }
+
+ if (vk == VK_LCONTROL || vk == VK_RCONTROL)
+ {
+ if ((gKeyStateTable[VK_LCONTROL] & KS_DOWN_BIT) ||
+ (gKeyStateTable[VK_RCONTROL] & KS_DOWN_BIT))
+ {
+ gKeyStateTable[VK_CONTROL] |= KS_DOWN_BIT;
+ }
+ else
+ {
+ gKeyStateTable[VK_CONTROL] &= ~KS_DOWN_BIT;
+ }
+ }
+
+ if (vk == VK_LMENU || vk == VK_RMENU)
+ {
+ if ((gKeyStateTable[VK_LMENU] & KS_DOWN_BIT) ||
+ (gKeyStateTable[VK_RMENU] & KS_DOWN_BIT))
+ {
+ gKeyStateTable[VK_MENU] |= KS_DOWN_BIT;
+ }
+ else
+ {
+ gKeyStateTable[VK_MENU] &= ~KS_DOWN_BIT;
+ }
+ }
}
VOID DumpKeyState( PBYTE KeyState )
{
- int i;
-
- DbgPrint( "KeyState { " );
- for( i = 0; i < 0x100; i++ )
- {
- if( KeyState[i] )
- DbgPrint( "%02x(%02x) ", i, KeyState[i] );
- }
- DbgPrint( "};\n" );
+ int i;
+
+ DbgPrint( "KeyState { " );
+ for( i = 0; i < 0x100; i++ )
+ {
+ if( KeyState[i] )
+ DbgPrint( "%02x(%02x) ", i, KeyState[i] );
+ }
+ DbgPrint( "};\n" );
}
static BYTE KeysSet( PKBDTABLES pkKT, PBYTE KeyState,
int FakeModLeft, int FakeModRight )
{
- if( !KeyState || !pkKT )
- return 0;
+ if( !KeyState || !pkKT )
+ return 0;
- /* Search special codes first */
- if( FakeModLeft && KeyState[FakeModLeft] )
- return KeyState[FakeModLeft];
- else if( FakeModRight && KeyState[FakeModRight] )
- return KeyState[FakeModRight];
+ /* Search special codes first */
+ if( FakeModLeft && KeyState[FakeModLeft] )
+ return KeyState[FakeModLeft];
+ else if( FakeModRight && KeyState[FakeModRight] )
+ return KeyState[FakeModRight];
- return 0;
+ return 0;
}
/* Search the keyboard layout modifiers table for the shift bit. I don't
static DWORD FASTCALL GetShiftBit( PKBDTABLES pkKT, DWORD Vk )
{
- int i;
+ int i;
- for( i = 0; pkKT->pCharModifiers->pVkToBit[i].Vk; i++ )
- if( pkKT->pCharModifiers->pVkToBit[i].Vk == Vk )
- return pkKT->pCharModifiers->pVkToBit[i].ModBits;
+ for( i = 0; pkKT->pCharModifiers->pVkToBit[i].Vk; i++ )
+ if( pkKT->pCharModifiers->pVkToBit[i].Vk == Vk )
+ return pkKT->pCharModifiers->pVkToBit[i].ModBits;
- return 0;
+ return 0;
}
static DWORD ModBits( PKBDTABLES pkKT, PBYTE KeyState )
{
- DWORD ModBits = 0;
+ DWORD ModBits = 0;
- if( !KeyState )
- return 0;
+ if( !KeyState )
+ return 0;
- /* DumpKeyState( KeyState ); */
+ /* DumpKeyState( KeyState ); */
- if (KeysSet( pkKT, KeyState, VK_LSHIFT, VK_RSHIFT ) &
- KS_DOWN_BIT)
- ModBits |= GetShiftBit( pkKT, VK_SHIFT );
+ if (KeysSet( pkKT, KeyState, VK_LSHIFT, VK_RSHIFT ) &
+ KS_DOWN_BIT)
+ ModBits |= GetShiftBit( pkKT, VK_SHIFT );
- if (KeysSet( pkKT, KeyState, VK_SHIFT, 0 ) &
- KS_DOWN_BIT)
- ModBits |= GetShiftBit( pkKT, VK_SHIFT );
+ if (KeysSet( pkKT, KeyState, VK_SHIFT, 0 ) &
+ KS_DOWN_BIT)
+ ModBits |= GetShiftBit( pkKT, VK_SHIFT );
- if (KeysSet( pkKT, KeyState, VK_LCONTROL, VK_RCONTROL ) &
- KS_DOWN_BIT )
- ModBits |= GetShiftBit( pkKT, VK_CONTROL );
+ if (KeysSet( pkKT, KeyState, VK_LCONTROL, VK_RCONTROL ) &
+ KS_DOWN_BIT )
+ ModBits |= GetShiftBit( pkKT, VK_CONTROL );
- if (KeysSet( pkKT, KeyState, VK_CONTROL, 0 ) &
- KS_DOWN_BIT )
- ModBits |= GetShiftBit( pkKT, VK_CONTROL );
+ if (KeysSet( pkKT, KeyState, VK_CONTROL, 0 ) &
+ KS_DOWN_BIT )
+ ModBits |= GetShiftBit( pkKT, VK_CONTROL );
- if (KeysSet( pkKT, KeyState, VK_LMENU, VK_RMENU ) &
- KS_DOWN_BIT )
- ModBits |= GetShiftBit( pkKT, VK_MENU );
+ if (KeysSet( pkKT, KeyState, VK_LMENU, VK_RMENU ) &
+ KS_DOWN_BIT )
+ ModBits |= GetShiftBit( pkKT, VK_MENU );
- /* Handle Alt+Gr */
- if (pkKT->fLocalFlags & 0x1)
- if (KeysSet( pkKT, KeyState, VK_RMENU, 0 ) &
- KS_DOWN_BIT)
- ModBits |= GetShiftBit( pkKT, VK_CONTROL );
+ /* Handle Alt+Gr */
+ if (pkKT->fLocalFlags & 0x1)
+ if (KeysSet( pkKT, KeyState, VK_RMENU, 0 ) &
+ KS_DOWN_BIT)
+ ModBits |= GetShiftBit( pkKT, VK_CONTROL );
- /* Deal with VK_CAPITAL */
- if (KeysSet( pkKT, KeyState, VK_CAPITAL, 0 ) & KS_LOCK_BIT)
- {
- ModBits |= CAPITAL_BIT;
- }
+ /* Deal with VK_CAPITAL */
+ if (KeysSet( pkKT, KeyState, VK_CAPITAL, 0 ) & KS_LOCK_BIT)
+ {
+ ModBits |= CAPITAL_BIT;
+ }
- /* Deal with VK_NUMLOCK */
- if (KeysSet( pkKT, KeyState, VK_NUMLOCK, 0 ) & KS_LOCK_BIT)
- {
- ModBits |= NUMLOCK_BIT;
- }
+ /* Deal with VK_NUMLOCK */
+ if (KeysSet( pkKT, KeyState, VK_NUMLOCK, 0 ) & KS_LOCK_BIT)
+ {
+ ModBits |= NUMLOCK_BIT;
+ }
- TRACE( "Current Mod Bits: %x\n", ModBits );
+ TRACE( "Current Mod Bits: %x\n", ModBits );
- return ModBits;
+ return ModBits;
}
static BOOL TryToTranslateChar(WORD wVirtKey,
PWCHAR pwcTranslatedChar,
PKBDTABLES keyLayout )
{
- PVK_TO_WCHAR_TABLE vtwTbl;
- PVK_TO_WCHARS10 vkPtr;
- size_t size_this_entry;
- int nMod;
- DWORD CapsMod = 0, CapsState = 0;
-
- CapsState = ModBits & ~MOD_BITS_MASK;
- ModBits = ModBits & MOD_BITS_MASK;
-
- TRACE ( "TryToTranslate: %04x %x\n", wVirtKey, ModBits );
-
- if (ModBits > keyLayout->pCharModifiers->wMaxModBits)
- {
- return FALSE;
- }
-
- for (nMod = 0; keyLayout->pVkToWcharTable[nMod].nModifications; nMod++)
- {
- vtwTbl = &keyLayout->pVkToWcharTable[nMod];
- size_this_entry = vtwTbl->cbSize;
- vkPtr = (PVK_TO_WCHARS10)((BYTE *)vtwTbl->pVkToWchars);
- while(vkPtr->VirtualKey)
- {
- if( wVirtKey == (vkPtr->VirtualKey & 0xff) )
- {
- CapsMod = keyLayout->pCharModifiers->ModNumber
- [ModBits ^
- ((CapsState & CAPITAL_BIT) ? vkPtr->Attributes : 0)];
-
- if( CapsMod >= keyLayout->pVkToWcharTable[nMod].nModifications )
- {
- return FALSE;
- }
+ PVK_TO_WCHAR_TABLE vtwTbl;
+ PVK_TO_WCHARS10 vkPtr;
+ size_t size_this_entry;
+ int nMod;
+ DWORD CapsMod = 0, CapsState = 0;
- if( vkPtr->wch[CapsMod] == WCH_NONE )
- {
- return FALSE;
- }
+ CapsState = ModBits & ~MOD_BITS_MASK;
+ ModBits = ModBits & MOD_BITS_MASK;
- *pbDead = vkPtr->wch[CapsMod] == WCH_DEAD;
- *pbLigature = vkPtr->wch[CapsMod] == WCH_LGTR;
- *pwcTranslatedChar = vkPtr->wch[CapsMod];
+ TRACE ( "TryToTranslate: %04x %x\n", wVirtKey, ModBits );
- TRACE("%d %04x: CapsMod %08x CapsState %08x Char %04x\n",
- nMod, wVirtKey,
- CapsMod, CapsState, *pwcTranslatedChar);
+ if (ModBits > keyLayout->pCharModifiers->wMaxModBits)
+ {
+ return FALSE;
+ }
- if( *pbDead )
+ for (nMod = 0; keyLayout->pVkToWcharTable[nMod].nModifications; nMod++)
+ {
+ vtwTbl = &keyLayout->pVkToWcharTable[nMod];
+ size_this_entry = vtwTbl->cbSize;
+ vkPtr = (PVK_TO_WCHARS10)((BYTE *)vtwTbl->pVkToWchars);
+ while(vkPtr->VirtualKey)
+ {
+ if( wVirtKey == (vkPtr->VirtualKey & 0xff) )
{
- vkPtr = (PVK_TO_WCHARS10)(((BYTE *)vkPtr) + size_this_entry);
- if( vkPtr->VirtualKey != 0xff )
- {
- TRACE( "Found dead key with no trailer in the table.\n" );
- TRACE( "VK: %04x, ADDR: %p\n", wVirtKey, vkPtr );
- return FALSE;
- }
- *pwcTranslatedChar = vkPtr->wch[CapsMod];
+ CapsMod = keyLayout->pCharModifiers->ModNumber
+ [ModBits ^
+ ((CapsState & CAPITAL_BIT) ? vkPtr->Attributes : 0)];
+
+ if( CapsMod >= keyLayout->pVkToWcharTable[nMod].nModifications )
+ {
+ return FALSE;
+ }
+
+ if( vkPtr->wch[CapsMod] == WCH_NONE )
+ {
+ return FALSE;
+ }
+
+ *pbDead = vkPtr->wch[CapsMod] == WCH_DEAD;
+ *pbLigature = vkPtr->wch[CapsMod] == WCH_LGTR;
+ *pwcTranslatedChar = vkPtr->wch[CapsMod];
+
+ TRACE("%d %04x: CapsMod %08x CapsState %08x Char %04x\n",
+ nMod, wVirtKey,
+ CapsMod, CapsState, *pwcTranslatedChar);
+
+ if( *pbDead )
+ {
+ vkPtr = (PVK_TO_WCHARS10)(((BYTE *)vkPtr) + size_this_entry);
+ if( vkPtr->VirtualKey != 0xff )
+ {
+ TRACE( "Found dead key with no trailer in the table.\n" );
+ TRACE( "VK: %04x, ADDR: %p\n", wVirtKey, vkPtr );
+ return FALSE;
+ }
+ *pwcTranslatedChar = vkPtr->wch[CapsMod];
+ }
+ return TRUE;
}
- return TRUE;
- }
- vkPtr = (PVK_TO_WCHARS10)(((BYTE *)vkPtr) + size_this_entry);
- }
- }
- return FALSE;
+ vkPtr = (PVK_TO_WCHARS10)(((BYTE *)vkPtr) + size_this_entry);
+ }
+ }
+ return FALSE;
}
static
UINT wFlags,
PKBDTABLES pkKT)
{
- WCHAR wcTranslatedChar;
- BOOL bDead;
- BOOL bLigature;
-
- if( !pkKT )
- return 0;
-
- if( TryToTranslateChar( wVirtKey,
- ModBits( pkKT, lpKeyState ),
- &bDead,
- &bLigature,
- &wcTranslatedChar,
- pkKT ) )
- {
- if( bLigature )
- {
- WARN("Not handling ligature (yet)\n" );
- return 0;
- }
-
- if( cchBuff > 0 )
- pwszBuff[0] = wcTranslatedChar;
-
- return bDead ? -1 : 1;
- }
-
- return 0;
+ WCHAR wcTranslatedChar;
+ BOOL bDead;
+ BOOL bLigature;
+
+ if( !pkKT )
+ return 0;
+
+ if( TryToTranslateChar( wVirtKey,
+ ModBits( pkKT, lpKeyState ),
+ &bDead,
+ &bLigature,
+ &wcTranslatedChar,
+ pkKT ) )
+ {
+ if( bLigature )
+ {
+ WARN("Not handling ligature (yet)\n" );
+ return 0;
+ }
+
+ if( cchBuff > 0 )
+ pwszBuff[0] = wcTranslatedChar;
+
+ return bDead ? -1 : 1;
+ }
+
+ return 0;
}
DWORD FASTCALL UserGetAsyncKeyState(DWORD key)
{
- DWORD ret = 0;
-
- if( key < 0x100 )
- {
- ret = ((DWORD)(gKeyStateTable[key] & KS_DOWN_BIT) << 8 ) |
- (gKeyStateTable[key] & KS_LOCK_BIT);
- if ( ret & 0x8000 )
- ret |= 0xFFFF0000; // If down, windows returns 0xFFFF8000.
- }
- else
- {
- EngSetLastError(ERROR_INVALID_PARAMETER);
- }
- return ret;
+ DWORD ret = 0;
+
+ if( key < 0x100 )
+ {
+ ret = ((DWORD)(gKeyStateTable[key] & KS_DOWN_BIT) << 8 ) |
+ (gKeyStateTable[key] & KS_LOCK_BIT);
+ if ( ret & 0x8000 )
+ ret |= 0xFFFF0000; // If down, windows returns 0xFFFF8000.
+ }
+ else
+ {
+ EngSetLastError(ERROR_INVALID_PARAMETER);
+ }
+ return ret;
}
/***********************************************************************
SHORT
APIENTRY
NtUserGetAsyncKeyState(
- INT key)
+ INT key)
{
- DECLARE_RETURN(SHORT);
+ DECLARE_RETURN(SHORT);
- TRACE("Enter NtUserGetAsyncKeyState\n");
- UserEnterExclusive();
+ TRACE("Enter NtUserGetAsyncKeyState\n");
+ UserEnterExclusive();
- RETURN((SHORT)UserGetAsyncKeyState(key));
+ RETURN((SHORT)UserGetAsyncKeyState(key));
CLEANUP:
- TRACE("Leave NtUserGetAsyncKeyState, ret=%i\n",_ret_);
- UserLeave();
- END_CLEANUP;
+ TRACE("Leave NtUserGetAsyncKeyState, ret=%i\n", _ret_);
+ UserLeave();
+ END_CLEANUP;
}
IntTranslateKbdMessage(LPMSG lpMsg,
UINT flags)
{
- PTHREADINFO pti;
- static INT dead_char = 0;
- LONG UState = 0;
- WCHAR wp[2] = { 0 };
- MSG NewMsg = { 0 };
- PKBDTABLES keyLayout;
- PWND pWndMsg;
- BOOL Result = FALSE;
-
- pWndMsg = UserGetWindowObject(lpMsg->hwnd);
- if (!pWndMsg) // Must have a window!
- {
- ERR("No Window for Translate.\n");
- return FALSE;
- }
-
- pti = pWndMsg->head.pti;
- keyLayout = pti->KeyboardLayout->KBTables;
- if( !keyLayout )
- return FALSE;
-
- if (lpMsg->message < WM_KEYFIRST || lpMsg->message > WM_KEYLAST)
- return FALSE;
- if (lpMsg->message != WM_KEYDOWN && lpMsg->message != WM_SYSKEYDOWN)
- return FALSE;
-
- /* All messages have to contain the cursor point. */
- NewMsg.pt = gpsi->ptCursor;
-
- TRACE("IntTranslateKbdMessage %s\n", lpMsg->message == WM_SYSKEYDOWN ? "WM_SYSKEYDOWN" : "WM_KEYDOWN");
+ PTHREADINFO pti;
+ static INT dead_char = 0;
+ LONG UState = 0;
+ WCHAR wp[2] = { 0 };
+ MSG NewMsg = { 0 };
+ PKBDTABLES keyLayout;
+ PWND pWndMsg;
+ BOOL Result = FALSE;
+
+ pWndMsg = UserGetWindowObject(lpMsg->hwnd);
+ if (!pWndMsg) // Must have a window!
+ {
+ ERR("No Window for Translate.\n");
+ return FALSE;
+ }
+
+ pti = pWndMsg->head.pti;
+ keyLayout = pti->KeyboardLayout->KBTables;
+ if( !keyLayout )
+ return FALSE;
+
+ if (lpMsg->message < WM_KEYFIRST || lpMsg->message > WM_KEYLAST)
+ return FALSE;
+ if (lpMsg->message != WM_KEYDOWN && lpMsg->message != WM_SYSKEYDOWN)
+ return FALSE;
+
+ /* All messages have to contain the cursor point. */
+ NewMsg.pt = gpsi->ptCursor;
+
+ TRACE("IntTranslateKbdMessage %s\n", lpMsg->message == WM_SYSKEYDOWN ? "WM_SYSKEYDOWN" : "WM_KEYDOWN");
switch (lpMsg->wParam)
{
- case VK_PACKET:
- NewMsg.message = (lpMsg->message == WM_KEYDOWN) ? WM_CHAR : WM_SYSCHAR;
- NewMsg.hwnd = lpMsg->hwnd;
- NewMsg.wParam = HIWORD(lpMsg->lParam);
- NewMsg.lParam = LOWORD(lpMsg->lParam);
- MsqPostMessage(pti->MessageQueue, &NewMsg, FALSE, QS_KEY);
- return TRUE;
+ case VK_PACKET:
+ NewMsg.message = (lpMsg->message == WM_KEYDOWN) ? WM_CHAR : WM_SYSCHAR;
+ NewMsg.hwnd = lpMsg->hwnd;
+ NewMsg.wParam = HIWORD(lpMsg->lParam);
+ NewMsg.lParam = LOWORD(lpMsg->lParam);
+ MsqPostMessage(pti->MessageQueue, &NewMsg, FALSE, QS_KEY);
+ return TRUE;
}
- UState = ToUnicodeInner( lpMsg->wParam,
- HIWORD(lpMsg->lParam) & 0xff,
- gKeyStateTable,
- wp,
- 2,
- 0,
- keyLayout );
-
- if (UState == 1)
- {
- NewMsg.message = (lpMsg->message == WM_KEYDOWN) ? WM_CHAR : WM_SYSCHAR;
- if (dead_char)
- {
- ULONG i;
- WCHAR first, second;
- TRACE("PREVIOUS DEAD CHAR: %c\n", dead_char);
-
- for( i = 0; keyLayout->pDeadKey[i].dwBoth; i++ )
- {
- first = keyLayout->pDeadKey[i].dwBoth >> 16;
- second = keyLayout->pDeadKey[i].dwBoth;
- if (first == dead_char && second == wp[0])
+ UState = ToUnicodeInner( lpMsg->wParam,
+ HIWORD(lpMsg->lParam) & 0xff,
+ gKeyStateTable,
+ wp,
+ 2,
+ 0,
+ keyLayout );
+
+ if (UState == 1)
+ {
+ NewMsg.message = (lpMsg->message == WM_KEYDOWN) ? WM_CHAR : WM_SYSCHAR;
+ if (dead_char)
+ {
+ ULONG i;
+ WCHAR first, second;
+ TRACE("PREVIOUS DEAD CHAR: %c\n", dead_char);
+
+ for( i = 0; keyLayout->pDeadKey[i].dwBoth; i++ )
{
- wp[0] = keyLayout->pDeadKey[i].wchComposed;
- dead_char = 0;
- break;
+ first = keyLayout->pDeadKey[i].dwBoth >> 16;
+ second = keyLayout->pDeadKey[i].dwBoth;
+ if (first == dead_char && second == wp[0])
+ {
+ wp[0] = keyLayout->pDeadKey[i].wchComposed;
+ dead_char = 0;
+ break;
+ }
}
- }
-
- TRACE("FINAL CHAR: %c\n", wp[0]);
- }
-
- if (dead_char)
- {
- NewMsg.hwnd = lpMsg->hwnd;
- NewMsg.wParam = dead_char;
- NewMsg.lParam = lpMsg->lParam;
- dead_char = 0;
- MsqPostMessage(pti->MessageQueue, &NewMsg, FALSE, QS_KEY);
- }
-
- NewMsg.hwnd = lpMsg->hwnd;
- NewMsg.wParam = wp[0];
- NewMsg.lParam = lpMsg->lParam;
- TRACE( "CHAR='%c' %04x %08x\n", wp[0], wp[0], lpMsg->lParam );
- MsqPostMessage(pti->MessageQueue, &NewMsg, FALSE, QS_KEY);
- Result = TRUE;
- }
- else if (UState == -1)
- {
- NewMsg.message =
- (lpMsg->message == WM_KEYDOWN) ? WM_DEADCHAR : WM_SYSDEADCHAR;
- NewMsg.hwnd = lpMsg->hwnd;
- NewMsg.wParam = wp[0];
- NewMsg.lParam = lpMsg->lParam;
- dead_char = wp[0];
- MsqPostMessage(pti->MessageQueue, &NewMsg, FALSE, QS_KEY);
- Result = TRUE;
- }
- TRACE("IntTranslateKbdMessage E %s\n", NewMsg.message == WM_CHAR ? "WM_CHAR" : "WM_SYSCHAR");
- return Result;
+
+ TRACE("FINAL CHAR: %c\n", wp[0]);
+ }
+
+ if (dead_char)
+ {
+ NewMsg.hwnd = lpMsg->hwnd;
+ NewMsg.wParam = dead_char;
+ NewMsg.lParam = lpMsg->lParam;
+ dead_char = 0;
+ MsqPostMessage(pti->MessageQueue, &NewMsg, FALSE, QS_KEY);
+ }
+
+ NewMsg.hwnd = lpMsg->hwnd;
+ NewMsg.wParam = wp[0];
+ NewMsg.lParam = lpMsg->lParam;
+ TRACE( "CHAR='%c' %04x %08x\n", wp[0], wp[0], lpMsg->lParam );
+ MsqPostMessage(pti->MessageQueue, &NewMsg, FALSE, QS_KEY);
+ Result = TRUE;
+ }
+ else if (UState == -1)
+ {
+ NewMsg.message =
+ (lpMsg->message == WM_KEYDOWN) ? WM_DEADCHAR : WM_SYSDEADCHAR;
+ NewMsg.hwnd = lpMsg->hwnd;
+ NewMsg.wParam = wp[0];
+ NewMsg.lParam = lpMsg->lParam;
+ dead_char = wp[0];
+ MsqPostMessage(pti->MessageQueue, &NewMsg, FALSE, QS_KEY);
+ Result = TRUE;
+ }
+ TRACE("IntTranslateKbdMessage E %s\n", NewMsg.message == WM_CHAR ? "WM_CHAR" : "WM_SYSCHAR");
+ return Result;
}
static UINT VkToScan( UINT Code, BOOL ExtCode, PKBDTABLES pkKT )
{
- int i;
+ int i;
- for( i = 0; i < pkKT->bMaxVSCtoVK; i++ )
- {
- if( pkKT->pusVSCtoVK[i] == Code )
- {
- return i;
- }
- }
+ for( i = 0; i < pkKT->bMaxVSCtoVK; i++ )
+ {
+ if( pkKT->pusVSCtoVK[i] == Code )
+ {
+ return i;
+ }
+ }
- return 0;
+ return 0;
}
UINT ScanToVk( UINT Code, BOOL ExtKey, PKBDTABLES pkKT )
{
- if( !pkKT )
- {
- TRACE("ScanToVk: No layout\n");
- return 0;
- }
-
- if( ExtKey )
- {
- int i;
-
- for( i = 0; pkKT->pVSCtoVK_E0[i].Vsc; i++ )
- {
- if( pkKT->pVSCtoVK_E0[i].Vsc == Code )
- return pkKT->pVSCtoVK_E0[i].Vk & 0xff;
- }
- for( i = 0; pkKT->pVSCtoVK_E1[i].Vsc; i++ )
- {
- if( pkKT->pVSCtoVK_E1[i].Vsc == Code )
- return pkKT->pVSCtoVK_E1[i].Vk & 0xff;
- }
-
- return 0;
- }
- else
- {
- if( Code >= pkKT->bMaxVSCtoVK )
- {
- return 0;
- }
- return pkKT->pusVSCtoVK[Code] & 0xff;
- }
+ if( !pkKT )
+ {
+ TRACE("ScanToVk: No layout\n");
+ return 0;
+ }
+
+ if( ExtKey )
+ {
+ int i;
+
+ for( i = 0; pkKT->pVSCtoVK_E0[i].Vsc; i++ )
+ {
+ if( pkKT->pVSCtoVK_E0[i].Vsc == Code )
+ return pkKT->pVSCtoVK_E0[i].Vk & 0xff;
+ }
+ for( i = 0; pkKT->pVSCtoVK_E1[i].Vsc; i++ )
+ {
+ if( pkKT->pVSCtoVK_E1[i].Vsc == Code )
+ return pkKT->pVSCtoVK_E1[i].Vk & 0xff;
+ }
+
+ return 0;
+ }
+ else
+ {
+ if( Code >= pkKT->bMaxVSCtoVK )
+ {
+ return 0;
+ }
+ return pkKT->pusVSCtoVK[Code] & 0xff;
+ }
}
/*
static UINT IntMapVirtualKeyEx( UINT Code, UINT Type, PKBDTABLES keyLayout )
{
- UINT ret = 0;
-
- switch( Type )
- {
- case MAPVK_VK_TO_VSC:
- if( Code == VK_SHIFT )
- Code = VK_LSHIFT;
- if( Code == VK_MENU )
- Code = VK_LMENU;
- if( Code == VK_CONTROL )
- Code = VK_LCONTROL;
- ret = VkToScan( Code, FALSE, keyLayout );
- break;
-
- case MAPVK_VSC_TO_VK:
- ret =
- DontDistinguishShifts
- (IntMapVirtualKeyEx( Code, MAPVK_VSC_TO_VK_EX, keyLayout ) );
- break;
-
- case MAPVK_VK_TO_CHAR:
- {
+ UINT ret = 0;
+
+ switch( Type )
+ {
+ case MAPVK_VK_TO_VSC:
+ if( Code == VK_SHIFT )
+ Code = VK_LSHIFT;
+ if( Code == VK_MENU )
+ Code = VK_LMENU;
+ if( Code == VK_CONTROL )
+ Code = VK_LCONTROL;
+ ret = VkToScan( Code, FALSE, keyLayout );
+ break;
+
+ case MAPVK_VSC_TO_VK:
+ ret =
+ DontDistinguishShifts
+ (IntMapVirtualKeyEx( Code, MAPVK_VSC_TO_VK_EX, keyLayout ) );
+ break;
+
+ case MAPVK_VK_TO_CHAR:
+ {
WCHAR wp[2] = {0};
ret = VkToScan( Code, FALSE, keyLayout );
ToUnicodeInner( Code, ret, 0, wp, 2, 0, keyLayout );
ret = wp[0];
- }
- break;
-
- case MAPVK_VSC_TO_VK_EX:
-
- ret = ScanToVk( Code, FALSE, keyLayout );
- break;
-
- case MAPVK_VK_TO_VSC_EX:
- STUB;
- break;
-
- default:
- ERR("Wrong type value: %u\n", Type);
- }
-
- return ret;
+ }
+ break;
+
+ case MAPVK_VSC_TO_VK_EX:
+
+ ret = ScanToVk( Code, FALSE, keyLayout );
+ break;
+
+ case MAPVK_VK_TO_VSC_EX:
+ STUB;
+ break;
+
+ default:
+ ERR("Wrong type value: %u\n", Type);
+ }
+
+ return ret;
}
UINT
APIENTRY
NtUserMapVirtualKeyEx( UINT Code, UINT Type, DWORD keyboardId, HKL dwhkl )
{
- PTHREADINFO pti;
- PKBDTABLES keyLayout;
- DECLARE_RETURN(UINT);
+ PTHREADINFO pti;
+ PKBDTABLES keyLayout;
+ DECLARE_RETURN(UINT);
- TRACE("Enter NtUserMapVirtualKeyEx\n");
- UserEnterExclusive();
+ TRACE("Enter NtUserMapVirtualKeyEx\n");
+ UserEnterExclusive();
- pti = PsGetCurrentThreadWin32Thread();
- keyLayout = pti ? pti->KeyboardLayout->KBTables : 0;
+ pti = PsGetCurrentThreadWin32Thread();
+ keyLayout = pti ? pti->KeyboardLayout->KBTables : 0;
- if( !keyLayout )
- RETURN(0);
+ if( !keyLayout )
+ RETURN(0);
- RETURN(IntMapVirtualKeyEx( Code, Type, keyLayout ));
+ RETURN(IntMapVirtualKeyEx( Code, Type, keyLayout ));
CLEANUP:
- TRACE("Leave NtUserMapVirtualKeyEx, ret=%i\n",_ret_);
- UserLeave();
- END_CLEANUP;
+ TRACE("Leave NtUserMapVirtualKeyEx, ret=%i\n", _ret_);
+ UserLeave();
+ END_CLEANUP;
}
int
APIENTRY
NtUserToUnicodeEx(
- UINT wVirtKey,
- UINT wScanCode,
- PBYTE lpKeyState,
- LPWSTR pwszBuff,
- int cchBuff,
- UINT wFlags,
- HKL dwhkl )
+ UINT wVirtKey,
+ UINT wScanCode,
+ PBYTE lpKeyState,
+ LPWSTR pwszBuff,
+ int cchBuff,
+ UINT wFlags,
+ HKL dwhkl )
{
- PTHREADINFO pti;
- BYTE KeyStateBuf[0x100];
- PWCHAR OutPwszBuff = 0;
- int ret = 0;
- DECLARE_RETURN(int);
-
- TRACE("Enter NtUserSetKeyboardState\n");
- UserEnterShared();//fixme: this syscall doesnt seem to need any locking...
-
- /* Key up? */
- if (wScanCode & SC_KEY_UP)
- {
- RETURN(0);
- }
-
- if( !NT_SUCCESS(MmCopyFromCaller(KeyStateBuf,
- lpKeyState,
- sizeof(KeyStateBuf))) )
- {
- ERR( "Couldn't copy key state from caller.\n" );
- RETURN(0);
- }
-
- /* Virtual code is correct? */
- if (wVirtKey < 0x100)
- {
- OutPwszBuff = ExAllocatePoolWithTag(NonPagedPool,sizeof(WCHAR) * cchBuff, TAG_STRING);
- if( !OutPwszBuff )
- {
- ERR( "ExAllocatePoolWithTag(%d) failed\n", sizeof(WCHAR) * cchBuff);
- RETURN(0);
- }
- RtlZeroMemory( OutPwszBuff, sizeof( WCHAR ) * cchBuff );
-
- pti = PsGetCurrentThreadWin32Thread();
- ret = ToUnicodeInner( wVirtKey,
- wScanCode,
- KeyStateBuf,
- OutPwszBuff,
- cchBuff,
- wFlags,
- pti ? pti->KeyboardLayout->KBTables : 0 );
-
- MmCopyToCaller(pwszBuff,OutPwszBuff,sizeof(WCHAR)*cchBuff);
- ExFreePoolWithTag(OutPwszBuff, TAG_STRING);
- }
-
- RETURN(ret);
+ PTHREADINFO pti;
+ BYTE KeyStateBuf[0x100];
+ PWCHAR OutPwszBuff = 0;
+ int ret = 0;
+ DECLARE_RETURN(int);
+
+ TRACE("Enter NtUserSetKeyboardState\n");
+ UserEnterShared();//fixme: this syscall doesnt seem to need any locking...
+
+ /* Key up? */
+ if (wScanCode & SC_KEY_UP)
+ {
+ RETURN(0);
+ }
+
+ if( !NT_SUCCESS(MmCopyFromCaller(KeyStateBuf,
+ lpKeyState,
+ sizeof(KeyStateBuf))) )
+ {
+ ERR( "Couldn't copy key state from caller.\n" );
+ RETURN(0);
+ }
+
+ /* Virtual code is correct? */
+ if (wVirtKey < 0x100)
+ {
+ OutPwszBuff = ExAllocatePoolWithTag(NonPagedPool, sizeof(WCHAR) * cchBuff, TAG_STRING);
+ if( !OutPwszBuff )
+ {
+ ERR( "ExAllocatePoolWithTag(%d) failed\n", sizeof(WCHAR) * cchBuff);
+ RETURN(0);
+ }
+ RtlZeroMemory( OutPwszBuff, sizeof( WCHAR ) * cchBuff );
+
+ pti = PsGetCurrentThreadWin32Thread();
+ ret = ToUnicodeInner( wVirtKey,
+ wScanCode,
+ KeyStateBuf,
+ OutPwszBuff,
+ cchBuff,
+ wFlags,
+ pti ? pti->KeyboardLayout->KBTables : 0 );
+
+ MmCopyToCaller(pwszBuff, OutPwszBuff, sizeof(WCHAR)*cchBuff);
+ ExFreePoolWithTag(OutPwszBuff, TAG_STRING);
+ }
+
+ RETURN(ret);
CLEANUP:
- TRACE("Leave NtUserSetKeyboardState, ret=%i\n",_ret_);
- UserLeave();
- END_CLEANUP;
+ TRACE("Leave NtUserSetKeyboardState, ret=%i\n", _ret_);
+ UserLeave();
+ END_CLEANUP;
}
static int W32kSimpleToupper( int ch )
{
- if( ch >= 'a' && ch <= 'z' )
- ch = ch - 'a' + 'A';
- return ch;
+ if( ch >= 'a' && ch <= 'z' )
+ ch = ch - 'a' + 'A';
+ return ch;
}
DWORD
APIENTRY
NtUserGetKeyNameText( LONG lParam, LPWSTR lpString, int nSize )
{
- PTHREADINFO pti;
- int i;
- DWORD ret = 0;
- UINT CareVk = 0;
- UINT VkCode = 0;
- UINT ScanCode = (lParam >> 16) & 0xff;
- BOOL ExtKey = lParam & (1<<24) ? TRUE : FALSE;
- PKBDTABLES keyLayout;
- VSC_LPWSTR *KeyNames;
- DECLARE_RETURN(DWORD);
-
- TRACE("Enter NtUserGetKeyNameText\n");
- UserEnterShared();
-
- pti = PsGetCurrentThreadWin32Thread();
- keyLayout = pti ? pti->KeyboardLayout->KBTables : 0;
-
- if( !keyLayout || nSize < 1 )
- RETURN(0);
-
- if( lParam & (1<<25) )
- {
- CareVk = VkCode = ScanToVk( ScanCode, ExtKey, keyLayout );
- switch (VkCode)
- {
- case VK_RSHIFT:
- ScanCode |= 0x100;
- case VK_LSHIFT:
- VkCode = VK_SHIFT;
- break;
- case VK_LCONTROL:
- case VK_RCONTROL:
- VkCode = VK_CONTROL;
- break;
- case VK_LMENU:
- case VK_RMENU:
- VkCode = VK_MENU;
- break;
- }
- }
- else
- {
- VkCode = ScanToVk( ScanCode, ExtKey, keyLayout );
- }
-
- KeyNames = 0;
-
- if( CareVk != VkCode )
- ScanCode = VkToScan( VkCode, ExtKey, keyLayout );
-
- if( ExtKey )
- KeyNames = keyLayout->pKeyNamesExt;
- else
- KeyNames = keyLayout->pKeyNames;
-
- for( i = 0; KeyNames[i].pwsz; i++ )
- {
- if( KeyNames[i].vsc == ScanCode )
- {
- UINT StrLen = wcslen(KeyNames[i].pwsz);
- UINT StrMax = StrLen > (nSize - 1) ? (nSize - 1) : StrLen;
- WCHAR null_wc = 0;
- if( NT_SUCCESS( MmCopyToCaller( lpString,
- KeyNames[i].pwsz,
- StrMax * sizeof(WCHAR) ) ) &&
- NT_SUCCESS( MmCopyToCaller( lpString + StrMax,
- &null_wc,
- sizeof( WCHAR ) ) ) )
- {
- ret = StrMax;
- break;
- }
- }
- }
+ PTHREADINFO pti;
+ int i;
+ DWORD ret = 0;
+ UINT CareVk = 0;
+ UINT VkCode = 0;
+ UINT ScanCode = (lParam >> 16) & 0xff;
+ BOOL ExtKey = lParam & (1 << 24) ? TRUE : FALSE;
+ PKBDTABLES keyLayout;
+ VSC_LPWSTR *KeyNames;
+ DECLARE_RETURN(DWORD);
+
+ TRACE("Enter NtUserGetKeyNameText\n");
+ UserEnterShared();
+
+ pti = PsGetCurrentThreadWin32Thread();
+ keyLayout = pti ? pti->KeyboardLayout->KBTables : 0;
+
+ if( !keyLayout || nSize < 1 )
+ RETURN(0);
+
+ if( lParam & (1 << 25) )
+ {
+ CareVk = VkCode = ScanToVk( ScanCode, ExtKey, keyLayout );
+ switch (VkCode)
+ {
+ case VK_RSHIFT:
+ ScanCode |= 0x100;
+ case VK_LSHIFT:
+ VkCode = VK_SHIFT;
+ break;
+ case VK_LCONTROL:
+ case VK_RCONTROL:
+ VkCode = VK_CONTROL;
+ break;
+ case VK_LMENU:
+ case VK_RMENU:
+ VkCode = VK_MENU;
+ break;
+ }
+ }
+ else
+ {
+ VkCode = ScanToVk( ScanCode, ExtKey, keyLayout );
+ }
- if( ret == 0 )
- {
- WCHAR UCName[2];
+ KeyNames = 0;
- UCName[0] = W32kSimpleToupper(IntMapVirtualKeyEx( VkCode, MAPVK_VK_TO_CHAR, keyLayout ));
- UCName[1] = 0;
- ret = 1;
+ if( CareVk != VkCode )
+ ScanCode = VkToScan( VkCode, ExtKey, keyLayout );
- if( !NT_SUCCESS(MmCopyToCaller( lpString, UCName, 2 * sizeof(WCHAR) )) )
- RETURN(0);
- }
+ if( ExtKey )
+ KeyNames = keyLayout->pKeyNamesExt;
+ else
+ KeyNames = keyLayout->pKeyNames;
+
+ for( i = 0; KeyNames[i].pwsz; i++ )
+ {
+ if( KeyNames[i].vsc == ScanCode )
+ {
+ UINT StrLen = wcslen(KeyNames[i].pwsz);
+ UINT StrMax = StrLen > (nSize - 1) ? (nSize - 1) : StrLen;
+ WCHAR null_wc = 0;
+ if( NT_SUCCESS( MmCopyToCaller( lpString,
+ KeyNames[i].pwsz,
+ StrMax * sizeof(WCHAR) ) ) &&
+ NT_SUCCESS( MmCopyToCaller( lpString + StrMax,
+ &null_wc,
+ sizeof( WCHAR ) ) ) )
+ {
+ ret = StrMax;
+ break;
+ }
+ }
+ }
+
+ if( ret == 0 )
+ {
+ WCHAR UCName[2];
+
+ UCName[0] = W32kSimpleToupper(IntMapVirtualKeyEx( VkCode, MAPVK_VK_TO_CHAR, keyLayout ));
+ UCName[1] = 0;
+ ret = 1;
+
+ if( !NT_SUCCESS(MmCopyToCaller( lpString, UCName, 2 * sizeof(WCHAR) )) )
+ RETURN(0);
+ }
- RETURN(ret);
+ RETURN(ret);
CLEANUP:
- TRACE("Leave NtUserGetKeyNameText, ret=%i\n",_ret_);
- UserLeave();
- END_CLEANUP;
+ TRACE("Leave NtUserGetKeyNameText, ret=%i\n", _ret_);
+ UserLeave();
+ END_CLEANUP;
}
/*
PKBDTABLES KeyboardLayout,
BYTE Prefix)
{
- DWORD ScanCode = 0, ModifierBits = 0;
- DWORD i = 0;
- DWORD BaseMapping = 0;
- DWORD RawVk = 0;
- static WORD NumpadConversion[][2] =
- { { VK_DELETE, VK_DECIMAL },
+ DWORD ScanCode = 0, ModifierBits = 0;
+ DWORD i = 0;
+ DWORD BaseMapping = 0;
+ DWORD RawVk = 0;
+ static WORD NumpadConversion[][2] =
+ { { VK_DELETE, VK_DECIMAL },
{ VK_INSERT, VK_NUMPAD0 },
{ VK_END, VK_NUMPAD1 },
{ VK_DOWN, VK_NUMPAD2 },
{ VK_HOME, VK_NUMPAD7 },
{ VK_UP, VK_NUMPAD8 },
{ VK_PRIOR, VK_NUMPAD9 },
- { 0,0 } };
- PVSC_VK VscVkTable = NULL;
-
- if( !KeyboardLayout || !Msg ||
- (Msg->message != WM_KEYDOWN && Msg->message != WM_SYSKEYDOWN &&
- Msg->message != WM_KEYUP && Msg->message != WM_SYSKEYUP) )
- {
- return;
- }
-
- /* arty -- handle numpad -- On real windows, the actual key produced
- * by the messaging layer is different based on the state of numlock. */
- ModifierBits = ModBits(KeyboardLayout,gKeyStateTable);
-
- /* Get the raw scan code, so we can look up whether the key is a numpad
- * key
- *
- * Shift and the LP_EXT_BIT cancel. */
- ScanCode = (Msg->lParam >> 16) & 0xff;
- TRACE("ScanCode %04x\n",ScanCode);
-
- BaseMapping = Msg->wParam =
- IntMapVirtualKeyEx( ScanCode, MAPVK_VSC_TO_VK, KeyboardLayout );
- if( Prefix == 0 )
- {
- if( ScanCode >= KeyboardLayout->bMaxVSCtoVK )
- RawVk = 0xff;
- else
- RawVk = KeyboardLayout->pusVSCtoVK[ScanCode];
- }
- else
- {
- if( Prefix == 0xE0 )
- {
- /* ignore shift codes */
- if( ScanCode == 0x2A || ScanCode == 0x36 )
- {
+ { 0, 0 }
+ };
+ PVSC_VK VscVkTable = NULL;
+
+ if( !KeyboardLayout || !Msg ||
+ (Msg->message != WM_KEYDOWN && Msg->message != WM_SYSKEYDOWN &&
+ Msg->message != WM_KEYUP && Msg->message != WM_SYSKEYUP) )
+ {
+ return;
+ }
+
+ /* arty -- handle numpad -- On real windows, the actual key produced
+ * by the messaging layer is different based on the state of numlock. */
+ ModifierBits = ModBits(KeyboardLayout, gKeyStateTable);
+
+ /* Get the raw scan code, so we can look up whether the key is a numpad
+ * key
+ *
+ * Shift and the LP_EXT_BIT cancel. */
+ ScanCode = (Msg->lParam >> 16) & 0xff;
+ TRACE("ScanCode %04x\n", ScanCode);
+
+ BaseMapping = Msg->wParam =
+ IntMapVirtualKeyEx( ScanCode, MAPVK_VSC_TO_VK, KeyboardLayout );
+ if( Prefix == 0 )
+ {
+ if( ScanCode >= KeyboardLayout->bMaxVSCtoVK )
+ RawVk = 0xff;
+ else
+ RawVk = KeyboardLayout->pusVSCtoVK[ScanCode];
+ }
+ else
+ {
+ if( Prefix == 0xE0 )
+ {
+ /* ignore shift codes */
+ if( ScanCode == 0x2A || ScanCode == 0x36 )
+ {
+ return;
+ }
+ VscVkTable = KeyboardLayout->pVSCtoVK_E0;
+ }
+ else if( Prefix == 0xE1 )
+ {
+ VscVkTable = KeyboardLayout->pVSCtoVK_E1;
+ }
+
+ if (!VscVkTable)
+ {
+ ERR("somethings wrong, Prefix=0x%x", Prefix);
return;
- }
- VscVkTable = KeyboardLayout->pVSCtoVK_E0;
- }
- else if( Prefix == 0xE1 )
- {
- VscVkTable = KeyboardLayout->pVSCtoVK_E1;
- }
-
- if (!VscVkTable)
- {
- ERR("somethings wrong, Prefix=0x%x", Prefix);
- return;
- }
-
- RawVk = 0xff;
- while (VscVkTable->Vsc)
- {
- if( VscVkTable->Vsc == ScanCode )
- {
- RawVk = VscVkTable->Vk;
- }
- VscVkTable++;
- }
- }
-
- if ((ModifierBits & NUMLOCK_BIT) &&
- !(ModifierBits & GetShiftBit(KeyboardLayout, VK_SHIFT)) &&
- (RawVk & KNUMP) &&
- !(Msg->lParam & LP_EXT_BIT))
- {
- /* The key in question is a numpad key. Search for a translation. */
- for (i = 0; NumpadConversion[i][0]; i++)
- {
- if ((BaseMapping & 0xff) == NumpadConversion[i][0]) /* RawVk? */
- {
- Msg->wParam = NumpadConversion[i][1];
- break;
- }
- }
- }
-
- TRACE("Key: [%04x -> %04x]\n", BaseMapping, Msg->wParam);
-
- /* Now that we have the VK, we can set the keymap appropriately
- * This is a better place for this code, as it's guaranteed to be
- * run, unlike translate message. */
- if (Msg->message == WM_KEYDOWN || Msg->message == WM_SYSKEYDOWN)
- {
- SetKeyState( ScanCode, Msg->wParam, Msg->lParam & LP_EXT_BIT,
- TRUE ); /* Strike key */
- }
- else if (Msg->message == WM_KEYUP || Msg->message == WM_SYSKEYUP)
- {
- SetKeyState( ScanCode, Msg->wParam, Msg->lParam & LP_EXT_BIT,
- FALSE ); /* Release key */
- }
-
- /* We need to unset SYSKEYDOWN if the ALT key is an ALT+Gr */
- if( gKeyStateTable[VK_RMENU] & KS_DOWN_BIT )
- {
- if( Msg->message == WM_SYSKEYDOWN )
- Msg->message = WM_KEYDOWN;
- else
- Msg->message = WM_KEYUP;
- }
+ }
+
+ RawVk = 0xff;
+ while (VscVkTable->Vsc)
+ {
+ if( VscVkTable->Vsc == ScanCode )
+ {
+ RawVk = VscVkTable->Vk;
+ }
+ VscVkTable++;
+ }
+ }
+
+ if ((ModifierBits & NUMLOCK_BIT) &&
+ !(ModifierBits & GetShiftBit(KeyboardLayout, VK_SHIFT)) &&
+ (RawVk & KNUMP) &&
+ !(Msg->lParam & LP_EXT_BIT))
+ {
+ /* The key in question is a numpad key. Search for a translation. */
+ for (i = 0; NumpadConversion[i][0]; i++)
+ {
+ if ((BaseMapping & 0xff) == NumpadConversion[i][0]) /* RawVk? */
+ {
+ Msg->wParam = NumpadConversion[i][1];
+ break;
+ }
+ }
+ }
+
+ TRACE("Key: [%04x -> %04x]\n", BaseMapping, Msg->wParam);
+
+ /* Now that we have the VK, we can set the keymap appropriately
+ * This is a better place for this code, as it's guaranteed to be
+ * run, unlike translate message. */
+ if (Msg->message == WM_KEYDOWN || Msg->message == WM_SYSKEYDOWN)
+ {
+ SetKeyState( ScanCode, Msg->wParam, Msg->lParam & LP_EXT_BIT,
+ TRUE ); /* Strike key */
+ }
+ else if (Msg->message == WM_KEYUP || Msg->message == WM_SYSKEYUP)
+ {
+ SetKeyState( ScanCode, Msg->wParam, Msg->lParam & LP_EXT_BIT,
+ FALSE ); /* Release key */
+ }
+
+ /* We need to unset SYSKEYDOWN if the ALT key is an ALT+Gr */
+ if( gKeyStateTable[VK_RMENU] & KS_DOWN_BIT )
+ {
+ if( Msg->message == WM_SYSKEYDOWN )
+ Msg->message = WM_KEYDOWN;
+ else
+ Msg->message = WM_KEYUP;
+ }
}
DWORD FASTCALL
UserGetKeyboardType(
- DWORD TypeFlag)
+ DWORD TypeFlag)
{
- switch(TypeFlag)
- {
- case 0: /* Keyboard type */
- return 4; /* AT-101 */
- case 1: /* Keyboard Subtype */
- return 0; /* There are no defined subtypes */
- case 2: /* Number of F-keys */
- return 12; /* We're doing an 101 for now, so return 12 F-keys */
- default:
- ERR("Unknown type!\n");
- return 0; /* The book says 0 here, so 0 */
- }
+ switch(TypeFlag)
+ {
+ case 0: /* Keyboard type */
+ return 4; /* AT-101 */
+ case 1: /* Keyboard Subtype */
+ return 0; /* There are no defined subtypes */
+ case 2: /* Number of F-keys */
+ return 12; /* We're doing an 101 for now, so return 12 F-keys */
+ default:
+ ERR("Unknown type!\n");
+ return 0; /* The book says 0 here, so 0 */
+ }
}
DWORD
APIENTRY
NtUserVkKeyScanEx(
- WCHAR wChar,
- HKL hKeyboardLayout,
- BOOL UsehKL ) // TRUE from KeyboardLayout, FALSE from pkbl = (THREADINFO)->KeyboardLayout
+ WCHAR wChar,
+ HKL hKeyboardLayout,
+ BOOL UsehKL ) // TRUE from KeyboardLayout, FALSE from pkbl = (THREADINFO)->KeyboardLayout
{
- PKBDTABLES KeyLayout;
- PVK_TO_WCHAR_TABLE vtwTbl;
- PVK_TO_WCHARS10 vkPtr;
- size_t size_this_entry;
- int nMod;
- PKBL pkbl = NULL;
- DWORD CapsMod = 0, CapsState = 0, Ret = -1;
-
- TRACE("NtUserVkKeyScanEx() wChar %d, KbdLayout 0x%p\n", wChar, hKeyboardLayout);
- UserEnterShared();
-
- if (UsehKL)
- {
- if ( !hKeyboardLayout || !(pkbl = UserHklToKbl(hKeyboardLayout)))
- goto Exit;
- }
- else // From VkKeyScanAW it is FALSE so KeyboardLayout is white noise.
- {
- pkbl = ((PTHREADINFO)PsGetCurrentThreadWin32Thread())->KeyboardLayout;
- }
-
- KeyLayout = pkbl->KBTables;
-
- for (nMod = 0; KeyLayout->pVkToWcharTable[nMod].nModifications; nMod++)
- {
- vtwTbl = &KeyLayout->pVkToWcharTable[nMod];
- size_this_entry = vtwTbl->cbSize;
- vkPtr = (PVK_TO_WCHARS10)((BYTE *)vtwTbl->pVkToWchars);
-
- while(vkPtr->VirtualKey)
- {
- /*
- 0x01 Shift key
- 0x02 Ctrl key
- 0x04 Alt key
- Should have only 8 valid possibilities. Including zero.
- */
- for(CapsState = 0; CapsState < vtwTbl->nModifications; CapsState++)
- {
- if(vkPtr->wch[CapsState] == wChar)
+ PKBDTABLES KeyLayout;
+ PVK_TO_WCHAR_TABLE vtwTbl;
+ PVK_TO_WCHARS10 vkPtr;
+ size_t size_this_entry;
+ int nMod;
+ PKBL pkbl = NULL;
+ DWORD CapsMod = 0, CapsState = 0, Ret = -1;
+
+ TRACE("NtUserVkKeyScanEx() wChar %d, KbdLayout 0x%p\n", wChar, hKeyboardLayout);
+ UserEnterShared();
+
+ if (UsehKL)
+ {
+ if ( !hKeyboardLayout || !(pkbl = UserHklToKbl(hKeyboardLayout)))
+ goto Exit;
+ }
+ else // From VkKeyScanAW it is FALSE so KeyboardLayout is white noise.
+ {
+ pkbl = ((PTHREADINFO)PsGetCurrentThreadWin32Thread())->KeyboardLayout;
+ }
+
+ KeyLayout = pkbl->KBTables;
+
+ for (nMod = 0; KeyLayout->pVkToWcharTable[nMod].nModifications; nMod++)
+ {
+ vtwTbl = &KeyLayout->pVkToWcharTable[nMod];
+ size_this_entry = vtwTbl->cbSize;
+ vkPtr = (PVK_TO_WCHARS10)((BYTE *)vtwTbl->pVkToWchars);
+
+ while(vkPtr->VirtualKey)
+ {
+ /*
+ 0x01 Shift key
+ 0x02 Ctrl key
+ 0x04 Alt key
+ Should have only 8 valid possibilities. Including zero.
+ */
+ for(CapsState = 0; CapsState < vtwTbl->nModifications; CapsState++)
{
- CapsMod = KeyLayout->pCharModifiers->ModNumber[CapsState];
- TRACE("nMod %d wC %04x: CapsMod %08x CapsState %08x MaxModBits %08x\n",
- nMod, wChar, CapsMod, CapsState, KeyLayout->pCharModifiers->wMaxModBits);
- Ret = ((CapsMod << 8)|(vkPtr->VirtualKey & 0xff));
- goto Exit;
+ if(vkPtr->wch[CapsState] == wChar)
+ {
+ CapsMod = KeyLayout->pCharModifiers->ModNumber[CapsState];
+ TRACE("nMod %d wC %04x: CapsMod %08x CapsState %08x MaxModBits %08x\n",
+ nMod, wChar, CapsMod, CapsState, KeyLayout->pCharModifiers->wMaxModBits);
+ Ret = ((CapsMod << 8) | (vkPtr->VirtualKey & 0xff));
+ goto Exit;
+ }
}
- }
- vkPtr = (PVK_TO_WCHARS10)(((BYTE *)vkPtr) + size_this_entry);
- }
- }
+ vkPtr = (PVK_TO_WCHARS10)(((BYTE *)vkPtr) + size_this_entry);
+ }
+ }
Exit:
- UserLeave();
- return Ret;
+ UserLeave();
+ return Ret;
}