[ros-diffs] [rharabien] 54107: [WIN32K] - Right ALT on some keyboard sends LCONTROL and RALT key events - Shift has never extended bit in key messages - Fixes about 32 user32:input winetest - Don't allow to re...

rharabien at svn.reactos.org rharabien at svn.reactos.org
Thu Oct 13 13:23:58 UTC 2011


Author: rharabien
Date: Thu Oct 13 13:23:57 2011
New Revision: 54107

URL: http://svn.reactos.org/svn/reactos?rev=54107&view=rev
Log:
[WIN32K]
- Right ALT on some keyboard sends LCONTROL and RALT key events
- Shift has never extended bit in key messages
- Fixes about 32 user32:input winetest
- Don't allow to register hotkeys with special keys combinations (eg. WIN key)
- Set last error in RegisterHotKey if hotkey is already registered

Modified:
    trunk/reactos/subsystems/win32/win32k/include/hotkey.h
    trunk/reactos/subsystems/win32/win32k/include/input.h
    trunk/reactos/subsystems/win32/win32k/ntuser/hotkey.c
    trunk/reactos/subsystems/win32/win32k/ntuser/input.c
    trunk/reactos/subsystems/win32/win32k/ntuser/keyboard.c
    trunk/reactos/subsystems/win32/win32k/ntuser/msgqueue.c

Modified: trunk/reactos/subsystems/win32/win32k/include/hotkey.h
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/include/hotkey.h?rev=54107&r1=54106&r2=54107&view=diff
==============================================================================
--- trunk/reactos/subsystems/win32/win32k/include/hotkey.h [iso-8859-1] (original)
+++ trunk/reactos/subsystems/win32/win32k/include/hotkey.h [iso-8859-1] Thu Oct 13 13:23:57 2011
@@ -1,22 +1,25 @@
 #pragma once
 
-typedef struct _HOT_KEY_ITEM
+typedef struct _HOT_KEY
 {
-  LIST_ENTRY ListEntry;
-  struct _ETHREAD *Thread;
-  HWND hWnd;
-  int id;
-  UINT fsModifiers;
-  UINT vk;
-} HOT_KEY_ITEM, *PHOT_KEY_ITEM;
+    struct _ETHREAD *pThread;
+    HWND hWnd;
+    UINT fsModifiers;
+    UINT vk;
+    INT id;
+    struct _HOT_KEY *pNext;
+} HOT_KEY, *PHOT_KEY;
 
-#define IDHOT_REACTOS (-9)
+/* Special Hot Keys */
+#define IDHK_F12       -5
+#define IDHK_SHIFTF12  -6
+#define IDHK_WINKEY    -7
+#define IDHK_REACTOS   -8
 
 INIT_FUNCTION NTSTATUS NTAPI InitHotkeyImpl(VOID);
 
-PHOT_KEY_ITEM FASTCALL IsHotKey(UINT fsModifiers, WORD wVk);
 VOID FASTCALL UnregisterWindowHotKeys(PWND Window);
-VOID FASTCALL UnregisterThreadHotKeys(struct _ETHREAD *Thread);
+VOID FASTCALL UnregisterThreadHotKeys(struct _ETHREAD *pThread);
 BOOL NTAPI co_UserProcessHotKeys(WORD wVk, BOOL bIsDown);
 UINT FASTCALL DefWndGetHotKey(HWND hwnd);
 INT FASTCALL DefWndSetHotKey(PWND pWnd, WPARAM wParam);

Modified: trunk/reactos/subsystems/win32/win32k/include/input.h
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/include/input.h?rev=54107&r1=54106&r2=54107&view=diff
==============================================================================
--- trunk/reactos/subsystems/win32/win32k/include/input.h [iso-8859-1] (original)
+++ trunk/reactos/subsystems/win32/win32k/include/input.h [iso-8859-1] Thu Oct 13 13:23:57 2011
@@ -33,17 +33,12 @@
 /* Scan Codes */
 #define SC_KEY_UP        0x8000
 /* lParam bits */
-#define LP_EXT_BIT         (KF_EXTENDED<<16)
 #define LP_DO_NOT_CARE_BIT (1<<25) // for GetKeyNameText
-#define LP_DLGMODE         (KF_DLGMODE<<16)
-#define LP_MENUMODE        (KF_MENUMODE<<16)
-#define LP_CONTEXT_BIT     (KF_ALTDOWN<<16)
-#define LP_PREV_STATE_BIT  (KF_REPEAT<<16)
-#define LP_TRANSITION_BIT  (KF_UP<<16)
 
 
 INIT_FUNCTION NTSTATUS NTAPI InitInputImpl(VOID);
 INIT_FUNCTION NTSTATUS NTAPI InitKeyboardImpl(VOID);
+VOID NTAPI UserInitKeyboard(HANDLE hKeyboardDevice);
 PKBL W32kGetDefaultKeyLayout(VOID);
 VOID NTAPI UserProcessKeyboardInput(PKEYBOARD_INPUT_DATA pKeyInput);
 BOOL NTAPI UserSendKeyboardInput(KEYBDINPUT *pKbdInput, BOOL bInjected);

Modified: trunk/reactos/subsystems/win32/win32k/ntuser/hotkey.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/ntuser/hotkey.c?rev=54107&r1=54106&r2=54107&view=diff
==============================================================================
--- trunk/reactos/subsystems/win32/win32k/ntuser/hotkey.c [iso-8859-1] (original)
+++ trunk/reactos/subsystems/win32/win32k/ntuser/hotkey.c [iso-8859-1] Thu Oct 13 13:23:57 2011
@@ -19,7 +19,13 @@
 
 /* GLOBALS *******************************************************************/
 
-LIST_ENTRY gHotkeyList;
+/* Hardcoded hotkeys. See http://ivanlef0u.fr/repo/windoz/VI20051005.html */
+/*                   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};
+
+PHOT_KEY gphkFirst = &hkWinKey;
 
 /* FUNCTIONS *****************************************************************/
 
@@ -28,19 +34,14 @@
 NTAPI
 InitHotkeyImpl(VOID)
 {
-    InitializeListHead(&gHotkeyList);
-
     return STATUS_SUCCESS;
 }
 
-#if 0 //not used
-NTSTATUS FASTCALL
+/*NTSTATUS FASTCALL
 CleanupHotKeys(VOID)
 {
-
     return STATUS_SUCCESS;
-}
-#endif
+}*/
 
 /*
  * IntGetModifiers
@@ -69,151 +70,235 @@
     return fModifiers;
 }
 
+/*
+ * UnregisterWindowHotKeys
+ *
+ * Removes hotkeys registered by specified window on its cleanup
+ */
 VOID FASTCALL
