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
struct thread_input
{
struct object obj; /* object header */
struct desktop *desktop; /* desktop that this thread input belongs to */
user_handle_t focus; /* focus window */
user_handle_t capture; /* capture window */
user_handle_t active; /* active window */
......@@ -188,12 +189,17 @@ static void set_caret_window( struct thread_input *input, user_handle_t win )
}
/* 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;
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->capture = 0;
input->active = 0;
......@@ -222,7 +228,7 @@ static struct msg_queue *create_msg_queue( struct thread *thread, struct thread_
struct msg_queue *queue;
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 )))
{
queue->wake_bits = 0;
......@@ -797,6 +803,7 @@ static void thread_input_destroy( struct object *obj )
if (foreground_input == input) foreground_input = NULL;
empty_msg_list( &input->msg_list );
release_object( input->desktop );
}
/* fix the thread input data when a window is destroyed */
......@@ -841,10 +848,20 @@ int init_thread_queue( struct thread *thread )
/* attach two thread input data structures */
int attach_thread_input( struct thread *thread_from, struct thread *thread_to )
{
struct desktop *desktop;
struct thread_input *input;
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 );
if (input->desktop != desktop)
{
set_error( STATUS_ACCESS_DENIED );
release_object( input );
release_object( desktop );
return 0;
}
release_object( desktop );
if (thread_from->queue)
{
......@@ -860,17 +877,11 @@ int attach_thread_input( struct thread *thread_from, struct thread *thread_to )
}
/* 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;
if (!thread_from->queue || !thread_to->queue ||
thread_from->queue->input != thread_to->queue->input)
{
set_error( STATUS_ACCESS_DENIED );
return;
}
if ((input = create_thread_input()))
if ((input = create_thread_input( thread_from )))
{
release_thread_input( thread_from );
thread_from->queue->input = input;
......@@ -1146,7 +1157,7 @@ static user_handle_t find_hardware_message_window( struct thread_input *input, s
if (!input || !(win = input->capture))
{
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;
......@@ -1808,7 +1819,14 @@ DECL_HANDLER(attach_thread_input)
if (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 );
release_object( thread_from );
......
......@@ -56,6 +56,7 @@ struct desktop
unsigned int flags; /* desktop flags */
struct winstation *winstation; /* winstation this desktop belongs to */
struct list entry; /* entry in winstation list of desktops */
struct window *top_window; /* desktop window for this desktop */
};
/* user handles functions */
......@@ -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 int init_thread_queue( struct thread *thread );
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,
unsigned int wparam, unsigned int lparam );
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 );
/* window functions */
extern void destroy_window( struct window *win );
extern void destroy_thread_windows( struct thread *thread );
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_window_visible( user_handle_t window );
extern int make_window_active( user_handle_t window );
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 struct window_class *get_window_class( user_handle_t window );
......
......@@ -111,7 +111,8 @@ static void winstation_dump( struct object *obj, int verbose )
{
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 );
fputc( '\n', stderr );
}
......@@ -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 */
desktop->flags = flags;
desktop->winstation = (struct winstation *)grab_object( winstation );
desktop->top_window = NULL;
list_add_tail( &winstation->desktops, &desktop->entry );
}
}
......@@ -198,7 +200,8 @@ static void desktop_dump( struct object *obj, int verbose )
{
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 );
fputc( '\n', stderr );
}
......@@ -218,6 +221,7 @@ static void desktop_destroy( struct object *obj )
{
struct desktop *desktop = (struct desktop *)obj;
if (desktop->top_window) destroy_window( desktop->top_window );
list_remove( &desktop->entry );
release_object( desktop->winstation );
}
......@@ -457,6 +461,8 @@ DECL_HANDLER(set_thread_desktop)
else
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 );
release_object( new_desktop );
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