From c19af910ebafa9b1928b0f67bee68f6b0b237e8e Mon Sep 17 00:00:00 2001 From: Alexandre Julliard Date: Thu, 17 Jan 2008 19:53:59 +0100 Subject: [PATCH] winex11.drv: Don't create a win_data structure for the desktop window, except in the process that owns it. Handle desktop size changes by sending a message to the desktop owner. --- dlls/winex11.drv/desktop.c | 35 ------------ dlls/winex11.drv/event.c | 3 + dlls/winex11.drv/window.c | 106 ++++++++++++++++++++---------------- dlls/winex11.drv/winpos.c | 28 ++++++---- dlls/winex11.drv/x11drv.h | 5 +- dlls/winex11.drv/xrandr.c | 2 +- dlls/winex11.drv/xvidmode.c | 3 +- 7 files changed, 85 insertions(+), 97 deletions(-) diff --git a/dlls/winex11.drv/desktop.c b/dlls/winex11.drv/desktop.c index 9fb710a0b2e..1ec6a5dd534 100644 --- a/dlls/winex11.drv/desktop.c +++ b/dlls/winex11.drv/desktop.c @@ -68,41 +68,6 @@ static void make_modes(void) } } -/*********************************************************************** - * X11DRV_resize_desktop - * - * Reset the desktop window size and WM hints - */ -static int X11DRV_resize_desktop( unsigned int width, unsigned int height ) -{ - XSizeHints *size_hints; - Display *display = thread_display(); - Window w = root_window; - /* set up */ - wine_tsx11_lock(); - size_hints = XAllocSizeHints(); - if (!size_hints) - { - ERR("Not enough memory for window manager hints.\n" ); - wine_tsx11_unlock(); - return 0; - } - size_hints->min_width = size_hints->max_width = width; - size_hints->min_height = size_hints->max_height = height; - size_hints->flags = PMinSize | PMaxSize | PSize; - - /* do the work */ - XSetWMNormalHints( display, w, size_hints ); - XResizeWindow( display, w, width, height ); - - /* clean up */ - XFree( size_hints ); - XFlush( display ); - wine_tsx11_unlock(); - X11DRV_handle_desktop_resize( width, height ); - return 1; -} - static int X11DRV_desktop_GetCurrentMode(void) { unsigned int i; diff --git a/dlls/winex11.drv/event.c b/dlls/winex11.drv/event.c index 726ff3ec84a..8e7eba45b84 100644 --- a/dlls/winex11.drv/event.c +++ b/dlls/winex11.drv/event.c @@ -964,6 +964,9 @@ LRESULT X11DRV_WindowMessage( HWND hwnd, UINT msg, WPARAM wp, LPARAM lp ) return SendMessageW( hwnd, WM_SYSCOMMAND, SC_CLOSE, 0 ); case WM_X11DRV_SET_WIN_FORMAT: return X11DRV_set_win_format( hwnd, (XID)wp ); + case WM_X11DRV_RESIZE_DESKTOP: + X11DRV_resize_desktop( LOWORD(lp), HIWORD(lp) ); + return 0; default: FIXME( "got window msg %x hwnd %p wp %lx lp %lx\n", msg, hwnd, wp, lp ); return 0; diff --git a/dlls/winex11.drv/window.c b/dlls/winex11.drv/window.c index 7348f2a62ea..e39a5cec9c3 100644 --- a/dlls/winex11.drv/window.c +++ b/dlls/winex11.drv/window.c @@ -998,6 +998,9 @@ void X11DRV_sync_window_position( Display *display, struct x11drv_win_data *data } } + /* only the size is allowed to change for the desktop window */ + if (data->whole_window == root_window) mask &= CWWidth | CWHeight; + if (mask) { DWORD style = GetWindowLongW( data->hwnd, GWL_STYLE ); @@ -1225,46 +1228,27 @@ static struct x11drv_win_data *alloc_win_data( Display *display, HWND hwnd ) } -/* fill in the desktop X window id in the x11drv_win_data structure */ +/* initialize the desktop window id in the desktop manager process */ static void get_desktop_xwin( Display *display, struct x11drv_win_data *data ) { - Window win = (Window)GetPropA( data->hwnd, whole_window_prop ); - - if (win) - { - unsigned int width, height; - - /* retrieve the real size of the desktop */ - SERVER_START_REQ( get_window_rectangles ) - { - req->handle = data->hwnd; - wine_server_call( req ); - width = reply->window.right - reply->window.left; - height = reply->window.bottom - reply->window.top; - } - SERVER_END_REQ; - data->whole_window = win; - if (win != root_window) X11DRV_init_desktop( win, width, height ); - } - else + data->whole_window = root_window; + if (root_window != DefaultRootWindow( display )) { VisualID visualid; wine_tsx11_lock(); visualid = XVisualIDFromVisual(visual); wine_tsx11_unlock(); + data->managed = TRUE; + SetPropA( data->hwnd, managed_prop, (HANDLE)1 ); SetPropA( data->hwnd, whole_window_prop, (HANDLE)root_window ); SetPropA( data->hwnd, visual_id_prop, (HANDLE)visualid ); - data->whole_window = root_window; - X11DRV_SetWindowPos( data->hwnd, 0, &virtual_screen_rect, &virtual_screen_rect, - SWP_NOZORDER | SWP_NOACTIVATE, NULL ); - if (root_window != DefaultRootWindow( display )) - { - data->managed = TRUE; - SetPropA( data->hwnd, managed_prop, (HANDLE)1 ); - set_initial_wm_hints( display, data ); - } + set_initial_wm_hints( display, data ); } + SetWindowPos( data->hwnd, 0, virtual_screen_rect.left, virtual_screen_rect.top, + virtual_screen_rect.right - virtual_screen_rect.left, + virtual_screen_rect.bottom - virtual_screen_rect.top, + SWP_NOZORDER | SWP_NOACTIVATE ); } /********************************************************************** @@ -1272,13 +1256,39 @@ static void get_desktop_xwin( Display *display, struct x11drv_win_data *data ) */ BOOL X11DRV_CreateDesktopWindow( HWND hwnd ) { - Display *display = thread_display(); - struct x11drv_win_data *data; + unsigned int width, height; - if (!(data = alloc_win_data( display, hwnd ))) return FALSE; - - get_desktop_xwin( display, data ); + /* retrieve the real size of the desktop */ + SERVER_START_REQ( get_window_rectangles ) + { + req->handle = hwnd; + wine_server_call( req ); + width = reply->window.right - reply->window.left; + height = reply->window.bottom - reply->window.top; + } + SERVER_END_REQ; + if (!width && !height) /* not initialized yet */ + { + SERVER_START_REQ( set_window_pos ) + { + req->handle = hwnd; + req->previous = 0; + req->flags = SWP_NOZORDER; + req->window.left = virtual_screen_rect.left; + req->window.top = virtual_screen_rect.top; + req->window.right = virtual_screen_rect.right; + req->window.bottom = virtual_screen_rect.bottom; + req->client = req->window; + wine_server_call( req ); + } + SERVER_END_REQ; + } + else + { + Window win = (Window)GetPropA( hwnd, whole_window_prop ); + if (win && win != root_window) X11DRV_init_desktop( win, width, height ); + } return TRUE; } @@ -1321,18 +1331,18 @@ BOOL X11DRV_CreateWindow( HWND hwnd, CREATESTRUCTA *cs, BOOL unicode ) cs->cy = 0; } - /* 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 | SWP_NOACTIVATE, NULL ); + if (hwnd == GetDesktopWindow()) get_desktop_xwin( display, data ); + else + { + /* 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 | SWP_NOACTIVATE, 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 ); + /* 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; + } } /* get class or window DC if needed */ @@ -1493,7 +1503,11 @@ Window X11DRV_get_whole_window( HWND hwnd ) { struct x11drv_win_data *data = X11DRV_get_win_data( hwnd ); - if (!data) return (Window)GetPropA( hwnd, whole_window_prop ); + if (!data) + { + if (hwnd == GetDesktopWindow()) return root_window; + return (Window)GetPropA( hwnd, whole_window_prop ); + } return data->whole_window; } diff --git a/dlls/winex11.drv/winpos.c b/dlls/winex11.drv/winpos.c index 3b148c669cb..39ac43a3aa4 100644 --- a/dlls/winex11.drv/winpos.c +++ b/dlls/winex11.drv/winpos.c @@ -873,30 +873,36 @@ static BOOL CALLBACK update_windows_on_desktop_resize( HWND hwnd, LPARAM lparam /*********************************************************************** - * X11DRV_handle_desktop_resize + * X11DRV_resize_desktop */ -void X11DRV_handle_desktop_resize( unsigned int width, unsigned int height ) +void X11DRV_resize_desktop( unsigned int width, unsigned int height ) { HWND hwnd = GetDesktopWindow(); struct x11drv_win_data *data; struct desktop_resize_data resize_data; - if (!(data = X11DRV_get_win_data( hwnd ))) return; - SetRect( &resize_data.old_screen_rect, 0, 0, screen_width, screen_height ); resize_data.old_virtual_rect = virtual_screen_rect; screen_width = width; screen_height = height; xinerama_init(); - TRACE("desktop %p change to (%dx%d)\n", hwnd, width, height); - data->lock_changes++; - X11DRV_SetWindowPos( hwnd, 0, &virtual_screen_rect, &virtual_screen_rect, - SWP_NOZORDER | SWP_NOMOVE | SWP_NOACTIVATE, NULL ); - data->lock_changes--; ClipCursor(NULL); - SendMessageTimeoutW( HWND_BROADCAST, WM_DISPLAYCHANGE, screen_bpp, - MAKELPARAM( width, height ), SMTO_ABORTIFHUNG, 2000, NULL ); + + if (!(data = X11DRV_get_win_data( hwnd ))) + { + SendMessageW( hwnd, WM_X11DRV_RESIZE_DESKTOP, 0, MAKELPARAM( width, height ) ); + } + else + { + TRACE( "desktop %p change to (%dx%d)\n", hwnd, width, height ); + SetWindowPos( hwnd, 0, virtual_screen_rect.left, virtual_screen_rect.top, + virtual_screen_rect.right - virtual_screen_rect.left, + virtual_screen_rect.bottom - virtual_screen_rect.top, + SWP_NOZORDER | SWP_NOACTIVATE ); + SendMessageTimeoutW( HWND_BROADCAST, WM_DISPLAYCHANGE, screen_bpp, + MAKELPARAM( width, height ), SMTO_ABORTIFHUNG, 2000, NULL ); + } EnumWindows( update_windows_on_desktop_resize, (LPARAM)&resize_data ); } diff --git a/dlls/winex11.drv/x11drv.h b/dlls/winex11.drv/x11drv.h index 33289814c34..6f71b75f9ba 100644 --- a/dlls/winex11.drv/x11drv.h +++ b/dlls/winex11.drv/x11drv.h @@ -644,7 +644,8 @@ enum x11drv_window_messages { WM_X11DRV_ACQUIRE_SELECTION = 0x80001000, WM_X11DRV_DELETE_WINDOW, - WM_X11DRV_SET_WIN_FORMAT + WM_X11DRV_SET_WIN_FORMAT, + WM_X11DRV_RESIZE_DESKTOP }; /* _NET_WM_STATE properties that we keep track of */ @@ -733,7 +734,7 @@ extern void X11DRV_set_wm_hints( Display *display, struct x11drv_win_data *data extern void xinerama_init(void); extern void X11DRV_init_desktop( Window win, unsigned int width, unsigned int height ); -extern void X11DRV_handle_desktop_resize(unsigned int width, unsigned int height); +extern void X11DRV_resize_desktop(unsigned int width, unsigned int height); extern void X11DRV_Settings_AddDepthModes(void); extern void X11DRV_Settings_AddOneMode(unsigned int width, unsigned int height, unsigned int bpp, unsigned int freq); extern int X11DRV_Settings_CreateDriver(LPDDHALINFO info); diff --git a/dlls/winex11.drv/xrandr.c b/dlls/winex11.drv/xrandr.c index ad2dc0886e4..fd930a262db 100644 --- a/dlls/winex11.drv/xrandr.c +++ b/dlls/winex11.drv/xrandr.c @@ -229,7 +229,7 @@ static LONG X11DRV_XRandR_SetCurrentMode(int mode) wine_tsx11_unlock(); if (stat == RRSetConfigSuccess) { - X11DRV_handle_desktop_resize( dd_modes[mode].dwWidth, dd_modes[mode].dwHeight ); + X11DRV_resize_desktop( dd_modes[mode].dwWidth, dd_modes[mode].dwHeight ); return DISP_CHANGE_SUCCESSFUL; } diff --git a/dlls/winex11.drv/xvidmode.c b/dlls/winex11.drv/xvidmode.c index 49c48b3f85c..2c963d6a619 100644 --- a/dlls/winex11.drv/xvidmode.c +++ b/dlls/winex11.drv/xvidmode.c @@ -131,8 +131,7 @@ static LONG X11DRV_XF86VM_SetCurrentMode(int mode) #endif XSync(gdi_display, False); wine_tsx11_unlock(); - X11DRV_handle_desktop_resize( real_xf86vm_modes[mode]->hdisplay, - real_xf86vm_modes[mode]->vdisplay ); + X11DRV_resize_desktop( real_xf86vm_modes[mode]->hdisplay, real_xf86vm_modes[mode]->vdisplay ); return DISP_CHANGE_SUCCESSFUL; }