winex11.drv: Don't create a win_data structure for the desktop window, except in the process that owns it.

Handle desktop size changes by sending a message to the desktop owner.
diff --git a/dlls/winex11.drv/desktop.c b/dlls/winex11.drv/desktop.c
index 9fb710a..1ec6a5d 100644
--- a/dlls/winex11.drv/desktop.c
+++ b/dlls/winex11.drv/desktop.c
@@ -68,41 +68,6 @@
     }
 }
 
-/***********************************************************************
- *		X11DRV_resize_desktop
- *
- * Reset the desktop window size and WM hints
- */
-static int X11DRV_resize_desktop( unsigned int width, unsigned int height )
-{
-    XSizeHints *size_hints;
-    Display *display = thread_display();
-    Window w = root_window;
-    /* set up */
-    wine_tsx11_lock();
-    size_hints  = XAllocSizeHints();
-    if (!size_hints)
-    {
-        ERR("Not enough memory for window manager hints.\n" );
-        wine_tsx11_unlock();
-        return 0;
-    }
-    size_hints->min_width = size_hints->max_width = width;
-    size_hints->min_height = size_hints->max_height = height;
-    size_hints->flags = PMinSize | PMaxSize | PSize;
-
-    /* do the work */
-    XSetWMNormalHints( display, w, size_hints );
-    XResizeWindow( display, w, width, height );
-
-    /* clean up */
-    XFree( size_hints );
-    XFlush( display );
-    wine_tsx11_unlock();
-    X11DRV_handle_desktop_resize( width, height );
-    return 1;
-}
-
 static int X11DRV_desktop_GetCurrentMode(void)
 {
     unsigned int i;
diff --git a/dlls/winex11.drv/event.c b/dlls/winex11.drv/event.c
index 726ff3e..8e7eba4 100644
--- a/dlls/winex11.drv/event.c
+++ b/dlls/winex11.drv/event.c
@@ -964,6 +964,9 @@
         return SendMessageW( hwnd, WM_SYSCOMMAND, SC_CLOSE, 0 );
     case WM_X11DRV_SET_WIN_FORMAT:
         return X11DRV_set_win_format( hwnd, (XID)wp );
+    case WM_X11DRV_RESIZE_DESKTOP:
+        X11DRV_resize_desktop( LOWORD(lp), HIWORD(lp) );
+        return 0;
     default:
         FIXME( "got window msg %x hwnd %p wp %lx lp %lx\n", msg, hwnd, wp, lp );
         return 0;
diff --git a/dlls/winex11.drv/window.c b/dlls/winex11.drv/window.c
index 7348f2a..e39a5ce 100644
--- a/dlls/winex11.drv/window.c
+++ b/dlls/winex11.drv/window.c
@@ -998,6 +998,9 @@
         }
     }
 
+    /* only the size is allowed to change for the desktop window */
+    if (data->whole_window == root_window) mask &= CWWidth | CWHeight;
+
     if (mask)
     {
         DWORD style = GetWindowLongW( data->hwnd, GWL_STYLE );
@@ -1225,46 +1228,27 @@
 }
 
 
