* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS Win32k subsystem
* PURPOSE: HotKey support
- * FILE: subsystems/win32/win32k/ntuser/hotkey.c
+ * FILE: win32ss/user/ntuser/hotkey.c
* PROGRAMER: Eric Kohl
*/
* By default the key is VK-F12 on a 101-key keyboard, and is VK_SUBTRACT
* (hyphen / substract sign) on a 82-key keyboard.
*/
-/* thread hwnd modifiers vk id next */
-// HOT_KEY hkF12 = {NULL, NULL, 0, VK_F12, IDHK_F12, NULL};
-// HOT_KEY hkShiftF12 = {NULL, NULL, MOD_SHIFT, VK_F12, IDHK_SHIFTF12, &hkF12};
-// HOT_KEY hkWinKey = {NULL, NULL, MOD_WIN, 0, IDHK_WINKEY, &hkShiftF12};
-HOT_KEY hkWinKey = {NULL, NULL, MOD_WIN, 0, IDHK_WINKEY, NULL};
+/* pti pwnd modifiers vk id next */
+// HOT_KEY hkF12 = {NULL, 1, 0, VK_F12, IDHK_F12, NULL};
+// HOT_KEY hkShiftF12 = {NULL, 1, MOD_SHIFT, VK_F12, IDHK_SHIFTF12, &hkF12};
+// HOT_KEY hkWinKey = {NULL, 1, MOD_WIN, 0, IDHK_WINKEY, &hkShiftF12};
-PHOT_KEY gphkFirst = &hkWinKey;
+PHOT_KEY gphkFirst = NULL;
BOOL bWinHotkeyActive = FALSE;
/* FUNCTIONS *****************************************************************/
+VOID FASTCALL
+StartDebugHotKeys(VOID)
+{
+ UINT vk = VK_F12;
+ UserUnregisterHotKey(PWND_BOTTOM, IDHK_F12);
+ UserUnregisterHotKey(PWND_BOTTOM, IDHK_SHIFTF12);
+ if (!ENHANCED_KEYBOARD(gKeyboardInfo.KeyboardIdentifier))
+ {
+ vk = VK_SUBTRACT;
+ }
+ UserRegisterHotKey(PWND_BOTTOM, IDHK_SHIFTF12, MOD_SHIFT, vk);
+ UserRegisterHotKey(PWND_BOTTOM, IDHK_F12, 0, vk);
+ ERR("Start up the debugger hotkeys!! Should see this once!\n");
+}
+
/*
* IntGetModifiers
*
UnregisterWindowHotKeys(PWND pWnd)
{
PHOT_KEY pHotKey = gphkFirst, phkNext, *pLink = &gphkFirst;
- HWND hWnd = pWnd->head.h;
while (pHotKey)
{
phkNext = pHotKey->pNext;
/* Should we delete this hotkey? */
- if (pHotKey->hWnd == hWnd)
+ if (pHotKey->pWnd == pWnd)
{
/* Update next ptr for previous hotkey and free memory */
*pLink = phkNext;
* Removes hotkeys registered by specified thread on its cleanup
*/
VOID FASTCALL
-UnregisterThreadHotKeys(struct _ETHREAD *pThread)
+UnregisterThreadHotKeys(PTHREADINFO pti)
{
PHOT_KEY pHotKey = gphkFirst, phkNext, *pLink = &gphkFirst;
phkNext = pHotKey->pNext;
/* Should we delete this hotkey? */
- if (pHotKey->pThread == pThread)
+ if (pHotKey->pti == pti)
{
/* Update next ptr for previous hotkey and free memory */
*pLink = phkNext;
{
UINT fModifiers;
PHOT_KEY pHotKey;
+ PWND pWnd;
+ BOOL DoNotPostMsg = FALSE;
if (wVk == VK_SHIFT || wVk == VK_CONTROL || wVk == VK_MENU ||
wVk == VK_LWIN || wVk == VK_RWIN)
wVk = 0;
}
- /* Check if it is a hotkey */
fModifiers = IntGetModifiers(gafAsyncKeyState);
+
+ /* Check if it is a hotkey */
pHotKey = IsHotKey(fModifiers, wVk);
+
if (pHotKey)
{
+ TRACE("Hot key Found\n");
+ /* FIXME: See comment about "UserDebuggerHotKey" on top of this file. */
+ if (pHotKey->id == IDHK_SHIFTF12 || pHotKey->id == IDHK_F12)
+ {
+ if (bIsDown)
+ {
+ ERR("Hot key pressed for Debug Activation! ShiftF12 = %d or F12 = %d\n",pHotKey->id == IDHK_SHIFTF12 , pHotKey->id == IDHK_F12);
+ //DoNotPostMsg = co_ActivateDebugger(); // FIXME
+ }
+ return DoNotPostMsg;
+ }
+
/* Process hotkey if it is key up event */
if (!bIsDown)
{
- TRACE("Hot key pressed (hWnd %p, id %d)\n", pHotKey->hWnd, pHotKey->id);
+ TRACE("Hot key pressed (pWnd %p, id %d)\n", pHotKey->pWnd, pHotKey->id);
- /* WIN and F12 keys are hardcoded here. See comments on top of this file. */
- if (pHotKey == &hkWinKey)
+ /* WIN and F12 keys are not hardcoded here. See comments on top of this file. */
+ if (pHotKey->id == IDHK_WINKEY && bWinHotkeyActive == TRUE)
{
- if(bWinHotkeyActive == TRUE)
+ pWnd = ValidateHwndNoErr(InputWindowStation->ShellWindow);
+ if (pWnd)
{
- UserPostMessage(InputWindowStation->ShellWindow, WM_SYSCOMMAND, SC_TASKLIST, 0);
- bWinHotkeyActive = FALSE;
+ TRACE("System Hot key Id %d Key %d\n",pHotKey->id, wVk );
+ UserPostMessage(UserHMGetHandle(pWnd), WM_SYSCOMMAND, SC_TASKLIST, 0);
+ //ptiLastInput = pWnd->head.pti;
+ bWinHotkeyActive = FALSE;
+ return TRUE;
}
}
-#if 0 /* FIXME: See comment about "UserDebuggerHotKey" on top of this file. */
- else if (pHotKey == &hkF12 || pHotKey == &hkShiftF12)
- {
- //co_ActivateDebugger(); // FIXME
- }
-#endif
- else if (pHotKey->id == IDHK_REACTOS && !pHotKey->pThread) // FIXME: Those hotkeys doesn't depend on RegisterHotKey
+
+ if (!pHotKey->pWnd)
{
- UserPostMessage(pHotKey->hWnd, WM_SYSCOMMAND, SC_HOTKEY, (LPARAM)pHotKey->hWnd);
+ TRACE("UPTM Hot key Id %d Key %d\n",pHotKey->id, wVk );
+ UserPostThreadMessage(pHotKey->pti, WM_HOTKEY, pHotKey->id, MAKELONG(fModifiers, wVk));
+ //ptiLastInput = pHotKey->pti;
}
else
{
- /* If a hotkey with the WIN modifier was activated, do not treat the release of the WIN key as a hotkey*/
- if((pHotKey->fsModifiers & MOD_WIN) != 0)
- bWinHotkeyActive = FALSE;
-
- MsqPostHotKeyMessage(pHotKey->pThread,
- pHotKey->hWnd,
- (WPARAM)pHotKey->id,
- MAKELPARAM((WORD)fModifiers, wVk));
- }
- }
- else
- {
- if (pHotKey == &hkWinKey)
- {
- /* The user pressed the win key */
- bWinHotkeyActive = TRUE;
+ if (pHotKey->pWnd == PWND_BOTTOM)
+ {
+ if (gpqForeground != NULL)
+ {
+ pWnd = gpqForeground->spwndFocus;
+ }
+ else
+ return FALSE;
+ }
+ else
+ {
+ pWnd = pHotKey->pWnd;
+ }
+ if (pWnd)
+ {
+ if (pWnd == pWnd->head.rpdesk->pDeskInfo->spwndShell && pHotKey->id == SC_TASKLIST)
+ {
+ ERR("Sending to shell window w/o IDHK_WINKEY..\n");
+ UserPostMessage(UserHMGetHandle(pWnd), WM_SYSCOMMAND, SC_TASKLIST, 0);
+ }
+ else
+ {
+ UserPostMessage(UserHMGetHandle(pWnd), WM_HOTKEY, pHotKey->id, MAKELONG(fModifiers, wVk));
+ }
+ //ptiLastInput = pWnd->head.pti;
+ }
}
+ return TRUE; /* Don't send any message */
}
-
- return TRUE; /* Don't send any message */
+ else /* The user pressed the win key */
+ if (pHotKey->id == IDHK_WINKEY) bWinHotkeyActive = TRUE;
}
-
return FALSE;
}
* GetHotKey message support
*/
UINT FASTCALL
-DefWndGetHotKey(HWND hWnd)
+DefWndGetHotKey(PWND pWnd)
{
PHOT_KEY pHotKey = gphkFirst;
while (pHotKey)
{
- if (pHotKey->hWnd == hWnd && pHotKey->id == IDHK_REACTOS)
+ if (pHotKey->pWnd == pWnd && pHotKey->id == IDHK_REACTOS)
{
/* We have found it */
return MAKELONG(pHotKey->vk, pHotKey->fsModifiers);
{
UINT fsModifiers, vk;
PHOT_KEY pHotKey, *pLink;
- HWND hWnd;
INT iRet = 1;
WARN("DefWndSetHotKey wParam 0x%x\n", wParam);
vk = LOWORD(wParam);
fsModifiers = HIWORD(wParam);
- hWnd = UserHMGetHandle(pWnd);
if (wParam)
{
pHotKey->vk == vk &&
pHotKey->id == IDHK_REACTOS)
{
- if (pHotKey->hWnd != hWnd)
+ if (pHotKey->pWnd != pWnd)
iRet = 2; // Another window already has the same hot key.
break;
}
pLink = &gphkFirst;
while (pHotKey)
{
- if (pHotKey->hWnd == hWnd &&
+ if (pHotKey->pWnd == pWnd &&
pHotKey->id == IDHK_REACTOS)
{
/* This window has already hotkey registered */
if (pHotKey == NULL)
return 0;
- pHotKey->hWnd = hWnd;
+ pHotKey->pWnd = pWnd;
pHotKey->id = IDHK_REACTOS; // Don't care, these hot keys are unrelated to the hot keys set by RegisterHotKey
pHotKey->pNext = gphkFirst;
gphkFirst = pHotKey;
/* A window can only have one hot key. If the window already has a
hot key associated with it, the new hot key replaces the old one. */
- pHotKey->pThread = NULL;
+ pHotKey->pti = NULL;
pHotKey->fsModifiers = fsModifiers;
pHotKey->vk = vk;
}
return iRet;
}
+
+BOOL FASTCALL
+UserRegisterHotKey(PWND pWnd,
+ int id,
+ UINT fsModifiers,
+ UINT vk)
+{
+ PHOT_KEY pHotKey;
+ PTHREADINFO pHotKeyThread;
+
+ /* Find hotkey thread */
+ if (pWnd == NULL || pWnd == PWND_BOTTOM)
+ {
+ pHotKeyThread = PsGetCurrentThreadWin32Thread();
+ }
+ else
+ {
+ pHotKeyThread = pWnd->head.pti;
+ }
+
+ /* Check for existing hotkey */
+ if (IsHotKey(fsModifiers, vk))
+ {
+ EngSetLastError(ERROR_HOTKEY_ALREADY_REGISTERED);
+ WARN("Hotkey already exists\n");
+ return FALSE;
+ }
+
+ /* Create new hotkey */
+ pHotKey = ExAllocatePoolWithTag(PagedPool, sizeof(HOT_KEY), USERTAG_HOTKEY);
+ if (pHotKey == NULL)
+ {
+ EngSetLastError(ERROR_NOT_ENOUGH_MEMORY);
+ return FALSE;
+ }
+
+ pHotKey->pti = pHotKeyThread;
+ pHotKey->pWnd = pWnd;
+ pHotKey->fsModifiers = fsModifiers;
+ pHotKey->vk = vk;
+ pHotKey->id = id;
+
+ /* Insert hotkey to the global list */
+ pHotKey->pNext = gphkFirst;
+ gphkFirst = pHotKey;
+
+ return TRUE;
+}
+
+BOOL FASTCALL
+UserUnregisterHotKey(PWND pWnd, int id)
+{
+ PHOT_KEY pHotKey = gphkFirst, phkNext, *pLink = &gphkFirst;
+ BOOL bRet = FALSE;
+
+ while (pHotKey)
+ {
+ /* Save next ptr for later use */
+ phkNext = pHotKey->pNext;
+
+ /* Should we delete this hotkey? */
+ if (pHotKey->pWnd == pWnd && pHotKey->id == id)
+ {
+ /* Update next ptr for previous hotkey and free memory */
+ *pLink = phkNext;
+ ExFreePoolWithTag(pHotKey, USERTAG_HOTKEY);
+
+ bRet = TRUE;
+ }
+ else /* This hotkey will stay, use its next ptr */
+ pLink = &pHotKey->pNext;
+
+ /* Move to the next entry */
+ pHotKey = phkNext;
+ }
+ return bRet;
+}
+
+
/* SYSCALLS *****************************************************************/
UINT vk)
{
PHOT_KEY pHotKey;
- PWND pWnd;
- PETHREAD pHotKeyThread;
+ PWND pWnd = NULL;
+ PTHREADINFO pHotKeyThread;
BOOL bRet = FALSE;
TRACE("Enter NtUserRegisterHotKey\n");
/* Find hotkey thread */
if (hWnd == NULL)
{
- pHotKeyThread = PsGetCurrentThread();
+ pHotKeyThread = gptiCurrent;
}
else
{
if (!pWnd)
goto cleanup;
- pHotKeyThread = pWnd->head.pti->pEThread;
+ pHotKeyThread = pWnd->head.pti;
+
+ /* Fix wine msg "Window on another thread" test_hotkey */
+ if (pWnd->head.pti != gptiCurrent)
+ {
+ WARN("Must be from the same Thread.\n");
+ goto cleanup;
+ }
}
/* Check for existing hotkey */
goto cleanup;
}
- pHotKey->pThread = pHotKeyThread;
- pHotKey->hWnd = hWnd;
+ pHotKey->pti = pHotKeyThread;
+ pHotKey->pWnd = pWnd;
pHotKey->fsModifiers = fsModifiers;
pHotKey->vk = vk;
pHotKey->id = id;
{
PHOT_KEY pHotKey = gphkFirst, phkNext, *pLink = &gphkFirst;
BOOL bRet = FALSE;
+ PWND pWnd;
TRACE("Enter NtUserUnregisterHotKey\n");
UserEnterExclusive();
/* Fail if given window is invalid */
- if (hWnd && !UserGetWindowObject(hWnd))
+ if (hWnd && !(pWnd = UserGetWindowObject(hWnd)))
goto cleanup;
while (pHotKey)
phkNext = pHotKey->pNext;
/* Should we delete this hotkey? */
- if (pHotKey->hWnd == hWnd && pHotKey->id == id)
+ if (pHotKey->pWnd == pWnd && pHotKey->id == id)
{
/* Update next ptr for previous hotkey and free memory */
*pLink = phkNext;
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* PURPOSE: Keyboard functions
- * FILE: subsystems/win32/win32k/ntuser/keyboard.c
+ * FILE: win32ss/user/ntuser/keyboard.c
* PROGRAMERS: Casper S. Hornstrup (chorns@users.sourceforge.net)
* Rafal Harabien (rafalh@reactos.org)
*/
static BYTE gafAsyncKeyStateRecentDown[256 / 8]; // 1 bit per key
static PKEYBOARD_INDICATOR_TRANSLATION gpKeyboardIndicatorTrans = NULL;
static KEYBOARD_INDICATOR_PARAMETERS gIndicators = {0, 0};
+KEYBOARD_ATTRIBUTES gKeyboardInfo;
/* FUNCTIONS *****************************************************************/
{
RtlZeroMemory(&gafAsyncKeyState, sizeof(gafAsyncKeyState));
RtlZeroMemory(&gafAsyncKeyStateRecentDown, sizeof(gafAsyncKeyStateRecentDown));
+ // Clear and set default information.
+ RtlZeroMemory(&gKeyboardInfo, sizeof(gKeyboardInfo));
+ gKeyboardInfo.KeyboardIdentifier.Type = 4; /* AT-101 */
+ gKeyboardInfo.NumberOfFunctionKeys = 12; /* We're doing an 101 for now, so return 12 F-keys */
return STATUS_SUCCESS;
}
* Asks the keyboard driver to send a small table that shows which
* lights should connect with which scancodes
*/
-static
+//static
NTSTATUS APIENTRY
IntKeyboardGetIndicatorTrans(HANDLE hKeyboardDevice,
PKEYBOARD_INDICATOR_TRANSLATION *ppIndicatorTrans)
{
NTSTATUS Status;
IO_STATUS_BLOCK Block;
-
+/*
IntKeyboardGetIndicatorTrans(hKeyboardDevice, &gpKeyboardIndicatorTrans);
Status = NtDeviceIoControlFile(hKeyboardDevice,
{
WARN("NtDeviceIoControlFile() failed, ignored\n");
}
-
SET_KEY_LOCKED(gafAsyncKeyState, VK_CAPITAL,
gIndicators.LedFlags & KEYBOARD_CAPS_LOCK_ON);
SET_KEY_LOCKED(gafAsyncKeyState, VK_NUMLOCK,
gIndicators.LedFlags & KEYBOARD_NUM_LOCK_ON);
SET_KEY_LOCKED(gafAsyncKeyState, VK_SCROLL,
gIndicators.LedFlags & KEYBOARD_SCROLL_LOCK_ON);
+*/
+ // FIXME: Need device driver to work! HID support more than one!!!!
+ Status = NtDeviceIoControlFile(hKeyboardDevice,
+ NULL,
+ NULL,
+ NULL,
+ &Block,
+ IOCTL_KEYBOARD_QUERY_ATTRIBUTES,
+ NULL, 0,
+ &gKeyboardInfo, sizeof(gKeyboardInfo));
+
+ if (!NT_SUCCESS(Status))
+ {
+ ERR("NtDeviceIoControlFile() failed, ignored\n");
+ }
+ ERR("Keyboard type %d, subtype %d and number of func keys %d\n",
+ gKeyboardInfo.KeyboardIdentifier.Type,
+ gKeyboardInfo.KeyboardIdentifier.Subtype,
+ gKeyboardInfo.NumberOfFunctionKeys);
}
/*
/* Check if this is a hotkey */
if (co_UserProcessHotKeys(wSimpleVk, bIsDown))
+ {
+ TRACE("HotKey Processed\n");
bPostMsg = FALSE;
-
+ }
wFixedVk = IntFixVk(wSimpleVk, bExt); /* LSHIFT + EXT = RSHIFT */
if (wSimpleVk == VK_SHIFT) /* shift can't be extended */
bExt = FALSE;
switch (dwTypeFlag)
{
case 0: /* Keyboard type */
- return 4; /* AT-101 */
+ return (DWORD)gKeyboardInfo.KeyboardIdentifier.Type;
case 1: /* Keyboard Subtype */
- return 0; /* There are no defined subtypes */
+ return (DWORD)gKeyboardInfo.KeyboardIdentifier.Subtype;
case 2: /* Number of F-keys */
- return 12; /* We're doing an 101 for now, so return 12 F-keys */
+ return (DWORD)gKeyboardInfo.NumberOfFunctionKeys;
default:
ERR("Unknown type!\n");
return 0; /* Note: we don't have to set last error here */
}
BOOL FASTCALL
-UserPostThreadMessage( DWORD idThread,
+UserPostThreadMessage( PTHREADINFO pti,
UINT Msg,
WPARAM wParam,
LPARAM lParam )
{
MSG Message;
- PETHREAD peThread;
- PTHREADINFO pThread;
LARGE_INTEGER LargeTickCount;
- NTSTATUS Status;
if (is_pointer_message(Msg))
{
EngSetLastError(ERROR_MESSAGE_SYNC_ONLY );
return FALSE;
}
+ Message.hwnd = NULL;
+ Message.message = Msg;
+ Message.wParam = wParam;
+ Message.lParam = lParam;
+ Message.pt = gpsi->ptCursor;
- Status = PsLookupThreadByThreadId((HANDLE)idThread,&peThread);
-
- if( Status == STATUS_SUCCESS )
- {
- pThread = (PTHREADINFO)peThread->Tcb.Win32Thread;
- if( !pThread ||
- !pThread->MessageQueue ||
- (pThread->TIF_flags & TIF_INCLEANUP))
- {
- ObDereferenceObject( peThread );
- return FALSE;
- }
-
- Message.hwnd = NULL;
- Message.message = Msg;
- Message.wParam = wParam;
- Message.lParam = lParam;
- Message.pt = gpsi->ptCursor;
-
- KeQueryTickCount(&LargeTickCount);
- Message.time = MsqCalculateMessageTime(&LargeTickCount);
- MsqPostMessage(pThread, &Message, FALSE, QS_POSTMESSAGE, 0);
- ObDereferenceObject( peThread );
- return TRUE;
- }
- else
- {
- SetLastNtError( Status );
- }
- return FALSE;
+ KeQueryTickCount(&LargeTickCount);
+ Message.time = MsqCalculateMessageTime(&LargeTickCount);
+ MsqPostMessage(pti, &Message, FALSE, QS_POSTMESSAGE, 0);
+ return TRUE;
}
BOOL FASTCALL
if (!Wnd)
{
- return UserPostThreadMessage( PtrToInt(PsGetCurrentThreadId()),
+ pti = PsGetCurrentThreadWin32Thread();
+ return UserPostThreadMessage( pti,
Msg,
wParam,
lParam);
LPARAM lParam)
{
BOOL ret;
+ PETHREAD peThread;
+ PTHREADINFO pThread;
+ NTSTATUS Status;
UserEnterExclusive();
- ret = UserPostThreadMessage( idThread, Msg, wParam, lParam);
+ Status = PsLookupThreadByThreadId((HANDLE)idThread,&peThread);
+ if ( Status == STATUS_SUCCESS )
+ {
+ pThread = (PTHREADINFO)peThread->Tcb.Win32Thread;
+ if( !pThread ||
+ !pThread->MessageQueue ||
+ (pThread->TIF_flags & TIF_INCLEANUP))
+ {
+ ObDereferenceObject( peThread );
+ goto exit;
+ }
+ ret = UserPostThreadMessage( pThread, Msg, wParam, lParam);
+ ObDereferenceObject( peThread );
+ }
+ else
+ {
+ SetLastNtError( Status );
+ }
+exit:
UserLeave();
-
return ret;
}