Author: cwittich
Date: Mon Oct 26 09:50:00 2009
New Revision: 43772
URL:
http://svn.reactos.org/svn/reactos?rev=43772&view=rev
Log:
implement IntKeyboardInput based on wine
Modified:
trunk/reactos/subsystems/win32/win32k/ntuser/input.c
trunk/reactos/subsystems/win32/win32k/ntuser/keyboard.c
Modified: trunk/reactos/subsystems/win32/win32k/ntuser/input.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/nt…
==============================================================================
--- trunk/reactos/subsystems/win32/win32k/ntuser/input.c [iso-8859-1] (original)
+++ trunk/reactos/subsystems/win32/win32k/ntuser/input.c [iso-8859-1] Mon Oct 26 09:50:00
2009
@@ -35,6 +35,8 @@
static CLIENT_ID RawInputThreadId;
static KEVENT InputThreadsStart;
static BOOLEAN InputThreadsRunning = FALSE;
+static BYTE TrackSysKey = 0; /* determine whether ALT key up will cause a WM_SYSKEYUP
+ or a WM_KEYUP message */
/* FUNCTIONS *****************************************************************/
DWORD IntLastInputTick(BOOL LastInputTickSetGet);
@@ -1303,7 +1305,177 @@
BOOL FASTCALL
IntKeyboardInput(KEYBDINPUT *ki)
{
- return FALSE;
+ PUSER_MESSAGE_QUEUE FocusMessageQueue;
+ PTHREADINFO pti;
+ MSG Msg;
+ LARGE_INTEGER LargeTickCount;
+ KBDLLHOOKSTRUCT KbdHookData;
+ WORD flags, wVkStripped, wVkL, wVkR, wVk = ki->wVk, vk_hook = ki->wVk;
+ BOOLEAN Entered = FALSE;
+
+ Msg.lParam = 0;
+
+ // Condition may arise when calling MsqPostMessage and waiting for an event.
+ if (!UserIsEntered())
+ {
+ // Fixme: Not sure ATM if this thread is locked.
+ UserEnterExclusive();
+ Entered = TRUE;
+ }
+
+ wVk = LOBYTE(wVk);
+ Msg.wParam = wVk;
+ flags = LOBYTE(ki->wScan);
+
+ if (ki->dwFlags & KEYEVENTF_EXTENDEDKEY) flags |= KF_EXTENDED;
+ /* FIXME: set KF_DLGMODE and KF_MENUMODE when needed */
+
+ /* 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 ((gQueueKeyStateTable[VK_MENU] & 0x80) &&
+ ((wVkStripped == VK_MENU) || (wVkStripped == VK_CONTROL)
+ || !(gQueueKeyStateTable[VK_CONTROL] & 0x80)))
+ {
+ 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 ((gQueueKeyStateTable[VK_MENU] & 0x80 || wVkStripped == VK_MENU) &&
+ !(gQueueKeyStateTable[VK_CONTROL] & 0x80 || wVkStripped == VK_CONTROL))
+ {
+ Msg.message = WM_SYSKEYDOWN;
+ TrackSysKey = wVkStripped;
+ }
+ if (!(ki->dwFlags & KEYEVENTF_UNICODE) && gQueueKeyStateTable[wVk]
& 0x80) flags |= KF_REPEAT;
+ }
+
+ if (ki->dwFlags & KEYEVENTF_UNICODE)
+ {
+ vk_hook = Msg.wParam = wVk = VK_PACKET;
+ Msg.lParam = MAKELPARAM(1 /* repeat count */, ki->wScan);
+ }
+
+ FocusMessageQueue = IntGetFocusMessageQueue();
+
+ 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. */
+ pti = PsGetCurrentThreadWin32Thread();
+ IntGetCursorLocation(pti->Desktop->WindowStation,
+ &Msg.pt);
+
+ DPRINT1("Kbd Hook msg %d wParam %d lParam 0x%08x dropped by WH_KEYBOARD_LL
hook\n",
+ Msg.message, vk_hook, Msg.lParam);
+
+ KbdHookData.vkCode = vk_hook;
+ KbdHookData.scanCode = ki->wScan;
+ KbdHookData.flags = flags >> 8;
+ KbdHookData.time = Msg.time;
+ KbdHookData.dwExtraInfo = ki->dwExtraInfo;
+ if (co_HOOK_CallHooks(WH_KEYBOARD_LL, HC_ACTION, Msg.message, (LPARAM)
&KbdHookData))
+ {
+ DPRINT("Kbd msg %d wParam %d lParam 0x%08x dropped by WH_KEYBOARD_LL
hook\n",
+ Msg.message, vk_hook, Msg.lParam);
+ if (Entered) UserLeave();
+ return FALSE;
+ }
+
+ if (!(ki->dwFlags & KEYEVENTF_UNICODE))
+ {
+ if (ki->dwFlags & KEYEVENTF_KEYUP)
+ {
+ gQueueKeyStateTable[wVk] &= ~0x80;
+ gQueueKeyStateTable[wVkStripped] = gQueueKeyStateTable[wVkL] |
gQueueKeyStateTable[wVkR];
+ }
+ else
+ {
+ if (!(gQueueKeyStateTable[wVk] & 0x80)) gQueueKeyStateTable[wVk] ^= 0x01;
+ gQueueKeyStateTable[wVk] |= 0xc0;
+ gQueueKeyStateTable[wVkStripped] = gQueueKeyStateTable[wVkL] |
gQueueKeyStateTable[wVkR];
+ }
+
+ if (gQueueKeyStateTable[VK_MENU] & 0x80) flags |= KF_ALTDOWN;
+
+ if (wVkStripped == VK_SHIFT) flags &= ~KF_EXTENDED;
+
+ Msg.lParam = MAKELPARAM(1 /* repeat count */, flags);
+ }
+
+ if (FocusMessageQueue == NULL)
+ {
+ DPRINT("No focus message queue\n");
+ if (Entered) UserLeave();
+ return FALSE;
+ }
+
+ if (FocusMessageQueue->FocusWindow != (HWND)0)
+ {
+ Msg.hwnd = FocusMessageQueue->FocusWindow;
+ DPRINT("Msg.hwnd = %x\n", Msg.hwnd);
+
+ FocusMessageQueue->Desktop->DesktopInfo->LastInputWasKbd = TRUE;
+
+ IntGetCursorLocation(FocusMessageQueue->Desktop->WindowStation,
+ &Msg.pt);
+ MsqPostMessage(FocusMessageQueue, &Msg, FALSE, QS_KEY);
+ }
+ else
+ {
+ DPRINT("Invalid focus window handle\n");
+ }
+
+ if (Entered) UserLeave();
+
+ return TRUE;
}
BOOL FASTCALL
Modified: trunk/reactos/subsystems/win32/win32k/ntuser/keyboard.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/nt…
==============================================================================
--- trunk/reactos/subsystems/win32/win32k/ntuser/keyboard.c [iso-8859-1] (original)
+++ trunk/reactos/subsystems/win32/win32k/ntuser/keyboard.c [iso-8859-1] Mon Oct 26
09:50:00 2009
@@ -69,11 +69,11 @@
static UINT DontDistinguishShifts( UINT ret )
{
if( ret == VK_LSHIFT || ret == VK_RSHIFT )
- ret = VK_LSHIFT;
+ ret = VK_SHIFT;
if( ret == VK_LCONTROL || ret == VK_RCONTROL )
- ret = VK_LCONTROL;
+ ret = VK_CONTROL;
if( ret == VK_LMENU || ret == VK_RMENU )
- ret = VK_LMENU;
+ ret = VK_MENU;
return ret;
}
@@ -435,14 +435,27 @@
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;
-
- ScanCode = (lpMsg->lParam >> 16) & 0xff;
/* All messages have to contain the cursor point. */
IntGetCursorLocation(pti->Desktop->WindowStation,
&NewMsg.pt);
+
+ 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;
+ }
+
+ ScanCode = (lpMsg->lParam >> 16) & 0xff;
UState = ToUnicodeInner(lpMsg->wParam, HIWORD(lpMsg->lParam) & 0xff,
gQueueKeyStateTable, wp, 2, 0,
@@ -628,11 +641,11 @@
switch( Type )
{
case 0:
- if( Code == VK_RSHIFT )
+ if( Code == VK_SHIFT )
Code = VK_LSHIFT;
- if( Code == VK_RMENU )
+ if( Code == VK_MENU )
Code = VK_LMENU;
- if( Code == VK_RCONTROL )
+ if( Code == VK_CONTROL )
Code = VK_LCONTROL;
ret = VkToScan( Code, FALSE, keyLayout );
break;
@@ -706,7 +719,7 @@
DECLARE_RETURN(int);
DPRINT("Enter NtUserSetKeyboardState\n");
- UserEnterShared();//faxme: this syscall doesnt seem to need any locking...
+ UserEnterShared();//fixme: this syscall doesnt seem to need any locking...
if( !NT_SUCCESS(MmCopyFromCaller(KeyStateBuf,
@@ -785,12 +798,22 @@
if( lParam & (1<<25) )
{
CareVk = VkCode = ScanToVk( ScanCode, ExtKey, keyLayout );
- if( VkCode == VK_LSHIFT || VkCode == VK_RSHIFT )
- VkCode = VK_LSHIFT;
- if( VkCode == VK_LCONTROL || VkCode == VK_RCONTROL )
- VkCode = VK_LCONTROL;
- if( VkCode == VK_LMENU || VkCode == VK_RMENU )
- VkCode = VK_LMENU;
+ 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
{