Commit 5ad90c0f authored by Alexandre Julliard's avatar Alexandre Julliard

Tie windows and thread input structures to a specific desktop.

Support multiple desktop windows (one per desktop object). Use the window desktop to find the window station to use for property atoms.
parent 30d06da6
...@@ -94,6 +94,7 @@ struct timer ...@@ -94,6 +94,7 @@ struct timer
struct thread_input struct thread_input
{ {
struct object obj; /* object header */ struct object obj; /* object header */
struct desktop *desktop; /* desktop that this thread input belongs to */
user_handle_t focus; /* focus window */ user_handle_t focus; /* focus window */
user_handle_t capture; /* capture window */ user_handle_t capture; /* capture window */
user_handle_t active; /* active window */ user_handle_t active; /* active window */
...@@ -188,12 +189,17 @@ static void set_caret_window( struct thread_input *input, user_handle_t win ) ...@@ -188,12 +189,17 @@ static void set_caret_window( struct thread_input *input, user_handle_t win )
} }
/* create a thread input object */ /* create a thread input object */
static struct thread_input *create_thread_input(void) static struct thread_input *create_thread_input( struct thread *thread )
{ {
struct thread_input *input; struct thread_input *input;
if ((input = alloc_object( &thread_input_ops ))) if ((input = alloc_object( &thread_input_ops )))
{ {
if (!(input->desktop = get_thread_desktop( thread, 0 /* FIXME: access rights */ )))
{
free( input );
return NULL;
}
input->focus = 0; input->focus = 0;
input->capture = 0; input->capture = 0;
input->active = 0; input->active = 0;
...@@ -222,7 +228,7 @@ static struct msg_queue *create_msg_queue( struct thread *thread, struct thread_ ...@@ -222,7 +228,7 @@ static struct msg_queue *create_msg_queue( struct thread *thread, struct thread_
struct msg_queue *queue; struct msg_queue *queue;
int i; int i;
if (!input && !(input = create_thread_input())) return NULL; if (!input && !(input = create_thread_input( thread ))) return NULL;
if ((queue = alloc_object( &msg_queue_ops ))) if ((queue = alloc_object( &msg_queue_ops )))
{ {
queue->wake_bits = 0; queue->wake_bits = 0;
...@@ -797,6 +803,7 @@ static void thread_input_destroy( struct object *obj ) ...@@ -797,6 +803,7 @@ static void thread_input_destroy( struct object *obj )
if (foreground_input == input) foreground_input = NULL; if (foreground_input == input) foreground_input = NULL;
empty_msg_list( &input->msg_list ); empty_msg_list( &input->msg_list );
release_object( input->desktop );
} }
/* fix the thread input data when a window is destroyed */ /* fix the thread input data when a window is destroyed */
...@@ -841,10 +848,20 @@ int init_thread_queue( struct thread *thread ) ...@@ -841,10 +848,20 @@ int init_thread_queue( struct thread *thread )
/* attach two thread input data structures */ /* attach two thread input data structures */
int attach_thread_input( struct thread *thread_from, struct thread *thread_to ) int attach_thread_input( struct thread *thread_from, struct thread *thread_to )
{ {
struct desktop *desktop;
struct thread_input *input; struct thread_input *input;
if (!thread_to->queue && !(thread_to->queue = create_msg_queue( thread_to, NULL ))) return 0; if (!thread_to->queue && !(thread_to->queue = create_msg_queue( thread_to, NULL ))) return 0;
if (!(desktop = get_thread_desktop( thread_from, 0 ))) return 0;
input = (struct thread_input *)grab_object( thread_to->queue->input ); input = (struct thread_input *)grab_object( thread_to->queue->input );
if (input->desktop != desktop)
{
set_error( STATUS_ACCESS_DENIED );
release_object( input );
release_object( desktop );
return 0;
}
release_object( desktop );
if (thread_from->queue) if (thread_from->queue)
{ {
...@@ -860,17 +877,11 @@ int attach_thread_input( struct thread *thread_from, struct thread *thread_to ) ...@@ -860,17 +877,11 @@ int attach_thread_input( struct thread *thread_from, struct thread *thread_to )
} }
/* detach two thread input data structures */ /* detach two thread input data structures */
static void detach_thread_input( struct thread *thread_from, struct thread *thread_to ) void detach_thread_input( struct thread *thread_from )
{ {
struct thread_input *input; struct thread_input *input;
if (!thread_from->queue || !thread_to->queue || if ((input = create_thread_input( thread_from )))
thread_from->queue->input != thread_to->queue->input)
{
set_error( STATUS_ACCESS_DENIED );
return;
}
if ((input = create_thread_input()))
{ {
release_thread_input( thread_from ); release_thread_input( thread_from );
thread_from->queue->input = input; thread_from->queue->input = input;
...@@ -1146,7 +1157,7 @@ static user_handle_t find_hardware_message_window( struct thread_input *input, s ...@@ -1146,7 +1157,7 @@ static user_handle_t find_hardware_message_window( struct thread_input *input, s
if (!input || !(win = input->capture)) if (!input || !(win = input->capture))
{ {
if (!(win = msg->win) || !is_window_visible( win )) if (!(win = msg->win) || !is_window_visible( win ))
win = window_from_point( msg->x, msg->y ); win = window_from_point( input->desktop, msg->x, msg->y );
} }
} }
return win; return win;
...@@ -1808,7 +1819,14 @@ DECL_HANDLER(attach_thread_input) ...@@ -1808,7 +1819,14 @@ DECL_HANDLER(attach_thread_input)
if (thread_from != thread_to) if (thread_from != thread_to)
{ {
if (req->attach) attach_thread_input( thread_from, thread_to ); if (req->attach) attach_thread_input( thread_from, thread_to );
else detach_thread_input( thread_from, thread_to ); else
{
if (thread_from->queue && thread_to->queue &&
thread_from->queue->input == thread_to->queue->input)
detach_thread_input( thread_from );
else
set_error( STATUS_ACCESS_DENIED );
}
} }
else set_error( STATUS_ACCESS_DENIED ); else set_error( STATUS_ACCESS_DENIED );
release_object( thread_from ); release_object( thread_from );
......
...@@ -56,6 +56,7 @@ struct desktop ...@@ -56,6 +56,7 @@ struct desktop
unsigned int flags; /* desktop flags */ unsigned int flags; /* desktop flags */
struct winstation *winstation; /* winstation this desktop belongs to */ struct winstation *winstation; /* winstation this desktop belongs to */
struct list entry; /* entry in winstation list of desktops */ struct list entry; /* entry in winstation list of desktops */
struct window *top_window; /* desktop window for this desktop */
}; };
/* user handles functions */ /* user handles functions */
...@@ -86,6 +87,7 @@ extern void inc_queue_paint_count( struct thread *thread, int incr ); ...@@ -86,6 +87,7 @@ extern void inc_queue_paint_count( struct thread *thread, int incr );
extern void queue_cleanup_window( struct thread *thread, user_handle_t win ); extern void queue_cleanup_window( struct thread *thread, user_handle_t win );
extern int init_thread_queue( struct thread *thread ); extern int init_thread_queue( struct thread *thread );
extern int attach_thread_input( struct thread *thread_from, struct thread *thread_to ); extern int attach_thread_input( struct thread *thread_from, struct thread *thread_to );
extern void detach_thread_input( struct thread *thread_from );
extern void post_message( user_handle_t win, unsigned int message, extern void post_message( user_handle_t win, unsigned int message,
unsigned int wparam, unsigned int lparam ); unsigned int wparam, unsigned int lparam );
extern void post_win_event( struct thread *thread, unsigned int event, extern void post_win_event( struct thread *thread, unsigned int event,
...@@ -121,13 +123,14 @@ extern int rect_in_region( struct region *region, const rectangle_t *rect ); ...@@ -121,13 +123,14 @@ extern int rect_in_region( struct region *region, const rectangle_t *rect );
/* window functions */ /* window functions */
extern void destroy_window( struct window *win );
extern void destroy_thread_windows( struct thread *thread ); extern void destroy_thread_windows( struct thread *thread );
extern int is_child_window( user_handle_t parent, user_handle_t child ); extern int is_child_window( user_handle_t parent, user_handle_t child );
extern int is_top_level_window( user_handle_t window ); extern int is_top_level_window( user_handle_t window );
extern int is_window_visible( user_handle_t window ); extern int is_window_visible( user_handle_t window );
extern int make_window_active( user_handle_t window ); extern int make_window_active( user_handle_t window );
extern struct thread *get_window_thread( user_handle_t handle ); extern struct thread *get_window_thread( user_handle_t handle );
extern user_handle_t window_from_point( int x, int y ); extern user_handle_t window_from_point( struct desktop *desktop, int x, int y );
extern user_handle_t find_window_to_repaint( user_handle_t parent, struct thread *thread ); extern user_handle_t find_window_to_repaint( user_handle_t parent, struct thread *thread );
extern struct window_class *get_window_class( user_handle_t window ); extern struct window_class *get_window_class( user_handle_t window );
......
...@@ -111,7 +111,8 @@ static void winstation_dump( struct object *obj, int verbose ) ...@@ -111,7 +111,8 @@ static void winstation_dump( struct object *obj, int verbose )
{ {
struct winstation *winstation = (struct winstation *)obj; struct winstation *winstation = (struct winstation *)obj;
fprintf( stderr, "Winstation flags=%x ", winstation->flags ); fprintf( stderr, "Winstation flags=%x clipboard=%p atoms=%p ",
winstation->flags, winstation->clipboard, winstation->atom_table );
dump_object_name( &winstation->obj ); dump_object_name( &winstation->obj );
fputc( '\n', stderr ); fputc( '\n', stderr );
} }
...@@ -187,6 +188,7 @@ static struct desktop *create_desktop( const WCHAR *name, size_t len, unsigned i ...@@ -187,6 +188,7 @@ static struct desktop *create_desktop( const WCHAR *name, size_t len, unsigned i
/* initialize it if it didn't already exist */ /* initialize it if it didn't already exist */
desktop->flags = flags; desktop->flags = flags;
desktop->winstation = (struct winstation *)grab_object( winstation ); desktop->winstation = (struct winstation *)grab_object( winstation );
desktop->top_window = NULL;
list_add_tail( &winstation->desktops, &desktop->entry ); list_add_tail( &winstation->desktops, &desktop->entry );
} }
} }
...@@ -198,7 +200,8 @@ static void desktop_dump( struct object *obj, int verbose ) ...@@ -198,7 +200,8 @@ static void desktop_dump( struct object *obj, int verbose )
{ {
struct desktop *desktop = (struct desktop *)obj; struct desktop *desktop = (struct desktop *)obj;
fprintf( stderr, "Desktop flags=%x winstation=%p ", desktop->flags, desktop->winstation ); fprintf( stderr, "Desktop flags=%x winstation=%p top_win=%p",
desktop->flags, desktop->winstation, desktop->top_window );
dump_object_name( &desktop->obj ); dump_object_name( &desktop->obj );
fputc( '\n', stderr ); fputc( '\n', stderr );
} }
...@@ -218,6 +221,7 @@ static void desktop_destroy( struct object *obj ) ...@@ -218,6 +221,7 @@ static void desktop_destroy( struct object *obj )
{ {
struct desktop *desktop = (struct desktop *)obj; struct desktop *desktop = (struct desktop *)obj;
if (desktop->top_window) destroy_window( desktop->top_window );
list_remove( &desktop->entry ); list_remove( &desktop->entry );
release_object( desktop->winstation ); release_object( desktop->winstation );
} }
...@@ -457,6 +461,8 @@ DECL_HANDLER(set_thread_desktop) ...@@ -457,6 +461,8 @@ DECL_HANDLER(set_thread_desktop)
else else
current->desktop = req->handle; /* FIXME: should we close the old one? */ current->desktop = req->handle; /* FIXME: should we close the old one? */
if (old_desktop != new_desktop) detach_thread_input( current );
if (old_desktop) release_object( old_desktop ); if (old_desktop) release_object( old_desktop );
release_object( new_desktop ); release_object( new_desktop );
release_object( winstation ); release_object( winstation );
......
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