-UnregisterWindowHotKeys(PWND Window)
-{
-    PHOT_KEY_ITEM HotKeyItem, tmp;
-
-    LIST_FOR_EACH_SAFE(HotKeyItem, tmp, &gHotkeyList, HOT_KEY_ITEM, ListEntry)
-    {
-        if (HotKeyItem->hWnd == Window->head.h)
-        {
-            RemoveEntryList(&HotKeyItem->ListEntry);
-            ExFreePool(HotKeyItem);
-        }
-    }
-}
-
+UnregisterWindowHotKeys(PWND pWnd)
+{
+    PHOT_KEY pHotKey = gphkFirst, phkNext, *pLink = &gphkFirst;
+    HWND hWnd = pWnd->head.h;
+
+    while (pHotKey)
+    {
+        /* Save next ptr for later use */
+        phkNext = pHotKey->pNext;
+
+        /* Should we delete this hotkey? */
+        if (pHotKey->hWnd == hWnd)
+        {
+            /* Update next ptr for previous hotkey and free memory */
+            *pLink = phkNext;
+            ExFreePoolWithTag(pHotKey, USERTAG_HOTKEY);
+        }
+        else /* This hotkey will stay, use its next ptr */
+            pLink = &pHotKey->pNext;
+
+        /* Move to the next entry */
+        pHotKey = phkNext;
+    }
+}
+
+/*
+ * UnregisterThreadHotKeys
+ *
+ * Removes hotkeys registered by specified thread on its cleanup
+ */
 VOID FASTCALL
