[User32|Win32k]
[reactos.git] / reactos / subsystems / win32 / win32k / ntuser / hotkey.c
index c2585f3..7f20d32 100644 (file)
@@ -40,7 +40,7 @@ windows/threads on destops not belonging to WinSta0 to set hotkeys (recieve noti
 
 /* INCLUDES ******************************************************************/
 
-#include <w32k.h>
+#include <win32k.h>
 
 #define NDEBUG
 #include <debug.h>
@@ -51,7 +51,9 @@ LIST_ENTRY gHotkeyList;
 
 /* FUNCTIONS *****************************************************************/
 
-NTSTATUS FASTCALL
+INIT_FUNCTION
+NTSTATUS
+NTAPI
 InitHotkeyImpl(VOID)
 {
    InitializeListHead(&gHotkeyList);
@@ -59,7 +61,6 @@ InitHotkeyImpl(VOID)
    return STATUS_SUCCESS;
 }
 
-
 #if 0 //not used
 NTSTATUS FASTCALL
 CleanupHotKeys(VOID)
@@ -69,7 +70,6 @@ CleanupHotKeys(VOID)
 }
 #endif
 
-
 BOOL FASTCALL
 GetHotKey (UINT fsModifiers,
            UINT vk,
@@ -100,15 +100,14 @@ GetHotKey (UINT fsModifiers,
    return FALSE;
 }
 
-
 VOID FASTCALL
-UnregisterWindowHotKeys(PWINDOW_OBJECT Window)
+UnregisterWindowHotKeys(PWND Window)
 {
    PHOT_KEY_ITEM HotKeyItem, tmp;
 
    LIST_FOR_EACH_SAFE(HotKeyItem, tmp, &gHotkeyList, HOT_KEY_ITEM, ListEntry)
    {
-      if (HotKeyItem->hWnd == Window->hSelf)
+      if (HotKeyItem->hWnd == Window->head.h)
       {
          RemoveEntryList (&HotKeyItem->ListEntry);
          ExFreePool (HotKeyItem);
@@ -117,7 +116,6 @@ UnregisterWindowHotKeys(PWINDOW_OBJECT Window)
 
 }
 
-
 VOID FASTCALL
 UnregisterThreadHotKeys(struct _ETHREAD *Thread)
 {
@@ -134,7 +132,6 @@ UnregisterThreadHotKeys(struct _ETHREAD *Thread)
 
 }
 
-
 static
 BOOL FASTCALL
 IsHotKey (UINT fsModifiers, UINT vk)
@@ -152,7 +149,111 @@ IsHotKey (UINT fsModifiers, UINT vk)
    return FALSE;
 }
 
+//
+// Get/SetHotKey message support.
+//
+UINT FASTCALL
+DefWndGetHotKey( HWND hwnd )
+{
+   PHOT_KEY_ITEM HotKeyItem;
+
+   DPRINT1("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);
+      }
+   }
+   return 0;
+}
+
+INT FASTCALL 
+DefWndSetHotKey( PWND pWnd, WPARAM wParam )
+{
+   UINT fsModifiers, vk;
+   PHOT_KEY_ITEM HotKeyItem;
+   HWND hWnd;
+   BOOL HaveSameWnd = FALSE;
+   INT Ret = 1;
+
+   DPRINT1("DefWndSetHotKey wParam 0x%x\n", wParam);
+
+   // A hot key cannot be associated with a child window.
+   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;
+
+   vk = LOWORD(wParam);
+   fsModifiers = HIWORD(wParam);   
+   hWnd = UserHMGetHandle(pWnd);
 
+   if (wParam)
+   {
+      LIST_FOR_EACH(HotKeyItem, &gHotkeyList, HOT_KEY_ITEM, ListEntry)
+      {
+         if ( HotKeyItem->fsModifiers == fsModifiers &&
+              HotKeyItem->vk == vk &&
+              HotKeyItem->id == IDHOT_REACTOS )
+         {
+            if (HotKeyItem->hWnd != hWnd)
+               Ret = 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;
+         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;
+}
 
 /* SYSCALLS *****************************************************************/
 
@@ -164,7 +265,7 @@ NtUserRegisterHotKey(HWND hWnd,
                      UINT vk)
 {
    PHOT_KEY_ITEM HotKeyItem;
-   PWINDOW_OBJECT Window;
+   PWND Window;
    PETHREAD HotKeyThread;
    DECLARE_RETURN(BOOL);
 
@@ -181,7 +282,7 @@ NtUserRegisterHotKey(HWND hWnd,
       {
          RETURN( FALSE);
       }
-      HotKeyThread = Window->pti->pEThread;
+      HotKeyThread = Window->head.pti->pEThread;
    }
 
    /* Check for existing hotkey */
@@ -190,7 +291,7 @@ NtUserRegisterHotKey(HWND hWnd,
       RETURN( FALSE);
    }
 
-   HotKeyItem = ExAllocatePoolWithTag (PagedPool, sizeof(HOT_KEY_ITEM), TAG_HOTKEY);
+   HotKeyItem = ExAllocatePoolWithTag (PagedPool, sizeof(HOT_KEY_ITEM), USERTAG_HOTKEY);
    if (HotKeyItem == NULL)
    {
       RETURN( FALSE);
@@ -217,7 +318,7 @@ BOOL APIENTRY
 NtUserUnregisterHotKey(HWND hWnd, int id)
 {
    PHOT_KEY_ITEM HotKeyItem;
-   PWINDOW_OBJECT Window;
+   PWND Window;
    DECLARE_RETURN(BOOL);
 
    DPRINT("Enter NtUserUnregisterHotKey\n");
@@ -233,7 +334,7 @@ NtUserUnregisterHotKey(HWND hWnd, int id)
       if (HotKeyItem->hWnd == hWnd && HotKeyItem->id == id)
       {
          RemoveEntryList (&HotKeyItem->ListEntry);
-         ExFreePool (HotKeyItem);
+         ExFreePoolWithTag(HotKeyItem, USERTAG_HOTKEY);
 
          RETURN( TRUE);
       }