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