-UnregisterThreadHotKeys(struct _ETHREAD *Thread)
-{
-    PHOT_KEY_ITEM HotKeyItem, tmp;
-
-    LIST_FOR_EACH_SAFE(HotKeyItem, tmp, &gHotkeyList, HOT_KEY_ITEM, ListEntry)
-    {
-        if (HotKeyItem->Thread == Thread)
-        {
-            RemoveEntryList(&HotKeyItem->ListEntry);
-            ExFreePool(HotKeyItem);
-        }
-    }
-
-}
-
-PHOT_KEY_ITEM FASTCALL
+UnregisterThreadHotKeys(struct _ETHREAD *pThread)
+{
+    PHOT_KEY pHotKey = gphkFirst, phkNext, *pLink = &gphkFirst;
+
+    while (pHotKey)
+    {
+        /* Save next ptr for later use */
+        phkNext = pHotKey->pNext;
+
+        /* Should we delete this hotkey? */
+        if (pHotKey->pThread == pThread)
+        {
+            /* Update next ptr for previous hotkey and free memory */
+            *pLink = phkNext;
+            ExFreePoolWithTag(pHotKey, USERTAG_HOTKEY);
+        }
+        else /* This hotkey will stay, use its next ptr */
+            pLink = &pHotKey->pNext;
+
+        /* Move to the next entry */
+        pHotKey = phkNext;
+    }
+}
+
+/*
+ * IsHotKey
+ *
+ * Checks if given key and modificators have corresponding hotkey
+ */
+static PHOT_KEY FASTCALL
 IsHotKey(UINT fsModifiers, WORD wVk)
 {
-    PHOT_KEY_ITEM pHotKeyItem;
-
-    LIST_FOR_EACH(pHotKeyItem, &gHotkeyList, HOT_KEY_ITEM, ListEntry)
-    {
-        if (pHotKeyItem->fsModifiers == fsModifiers && pHotKeyItem->vk == wVk)
-        {
-            return pHotKeyItem;
-        }
+    PHOT_KEY pHotKey = gphkFirst;
+
+    while (pHotKey)
+    {
+        if (pHotKey->fsModifiers == fsModifiers &&
+            pHotKey->vk == wVk)
+        {
+            /* We have found it */
+            return pHotKey;
+        }
+
+        /* Move to the next entry */
+        pHotKey = pHotKey->pNext;
     }
 
     return NULL;
 }
 
 /*
- * IntKeyboardSendWinKeyMsg
- *
- * Sends syscommand to shell, when WIN key is pressed
+ * SendSysCmdMsg
+ *
+ * Sends syscommand to specified window
  */
 static
 VOID NTAPI
-IntKeyboardSendWinKeyMsg()
+SendSysCmdMsg(HWND hWnd, WPARAM Cmd, LPARAM lParam)
 {
     PWND pWnd;
     MSG Msg;
-
-    if (!(pWnd = UserGetWindowObject(InputWindowStation->ShellWindow)))
-    {
-        ERR("Couldn't find window to send Windows key message!\n");
+    LARGE_INTEGER LargeTickCount;
+
+    /* Get ptr to given window */
+    pWnd = UserGetWindowObject(hWnd);
+    if (!pWnd)
+    {
+        WARN("Invalid window!\n");
         return;
     }
 
-    Msg.hwnd = InputWindowStation->ShellWindow;
+    /* Prepare WM_SYSCOMMAND message */
+    Msg.hwnd = hWnd;
     Msg.message = WM_SYSCOMMAND;
-    Msg.wParam = SC_TASKLIST;
-    Msg.lParam = 0;
-
-    /* The QS_HOTKEY is just a guess */
-    MsqPostMessage(pWnd->head.pti->MessageQueue, &Msg, FALSE, QS_HOTKEY);
-}
-
+    Msg.wParam = Cmd;
+    Msg.lParam = lParam;
+    KeQueryTickCount(&LargeTickCount);
+    Msg.time = MsqCalculateMessageTime(&LargeTickCount);
+    Msg.pt = gpsi->ptCursor;
+
+    /* Post message to window */
+    MsqPostMessage(pWnd->head.pti->MessageQueue, &Msg, FALSE, QS_POSTMESSAGE);
+}
+
+/*
+ * co_UserProcessHotKeys
+ *
+ * Sends WM_HOTKEY message if given keys are hotkey
+ */
 BOOL NTAPI
 co_UserProcessHotKeys(WORD wVk, BOOL bIsDown)
 {
     UINT fModifiers;
-    PHOT_KEY_ITEM pHotKey;
+    PHOT_KEY pHotKey;
+
+    if (wVk == VK_SHIFT || wVk == VK_CONTROL || wVk == VK_MENU ||
+        wVk == VK_LWIN || wVk == VK_RWIN)
+    {
+        /* Those keys are specified by modifiers */
+        wVk = 0;
+    }
 
     /* Check if it is a hotkey */
     fModifiers = IntGetModifiers(gafAsyncKeyState);
     pHotKey = IsHotKey(fModifiers, wVk);
     if (pHotKey)
     {
-        if (bIsDown)
-        {
-            TRACE("Hot key pressed (hWnd %lx, id %d)\n", pHotKey->hWnd, pHotKey->id);
-            MsqPostHotKeyMessage(pHotKey->Thread,
-                                 pHotKey->hWnd,
-                                 (WPARAM)pHotKey->id,
-                                 MAKELPARAM((WORD)fModifiers, wVk));
+        /* Process hotkey if it is key up event */
+        if (!bIsDown)
+        {
+            TRACE("Hot key pressed (hWnd %p, id %d)\n", pHotKey->hWnd, pHotKey->id);
+
+            /* WIN and F12 keys are hardcoded here. See: http://ivanlef0u.fr/repo/windoz/VI20051005.html */
+            if (pHotKey == &hkWinKey)
+                SendSysCmdMsg(InputWindowStation->ShellWindow, SC_TASKLIST, 0);
+            else if (pHotKey == &hkF12 || pHotKey == &hkShiftF12)
+            {
+                //co_ActivateDebugger(); // FIXME
+            }
+            else if (pHotKey->id == IDHK_REACTOS && !pHotKey->pThread) // FIXME: those hotkeys doesn't depend on RegisterHotKey
+            {
+                SendSysCmdMsg(pHotKey->hWnd, SC_HOTKEY, (LPARAM)pHotKey->hWnd);
+            }
+            else
+            {
+                MsqPostHotKeyMessage(pHotKey->pThread,
+                                     pHotKey->hWnd,
+                                     (WPARAM)pHotKey->id,
+                                     MAKELPARAM((WORD)fModifiers, wVk));
+            }
         }
 
         return TRUE; /* Don't send any message */
     }
 
-    if ((wVk == VK_LWIN || wVk == VK_RWIN) && fModifiers == 0)
-        IntKeyboardSendWinKeyMsg();
-
     return FALSE;
 }
 
 
-//
-// Get/SetHotKey message support.
-//
+/*
+ * DefWndGetHotKey
+ *
+ * GetHotKey message support
+ */
 UINT FASTCALL
-DefWndGetHotKey(HWND hwnd)
-{
-    PHOT_KEY_ITEM HotKeyItem;
-
-    ERR("DefWndGetHotKey\n");
-
-    if (IsListEmpty(&gHotkeyList)) return 0;
-
-    LIST_FOR_EACH(HotKeyItem, &gHotkeyList, HOT_KEY_ITEM, ListEntry)
-    {
-        if (HotKeyItem->hWnd == hwnd &&
-            HotKeyItem->id == IDHOT_REACTOS)
-        {
-            return MAKELONG(HotKeyItem->vk, HotKeyItem->fsModifiers);
-        }
-    }
+DefWndGetHotKey(HWND hWnd)
+{
+    PHOT_KEY pHotKey = gphkFirst;
+
+    WARN("DefWndGetHotKey\n");
+
+    while (pHotKey)
+    {
+        if (pHotKey->hWnd == hWnd && pHotKey->id == IDHK_REACTOS)
+        {
+            /* We have found it */
+            return MAKELONG(pHotKey->vk, pHotKey->fsModifiers);
+        }
+
+        /* Move to the next entry */
+        pHotKey = pHotKey->pNext;
+    }
+
     return 0;
 }
 
+/*
+ * DefWndSetHotKey
+ *
+ * SetHotKey message support
+ */
 INT FASTCALL
 DefWndSetHotKey(PWND pWnd, WPARAM wParam)
 {
     UINT fsModifiers, vk;
-    PHOT_KEY_ITEM HotKeyItem;
+    PHOT_KEY pHotKey, *pLink;
     HWND hWnd;
-    BOOL HaveSameWnd = FALSE;
-    INT Ret = 1;
-
-    ERR("DefWndSetHotKey wParam 0x%x\n", wParam);
+    INT iRet = 1;
+
+    WARN("DefWndSetHotKey wParam 0x%x\n", wParam);
 
     // A hot key cannot be associated with a child window.
-    if (pWnd->style & WS_CHILD) return 0;
+    if (pWnd->style & WS_CHILD)
+        return 0;
 
     // VK_ESCAPE, VK_SPACE, and VK_TAB are invalid hot keys.
     if (LOWORD(wParam) == VK_ESCAPE ||
         LOWORD(wParam) == VK_SPACE ||
-        LOWORD(wParam) == VK_TAB) return -1;
+        LOWORD(wParam) == VK_TAB)
+    {
+        return -1;
+    }
 
     vk = LOWORD(wParam);
     fsModifiers = HIWORD(wParam);
@@ -221,62 +306,68 @@
 
     if (wParam)
     {
-        LIST_FOR_EACH(HotKeyItem, &gHotkeyList, HOT_KEY_ITEM, ListEntry)
-        {
-            if (HotKeyItem->fsModifiers == fsModifiers &&
-                HotKeyItem->vk == vk &&
-                HotKeyItem->id == IDHOT_REACTOS)
+        pHotKey = gphkFirst;
+        while (pHotKey)
+        {
+            if (pHotKey->fsModifiers == fsModifiers &&
+                pHotKey->vk == vk &&
+                pHotKey->id == IDHK_REACTOS)
             {
-                if (HotKeyItem->hWnd != hWnd)
-                    Ret = 2; // Another window already has the same hot key.
+                if (pHotKey->hWnd != hWnd)
+                    iRet = 2; // Another window already has the same hot key.
                 break;
             }
-        }
-    }
-
-    LIST_FOR_EACH(HotKeyItem, &gHotkeyList, HOT_KEY_ITEM, ListEntry)
-    {
-        if (HotKeyItem->hWnd == hWnd &&
-            HotKeyItem->id == IDHOT_REACTOS)
-        {
-            HaveSameWnd = TRUE;
+
+            /* Move to the next entry */
+            pHotKey = pHotKey->pNext;
+        }
+    }
+    
+    pHotKey = gphkFirst;
+    pLink = &gphkFirst;
+    while (pHotKey)
+    {
+        if (pHotKey->hWnd == hWnd &&
+            pHotKey->id == IDHK_REACTOS)
+        {
+            /* This window has already hotkey registered */
             break;
         }
-    }
-
-    if (HaveSameWnd)
-    {
-        if (wParam == 0)
-        {   // Setting wParam to NULL removes the hot key associated with a window.
-            UnregisterWindowHotKeys(pWnd);
-        }
-        else
-        {   /* 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. */
-            HotKeyItem->fsModifiers = fsModifiers;
-            HotKeyItem->vk = vk;
-        }
-    }
-    else //
-    {
-        if (wParam == 0)
-            return 1; // Do nothing, exit.
-
-        HotKeyItem = ExAllocatePoolWithTag(PagedPool, sizeof(HOT_KEY_ITEM), USERTAG_HOTKEY);
-        if (HotKeyItem == NULL)
-        {
-            return 0;
-        }
-
-        HotKeyItem->Thread = pWnd->head.pti->pEThread;
-        HotKeyItem->hWnd = hWnd;
-        HotKeyItem->id = IDHOT_REACTOS; // Don't care, these hot keys are unrelated to the hot keys set by RegisterHotKey.
-        HotKeyItem->fsModifiers = fsModifiers;
-        HotKeyItem->vk = vk;
-
-        InsertHeadList(&gHotkeyList, &HotKeyItem->ListEntry);
-    }
-    return Ret;
+
+        /* Move to the next entry */
+        pLink = &pHotKey->pNext;
+        pHotKey = pHotKey->pNext;
+    }
+
+    if (wParam)
+    {
+        if (!pHotKey)
+        {
+            /* Create new hotkey */
+            pHotKey = ExAllocatePoolWithTag(PagedPool, sizeof(HOT_KEY), USERTAG_HOTKEY);
+            if (pHotKey == NULL)
+                return 0;
+
+            pHotKey->hWnd = hWnd;
+            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->fsModifiers = fsModifiers;
+        pHotKey->vk = vk;
+    }
+    else if (pHotKey)
+    {
+        /* Remove hotkey */
+        *pLink = pHotKey->pNext;
+        ExFreePoolWithTag(pHotKey, USERTAG_HOTKEY);
+    }
+
+    return iRet;
 }
 
 /* SYSCALLS *****************************************************************/
@@ -288,88 +379,110 @@
                      UINT fsModifiers,
                      UINT vk)
 {
-    PHOT_KEY_ITEM HotKeyItem;
-    PWND Window;
-    PETHREAD HotKeyThread;
-    DECLARE_RETURN(BOOL);
+    PHOT_KEY pHotKey;
+    PWND pWnd;
+    PETHREAD pHotKeyThread;
+    BOOL bRet = FALSE;
 
     TRACE("Enter NtUserRegisterHotKey\n");
+
+    if (fsModifiers & ~(MOD_ALT|MOD_CONTROL|MOD_SHIFT|MOD_WIN)) //FIXME: does win2k3 supports MOD_NOREPEAT?
+    {
+        WARN("Invalid modifiers: %x\n", fsModifiers);
+        EngSetLastError(ERROR_INVALID_FLAGS);
+        return 0;
+    }
+
     UserEnterExclusive();
 
+    /* Find hotkey thread */
     if (hWnd == NULL)
     {
-        HotKeyThread = PsGetCurrentThread();
+        pHotKeyThread = PsGetCurrentThread();
     }
     else
     {
-        if(!(Window = UserGetWindowObject(hWnd)))
-        {
-            RETURN( FALSE);
-        }
-        HotKeyThread = Window->head.pti->pEThread;
+        pWnd = UserGetWindowObject(hWnd);
+        if (!pWnd)
+            goto cleanup;
+
+        pHotKeyThread = pWnd->head.pti->pEThread;
     }
 
     /* Check for existing hotkey */
     if (IsHotKey(fsModifiers, vk))
     {
-        RETURN( FALSE);
-    }
-
-    HotKeyItem = ExAllocatePoolWithTag(PagedPool, sizeof(HOT_KEY_ITEM), USERTAG_HOTKEY);
-    if (HotKeyItem == NULL)
-    {
-        RETURN( FALSE);
-    }
-
-    HotKeyItem->Thread = HotKeyThread;
-    HotKeyItem->hWnd = hWnd;
-    HotKeyItem->id = id;
-    HotKeyItem->fsModifiers = fsModifiers;
-    HotKeyItem->vk = vk;
-
-    InsertHeadList(&gHotkeyList, &HotKeyItem->ListEntry);
-
-    RETURN( TRUE);
-
-CLEANUP:
-    TRACE("Leave NtUserRegisterHotKey, ret=%i\n", _ret_);
+        EngSetLastError(ERROR_HOTKEY_ALREADY_REGISTERED);
+        WARN("Hotkey already exists\n");
+        goto cleanup;
+    }
+
+    /* Create new hotkey */
+    pHotKey = ExAllocatePoolWithTag(PagedPool, sizeof(HOT_KEY), USERTAG_HOTKEY);
+    if (pHotKey == NULL)
+    {
+        EngSetLastError(ERROR_NOT_ENOUGH_MEMORY);
+        goto cleanup;
+    }
+
+    pHotKey->pThread = pHotKeyThread;
+    pHotKey->hWnd = hWnd;
+    pHotKey->fsModifiers = fsModifiers;
+    pHotKey->vk = vk;
+    pHotKey->id = id;
+
+    /* Insert hotkey to the global list */
+    pHotKey->pNext = gphkFirst;
+    gphkFirst = pHotKey;
+
+    bRet = TRUE;
+
+cleanup:
+    TRACE("Leave NtUserRegisterHotKey, ret=%i\n", bRet);
     UserLeave();
-    END_CLEANUP;
+    return bRet;
 }
 
 
 BOOL APIENTRY
 NtUserUnregisterHotKey(HWND hWnd, int id)
 {
-    PHOT_KEY_ITEM HotKeyItem;
-    PWND Window;
-    DECLARE_RETURN(BOOL);
+    PHOT_KEY pHotKey = gphkFirst, phkNext, *pLink = &gphkFirst;
+    PWND pWnd;
+    BOOL bRet = FALSE;
 
     TRACE("Enter NtUserUnregisterHotKey\n");
     UserEnterExclusive();
 
-    if(!(Window = UserGetWindowObject(hWnd)))
-    {
-        RETURN( FALSE);
-    }
-
-    LIST_FOR_EACH(HotKeyItem, &gHotkeyList, HOT_KEY_ITEM, ListEntry)
-    {
-        if (HotKeyItem->hWnd == hWnd && HotKeyItem->id == id)
-        {
-            RemoveEntryList(&HotKeyItem->ListEntry);
-            ExFreePoolWithTag(HotKeyItem, USERTAG_HOTKEY);
-
-            RETURN( TRUE);
-        }
-    }
-
-    RETURN( FALSE);
-
-CLEANUP:
-    TRACE("Leave NtUserUnregisterHotKey, ret=%i\n", _ret_);
+    pWnd = UserGetWindowObject(hWnd);
+    if (!pWnd)
+        goto cleanup;
+
+    while (pHotKey)
+    {
+        /* Save next ptr for later use */
+        phkNext = pHotKey->pNext;
+
+        /* Should we delete this hotkey? */
+        if (pHotKey->hWnd == hWnd && 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;
+    }
+
+cleanup:
+    TRACE("Leave NtUserUnregisterHotKey, ret=%i\n", bRet);
     UserLeave();
-    END_CLEANUP;
+    return bRet;
 }
 
 /* EOF */

Modified: trunk/reactos/subsystems/win32/win32k/ntuser/input.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/ntuser/input.c?rev=54107&r1=54106&r2=54107&view=diff
==============================================================================
--- trunk/reactos/subsystems/win32/win32k/ntuser/input.c [iso-8859-1] (original)
+++ trunk/reactos/subsystems/win32/win32k/ntuser/input.c [iso-8859-1] Thu Oct 13 13:23:57 2011
@@ -332,6 +332,8 @@
                             FILE_SYNCHRONOUS_IO_ALERT);
     } while (!NT_SUCCESS(Status));
 
