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/ntu... ============================================================================== --- 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/ntu... ============================================================================== --- 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 {