Commit c43b1ecb authored by Rémi Bernon's avatar Rémi Bernon Committed by Alexandre Julliard

server: Keep a list of processes that can receive rawinput messages.

parent f7303cf7
...@@ -684,6 +684,7 @@ struct process *create_process( int fd, struct process *parent, unsigned int fla ...@@ -684,6 +684,7 @@ struct process *create_process( int fd, struct process *parent, unsigned int fla
process->rawinput_mouse = NULL; process->rawinput_mouse = NULL;
process->rawinput_kbd = NULL; process->rawinput_kbd = NULL;
memset( &process->image_info, 0, sizeof(process->image_info) ); memset( &process->image_info, 0, sizeof(process->image_info) );
list_init( &process->rawinput_entry );
list_init( &process->kernel_object ); list_init( &process->kernel_object );
list_init( &process->thread_list ); list_init( &process->thread_list );
list_init( &process->locks ); list_init( &process->locks );
...@@ -784,6 +785,7 @@ static void process_destroy( struct object *obj ) ...@@ -784,6 +785,7 @@ static void process_destroy( struct object *obj )
if (process->idle_event) release_object( process->idle_event ); if (process->idle_event) release_object( process->idle_event );
if (process->id) free_ptid( process->id ); if (process->id) free_ptid( process->id );
if (process->token) release_object( process->token ); if (process->token) release_object( process->token );
list_remove( &process->rawinput_entry );
free( process->rawinput_devices ); free( process->rawinput_devices );
free( process->dir_cache ); free( process->dir_cache );
free( process->image ); free( process->image );
......
...@@ -83,6 +83,7 @@ struct process ...@@ -83,6 +83,7 @@ struct process
unsigned int rawinput_device_count; /* number of registered rawinput devices */ unsigned int rawinput_device_count; /* number of registered rawinput devices */
const struct rawinput_device *rawinput_mouse; /* rawinput mouse device, if any */ const struct rawinput_device *rawinput_mouse; /* rawinput mouse device, if any */
const struct rawinput_device *rawinput_kbd; /* rawinput keyboard device, if any */ const struct rawinput_device *rawinput_kbd; /* rawinput keyboard device, if any */
struct list rawinput_entry; /* entry in the rawinput process list */
struct list kernel_object; /* list of kernel object pointers */ struct list kernel_object; /* list of kernel object pointers */
pe_image_info_t image_info; /* main exe image info */ pe_image_info_t image_info; /* main exe image info */
}; };
......
...@@ -50,6 +50,8 @@ ...@@ -50,6 +50,8 @@
enum message_kind { SEND_MESSAGE, POST_MESSAGE }; enum message_kind { SEND_MESSAGE, POST_MESSAGE };
#define NB_MSG_KINDS (POST_MESSAGE+1) #define NB_MSG_KINDS (POST_MESSAGE+1)
/* list of processes registered for rawinput in the input desktop */
static struct list rawinput_processes = LIST_INIT(rawinput_processes);
struct message_result struct message_result
{ {
...@@ -2620,6 +2622,14 @@ static struct desktop *get_hardware_input_desktop( user_handle_t win ) ...@@ -2620,6 +2622,14 @@ static struct desktop *get_hardware_input_desktop( user_handle_t win )
return desktop; return desktop;
} }
/* enable or disable rawinput for a given process */
void set_rawinput_process( struct process *process, int enable )
{
list_remove( &process->rawinput_entry ); /* remove it first, it might already be in the list */
if (!process->rawinput_device_count || !enable) list_init( &process->rawinput_entry );
else list_add_tail( &rawinput_processes, &process->rawinput_entry );
}
/* 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)
...@@ -3639,12 +3649,15 @@ DECL_HANDLER(update_rawinput_devices) ...@@ -3639,12 +3649,15 @@ DECL_HANDLER(update_rawinput_devices)
unsigned int device_count = get_req_data_size() / sizeof (*devices); unsigned int device_count = get_req_data_size() / sizeof (*devices);
size_t size = device_count * sizeof(*devices); size_t size = device_count * sizeof(*devices);
struct process *process = current->process; struct process *process = current->process;
struct winstation *winstation;
struct desktop *desktop;
if (!size) if (!size)
{ {
process->rawinput_device_count = 0; process->rawinput_device_count = 0;
process->rawinput_mouse = NULL; process->rawinput_mouse = NULL;
process->rawinput_kbd = NULL; process->rawinput_kbd = NULL;
set_rawinput_process( process, 0 );
return; return;
} }
...@@ -3659,4 +3672,15 @@ DECL_HANDLER(update_rawinput_devices) ...@@ -3659,4 +3672,15 @@ DECL_HANDLER(update_rawinput_devices)
process->rawinput_mouse = find_rawinput_device( process, MAKELONG(HID_USAGE_GENERIC_MOUSE, HID_USAGE_PAGE_GENERIC) ); process->rawinput_mouse = find_rawinput_device( process, MAKELONG(HID_USAGE_GENERIC_MOUSE, HID_USAGE_PAGE_GENERIC) );
process->rawinput_kbd = find_rawinput_device( process, MAKELONG(HID_USAGE_GENERIC_KEYBOARD, HID_USAGE_PAGE_GENERIC) ); process->rawinput_kbd = find_rawinput_device( process, MAKELONG(HID_USAGE_GENERIC_KEYBOARD, HID_USAGE_PAGE_GENERIC) );
if ((winstation = get_visible_winstation()) && (desktop = get_input_desktop( winstation )))
{
struct thread *thread;
/* one of the process thread might be connected to the input desktop, update the full list */
LIST_FOR_EACH_ENTRY( thread, &desktop->threads, struct thread, desktop_entry )
set_rawinput_process( thread->process, 1 );
release_object( desktop );
}
} }
...@@ -125,6 +125,7 @@ extern void post_win_event( struct thread *thread, unsigned int event, ...@@ -125,6 +125,7 @@ extern void post_win_event( struct thread *thread, unsigned int event,
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 ); extern void free_hotkeys( struct desktop *desktop, user_handle_t window );
extern void set_rawinput_process( struct process *process, int enable );
/* region functions */ /* region functions */
......
...@@ -232,9 +232,27 @@ struct desktop *get_input_desktop( struct winstation *winstation ) ...@@ -232,9 +232,27 @@ struct desktop *get_input_desktop( struct winstation *winstation )
/* changes the winstation current input desktop and update its input time */ /* changes the winstation current input desktop and update its input time */
int set_input_desktop( struct winstation *winstation, struct desktop *new_desktop ) int set_input_desktop( struct winstation *winstation, struct desktop *new_desktop )
{ {
struct desktop *old_desktop = winstation->input_desktop;
struct thread *thread;
if (!(winstation->flags & WSF_VISIBLE)) return 0; if (!(winstation->flags & WSF_VISIBLE)) return 0;
if (new_desktop) new_desktop->input_time = current_time; if (new_desktop) new_desktop->input_time = current_time;
winstation->input_desktop = new_desktop; if (old_desktop == new_desktop) return 1;
if (old_desktop)
{
/* disconnect every process of the old input desktop from rawinput */
LIST_FOR_EACH_ENTRY( thread, &old_desktop->threads, struct thread, desktop_entry )
set_rawinput_process( thread->process, 0 );
}
if ((winstation->input_desktop = new_desktop))
{
/* connect every process of the new input desktop to rawinput */
LIST_FOR_EACH_ENTRY( thread, &new_desktop->threads, struct thread, desktop_entry )
set_rawinput_process( thread->process, 1 );
}
return 1; return 1;
} }
...@@ -376,6 +394,9 @@ static void add_desktop_thread( struct desktop *desktop, struct thread *thread ) ...@@ -376,6 +394,9 @@ static void add_desktop_thread( struct desktop *desktop, struct thread *thread )
desktop->close_timeout = NULL; desktop->close_timeout = NULL;
} }
} }
/* if thread process is now connected to the input desktop, let it receive rawinput */
if (desktop == desktop->winstation->input_desktop) set_rawinput_process( thread->process, 1 );
} }
/* remove a user of the desktop and start the close timeout if necessary */ /* remove a user of the desktop and start the close timeout if necessary */
...@@ -394,6 +415,13 @@ static void remove_desktop_thread( struct desktop *desktop, struct thread *threa ...@@ -394,6 +415,13 @@ static void remove_desktop_thread( struct desktop *desktop, struct thread *threa
if ((process = get_top_window_owner( desktop )) && desktop->users == process->running_threads && !desktop->close_timeout) if ((process = get_top_window_owner( desktop )) && desktop->users == process->running_threads && !desktop->close_timeout)
desktop->close_timeout = add_timeout_user( -TICKS_PER_SEC, close_desktop_timeout, desktop ); desktop->close_timeout = add_timeout_user( -TICKS_PER_SEC, close_desktop_timeout, desktop );
} }
if (desktop == desktop->winstation->input_desktop)
{
/* thread process might still be connected the input desktop through another thread, update the full list */
LIST_FOR_EACH_ENTRY( thread, &desktop->threads, struct thread, desktop_entry )
set_rawinput_process( thread->process, 1 );
}
} }
/* set the thread default desktop handle */ /* set the thread default desktop handle */
......
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