[PATCH 5/5] user32: Factorization of graphics drivers' SetWindowPos
Pierre d'Herbemont
pdherbemont at free.fr
Tue Jan 23 09:35:47 CST 2007
In this patch we really need X11DRV_WINPOS_SetWindowPos function, which
does exactly the same thing as user32's WINPOS_SetWindowPos. Hopefully
this function should be removed as soon as the call to
X11DRV_WINPOS_SetWindowPos from CreateWindow are moved into user32. But
that will have to wait until the DCE code is moved into user32.
Pierre.
---
dlls/user32/driver.c | 6 +-
dlls/user32/user_private.h | 2 +-
dlls/user32/winpos.c | 75 ++++++++++++++++++-
dlls/winex11.drv/window.c | 6 +-
dlls/winex11.drv/winpos.c | 185
+++++++++++++++++++++++++-------------------
dlls/winex11.drv/x11drv.h | 4 +-
6 files changed, 189 insertions(+), 89 deletions(-)
-------------- next part --------------
diff --git a/dlls/user32/driver.c b/dlls/user32/driver.c
index c0591bd..bac9d0d 100644
--- a/dlls/user32/driver.c
+++ b/dlls/user32/driver.c
@@ -382,7 +382,7 @@ static void nulldrv_SetParent( HWND hwnd
}
static BOOL nulldrv_SetWindowPos( HWND hwnd, HWND insert_after, const RECT *rectWindow,
- const RECT *rectClient, UINT swp_flags, const RECT *valid_rects )
+ const RECT *rectClient, UINT swp_flags, DWORD new_style )
{
return FALSE;
}
@@ -713,9 +713,9 @@ static void loaderdrv_SetParent( HWND hw
}
static BOOL loaderdrv_SetWindowPos( HWND hwnd, HWND insert_after, const RECT *rectWindow,
- const RECT *rectClient, UINT swp_flags, const RECT *valid_rects )
+ const RECT *rectClient, UINT swp_flags, DWORD new_style )
{
- return load_driver()->pSetWindowPos( hwnd, insert_after, rectWindow, rectClient, swp_flags, valid_rects );
+ return load_driver()->pSetWindowPos( hwnd, insert_after, rectWindow, rectClient, swp_flags, new_style );
}
static int loaderdrv_SetWindowRgn( HWND hwnd, HRGN hrgn, BOOL redraw )
diff --git a/dlls/user32/user_private.h b/dlls/user32/user_private.h
index cbaaf6a..a47b664 100644
--- a/dlls/user32/user_private.h
+++ b/dlls/user32/user_private.h
@@ -151,7 +151,7 @@ typedef struct tagUSER_DRIVER {
BOOL (*pScrollDC)(HDC, INT, INT, const RECT *, const RECT *, HRGN, LPRECT);
void (*pSetFocus)(HWND);
void (*pSetParent)(HWND,HWND,HWND);
- BOOL (*pSetWindowPos)(HWND,HWND,const RECT *,const RECT *,UINT,const RECT *);
+ BOOL (*pSetWindowPos)(HWND,HWND,const RECT *,const RECT *,UINT,DWORD);
int (*pSetWindowRgn)(HWND,HRGN,BOOL);
void (*pSetWindowIcon)(HWND,UINT,HICON);
void (*pSetWindowStyle)(HWND,DWORD);
diff --git a/dlls/user32/winpos.c b/dlls/user32/winpos.c
index 46f9a26..f36fd30 100644
--- a/dlls/user32/winpos.c
+++ b/dlls/user32/winpos.c
@@ -1546,6 +1546,79 @@ static BOOL fixup_flags( WINDOWPOS *winp
}
/***********************************************************************
+ * WINPOS_SetWindowPos
+ *
+ * User32 internal function
+ */
+BOOL WINPOS_SetWindowPos( HWND hwnd, HWND insert_after, const RECT *rectWindow,
+ const RECT *rectClient, UINT swp_flags, const RECT *valid_rects )
+{
+ RECT new_whole_rect, old_whole_rect;
+ WND *win;
+ DWORD new_style;
+ BOOL ret;
+
+ new_whole_rect = *rectWindow;
+ ret = USER_Driver->pGetVisibleRect( hwnd, &old_whole_rect, &new_whole_rect );
+
+ if (!IsRectEmpty( &valid_rects[0] ))
+ {
+ int x_offset = 0, y_offset = 0;
+
+ if (ret)
+ {
+ /* the X server will move the bits for us */
+ x_offset = old_whole_rect.left - new_whole_rect.left;
+ y_offset = old_whole_rect.top - new_whole_rect.top;
+ }
+
+ if (x_offset != valid_rects[1].left - valid_rects[0].left ||
+ y_offset != valid_rects[1].top - valid_rects[0].top)
+ {
+ /* FIXME: should copy the window bits here */
+ valid_rects = NULL;
+ }
+ }
+
+ if (!(win = WIN_GetPtr( hwnd ))) return FALSE;
+ if (win == WND_OTHER_PROCESS)
+ {
+ if (IsWindow( hwnd )) ERR( "cannot set rectangles of other process window %p\n", hwnd );
+ return FALSE;
+ }
+ SERVER_START_REQ( set_window_pos )
+ {
+ req->handle = hwnd;
+ req->previous = insert_after;
+ req->flags = swp_flags;
+ req->window.left = rectWindow->left;
+ req->window.top = rectWindow->top;
+ req->window.right = rectWindow->right;
+ req->window.bottom = rectWindow->bottom;
+ req->client.left = rectClient->left;
+ req->client.top = rectClient->top;
+ req->client.right = rectClient->right;
+ req->client.bottom = rectClient->bottom;
+ if (memcmp( rectWindow, &new_whole_rect, sizeof(RECT) ) || !IsRectEmpty( &valid_rects[0] ))
+ {
+ wine_server_add_data( req, &new_whole_rect, sizeof(new_whole_rect) );
+ if (!IsRectEmpty( &valid_rects[0] ))
+ wine_server_add_data( req, valid_rects, 2 * sizeof(*valid_rects) );
+ }
+ ret = !wine_server_call( req );
+ new_style = reply->new_style;
+ }
+ SERVER_END_REQ;
+
+ WIN_ReleasePtr( win );
+
+ if (!ret)
+ return ret;
+
+ return USER_Driver->pSetWindowPos(hwnd, insert_after, rectWindow, rectClient, swp_flags, new_style);
+}
+
+/***********************************************************************
* USER_SetWindowPos
*
* User32 internal function
@@ -1588,7 +1661,7 @@ BOOL USER_SetWindowPos( WINDOWPOS * winp
SWP_DoNCCalcSize( winpos, &newWindowRect, &newClientRect, valid_rects );
- if(!USER_Driver->pSetWindowPos( winpos->hwnd, winpos->hwndInsertAfter,
+ if(!WINPOS_SetWindowPos( winpos->hwnd, winpos->hwndInsertAfter,
&newWindowRect, &newClientRect, orig_flags, valid_rects ))
return FALSE;
diff --git a/dlls/winex11.drv/window.c b/dlls/winex11.drv/window.c
index 32720cb..0003da2 100644
--- a/dlls/winex11.drv/window.c
+++ b/dlls/winex11.drv/window.c
@@ -1041,7 +1041,7 @@ BOOL X11DRV_CreateWindow( HWND hwnd, CRE
/* 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, NULL );
+ X11DRV_WINPOS_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())
@@ -1085,7 +1085,7 @@ BOOL X11DRV_CreateWindow( HWND hwnd, CRE
if (cs->cy < 0) cs->cy = 0;
SetRect( &rect, cs->x, cs->y, cs->x + cs->cx, cs->y + cs->cy );
- if (!X11DRV_SetWindowPos( hwnd, 0, &rect, &rect, SWP_NOZORDER, NULL )) return FALSE;
+ if (!X11DRV_WINPOS_SetWindowPos( hwnd, 0, &rect, &rect, SWP_NOZORDER, NULL )) return FALSE;
}
/* send WM_NCCREATE */
@@ -1113,7 +1113,7 @@ BOOL X11DRV_CreateWindow( HWND hwnd, CRE
/* yes, even if the CBT hook was called with HWND_TOP */
insert_after = (wndPtr->dwStyle & WS_CHILD) ? HWND_BOTTOM : HWND_TOP;
- X11DRV_SetWindowPos( hwnd, insert_after, &wndPtr->rectWindow, &rect, 0, NULL );
+ X11DRV_WINPOS_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",
hwnd, wndPtr->rectWindow.left, wndPtr->rectWindow.top,
diff --git a/dlls/winex11.drv/winpos.c b/dlls/winex11.drv/winpos.c
index 7592c64..3b16e7d 100644
--- a/dlls/winex11.drv/winpos.c
+++ b/dlls/winex11.drv/winpos.c
@@ -254,14 +254,17 @@ BOOL X11DRV_GetVisibleRect( HWND hwnd, R
}
/***********************************************************************
- * SetWindowPos (X11DRV.@)
+ * X11DRV_WINPOS_SetWindowPos
+ *
+ * FIXME: Temporary function that will disappear as soon as CreateWindow
+ * will be properly factorized into user32
*/
-BOOL X11DRV_SetWindowPos( HWND hwnd, HWND insert_after, const RECT *rectWindow,
+BOOL X11DRV_WINPOS_SetWindowPos( HWND hwnd, HWND insert_after, const RECT *rectWindow,
const RECT *rectClient, UINT swp_flags, const RECT *valid_rects )
{
- RECT new_whole_rect, old_whole_rect, old_screen_rect;
+ RECT new_whole_rect, old_whole_rect;
WND *win;
- DWORD old_style, new_style;
+ DWORD new_style;
BOOL ret;
new_whole_rect = *rectWindow;
@@ -316,107 +319,129 @@ BOOL X11DRV_SetWindowPos( HWND hwnd, HWN
}
SERVER_END_REQ;
+ WIN_ReleasePtr( win );
+
+ if (!ret)
+ return ret;
+
+ return X11DRV_SetWindowPos(hwnd, insert_after, rectWindow, rectClient, swp_flags, new_style);
+}
+
+/***********************************************************************
+ * SetWindowPos (X11DRV.@)
+ */
+BOOL X11DRV_SetWindowPos( HWND hwnd, HWND insert_after, const RECT *rectWindow,
+ const RECT *rectClient, UINT swp_flags, DWORD new_style )
+{
+ RECT new_whole_rect, old_client_rect, old_screen_rect;
+ Display *display = thread_display();
+ struct x11drv_win_data *data;
+ DWORD old_style;
+ WND *win;
- if (ret)
+ if (!(win = WIN_GetPtr( hwnd ))) return FALSE;
+ if (win == WND_OTHER_PROCESS)
{
- struct x11drv_win_data *data;
- Display *display = thread_display();
- RECT old_client_rect;
+ if (IsWindow( hwnd )) ERR( "cannot set rectangles of other process window %p\n", hwnd );
+ return FALSE;
+ }
- /* invalidate DCEs */
+ /* invalidate DCEs */
- 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 );
- }
+ 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 );
+ }
- old_style = win->dwStyle;
+ old_style = win->dwStyle;
- if (win != WND_DESKTOP)
- {
- win->rectWindow = *rectWindow;
- win->rectClient = *rectClient;
- win->dwStyle = new_style;
- }
+ if (win != WND_DESKTOP)
+ {
+ win->rectWindow = *rectWindow;
+ win->rectClient = *rectClient;
+ win->dwStyle = new_style;
+ }
- if (!(data = X11DRV_get_win_data( hwnd ))) return FALSE;
+ if (!(data = X11DRV_get_win_data( hwnd ))) return FALSE;
- if(hwnd == GetDesktopWindow() || data->whole_window == DefaultRootWindow(gdi_display))
- {
- data->whole_rect = data->client_rect = data->window_rect = *rectWindow;
- WIN_ReleasePtr( win );
- return ret;
- }
+ if (hwnd == GetDesktopWindow() || data->whole_window == DefaultRootWindow(gdi_display))
+ {
+ data->whole_rect = data->client_rect = data->window_rect = *rectWindow;
+ WIN_ReleasePtr( win );
+ return TRUE;
+ }
+
+ new_whole_rect = *rectWindow;
+ X11DRV_window_to_X_rect( data, &new_whole_rect );
+
+ old_client_rect = data->client_rect;
- old_client_rect = data->client_rect;
+ data->window_rect = *rectWindow;
- 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 );
+
+ /* FIXME: copy the valid bits */
+
+ if (data->whole_window && !data->lock_changes)
+ {
+ if ((old_style & WS_VISIBLE) && !(new_style & WS_VISIBLE))
+ {
+ /* window got hidden, unmap it */
+ TRACE( "unmapping win %p\n", hwnd );
+ wine_tsx11_lock();
+ XUnmapWindow( display, data->whole_window );
+ wine_tsx11_unlock();
+ }
+ else if ((new_style & WS_VISIBLE) && !X11DRV_is_window_rect_mapped( rectWindow ))
+ {
+ /* resizing to zero size or off screen -> unmap */
+ TRACE( "unmapping zero size or off-screen win %p\n", hwnd );
+ wine_tsx11_lock();
+ XUnmapWindow( display, data->whole_window );
+ wine_tsx11_unlock();
+ }
+ }
- TRACE( "win %p window %s client %s style %08x\n",
- hwnd, wine_dbgstr_rect(rectWindow), wine_dbgstr_rect(rectClient), new_style );
+ X11DRV_sync_window_position( display, data, swp_flags, rectClient, &new_whole_rect );
- /* FIXME: copy the valid bits */
+ if (data->whole_window && !data->lock_changes)
+ {
+ BOOL new_fs_state, mapped = FALSE;
- if (data->whole_window && !data->lock_changes)
+ if ((new_style & WS_VISIBLE) && !(new_style & WS_MINIMIZE) &&
+ X11DRV_is_window_rect_mapped( rectWindow ))
{
- if ((old_style & WS_VISIBLE) && !(new_style & WS_VISIBLE))
+ if (!(old_style & WS_VISIBLE))
{
- /* window got hidden, unmap it */
- TRACE( "unmapping win %p\n", hwnd );
+ /* window got shown, map it */
+ TRACE( "mapping win %p\n", hwnd );
+ X11DRV_sync_window_style( display, data );
+ X11DRV_set_wm_hints( display, data );
wine_tsx11_lock();
- XUnmapWindow( display, data->whole_window );
+ XMapWindow( display, data->whole_window );
wine_tsx11_unlock();
+ mapped = TRUE;
}
- else if ((new_style & WS_VISIBLE) && !X11DRV_is_window_rect_mapped( rectWindow ))
+ else if ((swp_flags & (SWP_NOSIZE | SWP_NOMOVE)) != (SWP_NOSIZE | SWP_NOMOVE))
{
- /* resizing to zero size or off screen -> unmap */
- TRACE( "unmapping zero size or off-screen win %p\n", hwnd );
+ /* resizing from zero size to non-zero -> map */
+ TRACE( "mapping non zero size or off-screen win %p\n", hwnd );
wine_tsx11_lock();
- XUnmapWindow( display, data->whole_window );
+ XMapWindow( display, data->whole_window );
wine_tsx11_unlock();
+ mapped = TRUE;
}
- }
-
- X11DRV_sync_window_position( display, data, swp_flags, rectClient, &new_whole_rect );
-
- if (data->whole_window && !data->lock_changes)
- {
- BOOL new_fs_state, mapped = FALSE;
-
- if ((new_style & WS_VISIBLE) && !(new_style & WS_MINIMIZE) &&
- X11DRV_is_window_rect_mapped( rectWindow ))
- {
- if (!(old_style & WS_VISIBLE))
- {
- /* window got shown, map it */
- TRACE( "mapping win %p\n", hwnd );
- X11DRV_sync_window_style( display, data );
- X11DRV_set_wm_hints( display, data );
- wine_tsx11_lock();
- XMapWindow( display, data->whole_window );
- wine_tsx11_unlock();
- mapped = TRUE;
- }
- else if ((swp_flags & (SWP_NOSIZE | SWP_NOMOVE)) != (SWP_NOSIZE | SWP_NOMOVE))
- {
- /* resizing from zero size to non-zero -> map */
- TRACE( "mapping non zero size or off-screen win %p\n", hwnd );
- wine_tsx11_lock();
- XMapWindow( display, data->whole_window );
- wine_tsx11_unlock();
- mapped = TRUE;
- }
- SetRect( &old_screen_rect, 0, 0, screen_width, screen_height );
- if (fullscreen_state_changed( data, &old_client_rect, &old_screen_rect, &new_fs_state ) || mapped)
- update_fullscreen_state( display, data->whole_window, new_fs_state );
- }
+ SetRect( &old_screen_rect, 0, 0, screen_width, screen_height );
+ if (fullscreen_state_changed( data, &old_client_rect, &old_screen_rect, &new_fs_state ) || mapped)
+ update_fullscreen_state( display, data->whole_window, new_fs_state );
}
}
WIN_ReleasePtr( win );
- return ret;
+ return TRUE;
}
diff --git a/dlls/winex11.drv/x11drv.h b/dlls/winex11.drv/x11drv.h
index dc1d955..4697199 100644
--- a/dlls/winex11.drv/x11drv.h
+++ b/dlls/winex11.drv/x11drv.h
@@ -685,8 +685,10 @@ extern void X11DRV_sync_window_style( Di
extern void X11DRV_sync_window_position( Display *display, struct x11drv_win_data *data,
UINT swp_flags, const RECT *new_client_rect,
const RECT *new_whole_rect );
+extern BOOL X11DRV_WINPOS_SetWindowPos( HWND hwnd, HWND insert_after, const RECT *rectWindow,
+ const RECT *rectClient, UINT swp_flags, const RECT *valid_rects );
extern BOOL X11DRV_SetWindowPos( HWND hwnd, HWND insert_after, const RECT *rectWindow,
- const RECT *rectClient, UINT swp_flags, const RECT *validRects );
+ const RECT *rectClient, UINT swp_flags, DWORD new_style );
extern void X11DRV_set_wm_hints( Display *display, struct x11drv_win_data *data );
extern void xinerama_init(void);
More information about the wine-patches
mailing list