winex11.drv: Prepare for X11DRV_CreateWindow Factorization [1/2]

Pierre d'Herbemont pdherbemont at free.fr
Thu Dec 7 12:44:03 CST 2006


Hi,

Here the kind of fix you suggested for CreateWindow factorization. I 
have a few concern for this patch.

First Mac OS X/Xorg 6.5 doesn't pass `make test` I guess it's because my 
Xorg version is outdated.

However it passes user32 tests (that don't already fails on Mac OS X).

Second I am not sure you will like the 2/2 patch because it makes 
extensive use of USER_driver->pSetWindowPos. I am not sure that this is 
really sane. (that's why I broked this into two pieces)

I was thinking having a separate function in user32 to call wineserver's 
set_window_pos.

Pierre.
---
  dlls/winex11.drv/window.c |   82 
++++++++++++++++++++++++++------------------
  dlls/winex11.drv/winpos.c |   31 ++++++++++++-----
  dlls/winex11.drv/x11drv.h |    2 +-
  3 files changed, 71 insertions(+), 44 deletions(-)
-------------- next part --------------
diff --git a/dlls/winex11.drv/window.c b/dlls/winex11.drv/window.c
index 58b0c9c..5ff01e0 100644
--- a/dlls/winex11.drv/window.c
+++ b/dlls/winex11.drv/window.c
@@ -634,17 +634,17 @@ void X11DRV_set_iconic_state( HWND hwnd
  *
  * Convert a rect from client to X window coordinates
  */
-void X11DRV_window_to_X_rect( struct x11drv_win_data *data, RECT *rect )
+void X11DRV_window_to_X_rect( HWND hwnd, RECT *rect )
 {
     RECT rc;
 
-    if (!data->managed) return;
+    if (!is_window_managed(hwnd)) return;
     if (IsRectEmpty( rect )) return;
 
     rc.top = rc.bottom = rc.left = rc.right = 0;
 
-    AdjustWindowRectEx( &rc, GetWindowLongW( data->hwnd, GWL_STYLE ) & ~(WS_HSCROLL|WS_VSCROLL),
-                        FALSE, GetWindowLongW( data->hwnd, GWL_EXSTYLE ) );
+    AdjustWindowRectEx( &rc, GetWindowLongW( hwnd, GWL_STYLE ) & ~(WS_HSCROLL|WS_VSCROLL),
+                        FALSE, GetWindowLongW( hwnd, GWL_EXSTYLE ) );
 
     rect->left   -= rc.left;
     rect->right  -= rc.right;
@@ -756,7 +756,7 @@ static Window create_whole_window( Displ
     RECT rect;
 
     rect = data->window_rect;
-    X11DRV_window_to_X_rect( data, &rect );
+    X11DRV_window_to_X_rect( data->hwnd, &rect );
 
     if (!(cx = rect.right - rect.left)) cx = 1;
     if (!(cy = rect.bottom - rect.top)) cy = 1;
@@ -1006,16 +1006,16 @@ BOOL X11DRV_CreateWindow( HWND hwnd, CRE
 {
     Display *display = thread_display();
     WND *wndPtr;
-    struct x11drv_win_data *data;
+    struct x11drv_win_data *data = NULL;
     HWND insert_after;
     RECT rect;
+    RECT window, client;
+    LPWSTR text;
     DWORD style;
     CBT_CREATEWNDA cbtc;
     CREATESTRUCTA cbcs;
     BOOL ret = FALSE;
 
-    if (!(data = alloc_win_data( display, hwnd ))) return FALSE;
-
     if (cs->cx > 65535)
     {
         ERR( "invalid window width %d\n", cs->cx );
@@ -1041,19 +1041,6 @@ BOOL X11DRV_CreateWindow( HWND hwnd, CRE
     SetRect( &rect, cs->x, cs->y, cs->x + cs->cx, cs->y + cs->cy );
     X11DRV_SetWindowPos( hwnd, 0, &rect, &rect, SWP_NOZORDER, 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 );
-    }
-
-    /* get class or window DC if needed */
-    alloc_window_dce( data );
-
     /* Call the WH_CBT hook */
 
     /* the window style passed to the hook must be the real window style,
@@ -1098,31 +1085,26 @@ BOOL X11DRV_CreateWindow( HWND hwnd, CRE
         return FALSE;
     }
 
-    /* make sure the window is still valid */
-    if (!(data = X11DRV_get_win_data( hwnd ))) return FALSE;
-    if (data->whole_window) X11DRV_sync_window_style( display, data );
+    if (!(wndPtr = WIN_GetPtr(hwnd))) return FALSE;
 
     /* send WM_NCCALCSIZE */
-    rect = data->window_rect;
+    rect = wndPtr->rectWindow;
+    WIN_ReleasePtr( wndPtr );
+
     SendMessageW( hwnd, WM_NCCALCSIZE, FALSE, (LPARAM)&rect );
 
+    /* yes, even if the CBT hook was called with HWND_TOP */
     if (!(wndPtr = WIN_GetPtr(hwnd))) return FALSE;
 
-    /* yes, even if the CBT hook was called with HWND_TOP */
     insert_after = ((wndPtr->dwStyle & (WS_CHILD|WS_MAXIMIZE)) == WS_CHILD) ? HWND_BOTTOM : HWND_TOP;
 
     X11DRV_SetWindowPos( hwnd, insert_after, &wndPtr->rectWindow, &rect, 0, NULL );
 
-    TRACE( "win %p window %d,%d,%d,%d client %d,%d,%d,%d whole %d,%d,%d,%d X client %d,%d,%d,%d xwin %x\n",
+    TRACE( "win %p window %d,%d,%d,%d client %d,%d,%d,%d\n",
            hwnd, wndPtr->rectWindow.left, wndPtr->rectWindow.top,
            wndPtr->rectWindow.right, wndPtr->rectWindow.bottom,
            wndPtr->rectClient.left, wndPtr->rectClient.top,
-           wndPtr->rectClient.right, wndPtr->rectClient.bottom,
-           data->whole_rect.left, data->whole_rect.top,
-           data->whole_rect.right, data->whole_rect.bottom,
-           data->client_rect.left, data->client_rect.top,
-           data->client_rect.right, data->client_rect.bottom,
-           (unsigned int)data->whole_window );
+           wndPtr->rectClient.right, wndPtr->rectClient.bottom);
 
     WIN_ReleasePtr( wndPtr );
 
@@ -1152,8 +1134,40 @@ BOOL X11DRV_CreateWindow( HWND hwnd, CRE
     }
     else WIN_ReleasePtr( wndPtr );
 
-    /* Show the window, maximizing or minimizing if needed */
+    
+    if (!(data = alloc_win_data( display, hwnd ))) return FALSE;
+    
+    /* initialize the win data dimensions before calling create_whole_window/get_desktop_xwin */
+    if (!(wndPtr = WIN_GetPtr(hwnd)) || wndPtr == WND_OTHER_PROCESS) return FALSE;
+    window = wndPtr->rectWindow;
+    client = wndPtr->rectClient;
+    WIN_ReleasePtr( wndPtr );
+
+    X11DRV_SetWindowPos(hwnd, insert_after, &window, &client, SWP_NOZORDER, 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 );
+    }
+
+    /* get class or window DC if needed */
+    alloc_window_dce( data );
+    
+    /* Make sure we've updated the window title if SetWindowText was called
+       before alloc_win_data */
+    if (!(wndPtr = WIN_GetPtr(hwnd)) || wndPtr == WND_OTHER_PROCESS) return FALSE;
+    text = wndPtr->text;
+    WIN_ReleasePtr( wndPtr );
+    
+    if(text)
+        X11DRV_SetWindowText(hwnd, text);
 
+    /* Show the window, maximizing or minimizing if needed */
     style = GetWindowLongW( hwnd, GWL_STYLE );
     if (style & (WS_MINIMIZE | WS_MAXIMIZE))
     {
diff --git a/dlls/winex11.drv/winpos.c b/dlls/winex11.drv/winpos.c
index 5a88a74..3f889bc 100644
--- a/dlls/winex11.drv/winpos.c
+++ b/dlls/winex11.drv/winpos.c
@@ -234,18 +234,19 @@ BOOL X11DRV_SetWindowPos( HWND hwnd, HWN
     DWORD old_style, new_style;
     BOOL ret;
 
-    if (!(data = X11DRV_get_win_data( hwnd ))) return FALSE;
+    data = X11DRV_get_win_data( hwnd );
 
     new_whole_rect = *rectWindow;
-    X11DRV_window_to_X_rect( data, &new_whole_rect );
+    X11DRV_window_to_X_rect( hwnd, &new_whole_rect );
 
-    old_client_rect = data->client_rect;
+    if(data)
+        old_client_rect = data->client_rect;
 
     if (!IsRectEmpty( &valid_rects[0] ))
     {
         int x_offset = 0, y_offset = 0;
 
-        if (data->whole_window)
+        if (data && data->whole_window)
         {
             /* the X server will move the bits for us */
             x_offset = data->whole_rect.left - new_whole_rect.left;
@@ -258,6 +259,9 @@ BOOL X11DRV_SetWindowPos( HWND hwnd, HWN
             /* FIXME: should copy the window bits here */
             valid_rects = NULL;
         }
+        
+        if(!data)
+            valid_rects = NULL;
     }
 
     if (!(win = WIN_GetPtr( hwnd ))) return FALSE;
@@ -290,9 +294,10 @@ BOOL X11DRV_SetWindowPos( HWND hwnd, HWN
     }
     SERVER_END_REQ;
 
-    if (win == WND_DESKTOP || data->whole_window == DefaultRootWindow(gdi_display))
+    if (win == WND_DESKTOP || (data && data->whole_window == DefaultRootWindow(gdi_display)) )
     {
-        data->whole_rect = data->client_rect = data->window_rect = *rectWindow;
+        if(data)
+            data->whole_rect = data->client_rect = data->window_rect = *rectWindow;
         if (win != WND_DESKTOP)
         {
             win->rectWindow   = *rectWindow;
@@ -309,11 +314,12 @@ BOOL X11DRV_SetWindowPos( HWND hwnd, HWN
 
         /* invalidate DCEs */
 
-        if ((((swp_flags & SWP_AGG_NOPOSCHANGE) != SWP_AGG_NOPOSCHANGE) && (new_style & WS_VISIBLE)) ||
+        if ( (((swp_flags & SWP_AGG_NOPOSCHANGE) != SWP_AGG_NOPOSCHANGE) && (new_style & WS_VISIBLE)) ||
              (swp_flags & (SWP_HIDEWINDOW | SWP_SHOWWINDOW)))
         {
             RECT rect;
             UnionRect( &rect, rectWindow, &win->rectWindow );
+            
             invalidate_dce( hwnd, &rect );
         }
 
@@ -321,10 +327,17 @@ BOOL X11DRV_SetWindowPos( HWND hwnd, HWN
         win->rectClient   = *rectClient;
         old_style         = win->dwStyle;
         win->dwStyle      = new_style;
-        data->window_rect = *rectWindow;
-
+        
         TRACE( "win %p window %s client %s style %08x\n",
                hwnd, wine_dbgstr_rect(rectWindow), wine_dbgstr_rect(rectClient), new_style );
+        
+        if(!data)
+        {
+            WIN_ReleasePtr( win );
+            return ret;
+        }
+        
+        data->window_rect = *rectWindow;
 
         /* FIXME: copy the valid bits */
 
diff --git a/dlls/winex11.drv/x11drv.h b/dlls/winex11.drv/x11drv.h
index eb29a4e..c51bc9b 100644
--- a/dlls/winex11.drv/x11drv.h
+++ b/dlls/winex11.drv/x11drv.h
@@ -677,7 +677,7 @@ typedef int (*x11drv_error_callback)( Di
 extern void X11DRV_expect_error( Display *display, x11drv_error_callback callback, void *arg );
 extern int X11DRV_check_error(void);
 extern void X11DRV_set_iconic_state( HWND hwnd );
-extern void X11DRV_window_to_X_rect( struct x11drv_win_data *data, RECT *rect );
+extern void X11DRV_window_to_X_rect( HWND hwnd, RECT *rect );
 extern void X11DRV_X_to_window_rect( struct x11drv_win_data *data, RECT *rect );
 extern void X11DRV_sync_window_style( Display *display, struct x11drv_win_data *data );
 extern void X11DRV_sync_window_position( Display *display, struct x11drv_win_data *data,


More information about the wine-patches mailing list