+    UserInitKeyboard(ghKeyboardDevice);
+
     /* 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
@@ -355,22 +357,19 @@
     KeSetPriorityThread(&PsGetCurrentThread()->Tcb,
                         LOW_REALTIME_PRIORITY + 3);
 
-    //IntKeyboardGetIndicatorTrans(ghKeyboardDevice,
-   //                              &IndicatorTrans);
-
     for (;;)
     {
         /*
          * Wait to start input.
          */
-        TRACE( "Keyboard Input Thread Waiting for start event\n" );
+        TRACE("Keyboard Input Thread Waiting for start event\n");
         Status = KeWaitForSingleObject(&InputThreadsStart,
                                        0,
                                        KernelMode,
                                        TRUE,
                                        NULL);
 
-        TRACE( "Keyboard Input Thread Starting...\n" );
+        TRACE("Keyboard Input Thread Starting...\n");
         /*
          * Receive and process keyboard input.
          */
@@ -390,16 +389,16 @@
                                  NULL,
                                  NULL);
 
-            if(Status == STATUS_ALERTED && !InputThreadsRunning)
+            if (Status == STATUS_ALERTED && !InputThreadsRunning)
             {
                 break;
             }
-            if(Status == STATUS_PENDING)
+            if (Status == STATUS_PENDING)
             {
                 NtWaitForSingleObject(ghKeyboardDevice, FALSE, NULL);
                 Status = Iosb.Status;
             }
-            if(!NT_SUCCESS(Status))
+            if (!NT_SUCCESS(Status))
             {
                 ERR("Win32K: Failed to read from keyboard.\n");
                 return; //(Status);
@@ -427,7 +426,7 @@
             UserLeave();
         }
 
-        TRACE( "KeyboardInput Thread Stopped...\n" );
+        TRACE("KeyboardInput Thread Stopped...\n");
     }
 }
 

Modified: trunk/reactos/subsystems/win32/win32k/ntuser/keyboard.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/ntuser/keyboard.c?rev=54107&r1=54106&r2=54107&view=diff
==============================================================================
--- trunk/reactos/subsystems/win32/win32k/ntuser/keyboard.c [iso-8859-1] (original)
+++ trunk/reactos/subsystems/win32/win32k/ntuser/keyboard.c [iso-8859-1] Thu Oct 13 13:23:57 2011
@@ -11,8 +11,9 @@
 DBG_DEFAULT_CHANNEL(UserKbd);
 
 BYTE gafAsyncKeyState[256 * 2 / 8]; // 2 bits per key
-BYTE gafAsyncKeyStateRecentDown[256 / 8]; // 1 bit per key
+static BYTE gafAsyncKeyStateRecentDown[256 / 8]; // 1 bit per key
 static PKEYBOARD_INDICATOR_TRANSLATION gpKeyboardIndicatorTrans = NULL;
+static KEYBOARD_INDICATOR_PARAMETERS gIndicators = {0, 0};
 
 /* FUNCTIONS *****************************************************************/
 
@@ -97,42 +98,85 @@
 static
 NTSTATUS APIENTRY
 IntKeyboardUpdateLeds(HANDLE hKeyboardDevice,
+                      WORD wVk,
                       WORD wScanCode,
-                      BOOL bEnabled,
-                      PKEYBOARD_INDICATOR_TRANSLATION pIndicatorTrans)
+                      BOOL bEnabled)
 {
     NTSTATUS Status;
     UINT i;
-    static KEYBOARD_INDICATOR_PARAMETERS Indicators;
+    USHORT LedFlag = 0;
     IO_STATUS_BLOCK Block;
 
-    if (!pIndicatorTrans)
+    if (!gpKeyboardIndicatorTrans)
         return STATUS_NOT_SUPPORTED;
 
-    for (i = 0; i < pIndicatorTrans->NumberOfIndicatorKeys; i++)
-    {
-        if (pIndicatorTrans->IndicatorList[i].MakeCode == wScanCode)
-        {
-            if (bEnabled)
-                Indicators.LedFlags |= pIndicatorTrans->IndicatorList[i].IndicatorFlags;
-            else
-                Indicators.LedFlags = ~pIndicatorTrans->IndicatorList[i].IndicatorFlags;
-
-            /* Update the lights on the hardware */
-            Status = NtDeviceIoControlFile(hKeyboardDevice,
-                                           NULL,
-                                           NULL,
-                                           NULL,
-                                           &Block,
-                                           IOCTL_KEYBOARD_SET_INDICATORS,
-                                           &Indicators, sizeof(Indicators),
-                                           NULL, 0);
-
-            return Status;
-        }
+    switch (wVk)
+    {
+        case VK_CAPITAL: LedFlag = KEYBOARD_CAPS_LOCK_ON; break;
+        case VK_NUMLOCK: LedFlag = KEYBOARD_NUM_LOCK_ON; break;
+        case VK_SCROLL: LedFlag = KEYBOARD_SCROLL_LOCK_ON; break;
+        default:
+            for (i = 0; i < gpKeyboardIndicatorTrans->NumberOfIndicatorKeys; i++)
+            {
+                if (gpKeyboardIndicatorTrans->IndicatorList[i].MakeCode == wScanCode)
+                {
+                    LedFlag = gpKeyboardIndicatorTrans->IndicatorList[i].IndicatorFlags;
+                    break;
+                }
+            }
+    }
+
+    if (LedFlag)
+    {
+        if (bEnabled)
+            gIndicators.LedFlags |= LedFlag;
+        else
+            gIndicators.LedFlags = ~LedFlag;
+
+        /* Update the lights on the hardware */
+        Status = NtDeviceIoControlFile(hKeyboardDevice,
+                                       NULL,
+                                       NULL,
+                                       NULL,
+                                       &Block,
+                                       IOCTL_KEYBOARD_SET_INDICATORS,
+                                       &gIndicators, sizeof(gIndicators),
+                                       NULL, 0);
+
+        return Status;
     }
 
     return STATUS_SUCCESS;
+}
+
+/*
+ * UserInitKeyboard
+ *
+ * Initializes keyboard indicators translation and their state
+ */
+VOID NTAPI
+UserInitKeyboard(HANDLE hKeyboardDevice)
+{
+    NTSTATUS Status;
+    IO_STATUS_BLOCK Block;
+
+    IntKeyboardGetIndicatorTrans(hKeyboardDevice, &gpKeyboardIndicatorTrans);
+
+    Status = NtDeviceIoControlFile(hKeyboardDevice,
+                                   NULL,
+                                   NULL,
+                                   NULL,
+                                   &Block,
+                                   IOCTL_KEYBOARD_QUERY_INDICATORS,
+                                   NULL, 0,
+                                   &gIndicators, sizeof(gIndicators));
+
+    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);
 }
 
 /*
@@ -185,30 +229,6 @@
 
         default:
             return wVk;
-    }
-}
-
-/*
- * IntGetVkOtherSide
- *
- * Gets other side of vk: right -> left, left -> right
- */
-static
-WORD
-IntGetVkOtherSide(WORD wVk)
-{
-    switch (wVk)
-    {
-        case VK_LSHIFT: return VK_RSHIFT;
-        case VK_RSHIFT: return VK_LSHIFT;
-
-        case VK_LCONTROL: return VK_RCONTROL;
-        case VK_RCONTROL: return VK_LCONTROL;
-
-        case VK_LMENU: return VK_RMENU;
-        case VK_RMENU: return VK_LMENU;
-
-        default: return wVk;
     }
 }
 
@@ -239,24 +259,6 @@
 }
 
 /*
- * IntGetShiftBit
- *
- * Search the keyboard layout modifiers table for the shift bit
- */
-static
-DWORD FASTCALL
-IntGetShiftBit(PKBDTABLES pKbdTbl, WORD wVk)
-{
-    unsigned i;
-
-    for (i = 0; pKbdTbl->pCharModifiers->pVkToBit[i].Vk; i++)
-        if (pKbdTbl->pCharModifiers->pVkToBit[i].Vk == wVk)
-            return pKbdTbl->pCharModifiers->pVkToBit[i].ModBits;
-
-    return 0;
-}
-
-/*
  * IntGetModBits
  *
  * Gets layout specific modification bits, for example KBDSHIFT, KBDCTRL, KBDALT
@@ -272,10 +274,6 @@
     for (i = 0; pKbdTbl->pCharModifiers->pVkToBit[i].Vk; i++)
         if (IS_KEY_DOWN(pKeyState, pKbdTbl->pCharModifiers->pVkToBit[i].Vk))
             dwModBits |= pKbdTbl->pCharModifiers->pVkToBit[i].ModBits;
-
-    /* Handle Alt+Gr */
-    if ((pKbdTbl->fLocaleFlags & KLLF_ALTGR) && IS_KEY_DOWN(pKeyState, VK_RMENU))
-        dwModBits |= IntGetShiftBit(pKbdTbl, VK_CONTROL); /* Don't use KBDCTRL here */
 
     TRACE("Current Mod Bits: %lx\n", dwModBits);
 
@@ -616,20 +614,6 @@
 }
 
 /*
- * co_IntKeyboardSendAltKeyMsg
- *
- * Sends syscommand enabling window menu
- */
-static
-VOID NTAPI
-co_IntKeyboardSendAltKeyMsg()
-{
-    FIXME("co_IntKeyboardSendAltKeyMsg\n");
-    //co_MsqPostKeyboardMessage(WM_SYSCOMMAND,SC_KEYMENU,0); // This sends everything into a msg loop!
-}
-
-
-/*
  * UpdateAsyncKeyState
  *
  * Updates gafAsyncKeyState array
@@ -651,26 +635,40 @@
         SET_KEY_DOWN(gafAsyncKeyState, wVk, FALSE);
 }
 
-LRESULT
-co_CallLowLevelKeyboardHook(CONST MSG *pMsg, BOOL bInjected, DWORD dwExtraInfo)
+/*
+ * co_CallLowLevelKeyboardHook
+ *
+ * Calls WH_KEYBOARD_LL hook
+ */
+static LRESULT
+co_CallLowLevelKeyboardHook(WORD wVk, WORD wScanCode, DWORD dwFlags, BOOL bInjected, DWORD dwTime, DWORD dwExtraInfo)
 {
     KBDLLHOOKSTRUCT KbdHookData;
-
-    KbdHookData.vkCode = pMsg->wParam;
-    KbdHookData.scanCode = HIWORD(pMsg->lParam) & 0xFF;
+    UINT uMsg;
+
+    KbdHookData.vkCode = wVk;
+    KbdHookData.scanCode = wScanCode;
     KbdHookData.flags = 0;
-    if (pMsg->lParam & LP_EXT_BIT)
+    if (dwFlags & KEYEVENTF_EXTENDEDKEY)
         KbdHookData.flags |= LLKHF_EXTENDED;
     if (IS_KEY_DOWN(gafAsyncKeyState, VK_MENU))
         KbdHookData.flags |= LLKHF_ALTDOWN;
-    if (pMsg->message == WM_KEYUP || pMsg->message == WM_SYSKEYUP)
+    if (dwFlags & KEYEVENTF_KEYUP)
         KbdHookData.flags |= LLKHF_UP;
     if (bInjected)
         KbdHookData.flags |= LLKHF_INJECTED;
-    KbdHookData.time = pMsg->time;
+    KbdHookData.time = dwTime;
     KbdHookData.dwExtraInfo = dwExtraInfo;
 
-    return co_HOOK_CallHooks(WH_KEYBOARD_LL, HC_ACTION, pMsg->message, (LPARAM) &KbdHookData);
+    /* Note: it doesnt support WM_SYSKEYUP */
+    if (dwFlags & KEYEVENTF_KEYUP)
+        uMsg = WM_KEYUP;
+    else if (IS_KEY_DOWN(gafAsyncKeyState, VK_MENU) && !IS_KEY_DOWN(gafAsyncKeyState, VK_CONTROL))
+        uMsg = WM_SYSKEYDOWN;
+    else
+        uMsg = WM_KEYDOWN;
+
+    return co_HOOK_CallHooks(WH_KEYBOARD_LL, HC_ACTION, uMsg, (LPARAM)&KbdHookData);
 }
 
 /*
@@ -678,19 +676,141 @@
  *
  * Process keyboard input from input devices and SendInput API
  */
