Alexandre Julliard : winex11: Create the window data structure lazily, once the window is made visible.

Alexandre Julliard julliard at winehq.org
Thu Jan 24 07:20:57 CST 2008


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

Author: Alexandre Julliard <julliard at winehq.org>
Date:   Thu Jan 24 10:20:51 2008 +0100

winex11: Create the window data structure lazily, once the window is made visible.

---

 dlls/winex11.drv/window.c |   66 ++++++++++++++++++++++++++++++--------------
 dlls/winex11.drv/winpos.c |   17 ++++++++---
 dlls/winex11.drv/x11drv.h |    1 +
 3 files changed, 58 insertions(+), 26 deletions(-)

diff --git a/dlls/winex11.drv/window.c b/dlls/winex11.drv/window.c
index 73f9659..c21836d 100644
--- a/dlls/winex11.drv/window.c
+++ b/dlls/winex11.drv/window.c
@@ -312,7 +312,8 @@ BOOL X11DRV_set_win_format( HWND hwnd, XID fbconfig_id )
     HWND next_hwnd;
     int w, h;
 
-    if (!(data = X11DRV_get_win_data(hwnd))) return FALSE;
+    if (!(data = X11DRV_get_win_data(hwnd)) &&
+        !(data = X11DRV_create_win_data(hwnd))) return FALSE;
 
     wine_tsx11_lock();
 
@@ -651,7 +652,8 @@ void X11DRV_make_systray_window( HWND hwnd )
     struct x11drv_win_data *data;
     Window systray_window;
 
-    if (!(data = X11DRV_get_win_data( hwnd ))) return;
+    if (!(data = X11DRV_get_win_data( hwnd )) &&
+        !(data = X11DRV_create_win_data( hwnd ))) return;
 
     wine_tsx11_lock();
     if (!systray_atom)
@@ -1315,26 +1317,10 @@ BOOL X11DRV_CreateWindow( HWND hwnd, CREATESTRUCTA *cs, BOOL unicode )
     BOOL ret = FALSE;
     INT cx = cs->cx, cy = cs->cy;
 
-    if (hwnd == GetDesktopWindow())
+    if (hwnd == GetDesktopWindow() && root_window != DefaultRootWindow( display ))
     {
-        if (root_window != DefaultRootWindow( display ))
-        {
-            if (!create_desktop_win_data( display, hwnd )) return FALSE;
-        }
-    }
-    else
-    {
-        struct x11drv_win_data *data;
-
-        if (!(data = alloc_win_data( display, hwnd ))) return FALSE;
-
-        /* create an X window if it's a top level window */
-        if (GetAncestor( hwnd, GA_PARENT ) == GetDesktopWindow())
-        {
-            if (!create_whole_window( display, data )) goto failed;
-        }
-        /* get class or window DC if needed */
-        alloc_window_dce( data );
+        /* the desktop win data can't be created lazily */
+        if (!create_desktop_win_data( display, hwnd )) return FALSE;
     }
 
     /* Call the WH_CBT hook */
@@ -1467,6 +1453,44 @@ struct x11drv_win_data *X11DRV_get_win_data( HWND hwnd )
 
 
 /***********************************************************************
+ *		X11DRV_create_win_data
+ *
+ * Create an X11 data window structure for an existing window.
+ */
+struct x11drv_win_data *X11DRV_create_win_data( HWND hwnd )
+{
+    Display *display = thread_display();
+    struct x11drv_win_data *data;
+    HWND parent;
+
+    if (!(parent = GetAncestor( hwnd, GA_PARENT ))) return NULL;  /* desktop */
+    if (!(data = alloc_win_data( display, hwnd ))) return NULL;
+
+    GetWindowRect( hwnd, &data->window_rect );
+    MapWindowPoints( 0, parent, (POINT *)&data->window_rect, 2 );
+    data->whole_rect = data->window_rect;
+    GetClientRect( hwnd, &data->client_rect );
+    MapWindowPoints( hwnd, parent, (POINT *)&data->client_rect, 2 );
+
+    if (parent == GetDesktopWindow())
+    {
+        if (!create_whole_window( display, data ))
+        {
+            HeapFree( GetProcessHeap(), 0, data );
+            return NULL;
+        }
+        TRACE( "win %p/%lx window %s whole %s client %s\n",
+               hwnd, data->whole_window, wine_dbgstr_rect( &data->window_rect ),
+               wine_dbgstr_rect( &data->whole_rect ), wine_dbgstr_rect( &data->client_rect ));
+    }
+
+    /* get class or window DC if needed */
+    alloc_window_dce( data );
+    return data;
+}
+
+
+/***********************************************************************
  *		X11DRV_get_whole_window
  *
  * Return the X window associated with the full area of a window
diff --git a/dlls/winex11.drv/winpos.c b/dlls/winex11.drv/winpos.c
index 1489ebe..e5d16ee 100644
--- a/dlls/winex11.drv/winpos.c
+++ b/dlls/winex11.drv/winpos.c
@@ -134,13 +134,14 @@ void X11DRV_SetWindowStyle( HWND hwnd, DWORD old_style )
     DWORD new_style, changed;
 
     if (hwnd == GetDesktopWindow()) return;
-    if (!(data = X11DRV_get_win_data( hwnd ))) return;
-
     new_style = GetWindowLongW( hwnd, GWL_STYLE );
     changed = new_style ^ old_style;
 
     if (changed & WS_VISIBLE)
     {
+        if (!(data = X11DRV_get_win_data( hwnd )) &&
+            !(data = X11DRV_create_win_data( hwnd ))) return;
+
         if (data->whole_window && (new_style & WS_VISIBLE) &&
             X11DRV_is_window_rect_mapped( &data->window_rect ))
         {
@@ -161,7 +162,8 @@ void X11DRV_SetWindowStyle( HWND hwnd, DWORD old_style )
 
     if (changed & WS_DISABLED)
     {
-        if (data->whole_window && data->wm_hints)
+        data = X11DRV_get_win_data( hwnd );
+        if (data && data->wm_hints)
         {
             wine_tsx11_lock();
             data->wm_hints->input = !(new_style & WS_DISABLED);
@@ -357,7 +359,13 @@ BOOL X11DRV_SetWindowPos( HWND hwnd, HWND insert_after, const RECT *rectWindow,
                                 valid_rects, &visible_rect ))
         return FALSE;
 
-    if (!(data = X11DRV_get_win_data( hwnd ))) return FALSE;
+    new_style = GetWindowLongW( hwnd, GWL_STYLE );
+    if (!(data = X11DRV_get_win_data( hwnd )))
+    {
+        /* create the win data if the window is being made visible */
+        if (!(new_style & WS_VISIBLE)) return TRUE;
+        if (!(data = X11DRV_create_win_data( hwnd ))) return FALSE;
+    }
 
     /* check if we need to switch the window to managed */
     if (!data->managed && data->whole_window && managed_mode &&
@@ -376,7 +384,6 @@ BOOL X11DRV_SetWindowPos( HWND hwnd, HWND insert_after, const RECT *rectWindow,
         }
     }
 
-    new_style = GetWindowLongW( hwnd, GWL_STYLE );
     old_window_rect = data->window_rect;
     old_whole_rect  = data->whole_rect;
     old_client_rect = data->client_rect;
diff --git a/dlls/winex11.drv/x11drv.h b/dlls/winex11.drv/x11drv.h
index 5bcd76a..71ea670 100644
--- a/dlls/winex11.drv/x11drv.h
+++ b/dlls/winex11.drv/x11drv.h
@@ -682,6 +682,7 @@ struct x11drv_win_data
 };
 
 extern struct x11drv_win_data *X11DRV_get_win_data( HWND hwnd );
+extern struct x11drv_win_data *X11DRV_create_win_data( HWND hwnd );
 extern Window X11DRV_get_whole_window( HWND hwnd );
 extern XID X11DRV_get_fbconfig_id( HWND hwnd );
 extern Drawable X11DRV_get_gl_drawable( HWND hwnd );




More information about the wine-cvs mailing list