Commit c19af910 authored by Alexandre Julliard's avatar Alexandre Julliard

winex11.drv: Don't create a win_data structure for the desktop window, except in…

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.
parent a9e96734
......@@ -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;
......
......@@ -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;
......
......@@ -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 );
/* 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())
if (hwnd == GetDesktopWindow()) get_desktop_xwin( display, data );
else
{
get_desktop_xwin( display, data );
/* 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;
}
}
/* 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;
}
......
......@@ -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 );
}
......
......@@ -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);
......
......@@ -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;
}
......
......@@ -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;
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment