From 1ce36987eba0a9310f3e0ac6bd55148ededca7c6 Mon Sep 17 00:00:00 2001 From: Alexandre Julliard Date: Mon, 12 Feb 2018 15:49:23 +0100 Subject: [PATCH] winex11: Use the client window support also for XComposite child windows. Signed-off-by: Alexandre Julliard --- dlls/winex11.drv/opengl.c | 62 ++++--------------------- dlls/winex11.drv/window.c | 116 +++++++++++++++++++++++++++------------------- dlls/winex11.drv/x11drv.h | 4 +- 3 files changed, 80 insertions(+), 102 deletions(-) diff --git a/dlls/winex11.drv/opengl.c b/dlls/winex11.drv/opengl.c index e6708faab64..06964422594 100644 --- a/dlls/winex11.drv/opengl.c +++ b/dlls/winex11.drv/opengl.c @@ -259,7 +259,6 @@ struct gl_drawable GLXDrawable drawable; /* drawable for rendering with GL */ Window window; /* window if drawable is a GLXWindow */ Pixmap pixmap; /* base pixmap if drawable is a GLXPixmap */ - Colormap colormap; /* colormap used for the drawable */ const struct wgl_pixel_format *format; /* pixel format for the drawable */ SIZE pixmap_size; /* pixmap size for GLXPixmap drawables */ int swap_interval; @@ -1234,7 +1233,6 @@ static void release_gl_drawable( struct gl_drawable *gl ) TRACE( "destroying %lx drawable %lx\n", gl->window, gl->drawable ); pglXDestroyWindow( gdi_display, gl->drawable ); XDestroyWindow( gdi_display, gl->window ); - if (gl->colormap) XFreeColormap( gdi_display, gl->colormap ); break; case DC_GL_PIXMAP_WIN: TRACE( "destroying pixmap %lx drawable %lx\n", gl->pixmap, gl->drawable ); @@ -1398,56 +1396,22 @@ static struct gl_drawable *create_gl_drawable( HWND hwnd, const struct wgl_pixel if (GetAncestor( hwnd, GA_PARENT ) == GetDesktopWindow()) /* top-level window */ { - struct x11drv_win_data *data = get_win_data( hwnd ); - - if (data) - { - gl->type = DC_GL_WINDOW; - gl->window = create_client_window( data, visual ); - if (gl->window) - gl->drawable = pglXCreateWindow( gdi_display, gl->format->fbconfig, gl->window, NULL ); - release_win_data( data ); - TRACE( "%p created client %lx drawable %lx\n", hwnd, gl->window, gl->drawable ); - } + gl->type = DC_GL_WINDOW; + gl->window = create_client_window( hwnd, visual ); + if (gl->window) + gl->drawable = pglXCreateWindow( gdi_display, gl->format->fbconfig, gl->window, NULL ); + TRACE( "%p created client %lx drawable %lx\n", hwnd, gl->window, gl->drawable ); } #ifdef SONAME_LIBXCOMPOSITE else if(usexcomposite) { - static Window dummy_parent; - XSetWindowAttributes attrib; - - attrib.override_redirect = True; - attrib.border_pixel = 0; - if (!dummy_parent) - { - attrib.colormap = default_colormap; - dummy_parent = XCreateWindow( gdi_display, root_window, -1, -1, 1, 1, 0, default_visual.depth, - InputOutput, default_visual.visual, - CWColormap | CWBorderPixel | CWOverrideRedirect, &attrib ); - XMapWindow( gdi_display, dummy_parent ); - } - gl->colormap = XCreateColormap(gdi_display, dummy_parent, visual->visual, - (visual->class == PseudoColor || - visual->class == GrayScale || - visual->class == DirectColor) ? - AllocAll : AllocNone); - attrib.colormap = gl->colormap; - XInstallColormap(gdi_display, attrib.colormap); - gl->type = DC_GL_CHILD_WIN; - gl->window = XCreateWindow( gdi_display, dummy_parent, 0, 0, width, height, - 0, visual->depth, InputOutput, visual->visual, - CWColormap | CWBorderPixel | CWOverrideRedirect, &attrib ); + gl->window = create_client_window( hwnd, visual ); if (gl->window) { gl->drawable = pglXCreateWindow( gdi_display, gl->format->fbconfig, gl->window, NULL ); - if (gl->drawable) - { - pXCompositeRedirectWindow(gdi_display, gl->window, CompositeRedirectManual); - XMapWindow(gdi_display, gl->window); - } + pXCompositeRedirectWindow( gdi_display, gl->window, CompositeRedirectManual ); } - else XFreeColormap( gdi_display, gl->colormap ); TRACE( "%p created child %lx drawable %lx\n", hwnd, gl->window, gl->drawable ); } #endif @@ -1552,22 +1516,14 @@ static BOOL set_pixel_format(HDC hdc, int format, BOOL allow_change) /*********************************************************************** * sync_gl_drawable */ -void sync_gl_drawable( HWND hwnd, int width, int height ) +void sync_gl_drawable( HWND hwnd ) { struct gl_drawable *old, *new; - XWindowChanges changes; if (!(old = get_gl_drawable( hwnd, 0 ))) return; - TRACE( "setting drawable %lx size %dx%d\n", old->drawable, width, height ); - switch (old->type) { - case DC_GL_CHILD_WIN: - changes.width = min( max( 1, width ), 65535 ); - changes.height = min( max( 1, height ), 65535 ); - XConfigureWindow( gdi_display, old->window, CWWidth | CWHeight, &changes ); - break; case DC_GL_PIXMAP_WIN: if (!(new = create_gl_drawable( hwnd, old->format ))) break; mark_drawable_dirty( old, new ); @@ -3452,7 +3408,7 @@ struct opengl_funcs *get_glx_driver( UINT version ) return NULL; } -void sync_gl_drawable( HWND hwnd, int width, int height ) +void sync_gl_drawable( HWND hwnd ) { } diff --git a/dlls/winex11.drv/window.c b/dlls/winex11.drv/window.c index 568f34fc81d..6d79f065498 100644 --- a/dlls/winex11.drv/window.c +++ b/dlls/winex11.drv/window.c @@ -196,6 +196,26 @@ static BOOL has_owned_popups( HWND hwnd ) return result.found; } + +/*********************************************************************** + * alloc_win_data + */ +static struct x11drv_win_data *alloc_win_data( Display *display, HWND hwnd ) +{ + struct x11drv_win_data *data; + + if ((data = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*data)))) + { + data->display = display; + data->vis = default_visual; + data->hwnd = hwnd; + EnterCriticalSection( &win_data_section ); + XSaveContext( gdi_display, (XID)hwnd, win_data_context, (char *)data ); + } + return data; +} + + /*********************************************************************** * is_window_managed * @@ -1418,14 +1438,23 @@ static Window get_dummy_parent(void) /********************************************************************** * create_client_window */ -Window create_client_window( struct x11drv_win_data *data, const XVisualInfo *visual ) +Window create_client_window( HWND hwnd, const XVisualInfo *visual ) { Window dummy_parent = get_dummy_parent(); + struct x11drv_win_data *data = get_win_data( hwnd ); XSetWindowAttributes attr; - int x = data->client_rect.left - data->whole_rect.left; - int y = data->client_rect.top - data->whole_rect.top; - int cx = min( max( 1, data->client_rect.right - data->client_rect.left ), 65535 ); - int cy = min( max( 1, data->client_rect.bottom - data->client_rect.top ), 65535 ); + Window ret; + int x, y, cx, cy; + + if (!data) + { + /* explicitly create data for HWND_MESSAGE windows since they can be used for OpenGL */ + HWND parent = GetAncestor( hwnd, GA_PARENT ); + if (parent == GetDesktopWindow() || GetAncestor( parent, GA_PARENT )) return 0; + if (!(data = alloc_win_data( thread_init_display(), hwnd ))) return 0; + GetClientRect( hwnd, &data->client_rect ); + data->window_rect = data->whole_rect = data->client_rect; + } if (data->client_window) { @@ -1445,18 +1474,26 @@ Window create_client_window( struct x11drv_win_data *data, const XVisualInfo *vi attr.backing_store = NotUseful; attr.border_pixel = 0; - data->client_window = XCreateWindow( gdi_display, data->whole_window, x, y, cx, cy, - 0, default_visual.depth, InputOutput, visual->visual, - CWBitGravity | CWWinGravity | CWBackingStore | - CWColormap | CWBorderPixel, &attr ); - if (!data->client_window) return 0; - TRACE( "%p xwin %lx/%lx\n", data->hwnd, data->whole_window, data->client_window ); + x = data->client_rect.left - data->whole_rect.left; + y = data->client_rect.top - data->whole_rect.top; + cx = min( max( 1, data->client_rect.right - data->client_rect.left ), 65535 ); + cy = min( max( 1, data->client_rect.bottom - data->client_rect.top ), 65535 ); - XSaveContext( data->display, data->client_window, winContext, (char *)data->hwnd ); - XMapWindow( gdi_display, data->client_window ); - XSync( gdi_display, False ); - XSelectInput( data->display, data->client_window, ExposureMask ); - return data->client_window; + ret = data->client_window = XCreateWindow( gdi_display, + data->whole_window ? data->whole_window : dummy_parent, + x, y, cx, cy, 0, default_visual.depth, InputOutput, + visual->visual, CWBitGravity | CWWinGravity | + CWBackingStore | CWColormap | CWBorderPixel, &attr ); + if (data->client_window) + { + XSaveContext( data->display, data->client_window, winContext, (char *)data->hwnd ); + XMapWindow( gdi_display, data->client_window ); + XSync( gdi_display, False ); + if (data->whole_window) XSelectInput( data->display, data->client_window, ExposureMask ); + TRACE( "%p xwin %lx/%lx\n", data->hwnd, data->whole_window, data->client_window ); + } + release_win_data( data ); + return ret; } @@ -1540,6 +1577,10 @@ done: */ static void destroy_whole_window( struct x11drv_win_data *data, BOOL already_destroyed ) { + TRACE( "win %p xwin %lx/%lx\n", data->hwnd, data->whole_window, data->client_window ); + + if (data->client_window) XDeleteContext( data->display, data->client_window, winContext ); + if (!data->whole_window) { if (data->embedded) @@ -1551,23 +1592,20 @@ static void destroy_whole_window( struct x11drv_win_data *data, BOOL already_des XDeleteContext( data->display, xwin, winContext ); RemovePropA( data->hwnd, foreign_window_prop ); } + return; } - return; } - - - TRACE( "win %p xwin %lx/%lx\n", data->hwnd, data->whole_window, data->client_window ); - XDeleteContext( data->display, data->whole_window, winContext ); - if (data->client_window) + else { - XDeleteContext( data->display, data->client_window, winContext ); - if (!already_destroyed) + if (data->client_window && !already_destroyed) { XSelectInput( data->display, data->client_window, 0 ); XReparentWindow( data->display, data->client_window, get_dummy_parent(), 0, 0 ); + XSync( data->display, False ); } + XDeleteContext( data->display, data->whole_window, winContext ); + if (!already_destroyed) XDestroyWindow( data->display, data->whole_window ); } - if (!already_destroyed) XDestroyWindow( data->display, data->whole_window ); if (data->colormap) XFreeColormap( data->display, data->colormap ); data->whole_window = data->client_window = 0; data->colormap = 0; @@ -1703,22 +1741,6 @@ BOOL X11DRV_DestroyNotify( HWND hwnd, XEvent *event ) } -static struct x11drv_win_data *alloc_win_data( Display *display, HWND hwnd ) -{ - struct x11drv_win_data *data; - - if ((data = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*data)))) - { - data->display = display; - data->vis = default_visual; - data->hwnd = hwnd; - EnterCriticalSection( &win_data_section ); - XSaveContext( gdi_display, (XID)hwnd, win_data_context, (char *)data ); - } - return data; -} - - /* initialize the desktop window id in the desktop manager process */ BOOL create_desktop_win_data( Window win ) { @@ -2342,13 +2364,13 @@ void CDECL X11DRV_WindowPosChanged( HWND hwnd, HWND insert_after, UINT swp_flags if (!data->whole_window) { - int width = data->client_rect.right - data->client_rect.left; - int height = data->client_rect.bottom - data->client_rect.top; - + BOOL needs_resize = (!data->client_window && + (data->client_rect.right - data->client_rect.left != + old_client_rect.right - old_client_rect.left || + data->client_rect.bottom - data->client_rect.top != + old_client_rect.bottom - old_client_rect.top)); release_win_data( data ); - if (width != old_client_rect.right - old_client_rect.left || - height != old_client_rect.bottom - old_client_rect.top) - sync_gl_drawable( hwnd, width, height ); + if (needs_resize) sync_gl_drawable( hwnd ); return; } diff --git a/dlls/winex11.drv/x11drv.h b/dlls/winex11.drv/x11drv.h index 0b802763070..72036279c60 100644 --- a/dlls/winex11.drv/x11drv.h +++ b/dlls/winex11.drv/x11drv.h @@ -579,7 +579,7 @@ extern void release_win_data( struct x11drv_win_data *data ) DECLSPEC_HIDDEN; extern Window X11DRV_get_whole_window( HWND hwnd ) DECLSPEC_HIDDEN; extern XIC X11DRV_get_ic( HWND hwnd ) DECLSPEC_HIDDEN; -extern void sync_gl_drawable( HWND hwnd, int width, int height ) DECLSPEC_HIDDEN; +extern void sync_gl_drawable( HWND hwnd ) DECLSPEC_HIDDEN; extern void set_gl_drawable_parent( HWND hwnd, HWND parent ) DECLSPEC_HIDDEN; extern void destroy_gl_drawable( HWND hwnd ) DECLSPEC_HIDDEN; @@ -589,7 +589,7 @@ extern void update_user_time( Time time ) DECLSPEC_HIDDEN; extern void read_net_wm_states( Display *display, struct x11drv_win_data *data ) DECLSPEC_HIDDEN; extern void update_net_wm_states( struct x11drv_win_data *data ) DECLSPEC_HIDDEN; extern void make_window_embedded( struct x11drv_win_data *data ) DECLSPEC_HIDDEN; -extern Window create_client_window( struct x11drv_win_data *data, const XVisualInfo *visual ) DECLSPEC_HIDDEN; +extern Window create_client_window( HWND hwnd, const XVisualInfo *visual ) DECLSPEC_HIDDEN; extern void set_window_visual( struct x11drv_win_data *data, const XVisualInfo *vis, BOOL use_alpha ) DECLSPEC_HIDDEN; extern void change_systray_owner( Display *display, Window systray_window ) DECLSPEC_HIDDEN; extern void update_systray_balloon_position(void) DECLSPEC_HIDDEN; -- 2.11.4.GIT