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.
diff --git a/server/queue.c b/server/queue.c
index d827c0f..0b40a2a 100644
--- a/server/queue.c
+++ b/server/queue.c
@@ -94,6 +94,7 @@
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 @@
}
/* 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 @@
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 @@
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 @@
/* 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 @@
}
/* 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 @@
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 @@
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 );