Commit 4c83138f authored by Vincent Povirk's avatar Vincent Povirk Committed by Alexandre Julliard

server: Implement RegisterHotKey/UnregisterHotKey.

parent ba923199
...@@ -983,9 +983,25 @@ UINT WINAPI GetKeyboardLayoutList(INT nBuff, HKL *layouts) ...@@ -983,9 +983,25 @@ UINT WINAPI GetKeyboardLayoutList(INT nBuff, HKL *layouts)
*/ */
BOOL WINAPI RegisterHotKey(HWND hwnd,INT id,UINT modifiers,UINT vk) BOOL WINAPI RegisterHotKey(HWND hwnd,INT id,UINT modifiers,UINT vk)
{ {
static int once; BOOL ret;
if (!once++) FIXME_(keyboard)("(%p,%d,0x%08x,%X): stub\n",hwnd,id,modifiers,vk);
return TRUE; TRACE_(keyboard)("(%p,%d,0x%08x,%X)\n",hwnd,id,modifiers,vk);
/* FIXME: Register hotkey with user driver. */
SERVER_START_REQ( register_hotkey )
{
req->window = wine_server_user_handle( hwnd );
req->id = id;
req->flags = modifiers;
req->vkey = vk;
ret = !wine_server_call_err( req );
}
SERVER_END_REQ;
/* FIXME: Unregister new or replaced hotkey with user driver if necessary. */
return ret;
} }
/*********************************************************************** /***********************************************************************
...@@ -993,9 +1009,21 @@ BOOL WINAPI RegisterHotKey(HWND hwnd,INT id,UINT modifiers,UINT vk) ...@@ -993,9 +1009,21 @@ BOOL WINAPI RegisterHotKey(HWND hwnd,INT id,UINT modifiers,UINT vk)
*/ */
BOOL WINAPI UnregisterHotKey(HWND hwnd,INT id) BOOL WINAPI UnregisterHotKey(HWND hwnd,INT id)
{ {
static int once; BOOL ret;
if (!once++) FIXME_(keyboard)("(%p,%d): stub\n",hwnd,id);
return TRUE; TRACE_(keyboard)("(%p,%d)\n",hwnd,id);
SERVER_START_REQ( unregister_hotkey )
{
req->window = wine_server_user_handle( hwnd );
req->id = id;
ret = !wine_server_call_err( req );
}
SERVER_END_REQ;
/* FIXME: Unregister hotkey with user driver if necessary. */
return ret;
} }
/*********************************************************************** /***********************************************************************
......
...@@ -13155,8 +13155,8 @@ static void test_hotkey(void) ...@@ -13155,8 +13155,8 @@ static void test_hotkey(void)
SetLastError(0xdeadbeef); SetLastError(0xdeadbeef);
ret = UnregisterHotKey(NULL, 0); ret = UnregisterHotKey(NULL, 0);
todo_wine ok(ret == FALSE, "expected FALSE, got %i\n", ret); ok(ret == FALSE, "expected FALSE, got %i\n", ret);
todo_wine ok(GetLastError() == ERROR_HOTKEY_NOT_REGISTERED, "unexpected error %d\n", GetLastError()); ok(GetLastError() == ERROR_HOTKEY_NOT_REGISTERED, "unexpected error %d\n", GetLastError());
if (ret == TRUE) if (ret == TRUE)
{ {
...@@ -13247,7 +13247,7 @@ static void test_hotkey(void) ...@@ -13247,7 +13247,7 @@ static void test_hotkey(void)
} }
DispatchMessage(&msg); DispatchMessage(&msg);
} }
ok_sequence(WmHotkeyPress, "window hotkey press", FALSE); ok_sequence(WmHotkeyPress, "window hotkey press", TRUE);
key_state = GetAsyncKeyState(hotkey_letter); key_state = GetAsyncKeyState(hotkey_letter);
ok((key_state & 0x8000) == 0x8000, "unexpected key state %x\n", key_state); ok((key_state & 0x8000) == 0x8000, "unexpected key state %x\n", key_state);
...@@ -13255,7 +13255,7 @@ static void test_hotkey(void) ...@@ -13255,7 +13255,7 @@ static void test_hotkey(void)
keybd_event(hotkey_letter, 0, KEYEVENTF_KEYUP, 0); keybd_event(hotkey_letter, 0, KEYEVENTF_KEYUP, 0);
while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
DispatchMessage(&msg); DispatchMessage(&msg);
ok_sequence(WmHotkeyRelease, "window hotkey release", FALSE); ok_sequence(WmHotkeyRelease, "window hotkey release", TRUE);
keybd_event(VK_LWIN, 0, KEYEVENTF_KEYUP, 0); keybd_event(VK_LWIN, 0, KEYEVENTF_KEYUP, 0);
while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
...@@ -13278,7 +13278,7 @@ static void test_hotkey(void) ...@@ -13278,7 +13278,7 @@ static void test_hotkey(void)
} }
DispatchMessage(&msg); DispatchMessage(&msg);
} }
ok_sequence(WmHotkeyCombined, "window hotkey combined", FALSE); ok_sequence(WmHotkeyCombined, "window hotkey combined", TRUE);
/* Register same hwnd/id with different key combination */ /* Register same hwnd/id with different key combination */
ret = RegisterHotKey(test_window, 5, 0, hotkey_letter); ret = RegisterHotKey(test_window, 5, 0, hotkey_letter);
...@@ -13307,7 +13307,7 @@ static void test_hotkey(void) ...@@ -13307,7 +13307,7 @@ static void test_hotkey(void)
} }
DispatchMessage(&msg); DispatchMessage(&msg);
} }
ok_sequence(WmHotkeyNew, "window hotkey new", FALSE); ok_sequence(WmHotkeyNew, "window hotkey new", TRUE);
/* Unregister hotkey properly */ /* Unregister hotkey properly */
ret = UnregisterHotKey(test_window, 5); ret = UnregisterHotKey(test_window, 5);
...@@ -13351,7 +13351,7 @@ static void test_hotkey(void) ...@@ -13351,7 +13351,7 @@ static void test_hotkey(void)
ok(msg.hwnd != NULL, "unexpected thread message %x\n", msg.message); ok(msg.hwnd != NULL, "unexpected thread message %x\n", msg.message);
DispatchMessage(&msg); DispatchMessage(&msg);
} }
ok_sequence(WmHotkeyPress, "thread hotkey press", FALSE); ok_sequence(WmHotkeyPress, "thread hotkey press", TRUE);
keybd_event(hotkey_letter, 0, KEYEVENTF_KEYUP, 0); keybd_event(hotkey_letter, 0, KEYEVENTF_KEYUP, 0);
while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
...@@ -13359,7 +13359,7 @@ static void test_hotkey(void) ...@@ -13359,7 +13359,7 @@ static void test_hotkey(void)
ok(msg.hwnd != NULL, "unexpected thread message %x\n", msg.message); ok(msg.hwnd != NULL, "unexpected thread message %x\n", msg.message);
DispatchMessage(&msg); DispatchMessage(&msg);
} }
ok_sequence(WmHotkeyRelease, "thread hotkey release", FALSE); ok_sequence(WmHotkeyRelease, "thread hotkey release", TRUE);
keybd_event(VK_LWIN, 0, KEYEVENTF_KEYUP, 0); keybd_event(VK_LWIN, 0, KEYEVENTF_KEYUP, 0);
while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
......
...@@ -3724,6 +3724,42 @@ struct set_user_object_info_reply ...@@ -3724,6 +3724,42 @@ struct set_user_object_info_reply
struct register_hotkey_request
{
struct request_header __header;
user_handle_t window;
int id;
unsigned int flags;
unsigned int vkey;
char __pad_28[4];
};
struct register_hotkey_reply
{
struct reply_header __header;
int replaced;
unsigned int flags;
unsigned int vkey;
char __pad_20[4];
};
struct unregister_hotkey_request
{
struct request_header __header;
user_handle_t window;
int id;
char __pad_20[4];
};
struct unregister_hotkey_reply
{
struct reply_header __header;
unsigned int flags;
unsigned int vkey;
};
struct attach_thread_input_request struct attach_thread_input_request
{ {
struct request_header __header; struct request_header __header;
...@@ -5023,6 +5059,8 @@ enum request ...@@ -5023,6 +5059,8 @@ enum request
REQ_set_thread_desktop, REQ_set_thread_desktop,
REQ_enum_desktop, REQ_enum_desktop,
REQ_set_user_object_info, REQ_set_user_object_info,
REQ_register_hotkey,
REQ_unregister_hotkey,
REQ_attach_thread_input, REQ_attach_thread_input,
REQ_get_thread_input, REQ_get_thread_input,
REQ_get_last_input_time, REQ_get_last_input_time,
...@@ -5275,6 +5313,8 @@ union generic_request ...@@ -5275,6 +5313,8 @@ union generic_request
struct set_thread_desktop_request set_thread_desktop_request; struct set_thread_desktop_request set_thread_desktop_request;
struct enum_desktop_request enum_desktop_request; struct enum_desktop_request enum_desktop_request;
struct set_user_object_info_request set_user_object_info_request; struct set_user_object_info_request set_user_object_info_request;
struct register_hotkey_request register_hotkey_request;
struct unregister_hotkey_request unregister_hotkey_request;
struct attach_thread_input_request attach_thread_input_request; struct attach_thread_input_request attach_thread_input_request;
struct get_thread_input_request get_thread_input_request; struct get_thread_input_request get_thread_input_request;
struct get_last_input_time_request get_last_input_time_request; struct get_last_input_time_request get_last_input_time_request;
...@@ -5525,6 +5565,8 @@ union generic_reply ...@@ -5525,6 +5565,8 @@ union generic_reply
struct set_thread_desktop_reply set_thread_desktop_reply; struct set_thread_desktop_reply set_thread_desktop_reply;
struct enum_desktop_reply enum_desktop_reply; struct enum_desktop_reply enum_desktop_reply;
struct set_user_object_info_reply set_user_object_info_reply; struct set_user_object_info_reply set_user_object_info_reply;
struct register_hotkey_reply register_hotkey_reply;
struct unregister_hotkey_reply unregister_hotkey_reply;
struct attach_thread_input_reply attach_thread_input_reply; struct attach_thread_input_reply attach_thread_input_reply;
struct get_thread_input_reply get_thread_input_reply; struct get_thread_input_reply get_thread_input_reply;
struct get_last_input_time_reply get_last_input_time_reply; struct get_last_input_time_reply get_last_input_time_reply;
...@@ -5592,6 +5634,6 @@ union generic_reply ...@@ -5592,6 +5634,6 @@ union generic_reply
struct set_suspend_context_reply set_suspend_context_reply; struct set_suspend_context_reply set_suspend_context_reply;
}; };
#define SERVER_PROTOCOL_VERSION 423 #define SERVER_PROTOCOL_VERSION 424
#endif /* __WINE_WINE_SERVER_PROTOCOL_H */ #endif /* __WINE_WINE_SERVER_PROTOCOL_H */
...@@ -2632,6 +2632,29 @@ enum coords_relative ...@@ -2632,6 +2632,29 @@ enum coords_relative
#define SET_USER_OBJECT_FLAGS 1 #define SET_USER_OBJECT_FLAGS 1
/* Register a hotkey */
@REQ(register_hotkey)
user_handle_t window; /* handle to the window */
int id; /* hotkey identifier */
unsigned int flags; /* modifier keys */
unsigned int vkey; /* virtual key code */
@REPLY
int replaced; /* did we replace an existing hotkey? */
unsigned int flags; /* flags of replaced hotkey */
unsigned int vkey; /* virtual key code of replaced hotkey */
@END
/* Unregister a hotkey */
@REQ(unregister_hotkey)
user_handle_t window; /* handle to the window */
int id; /* hotkey identifier */
@REPLY
unsigned int flags; /* flags of removed hotkey */
unsigned int vkey; /* virtual key code of removed hotkey */
@END
/* Attach (or detach) thread inputs */ /* Attach (or detach) thread inputs */
@REQ(attach_thread_input) @REQ(attach_thread_input)
thread_id_t tid_from; /* thread to be attached */ thread_id_t tid_from; /* thread to be attached */
......
...@@ -136,6 +136,16 @@ struct msg_queue ...@@ -136,6 +136,16 @@ struct msg_queue
timeout_t last_get_msg; /* time of last get message call */ timeout_t last_get_msg; /* time of last get message call */
}; };
struct hotkey
{
struct list entry; /* entry in desktop hotkey list */
struct msg_queue *queue; /* queue owning this hotkey */
user_handle_t win; /* window handle */
int id; /* hotkey id */
unsigned int vkey; /* virtual key code */
unsigned int flags; /* key modifiers */
};
static void msg_queue_dump( struct object *obj, int verbose ); static void msg_queue_dump( struct object *obj, int verbose );
static int msg_queue_add_queue( struct object *obj, struct wait_queue_entry *entry ); static int msg_queue_add_queue( struct object *obj, struct wait_queue_entry *entry );
static void msg_queue_remove_queue( struct object *obj, struct wait_queue_entry *entry ); static void msg_queue_remove_queue( struct object *obj, struct wait_queue_entry *entry );
...@@ -905,11 +915,21 @@ static void msg_queue_destroy( struct object *obj ) ...@@ -905,11 +915,21 @@ static void msg_queue_destroy( struct object *obj )
{ {
struct msg_queue *queue = (struct msg_queue *)obj; struct msg_queue *queue = (struct msg_queue *)obj;
struct list *ptr; struct list *ptr;
struct hotkey *hotkey, *hotkey2;
int i; int i;
cleanup_results( queue ); cleanup_results( queue );
for (i = 0; i < NB_MSG_KINDS; i++) empty_msg_list( &queue->msg_list[i] ); for (i = 0; i < NB_MSG_KINDS; i++) empty_msg_list( &queue->msg_list[i] );
LIST_FOR_EACH_ENTRY_SAFE( hotkey, hotkey2, &queue->input->desktop->hotkeys, struct hotkey, entry )
{
if (hotkey->queue == queue)
{
list_remove( &hotkey->entry );
free( hotkey );
}
}
while ((ptr = list_head( &queue->pending_timers ))) while ((ptr = list_head( &queue->pending_timers )))
{ {
struct timer *timer = LIST_ENTRY( ptr, struct timer, entry ); struct timer *timer = LIST_ENTRY( ptr, struct timer, entry );
...@@ -1921,6 +1941,21 @@ void post_win_event( struct thread *thread, unsigned int event, ...@@ -1921,6 +1941,21 @@ void post_win_event( struct thread *thread, unsigned int event,
} }
} }
/* free all hotkeys on a desktop, optionally filtering by window */
void free_hotkeys( struct desktop *desktop, user_handle_t window )
{
struct hotkey *hotkey, *hotkey2;
LIST_FOR_EACH_ENTRY_SAFE( hotkey, hotkey2, &desktop->hotkeys, struct hotkey, entry )
{
if (!window || hotkey->win == window)
{
list_remove( &hotkey->entry );
free( hotkey );
}
}
}
/* check if the thread owning the window is hung */ /* check if the thread owning the window is hung */
DECL_HANDLER(is_window_hung) DECL_HANDLER(is_window_hung)
...@@ -2364,6 +2399,123 @@ DECL_HANDLER(kill_win_timer) ...@@ -2364,6 +2399,123 @@ DECL_HANDLER(kill_win_timer)
release_object( thread ); release_object( thread );
} }
DECL_HANDLER(register_hotkey)
{
struct desktop *desktop;
user_handle_t win_handle = req->window;
struct hotkey *hotkey;
struct hotkey *new_hotkey = NULL;
struct thread *thread;
const int modifier_flags = MOD_ALT|MOD_CONTROL|MOD_SHIFT|MOD_WIN;
if (!(desktop = get_thread_desktop( current, 0 ))) return;
if (win_handle)
{
if (!get_user_object_handle( &win_handle, USER_WINDOW ))
{
release_object( desktop );
set_win32_error( ERROR_INVALID_WINDOW_HANDLE );
return;
}
thread = get_window_thread( win_handle );
if (thread) release_object( thread );
if (thread != current)
{
release_object( desktop );
set_win32_error( ERROR_WINDOW_OF_OTHER_THREAD );
return;
}
}
LIST_FOR_EACH_ENTRY( hotkey, &desktop->hotkeys, struct hotkey, entry )
{
if (req->vkey == hotkey->vkey &&
(req->flags & modifier_flags) == (hotkey->flags & modifier_flags))
{
release_object( desktop );
set_win32_error( ERROR_HOTKEY_ALREADY_REGISTERED );
return;
}
if (current->queue == hotkey->queue && win_handle == hotkey->win && req->id == hotkey->id)
new_hotkey = hotkey;
}
if (new_hotkey)
{
reply->replaced = 1;
reply->flags = new_hotkey->flags;
reply->vkey = new_hotkey->vkey;
}
else
{
new_hotkey = mem_alloc( sizeof(*new_hotkey) );
if (new_hotkey)
{
list_add_tail( &desktop->hotkeys, &new_hotkey->entry );
new_hotkey->queue = current->queue;
new_hotkey->win = win_handle;
new_hotkey->id = req->id;
}
}
if (new_hotkey)
{
new_hotkey->flags = req->flags;
new_hotkey->vkey = req->vkey;
}
release_object( desktop );
}
DECL_HANDLER(unregister_hotkey)
{
struct desktop *desktop;
user_handle_t win_handle = req->window;
struct hotkey *hotkey;
struct thread *thread;
if (!(desktop = get_thread_desktop( current, 0 ))) return;
if (win_handle)
{
if (!get_user_object_handle( &win_handle, USER_WINDOW ))
{
release_object( desktop );
set_win32_error( ERROR_INVALID_WINDOW_HANDLE );
return;
}
thread = get_window_thread( win_handle );
if (thread) release_object( thread );
if (thread != current)
{
release_object( desktop );
set_win32_error( ERROR_WINDOW_OF_OTHER_THREAD );
return;
}
}
LIST_FOR_EACH_ENTRY( hotkey, &desktop->hotkeys, struct hotkey, entry )
{
if (current->queue == hotkey->queue && win_handle == hotkey->win && req->id == hotkey->id)
goto found;
}
release_object( desktop );
set_win32_error( ERROR_HOTKEY_NOT_REGISTERED );
return;
found:
reply->flags = hotkey->flags;
reply->vkey = hotkey->vkey;
list_remove( &hotkey->entry );
free( hotkey );
release_object( desktop );
}
/* attach (or detach) thread inputs */ /* attach (or detach) thread inputs */
DECL_HANDLER(attach_thread_input) DECL_HANDLER(attach_thread_input)
......
...@@ -291,6 +291,8 @@ DECL_HANDLER(get_thread_desktop); ...@@ -291,6 +291,8 @@ DECL_HANDLER(get_thread_desktop);
DECL_HANDLER(set_thread_desktop); DECL_HANDLER(set_thread_desktop);
DECL_HANDLER(enum_desktop); DECL_HANDLER(enum_desktop);
DECL_HANDLER(set_user_object_info); DECL_HANDLER(set_user_object_info);
DECL_HANDLER(register_hotkey);
DECL_HANDLER(unregister_hotkey);
DECL_HANDLER(attach_thread_input); DECL_HANDLER(attach_thread_input);
DECL_HANDLER(get_thread_input); DECL_HANDLER(get_thread_input);
DECL_HANDLER(get_last_input_time); DECL_HANDLER(get_last_input_time);
...@@ -542,6 +544,8 @@ static const req_handler req_handlers[REQ_NB_REQUESTS] = ...@@ -542,6 +544,8 @@ static const req_handler req_handlers[REQ_NB_REQUESTS] =
(req_handler)req_set_thread_desktop, (req_handler)req_set_thread_desktop,
(req_handler)req_enum_desktop, (req_handler)req_enum_desktop,
(req_handler)req_set_user_object_info, (req_handler)req_set_user_object_info,
(req_handler)req_register_hotkey,
(req_handler)req_unregister_hotkey,
(req_handler)req_attach_thread_input, (req_handler)req_attach_thread_input,
(req_handler)req_get_thread_input, (req_handler)req_get_thread_input,
(req_handler)req_get_last_input_time, (req_handler)req_get_last_input_time,
...@@ -1705,6 +1709,21 @@ C_ASSERT( sizeof(struct set_user_object_info_request) == 24 ); ...@@ -1705,6 +1709,21 @@ C_ASSERT( sizeof(struct set_user_object_info_request) == 24 );
C_ASSERT( FIELD_OFFSET(struct set_user_object_info_reply, is_desktop) == 8 ); C_ASSERT( FIELD_OFFSET(struct set_user_object_info_reply, is_desktop) == 8 );
C_ASSERT( FIELD_OFFSET(struct set_user_object_info_reply, old_obj_flags) == 12 ); C_ASSERT( FIELD_OFFSET(struct set_user_object_info_reply, old_obj_flags) == 12 );
C_ASSERT( sizeof(struct set_user_object_info_reply) == 16 ); C_ASSERT( sizeof(struct set_user_object_info_reply) == 16 );
C_ASSERT( FIELD_OFFSET(struct register_hotkey_request, window) == 12 );
C_ASSERT( FIELD_OFFSET(struct register_hotkey_request, id) == 16 );
C_ASSERT( FIELD_OFFSET(struct register_hotkey_request, flags) == 20 );
C_ASSERT( FIELD_OFFSET(struct register_hotkey_request, vkey) == 24 );
C_ASSERT( sizeof(struct register_hotkey_request) == 32 );
C_ASSERT( FIELD_OFFSET(struct register_hotkey_reply, replaced) == 8 );
C_ASSERT( FIELD_OFFSET(struct register_hotkey_reply, flags) == 12 );
C_ASSERT( FIELD_OFFSET(struct register_hotkey_reply, vkey) == 16 );
C_ASSERT( sizeof(struct register_hotkey_reply) == 24 );
C_ASSERT( FIELD_OFFSET(struct unregister_hotkey_request, window) == 12 );
C_ASSERT( FIELD_OFFSET(struct unregister_hotkey_request, id) == 16 );
C_ASSERT( sizeof(struct unregister_hotkey_request) == 24 );
C_ASSERT( FIELD_OFFSET(struct unregister_hotkey_reply, flags) == 8 );
C_ASSERT( FIELD_OFFSET(struct unregister_hotkey_reply, vkey) == 12 );
C_ASSERT( sizeof(struct unregister_hotkey_reply) == 16 );
C_ASSERT( FIELD_OFFSET(struct attach_thread_input_request, tid_from) == 12 ); C_ASSERT( FIELD_OFFSET(struct attach_thread_input_request, tid_from) == 12 );
C_ASSERT( FIELD_OFFSET(struct attach_thread_input_request, tid_to) == 16 ); C_ASSERT( FIELD_OFFSET(struct attach_thread_input_request, tid_to) == 16 );
C_ASSERT( FIELD_OFFSET(struct attach_thread_input_request, attach) == 20 ); C_ASSERT( FIELD_OFFSET(struct attach_thread_input_request, attach) == 20 );
......
...@@ -3078,6 +3078,33 @@ static void dump_set_user_object_info_reply( const struct set_user_object_info_r ...@@ -3078,6 +3078,33 @@ static void dump_set_user_object_info_reply( const struct set_user_object_info_r
dump_varargs_unicode_str( ", name=", cur_size ); dump_varargs_unicode_str( ", name=", cur_size );
} }
static void dump_register_hotkey_request( const struct register_hotkey_request *req )
{
fprintf( stderr, " window=%08x", req->window );
fprintf( stderr, ", id=%d", req->id );
fprintf( stderr, ", flags=%08x", req->flags );
fprintf( stderr, ", vkey=%08x", req->vkey );
}
static void dump_register_hotkey_reply( const struct register_hotkey_reply *req )
{
fprintf( stderr, " replaced=%d", req->replaced );
fprintf( stderr, ", flags=%08x", req->flags );
fprintf( stderr, ", vkey=%08x", req->vkey );
}
static void dump_unregister_hotkey_request( const struct unregister_hotkey_request *req )
{
fprintf( stderr, " window=%08x", req->window );
fprintf( stderr, ", id=%d", req->id );
}
static void dump_unregister_hotkey_reply( const struct unregister_hotkey_reply *req )
{
fprintf( stderr, " flags=%08x", req->flags );
fprintf( stderr, ", vkey=%08x", req->vkey );
}
static void dump_attach_thread_input_request( const struct attach_thread_input_request *req ) static void dump_attach_thread_input_request( const struct attach_thread_input_request *req )
{ {
fprintf( stderr, " tid_from=%04x", req->tid_from ); fprintf( stderr, " tid_from=%04x", req->tid_from );
...@@ -4057,6 +4084,8 @@ static const dump_func req_dumpers[REQ_NB_REQUESTS] = { ...@@ -4057,6 +4084,8 @@ static const dump_func req_dumpers[REQ_NB_REQUESTS] = {
(dump_func)dump_set_thread_desktop_request, (dump_func)dump_set_thread_desktop_request,
(dump_func)dump_enum_desktop_request, (dump_func)dump_enum_desktop_request,
(dump_func)dump_set_user_object_info_request, (dump_func)dump_set_user_object_info_request,
(dump_func)dump_register_hotkey_request,
(dump_func)dump_unregister_hotkey_request,
(dump_func)dump_attach_thread_input_request, (dump_func)dump_attach_thread_input_request,
(dump_func)dump_get_thread_input_request, (dump_func)dump_get_thread_input_request,
(dump_func)dump_get_last_input_time_request, (dump_func)dump_get_last_input_time_request,
...@@ -4305,6 +4334,8 @@ static const dump_func reply_dumpers[REQ_NB_REQUESTS] = { ...@@ -4305,6 +4334,8 @@ static const dump_func reply_dumpers[REQ_NB_REQUESTS] = {
NULL, NULL,
(dump_func)dump_enum_desktop_reply, (dump_func)dump_enum_desktop_reply,
(dump_func)dump_set_user_object_info_reply, (dump_func)dump_set_user_object_info_reply,
(dump_func)dump_register_hotkey_reply,
(dump_func)dump_unregister_hotkey_reply,
NULL, NULL,
(dump_func)dump_get_thread_input_reply, (dump_func)dump_get_thread_input_reply,
(dump_func)dump_get_last_input_time_reply, (dump_func)dump_get_last_input_time_reply,
...@@ -4553,6 +4584,8 @@ static const char * const req_names[REQ_NB_REQUESTS] = { ...@@ -4553,6 +4584,8 @@ static const char * const req_names[REQ_NB_REQUESTS] = {
"set_thread_desktop", "set_thread_desktop",
"enum_desktop", "enum_desktop",
"set_user_object_info", "set_user_object_info",
"register_hotkey",
"unregister_hotkey",
"attach_thread_input", "attach_thread_input",
"get_thread_input", "get_thread_input",
"get_last_input_time", "get_last_input_time",
...@@ -4655,9 +4688,12 @@ static const struct ...@@ -4655,9 +4688,12 @@ static const struct
{ "ERROR_CLASS_DOES_NOT_EXIST", 0xc0010000 | ERROR_CLASS_DOES_NOT_EXIST }, { "ERROR_CLASS_DOES_NOT_EXIST", 0xc0010000 | ERROR_CLASS_DOES_NOT_EXIST },
{ "ERROR_CLASS_HAS_WINDOWS", 0xc0010000 | ERROR_CLASS_HAS_WINDOWS }, { "ERROR_CLASS_HAS_WINDOWS", 0xc0010000 | ERROR_CLASS_HAS_WINDOWS },
{ "ERROR_CLIPBOARD_NOT_OPEN", 0xc0010000 | ERROR_CLIPBOARD_NOT_OPEN }, { "ERROR_CLIPBOARD_NOT_OPEN", 0xc0010000 | ERROR_CLIPBOARD_NOT_OPEN },
{ "ERROR_HOTKEY_ALREADY_REGISTERED", 0xc0010000 | ERROR_HOTKEY_ALREADY_REGISTERED },
{ "ERROR_HOTKEY_NOT_REGISTERED", 0xc0010000 | ERROR_HOTKEY_NOT_REGISTERED },
{ "ERROR_INVALID_CURSOR_HANDLE", 0xc0010000 | ERROR_INVALID_CURSOR_HANDLE }, { "ERROR_INVALID_CURSOR_HANDLE", 0xc0010000 | ERROR_INVALID_CURSOR_HANDLE },
{ "ERROR_INVALID_INDEX", 0xc0010000 | ERROR_INVALID_INDEX }, { "ERROR_INVALID_INDEX", 0xc0010000 | ERROR_INVALID_INDEX },
{ "ERROR_INVALID_WINDOW_HANDLE", 0xc0010000 | ERROR_INVALID_WINDOW_HANDLE }, { "ERROR_INVALID_WINDOW_HANDLE", 0xc0010000 | ERROR_INVALID_WINDOW_HANDLE },
{ "ERROR_WINDOW_OF_OTHER_THREAD", 0xc0010000 | ERROR_WINDOW_OF_OTHER_THREAD },
{ "FILE_DELETED", STATUS_FILE_DELETED }, { "FILE_DELETED", STATUS_FILE_DELETED },
{ "FILE_IS_A_DIRECTORY", STATUS_FILE_IS_A_DIRECTORY }, { "FILE_IS_A_DIRECTORY", STATUS_FILE_IS_A_DIRECTORY },
{ "FILE_LOCK_CONFLICT", STATUS_FILE_LOCK_CONFLICT }, { "FILE_LOCK_CONFLICT", STATUS_FILE_LOCK_CONFLICT },
......
...@@ -70,6 +70,7 @@ struct desktop ...@@ -70,6 +70,7 @@ struct desktop
struct window *top_window; /* desktop window for this desktop */ struct window *top_window; /* desktop window for this desktop */
struct window *msg_window; /* HWND_MESSAGE top window */ struct window *msg_window; /* HWND_MESSAGE top window */
struct hook_table *global_hooks; /* table of global hooks on this desktop */ struct hook_table *global_hooks; /* table of global hooks on this desktop */
struct list hotkeys; /* list of registered hotkeys */
struct timeout_user *close_timeout; /* timeout before closing the desktop */ struct timeout_user *close_timeout; /* timeout before closing the desktop */
struct thread_input *foreground_input; /* thread input of foreground thread */ struct thread_input *foreground_input; /* thread input of foreground thread */
unsigned int users; /* processes and threads using this desktop */ unsigned int users; /* processes and threads using this desktop */
...@@ -114,6 +115,7 @@ extern void post_win_event( struct thread *thread, unsigned int event, ...@@ -114,6 +115,7 @@ extern void post_win_event( struct thread *thread, unsigned int event,
unsigned int child_id, client_ptr_t proc, unsigned int child_id, client_ptr_t proc,
const WCHAR *module, data_size_t module_size, const WCHAR *module, data_size_t module_size,
user_handle_t handle ); user_handle_t handle );
extern void free_hotkeys( struct desktop *desktop, user_handle_t window );
/* region functions */ /* region functions */
......
...@@ -1727,6 +1727,7 @@ void destroy_window( struct window *win ) ...@@ -1727,6 +1727,7 @@ void destroy_window( struct window *win )
if (win == shell_listview) shell_listview = NULL; if (win == shell_listview) shell_listview = NULL;
if (win == progman_window) progman_window = NULL; if (win == progman_window) progman_window = NULL;
if (win == taskman_window) taskman_window = NULL; if (win == taskman_window) taskman_window = NULL;
free_hotkeys( win->desktop, win->handle );
free_user_handle( win->handle ); free_user_handle( win->handle );
destroy_properties( win ); destroy_properties( win );
list_remove( &win->entry ); list_remove( &win->entry );
......
...@@ -235,6 +235,7 @@ static struct desktop *create_desktop( const struct unicode_str *name, unsigned ...@@ -235,6 +235,7 @@ static struct desktop *create_desktop( const struct unicode_str *name, unsigned
memset( &desktop->cursor, 0, sizeof(desktop->cursor) ); memset( &desktop->cursor, 0, sizeof(desktop->cursor) );
memset( desktop->keystate, 0, sizeof(desktop->keystate) ); memset( desktop->keystate, 0, sizeof(desktop->keystate) );
list_add_tail( &winstation->desktops, &desktop->entry ); list_add_tail( &winstation->desktops, &desktop->entry );
list_init( &desktop->hotkeys );
} }
} }
free( full_name ); free( full_name );
...@@ -273,6 +274,7 @@ static void desktop_destroy( struct object *obj ) ...@@ -273,6 +274,7 @@ static void desktop_destroy( struct object *obj )
{ {
struct desktop *desktop = (struct desktop *)obj; struct desktop *desktop = (struct desktop *)obj;
free_hotkeys( desktop, 0 );
if (desktop->top_window) destroy_window( desktop->top_window ); if (desktop->top_window) destroy_window( desktop->top_window );
if (desktop->msg_window) destroy_window( desktop->msg_window ); if (desktop->msg_window) destroy_window( desktop->msg_window );
if (desktop->global_hooks) release_object( desktop->global_hooks ); if (desktop->global_hooks) release_object( desktop->global_hooks );
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment