* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
-/* $Id$
- *
+/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* PURPOSE: HotKey support
/* INCLUDES ******************************************************************/
-#include <w32k.h>
+#include <win32k.h>
#define NDEBUG
#include <debug.h>
/* FUNCTIONS *****************************************************************/
-NTSTATUS FASTCALL
-InitHotkeyImpl()
+INIT_FUNCTION
+NTSTATUS
+NTAPI
+InitHotkeyImpl(VOID)
{
InitializeListHead(&gHotkeyList);
return STATUS_SUCCESS;
}
-
#if 0 //not used
NTSTATUS FASTCALL
-CleanupHotKeys()
+CleanupHotKeys(VOID)
{
return STATUS_SUCCESS;
}
#endif
-
BOOL FASTCALL
GetHotKey (UINT fsModifiers,
UINT vk,
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);
}
-
VOID FASTCALL
UnregisterThreadHotKeys(struct _ETHREAD *Thread)
{
PHOT_KEY_ITEM HotKeyItem, tmp;
- LIST_FOR_EACH_SAFE(HotKeyItem, tmp, &gHotkeyList, HOT_KEY_ITEM, ListEntry)
+ LIST_FOR_EACH_SAFE(HotKeyItem, tmp, &gHotkeyList, HOT_KEY_ITEM, ListEntry)
{
if (HotKeyItem->Thread == Thread)
{
}
-
-static
+static
BOOL FASTCALL
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 *****************************************************************/
-BOOL STDCALL
+BOOL APIENTRY
NtUserRegisterHotKey(HWND hWnd,
int id,
UINT fsModifiers,
UINT vk)
{
PHOT_KEY_ITEM HotKeyItem;
- PWINDOW_OBJECT Window;
+ PWND Window;
PETHREAD HotKeyThread;
DECLARE_RETURN(BOOL);
{
RETURN( FALSE);
}
- HotKeyThread = Window->OwnerThread;
+ HotKeyThread = Window->head.pti->pEThread;
}
/* Check for existing hotkey */
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);
}
-BOOL STDCALL
+BOOL APIENTRY
NtUserUnregisterHotKey(HWND hWnd, int id)
{
PHOT_KEY_ITEM HotKeyItem;
- PWINDOW_OBJECT Window;
+ PWND Window;
DECLARE_RETURN(BOOL);
DPRINT("Enter NtUserUnregisterHotKey\n");
if (HotKeyItem->hWnd == hWnd && HotKeyItem->id == id)
{
RemoveEntryList (&HotKeyItem->ListEntry);
- ExFreePool (HotKeyItem);
+ ExFreePoolWithTag(HotKeyItem, USERTAG_HOTKEY);
RETURN( TRUE);
}