-/* fill in the desktop X window id in the x11drv_win_data structure */
+/* initialize the desktop window id in the desktop manager process */
 static void get_desktop_xwin( Display *display, struct x11drv_win_data *data )
 {
-    Window win = (Window)GetPropA( data->hwnd, whole_window_prop );
-
-    if (win)
-    {
-        unsigned int width, height;
-
-        /* retrieve the real size of the desktop */
-        SERVER_START_REQ( get_window_rectangles )
-        {
-            req->handle = data->hwnd;
-            wine_server_call( req );
-            width  = reply->window.right - reply->window.left;
-            height = reply->window.bottom - reply->window.top;
-        }
-        SERVER_END_REQ;
-        data->whole_window = win;
-        if (win != root_window) X11DRV_init_desktop( win, width, height );
-    }
-    else
+    data->whole_window = root_window;
+    if (root_window != DefaultRootWindow( display ))
     {
         VisualID visualid;
 
         wine_tsx11_lock();
         visualid = XVisualIDFromVisual(visual);
         wine_tsx11_unlock();
+        data->managed = TRUE;
+        SetPropA( data->hwnd, managed_prop, (HANDLE)1 );
         SetPropA( data->hwnd, whole_window_prop, (HANDLE)root_window );
         SetPropA( data->hwnd, visual_id_prop, (HANDLE)visualid );
-        data->whole_window = root_window;
-        X11DRV_SetWindowPos( data->hwnd, 0, &virtual_screen_rect, &virtual_screen_rect,
-                             SWP_NOZORDER | SWP_NOACTIVATE, NULL );
-        if (root_window != DefaultRootWindow( display ))
-        {
-            data->managed = TRUE;
-            SetPropA( data->hwnd, managed_prop, (HANDLE)1 );
-            set_initial_wm_hints( display, data );
-        }
+        set_initial_wm_hints( display, data );
     }
+    SetWindowPos( data->hwnd, 0, virtual_screen_rect.left, virtual_screen_rect.top,
+                  virtual_screen_rect.right - virtual_screen_rect.left,
+                  virtual_screen_rect.bottom - virtual_screen_rect.top,
+                  SWP_NOZORDER | SWP_NOACTIVATE );
 }
 
 /**********************************************************************
@@ -1272,13 +1256,39 @@
  */
 BOOL X11DRV_CreateDesktopWindow( HWND hwnd )
 {
-    Display *display = thread_display();
-    struct x11drv_win_data *data;
+    unsigned int width, height;
 
-    if (!(data = alloc_win_data( display, hwnd ))) return FALSE;
+    /* retrieve the real size of the desktop */
+    SERVER_START_REQ( get_window_rectangles )
+    {
+        req->handle = hwnd;
+        wine_server_call( req );
+        width  = reply->window.right - reply->window.left;
+        height = reply->window.bottom - reply->window.top;
+    }
+    SERVER_END_REQ;
 
-    get_desktop_xwin( display, data );
-
+    if (!width && !height)  /* not initialized yet */
+    {
+        SERVER_START_REQ( set_window_pos )
+        {
+            req->handle        = hwnd;
+            req->previous      = 0;
+            req->flags         = SWP_NOZORDER;
+            req->window.left   = virtual_screen_rect.left;
+            req->window.top    = virtual_screen_rect.top;
+            req->window.right  = virtual_screen_rect.right;
+            req->window.bottom = virtual_screen_rect.bottom;
+            req->client        = req->window;
+            wine_server_call( req );
+        }
+        SERVER_END_REQ;
+    }
+    else
+    {
+        Window win = (Window)GetPropA( hwnd, whole_window_prop );
+        if (win && win != root_window) X11DRV_init_desktop( win, width, height );
+    }
     return TRUE;
 }
 
@@ -1321,18 +1331,18 @@
         cs->cy = 0;
     }
 
-    /* initialize the dimensions before sending WM_GETMINMAXINFO */
-    SetRect( &rect, cs->x, cs->y, cs->x + cs->cx, cs->y + cs->cy );
-    X11DRV_SetWindowPos( hwnd, 0, &rect, &rect, SWP_NOZORDER | SWP_NOACTIVATE, NULL );
+    if (hwnd == GetDesktopWindow()) get_desktop_xwin( display, data );
+    else
+    {
+        /* initialize the dimensions before sending WM_GETMINMAXINFO */
+        SetRect( &rect, cs->x, cs->y, cs->x + cs->cx, cs->y + cs->cy );
+        X11DRV_SetWindowPos( hwnd, 0, &rect, &rect, SWP_NOZORDER | SWP_NOACTIVATE, NULL );
 
-    /* create an X window if it's a top level window */
-    if (GetAncestor( hwnd, GA_PARENT ) == GetDesktopWindow())
-    {
-        if (!create_whole_window( display, data, cs->style )) goto failed;
-    }
-    else if (hwnd == GetDesktopWindow())
-    {
-        get_desktop_xwin( display, data );
+        /* create an X window if it's a top level window */
+        if (GetAncestor( hwnd, GA_PARENT ) == GetDesktopWindow())
+        {
+            if (!create_whole_window( display, data, cs->style )) goto failed;
+        }
     }
 
     /* get class or window DC if needed */
@@ -1493,7 +1503,11 @@
 {
     struct x11drv_win_data *data = X11DRV_get_win_data( hwnd );
 
-    if (!data) return (Window)GetPropA( hwnd, whole_window_prop );
+    if (!data)
+    {
+        if (hwnd == GetDesktopWindow()) return root_window;
+        return (Window)GetPropA( hwnd, whole_window_prop );
+    }
     return data->whole_window;
 }
 
diff --git a/dlls/winex11.drv/winpos.c b/dlls/winex11.drv/winpos.c
index 3b148c6..39ac43a 100644
--- a/dlls/winex11.drv/winpos.c
+++ b/dlls/winex11.drv/winpos.c
@@ -873,30 +873,36 @@
 
 
 /***********************************************************************
- *		X11DRV_handle_desktop_resize
+ *		X11DRV_resize_desktop
  */
-void X11DRV_handle_desktop_resize( unsigned int width, unsigned int height )
+void X11DRV_resize_desktop( unsigned int width, unsigned int height )
 {
     HWND hwnd = GetDesktopWindow();
     struct x11drv_win_data *data;
     struct desktop_resize_data resize_data;
 
-    if (!(data = X11DRV_get_win_data( hwnd ))) return;
-
     SetRect( &resize_data.old_screen_rect, 0, 0, screen_width, screen_height );
     resize_data.old_virtual_rect = virtual_screen_rect;
 
     screen_width  = width;
     screen_height = height;
     xinerama_init();
-    TRACE("desktop %p change to (%dx%d)\n", hwnd, width, height);
-    data->lock_changes++;
-    X11DRV_SetWindowPos( hwnd, 0, &virtual_screen_rect, &virtual_screen_rect,
-                         SWP_NOZORDER | SWP_NOMOVE | SWP_NOACTIVATE, NULL );
-    data->lock_changes--;
     ClipCursor(NULL);
-    SendMessageTimeoutW( HWND_BROADCAST, WM_DISPLAYCHANGE, screen_bpp,
-                         MAKELPARAM( width, height ), SMTO_ABORTIFHUNG, 2000, NULL );
+
+    if (!(data = X11DRV_get_win_data( hwnd )))
+    {
+        SendMessageW( hwnd, WM_X11DRV_RESIZE_DESKTOP, 0, MAKELPARAM( width, height ) );
+    }
+    else
+    {
+        TRACE( "desktop %p change to (%dx%d)\n", hwnd, width, height );
+        SetWindowPos( hwnd, 0, virtual_screen_rect.left, virtual_screen_rect.top,
+                      virtual_screen_rect.right - virtual_screen_rect.left,
+                      virtual_screen_rect.bottom - virtual_screen_rect.top,
+                      SWP_NOZORDER | SWP_NOACTIVATE );
+        SendMessageTimeoutW( HWND_BROADCAST, WM_DISPLAYCHANGE, screen_bpp,
+                             MAKELPARAM( width, height ), SMTO_ABORTIFHUNG, 2000, NULL );
+    }
 
     EnumWindows( update_windows_on_desktop_resize, (LPARAM)&resize_data );
 }
diff --git a/dlls/winex11.drv/x11drv.h b/dlls/winex11.drv/x11drv.h
index 3328981..6f71b75 100644
--- a/dlls/winex11.drv/x11drv.h
+++ b/dlls/winex11.drv/x11drv.h
@@ -644,7 +644,8 @@
 {
     WM_X11DRV_ACQUIRE_SELECTION = 0x80001000,
     WM_X11DRV_DELETE_WINDOW,
-    WM_X11DRV_SET_WIN_FORMAT
+    WM_X11DRV_SET_WIN_FORMAT,
+    WM_X11DRV_RESIZE_DESKTOP
 };
 
 /* _NET_WM_STATE properties that we keep track of */
@@ -733,7 +734,7 @@
 extern void xinerama_init(void);
 
 extern void X11DRV_init_desktop( Window win, unsigned int width, unsigned int height );
-extern void X11DRV_handle_desktop_resize(unsigned int width, unsigned int height);
+extern void X11DRV_resize_desktop(unsigned int width, unsigned int height);
 extern void X11DRV_Settings_AddDepthModes(void);
 extern void X11DRV_Settings_AddOneMode(unsigned int width, unsigned int height, unsigned int bpp, unsigned int freq);
 extern int X11DRV_Settings_CreateDriver(LPDDHALINFO info);
diff --git a/dlls/winex11.drv/xrandr.c b/dlls/winex11.drv/xrandr.c
index ad2dc08..fd930a2 100644
--- a/dlls/winex11.drv/xrandr.c
+++ b/dlls/winex11.drv/xrandr.c
@@ -229,7 +229,7 @@
     wine_tsx11_unlock();
     if (stat == RRSetConfigSuccess)
     {
-        X11DRV_handle_desktop_resize( dd_modes[mode].dwWidth, dd_modes[mode].dwHeight );
+        X11DRV_resize_desktop( dd_modes[mode].dwWidth, dd_modes[mode].dwHeight );
         return DISP_CHANGE_SUCCESSFUL;
     }
 
diff --git a/dlls/winex11.drv/xvidmode.c b/dlls/winex11.drv/xvidmode.c
index 49c48b3..2c963d6 100644
--- a/dlls/winex11.drv/xvidmode.c
+++ b/dlls/winex11.drv/xvidmode.c
@@ -131,8 +131,7 @@
 #endif
   XSync(gdi_display, False);
   wine_tsx11_unlock();
-  X11DRV_handle_desktop_resize( real_xf86vm_modes[mode]->hdisplay,
-                                real_xf86vm_modes[mode]->vdisplay );
+  X11DRV_resize_desktop( real_xf86vm_modes[mode]->hdisplay, real_xf86vm_modes[mode]->vdisplay );
   return DISP_CHANGE_SUCCESSFUL;
 }