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/winstation.c b/server/winstation.c
index 8c67d59..31f5e03 100644
--- a/server/winstation.c
+++ b/server/winstation.c
@@ -111,7 +111,8 @@
 {
     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 @@
             /* 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 @@
 {
     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 @@
 {
     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 @@
     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 );