+BOOL NTAPI
+ProcessKeyEvent(WORD wVk, WORD wScanCode, DWORD dwFlags, BOOL bInjected, DWORD dwTime, DWORD dwExtraInfo)
+{
+    WORD wSimpleVk = 0, wFixedVk, wVk2;
+    PUSER_MESSAGE_QUEUE pFocusQueue;
+    BOOL bExt = (dwFlags & KEYEVENTF_EXTENDEDKEY) ? TRUE : FALSE;
+    BOOL bIsDown = (dwFlags & KEYEVENTF_KEYUP) ? FALSE : TRUE;
+    BOOL bPacket = (dwFlags & KEYEVENTF_UNICODE) ? TRUE : FALSE;
+    BOOL bWasSimpleDown = FALSE, bPostMsg = TRUE, bIsSimpleDown;
+    MSG Msg;
+    static BOOL bMenuDownRecently = FALSE;
+
+    /* Get virtual key without shifts (VK_(L|R)* -> VK_*) */
+    wSimpleVk = IntSimplifyVk(wVk);
+    bWasSimpleDown = IS_KEY_DOWN(gafAsyncKeyState, wSimpleVk);
+
+    /* Update key without shifts */
+    wVk2 = IntFixVk(wSimpleVk, !bExt);
+    bIsSimpleDown = bIsDown || IS_KEY_DOWN(gafAsyncKeyState, wVk2);
+    UpdateAsyncKeyState(wSimpleVk, bIsSimpleDown);
+
+    if (bIsDown)
+    {
+        /* Update keyboard LEDs */
+        IntKeyboardUpdateLeds(ghKeyboardDevice,
+                              wSimpleVk,
+                              wScanCode,
+                              IS_KEY_LOCKED(gafAsyncKeyState, wSimpleVk));
+    }
+
+    /* Call WH_KEYBOARD_LL hook */
+    if (co_CallLowLevelKeyboardHook(wVk, wScanCode, dwFlags, bInjected, dwTime, dwExtraInfo))
+    {
+        ERR("Kbd msg %d wParam %d lParam 0x%08x dropped by WH_KEYBOARD_LL hook\n",
+            Msg.message, Msg.wParam, Msg.lParam);
+        bPostMsg = FALSE;
+    }
+
+    /* Check if this is a hotkey */
+    if (co_UserProcessHotKeys(wSimpleVk, bIsDown))
+        bPostMsg = FALSE;
+
+    wFixedVk = IntFixVk(wSimpleVk, bExt); /* LSHIFT + EXT = RSHIFT */
+    if (wSimpleVk == VK_SHIFT) /* shift can't be extended */
+        bExt = FALSE;
+
+    /* If it is F10 or ALT is down and CTRL is up, it's a system key */
+    if (wVk == VK_F10 ||
+        (wSimpleVk == VK_MENU && bMenuDownRecently) ||
+        (IS_KEY_DOWN(gafAsyncKeyState, VK_MENU) &&
+        !IS_KEY_DOWN(gafAsyncKeyState, VK_CONTROL)))
+    {
+        bMenuDownRecently = FALSE; // reset
+        if (bIsDown)
+        {
+            Msg.message = WM_SYSKEYDOWN;
+            if (wSimpleVk == VK_MENU)
+            {
+                // Note: If only LALT is pressed WM_SYSKEYUP is generated instead of WM_KEYUP
+                bMenuDownRecently = TRUE;
+            }
+        }
+        else
+            Msg.message = WM_SYSKEYUP;
+    }
+    else
+    {
+        bMenuDownRecently = FALSE;
+        if (bIsDown)
+            Msg.message = WM_KEYDOWN;
+        else
+            Msg.message = WM_KEYUP;
+    }
+
+    /* Update async state of not simplified vk here.
+       See user32_apitest:GetKeyState */
+    UpdateAsyncKeyState(wFixedVk, bIsDown);
+
+    /* Alt-Tab/Esc Check. Use FocusQueue or RIT Queue */
+    if (bIsSimpleDown && !bWasSimpleDown &&
+        IS_KEY_DOWN(gafAsyncKeyState, VK_MENU) &&
+        !IS_KEY_DOWN(gafAsyncKeyState, VK_CONTROL) &&
+        (wVk == VK_ESCAPE || wVk == VK_TAB))
+    {
+       TRACE("Alt-Tab/Esc Pressed wParam %x\n",Msg.wParam);
+    }
+
+    /* If we have a focus queue, post a keyboard message */
+    pFocusQueue = IntGetFocusMessageQueue();
+    if (pFocusQueue && bPostMsg)
+    {
+        /* Init message */
+        Msg.hwnd = pFocusQueue->FocusWindow;
+        Msg.wParam = wFixedVk & 0xFF; /* Note: it's simplified by msg queue */
+        Msg.lParam = MAKELPARAM(1, wScanCode);
+        Msg.time = dwTime;
+        Msg.pt = gpsi->ptCursor;
+
+        /* If it is VK_PACKET, high word of wParam is used for wchar */
+        if (!bPacket)
+        {
+            if (bExt)
+                Msg.lParam |= KF_EXTENDED << 16;
+            if (IS_KEY_DOWN(gafAsyncKeyState, VK_MENU))
+                Msg.lParam |= KF_ALTDOWN << 16;
+            if (bWasSimpleDown)
+                Msg.lParam |= KF_REPEAT << 16;
+            if (!bIsDown)
+                Msg.lParam |= KF_UP << 16;
+            /* FIXME: set KF_DLGMODE and KF_MENUMODE when needed */ 	 
+            if (pFocusQueue->QF_flags & QF_DIALOGACTIVE) 	 
+                Msg.lParam |= KF_DLGMODE << 16;
+            if (pFocusQueue->MenuOwner)//pFocusQueue->MenuState) // MenuState needs a start flag...
+                Msg.lParam |= KF_MENUMODE << 16;
+        }
+
+        /* Post a keyboard message */
+        TRACE("Posting keyboard msg %u wParam 0x%x lParam 0x%x\n", Msg.message, Msg.wParam, Msg.lParam);
+        MsqPostMessage(pFocusQueue, &Msg, TRUE, QS_KEY);
+    }
+
+    return TRUE;
+}
+
 BOOL NTAPI
 UserSendKeyboardInput(KEYBDINPUT *pKbdInput, BOOL bInjected)
 {
-    WORD wScanCode, wVk, wSimpleVk = 0, wVkOtherSide, wSysKey;
+    WORD wScanCode, wVk;
     PKBL pKbl = NULL;
     PKBDTABLES pKbdTbl;
     PUSER_MESSAGE_QUEUE pFocusQueue;
     struct _ETHREAD *pFocusThread;
     LARGE_INTEGER LargeTickCount;
+    DWORD dwTime;
     BOOL bExt = (pKbdInput->dwFlags & KEYEVENTF_EXTENDEDKEY) ? TRUE : FALSE;
-    BOOL bIsDown = (pKbdInput->dwFlags & KEYEVENTF_KEYUP) ? FALSE : TRUE;
-    BOOL bWasDown = FALSE, bPostMsg = TRUE;
-    MSG Msg;
 
     /* Find the target thread whose locale is in effect */
     pFocusQueue = IntGetFocusMessageQueue();
@@ -713,7 +833,7 @@
     pKbdTbl = pKbl->KBTables;
 
     /* Note: wScan field is always used */
-    wScanCode = pKbdInput->wScan & 0x7F;
+    wScanCode = pKbdInput->wScan;
 
     if (pKbdInput->dwFlags & KEYEVENTF_UNICODE)
     {
@@ -723,6 +843,7 @@
     }
     else
     {
+        wScanCode &= 0x7F;
         if (pKbdInput->dwFlags & KEYEVENTF_SCANCODE)
         {
             /* Don't ignore invalid scan codes */
@@ -733,129 +854,26 @@
         else
         {
             wVk = pKbdInput->wVk & 0xFF;
-
-            /* LSHIFT + EXT = RSHIFT */
-            wVk = IntSimplifyVk(wVk);
-            wVk = IntFixVk(wVk, bExt);
-        }
-
-        /* Get virtual key without shifts (VK_(L|R)* -> VK_*) */
-        wSimpleVk = IntSimplifyVk(wVk);
-        wVkOtherSide = IntGetVkOtherSide(wVk);
-        bWasDown = IS_KEY_DOWN(gafAsyncKeyState, wSimpleVk);
-
-        if (co_UserProcessHotKeys(wSimpleVk, bIsDown))
-            bPostMsg = FALSE;
-
-        /* Update key without shifts */
-        UpdateAsyncKeyState(wSimpleVk, bIsDown || IS_KEY_DOWN(gafAsyncKeyState, wVkOtherSide));
-    }
-
-    /* If it is F10 or ALT is down and CTRL is up, it's a system key */
-    wSysKey = (pKbdTbl->fLocaleFlags & KLLF_ALTGR) ? VK_LMENU : VK_MENU;
-    if (wVk == VK_F10 ||
-        //uVkNoShift == VK_MENU || // FIXME: If only LALT is pressed WM_SYSKEYUP is generated instead of WM_KEYUP
-        (IS_KEY_DOWN(gafAsyncKeyState, wSysKey) && // FIXME
-        !IS_KEY_DOWN(gafAsyncKeyState, VK_CONTROL)))
-    {
-        if (bIsDown)
-            Msg.message = WM_SYSKEYDOWN;
-        else
-            Msg.message = WM_SYSKEYUP;
-    }
-    else
-    {
-        if (bIsDown)
-            Msg.message = WM_KEYDOWN;
-        else
-            Msg.message = WM_KEYUP;
-    }
-
-    /* Init hwnd and lParam */
-    Msg.hwnd = pFocusQueue->FocusWindow;
-    Msg.lParam = MAKELPARAM(1, wScanCode);
-
-    /* If it is VK_PACKET, high word of wParam is used for wchar */
-    if (!(pKbdInput->dwFlags & KEYEVENTF_UNICODE))
-    {
-        if (bExt)
-            Msg.lParam |= LP_EXT_BIT;
-        if (IS_KEY_DOWN(gafAsyncKeyState, VK_MENU))
-            Msg.lParam |= LP_CONTEXT_BIT;
-        if (bWasDown)
-            Msg.lParam |= LP_PREV_STATE_BIT;
-        if (!bIsDown)
-            Msg.lParam |= LP_TRANSITION_BIT;
-    }
-
-    /* FIXME: set KF_DLGMODE and KF_MENUMODE when needed */ 	 
-    if ( pFocusQueue && pFocusQueue->QF_flags & QF_DIALOGACTIVE ) 	 
-       Msg.lParam |= LP_DLGMODE; 	 
-    if ( pFocusQueue && pFocusQueue->MenuOwner )//pFocusQueue->MenuState ) // MenuState needs a start flag...
-       Msg.lParam |= LP_MENUMODE;
-
-    /* Init wParam and cursor position */
-    Msg.wParam = wVk; // Note: it's simplified by msg queue
-    Msg.pt = gpsi->ptCursor;
+        }
+    }
 
     /* If time is given, use it */
     if (pKbdInput->time)
-        Msg.time = pKbdInput->time;
+        dwTime = pKbdInput->time;
     else
     {
         KeQueryTickCount(&LargeTickCount);
-        Msg.time = MsqCalculateMessageTime(&LargeTickCount);
-    }
-
-    if (!(pKbdInput->dwFlags & KEYEVENTF_UNICODE))
-    {
-        if (bIsDown)
-        {
-            /* Update keyboard LEDs */
-            if (!gpKeyboardIndicatorTrans)
-                IntKeyboardGetIndicatorTrans(ghKeyboardDevice, &gpKeyboardIndicatorTrans);
-            if (gpKeyboardIndicatorTrans)
-                IntKeyboardUpdateLeds(ghKeyboardDevice,
-                                      wScanCode,
-                                      IS_KEY_LOCKED(gafAsyncKeyState, wVk),
-                                      gpKeyboardIndicatorTrans);
-        }
-
-        /* Call hook */
-        if (co_CallLowLevelKeyboardHook(&Msg, bInjected, pKbdInput->dwExtraInfo))
-        {
-            ERR("Kbd msg %d wParam %d lParam 0x%08x dropped by WH_KEYBOARD_LL hook\n",
-                Msg.message, Msg.wParam, Msg.lParam);
-            bPostMsg = FALSE;
-        }
-
-        /* Update async state of not simplified vk here.
-           See user32_apitest:GetKeyState */
-        UpdateAsyncKeyState(wVk, bIsDown);
-
-        /* Support VK_*MENU keys */
-        if (!bIsDown && wSimpleVk == VK_MENU && !IS_KEY_DOWN(gafAsyncKeyState, VK_CONTROL))
-            co_IntKeyboardSendAltKeyMsg();
-    }
-
-    /* Alt-Tab/Esc Check. Use FocusQueue or RIT Queue */
-    if (!(pKbdInput->dwFlags & KEYEVENTF_KEYUP) &&
-        HIWORD(Msg.lParam) & KF_ALTDOWN  &&
-        ( Msg.wParam == VK_ESCAPE || Msg.wParam == VK_TAB ) )
-    {
-       TRACE("Alt-Tab/Esc Pressed wParam %x\n",Msg.wParam);
-    }
-
-    /* If we have a focus queue, post a keyboard message */
-    if (pFocusQueue && bPostMsg)
-    {
-        /* Post a keyboard message */
-        TRACE("Posting keyboard msg %u wParam 0x%x lParam 0x%x\n", Msg.message, Msg.wParam, Msg.lParam);
-        //co_MsqPostKeyboardMessage(Msg.message, Msg.wParam, Msg.lParam, bInjected);
-        MsqPostMessage(pFocusQueue, &Msg, TRUE, QS_KEY);
-    }
-
-    return TRUE;
+        dwTime = MsqCalculateMessageTime(&LargeTickCount);
+    }
+
+    if (wVk == VK_RMENU && (pKbdTbl->fLocaleFlags & KLLF_ALTGR))
+    {
+        /* For AltGr keyboards RALT generates CTRL events */
+        ProcessKeyEvent(VK_LCONTROL, 0, pKbdInput->dwFlags & KEYEVENTF_KEYUP, bInjected, dwTime, 0);
+    }
+
+    /* Finally process this key */
+    return ProcessKeyEvent(wVk, wScanCode, pKbdInput->dwFlags, bInjected, dwTime, pKbdInput->dwExtraInfo);
 }
 
 /* 
@@ -1102,7 +1120,7 @@
     UINT ret = 0;
 
     TRACE("Enter NtUserMapVirtualKeyEx\n");
-    UserEnterExclusive();
+    UserEnterShared();
 
     if (!dwhkl)
     {
@@ -1188,7 +1206,7 @@
     }
     RtlZeroMemory(pwszBuff, sizeof(WCHAR) * cchBuff);
 
-    UserEnterShared();
+    UserEnterExclusive(); // Note: we modify wchDead static variable
 
     if (dwhkl)
         pKbl = UserHklToKbl(dwhkl);
@@ -1227,7 +1245,7 @@
     PTHREADINFO pti;
     DWORD i, cchKeyName, dwRet = 0;
     WORD wScanCode = (lParam >> 16) & 0xFF;
-    BOOL bExtKey = (lParam & LP_EXT_BIT) ? TRUE : FALSE;
+    BOOL bExtKey = (HIWORD(lParam) & KF_EXTENDED) ? TRUE : FALSE;
     PKBDTABLES pKbdTbl;
     VSC_LPWSTR *pKeyNames = NULL;
     CONST WCHAR *pKeyName = NULL;
@@ -1235,6 +1253,8 @@
 
     TRACE("Enter NtUserGetKeyNameText\n");
 
+    UserEnterShared();
+
     /* Get current keyboard layout */
     pti = PsGetCurrentThreadWin32Thread();
     pKbdTbl = pti ? pti->KeyboardLayout->KBTables : 0;
@@ -1242,10 +1262,8 @@
     if (!pKbdTbl || cchSize < 1)
     {
         ERR("Invalid parameter\n");
-        return 0;
-    }
-
-    UserEnterShared();
+        goto cleanup;
+    }
 
     /* "Do not care" flag */
     if(lParam & LP_DO_NOT_CARE_BIT)
@@ -1309,6 +1327,7 @@
         EngSetLastError(ERROR_INVALID_PARAMETER);
     }
 
+cleanup:
     UserLeave();
     TRACE("Leave NtUserGetKeyNameText, ret=%i\n", dwRet);
     return dwRet;

Modified: trunk/reactos/subsystems/win32/win32k/ntuser/msgqueue.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/ntuser/msgqueue.c?rev=54107&r1=54106&r2=54107&view=diff
==============================================================================
--- trunk/reactos/subsystems/win32/win32k/ntuser/msgqueue.c [iso-8859-1] (original)
+++ trunk/reactos/subsystems/win32/win32k/ntuser/msgqueue.c [iso-8859-1] Thu Oct 13 13:23:57 2011
@@ -663,10 +663,10 @@
    id = wParam; // Check for hot keys unrelated to the hot keys set by RegisterHotKey.
 
    Mesg.hwnd    = hWnd;
-   Mesg.message = id != IDHOT_REACTOS ? WM_HOTKEY : WM_SYSCOMMAND;
-   Mesg.wParam  = id != IDHOT_REACTOS ? wParam    : SC_HOTKEY;
-   Mesg.lParam  = id != IDHOT_REACTOS ? lParam    : (LPARAM)hWnd;
-   Type         = id != IDHOT_REACTOS ? QS_HOTKEY : QS_POSTMESSAGE;
+   Mesg.message = id != IDHK_REACTOS ? WM_HOTKEY : WM_SYSCOMMAND;
+   Mesg.wParam  = id != IDHK_REACTOS ? wParam    : SC_HOTKEY;
+   Mesg.lParam  = id != IDHK_REACTOS ? lParam    : (LPARAM)hWnd;
+   Type         = id != IDHK_REACTOS ? QS_HOTKEY : QS_POSTMESSAGE;
    KeQueryTickCount(&LargeTickCount);
    Mesg.time    = MsqCalculateMessageTime(&LargeTickCount);
    Mesg.pt      = gpsi->ptCursor;




More information about the Ros-diffs mailing list