Alexandre Julliard : server: Make the foreground thread input per-desktop instead of global.

Alexandre Julliard julliard at winehq.org
Fri Feb 25 11:19:46 CST 2011


Module: wine
Branch: master
Commit: ac4aac747c2153d903922102da337bd77475750e
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=ac4aac747c2153d903922102da337bd77475750e

Author: Alexandre Julliard <julliard at winehq.org>
Date:   Thu Feb 24 16:45:04 2011 +0100

server: Make the foreground thread input per-desktop instead of global.

---

 server/queue.c      |   58 ++++++++++++++++++++++++++++++++++++---------------
 server/user.h       |   19 ++++++++--------
 server/winstation.c |    1 +
 3 files changed, 52 insertions(+), 26 deletions(-)

diff --git a/server/queue.c b/server/queue.c
index ae11901..7a25517 100644
--- a/server/queue.c
+++ b/server/queue.c
@@ -199,7 +199,6 @@ static const struct object_ops thread_input_ops =
 };
 
 /* pointer to input structure of foreground thread */
-static struct thread_input *foreground_input;
 static unsigned int last_input_time;
 
 static void free_message( struct message *msg );
@@ -894,9 +893,12 @@ static void thread_input_destroy( struct object *obj )
 {
     struct thread_input *input = (struct thread_input *)obj;
 
-    if (foreground_input == input) foreground_input = NULL;
     empty_msg_list( &input->msg_list );
-    if (input->desktop) release_object( input->desktop );
+    if (input->desktop)
+    {
+        if (input->desktop->foreground_input == input) input->desktop->foreground_input = NULL;
+        release_object( input->desktop );
+    }
 }
 
 /* fix the thread input data when a window is destroyed */
@@ -1704,8 +1706,9 @@ DECL_HANDLER(send_hardware_message)
 {
     struct message *msg;
     struct thread *thread = NULL;
+    struct desktop *desktop = NULL;
     struct hardware_msg_data *data;
-    struct thread_input *input = foreground_input;
+    struct thread_input *input;
 
     if (req->id)
     {
@@ -1717,15 +1720,18 @@ DECL_HANDLER(send_hardware_message)
             return;
         }
         input = thread->queue->input;
+        desktop = (struct desktop *)grab_object( input->desktop );
         reply->cursor = input->cursor;
         reply->count  = input->cursor_count;
     }
-
-    if (!req->msg || !(data = mem_alloc( sizeof(*data) )))
+    else
     {
-        if (thread) release_object( thread );
-        return;
+        if (!(desktop = get_thread_desktop( current, 0 ))) return;
+        input = desktop->foreground_input;
     }
+
+    if (!req->msg || !(data = mem_alloc( sizeof(*data) ))) goto done;
+
     memset( data, 0, sizeof(*data) );
     data->x    = req->x;
     data->y    = req->y;
@@ -1746,7 +1752,9 @@ DECL_HANDLER(send_hardware_message)
     }
     else free( data );
 
+done:
     if (thread) release_object( thread );
+    release_object( desktop );
 }
 
 /* post a quit message to the current queue */
@@ -2035,14 +2043,24 @@ DECL_HANDLER(attach_thread_input)
 DECL_HANDLER(get_thread_input)
 {
     struct thread *thread = NULL;
+    struct desktop *desktop;
     struct thread_input *input;
 
     if (req->tid)
     {
         if (!(thread = get_thread_from_id( req->tid ))) return;
+        if (!(desktop = get_thread_desktop( thread, 0 )))
+        {
+            release_object( thread );
+            return;
+        }
         input = thread->queue ? thread->queue->input : NULL;
     }
-    else input = foreground_input;  /* get the foreground thread info */
+    else
+    {
+        if (!(desktop = get_thread_desktop( current, 0 ))) return;
+        input = desktop->foreground_input;  /* get the foreground thread info */
+    }
 
     if (input)
     {
@@ -2058,8 +2076,9 @@ DECL_HANDLER(get_thread_input)
     }
 
     /* foreground window is active window of foreground thread */
-    reply->foreground = foreground_input ? foreground_input->active : 0;
+    reply->foreground = desktop->foreground_input ? desktop->foreground_input->active : 0;
     if (thread) release_object( thread );
+    release_object( desktop );
 }
 
 
@@ -2100,21 +2119,26 @@ DECL_HANDLER(set_key_state)
 /* set the system foreground window */
 DECL_HANDLER(set_foreground_window)
 {
-    struct thread *thread;
+    struct thread *thread = NULL;
+    struct desktop *desktop;
     struct msg_queue *queue = get_current_queue();
 
-    reply->previous = foreground_input ? foreground_input->active : 0;
-    reply->send_msg_old = (reply->previous && foreground_input != queue->input);
+    if (!(desktop = get_thread_desktop( current, 0 ))) return;
+    reply->previous = desktop->foreground_input ? desktop->foreground_input->active : 0;
+    reply->send_msg_old = (reply->previous && desktop->foreground_input != queue->input);
     reply->send_msg_new = FALSE;
 
     if (is_top_level_window( req->handle ) &&
-        ((thread = get_window_thread( req->handle ))))
+        ((thread = get_window_thread( req->handle ))) &&
+        (thread->queue->input->desktop == desktop))
     {
-        foreground_input = thread->queue->input;
-        reply->send_msg_new = (foreground_input != queue->input);
-        release_object( thread );
+        desktop->foreground_input = thread->queue->input;
+        reply->send_msg_new = (desktop->foreground_input != queue->input);
     }
     else set_win32_error( ERROR_INVALID_WINDOW_HANDLE );
+
+    if (thread) release_object( thread );
+    release_object( desktop );
 }
 
 
diff --git a/server/user.h b/server/user.h
index 6ac0398..708692a 100644
--- a/server/user.h
+++ b/server/user.h
@@ -53,15 +53,16 @@ struct winstation
 
 struct desktop
 {
-    struct object        obj;            /* object header */
-    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 */
-    struct window       *msg_window;     /* HWND_MESSAGE top window */
-    struct hook_table   *global_hooks;   /* table of global hooks on this desktop */
-    struct timeout_user *close_timeout;  /* timeout before closing the desktop */
-    unsigned int         users;          /* processes and threads using this desktop */
+    struct object        obj;              /* object header */
+    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 */
+    struct window       *msg_window;       /* HWND_MESSAGE top window */
+    struct hook_table   *global_hooks;     /* table of global hooks on this desktop */
+    struct timeout_user *close_timeout;    /* timeout before closing the desktop */
+    struct thread_input *foreground_input; /* thread input of foreground thread */
+    unsigned int         users;            /* processes and threads using this desktop */
 };
 
 /* user handles functions */
diff --git a/server/winstation.c b/server/winstation.c
index 7ddc277..b05efac 100644
--- a/server/winstation.c
+++ b/server/winstation.c
@@ -230,6 +230,7 @@ static struct desktop *create_desktop( const struct unicode_str *name, unsigned
             desktop->msg_window = NULL;
             desktop->global_hooks = NULL;
             desktop->close_timeout = NULL;
+            desktop->foreground_input = NULL;
             desktop->users = 0;
             list_add_tail( &winstation->desktops, &desktop->entry );
         }




More information about the wine-cvs mailing list