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