From: Rémi Bernon rbernon@codeweavers.com
--- dlls/winex11.drv/init.c | 37 ++++++++++++++++++--------- dlls/winex11.drv/opengl.c | 53 ++++++++++++++++++++++----------------- dlls/winex11.drv/vulkan.c | 2 +- dlls/winex11.drv/x11drv.h | 4 ++- 4 files changed, 59 insertions(+), 37 deletions(-)
diff --git a/dlls/winex11.drv/init.c b/dlls/winex11.drv/init.c index 039c4b0fefd..98964430a20 100644 --- a/dlls/winex11.drv/init.c +++ b/dlls/winex11.drv/init.c @@ -261,6 +261,7 @@ static const struct client_surface_funcs x11drv_client_surface_funcs; struct x11drv_client_surface { struct client_surface client; + Colormap colormap; Window window; RECT rect;
@@ -280,6 +281,7 @@ static void x11drv_client_surface_destroy( struct client_surface *client )
TRACE( "%s\n", debugstr_client_surface( client ) );
+ if (surface->colormap != default_colormap) XFreeColormap( gdi_display, surface->colormap ); if (surface->window) destroy_client_window( hwnd, surface->window ); if (surface->hdc_dst) NtGdiDeleteObjectApp( surface->hdc_dst ); if (surface->hdc_src) NtGdiDeleteObjectApp( surface->hdc_src ); @@ -426,25 +428,36 @@ static const struct client_surface_funcs x11drv_client_surface_funcs = .present = X11DRV_client_surface_present, };
-Window x11drv_client_surface_create( HWND hwnd, const XVisualInfo *visual, Colormap colormap, struct client_surface **client ) +static int visual_class_alloc( int class ) +{ + return class == PseudoColor || class == GrayScale || class == DirectColor ? AllocAll : AllocNone; +} + +Window x11drv_client_surface_create( HWND hwnd, int format, struct client_surface **client ) { struct x11drv_client_surface *surface; + XVisualInfo visual = default_visual; + Colormap colormap;
- if (!(surface = client_surface_create( sizeof(*surface), &x11drv_client_surface_funcs, hwnd ))) return None; - if (!(surface->window = create_client_window( hwnd, visual, colormap ))) - { - client_surface_release( &surface->client ); - return None; - } - if (!NtUserGetClientRect( hwnd, &surface->rect, NtUserGetDpiForWindow( hwnd ) )) - { - client_surface_release( &surface->client ); - return None; - } + if (format && !visual_from_pixel_format( format, &visual )) return None; + + if (visual.visualid == default_visual.visualid) colormap = default_colormap; + else colormap = XCreateColormap( gdi_display, get_dummy_parent(), visual.visual, visual_class_alloc( visual.class ) ); + if (!colormap) return None; + + if (!(surface = client_surface_create( sizeof(*surface), &x11drv_client_surface_funcs, hwnd ))) goto failed; + if (!(surface->window = create_client_window( hwnd, &visual, colormap ))) goto failed; + if (!NtUserGetClientRect( hwnd, &surface->rect, NtUserGetDpiForWindow( hwnd ) )) goto failed; + surface->colormap = colormap;
TRACE( "Created %s for client window %lx\n", debugstr_client_surface( &surface->client ), surface->window ); *client = &surface->client; return surface->window; + +failed: + if (surface) client_surface_release( &surface->client ); + XFreeColormap( gdi_display, colormap ); + return None; }
/********************************************************************** diff --git a/dlls/winex11.drv/opengl.c b/dlls/winex11.drv/opengl.c index b810689ff3d..64640fb798c 100644 --- a/dlls/winex11.drv/opengl.c +++ b/dlls/winex11.drv/opengl.c @@ -198,7 +198,6 @@ struct gl_drawable { struct opengl_drawable base; GLXDrawable drawable; /* drawable for rendering with GL */ - Colormap colormap; /* colormap for the client window */ };
static struct gl_drawable *impl_from_opengl_drawable( struct opengl_drawable *base ) @@ -471,13 +470,34 @@ static void x11drv_init_egl_platform( struct egl_platform *platform ) egl = platform; }
-static inline EGLConfig egl_config_for_format(int format) +static EGLConfig egl_config_for_format( int format ) { assert(format > 0 && format <= 2 * egl->config_count); if (format <= egl->config_count) return egl->configs[format - 1]; return egl->configs[format - egl->config_count - 1]; }
+static struct glx_pixel_format *glx_pixel_format_from_format( int format ) +{ + assert( format > 0 && format <= nb_pixel_formats ); + return &pixel_formats[format - 1]; +} + +BOOL visual_from_pixel_format( int format, XVisualInfo *visual ) +{ + if (use_egl) + { + *visual = default_visual; + return TRUE; + } + else + { + struct glx_pixel_format *fmt = glx_pixel_format_from_format( format ); + *visual = *fmt->visual; + return TRUE; + } +} + static BOOL x11drv_egl_surface_create( HWND hwnd, int format, struct opengl_drawable **drawable ) { struct opengl_drawable *previous; @@ -489,7 +509,7 @@ static BOOL x11drv_egl_surface_create( HWND hwnd, int format, struct opengl_draw if ((previous = *drawable) && previous->format == format) return TRUE; NtUserGetClientRect( hwnd, &rect, NtUserGetDpiForWindow( hwnd ) );
- if (!(window = x11drv_client_surface_create( hwnd, &default_visual, default_colormap, &client ))) return FALSE; + if (!(window = x11drv_client_surface_create( hwnd, 0, &client ))) return FALSE; gl = opengl_drawable_create( sizeof(*gl), &x11drv_egl_surface_funcs, format, client ); client_surface_release( client ); if (!gl) return FALSE; @@ -850,12 +870,6 @@ static UINT x11drv_init_pixel_formats( UINT *onscreen_count ) return size; }
-static struct glx_pixel_format *glx_pixel_format_from_format( int format ) -{ - assert( format > 0 && format <= nb_pixel_formats ); - return &pixel_formats[format - 1]; -} - static void x11drv_surface_destroy( struct opengl_drawable *base ) { struct gl_drawable *gl = impl_from_opengl_drawable( base ); @@ -863,7 +877,6 @@ static void x11drv_surface_destroy( struct opengl_drawable *base ) TRACE( "drawable %s\n", debugstr_opengl_drawable( base ) );
if (gl->drawable) pglXDestroyWindow( gdi_display, gl->drawable ); - if (gl->colormap) XFreeColormap( gdi_display, gl->colormap ); }
static BOOL set_swap_interval( struct gl_drawable *gl, int interval ) @@ -923,23 +936,16 @@ static BOOL x11drv_surface_create( HWND hwnd, int format, struct opengl_drawable struct opengl_drawable *previous; struct client_surface *client; struct gl_drawable *gl; - Colormap colormap; Window window; RECT rect;
if ((previous = *drawable) && previous->format == format) return TRUE; NtUserGetClientRect( hwnd, &rect, NtUserGetDpiForWindow( hwnd ) );
- colormap = XCreateColormap( gdi_display, get_dummy_parent(), fmt->visual->visual, - (fmt->visual->class == PseudoColor || fmt->visual->class == GrayScale || - fmt->visual->class == DirectColor) ? AllocAll : AllocNone ); - if (!colormap) return FALSE; - - if (!(window = x11drv_client_surface_create( hwnd, fmt->visual, colormap, &client ))) goto failed; + if (!(window = x11drv_client_surface_create( hwnd, format, &client ))) return FALSE; gl = opengl_drawable_create( sizeof(*gl), &x11drv_surface_funcs, format, client ); client_surface_release( client ); - if (!gl) goto failed; - gl->colormap = colormap; + if (!gl) return FALSE;
if (!(gl->drawable = pglXCreateWindow( gdi_display, fmt->fbconfig, window, NULL ))) { @@ -953,10 +959,6 @@ static BOOL x11drv_surface_create( HWND hwnd, int format, struct opengl_drawable if (previous) opengl_drawable_release( previous ); *drawable = &gl->base; return TRUE; - -failed: - XFreeColormap( gdi_display, colormap ); - return FALSE; }
static BOOL x11drv_describe_pixel_format( int format, struct wgl_pixel_format *pf ) @@ -1547,4 +1549,9 @@ void destroy_gl_drawable( HWND hwnd ) { }
+BOOL visual_from_pixel_format( int format, XVisualInfo *visual ) +{ + return FALSE; +} + #endif /* defined(SONAME_LIBGL) */ diff --git a/dlls/winex11.drv/vulkan.c b/dlls/winex11.drv/vulkan.c index 61e4327e379..54e01759e37 100644 --- a/dlls/winex11.drv/vulkan.c +++ b/dlls/winex11.drv/vulkan.c @@ -58,7 +58,7 @@ static VkResult X11DRV_vulkan_surface_create( HWND hwnd, const struct vulkan_ins
TRACE( "%p %p %p %p\n", hwnd, instance, handle, client );
- if (!(info.window = x11drv_client_surface_create( hwnd, &default_visual, default_colormap, client ))) return VK_ERROR_OUT_OF_HOST_MEMORY; + if (!(info.window = x11drv_client_surface_create( hwnd, 0, client ))) return VK_ERROR_OUT_OF_HOST_MEMORY; if (instance->p_vkCreateXlibSurfaceKHR( instance->host.instance, &info, NULL /* allocator */, handle )) { ERR("Failed to create Xlib surface\n"); diff --git a/dlls/winex11.drv/x11drv.h b/dlls/winex11.drv/x11drv.h index c69c83e5dd9..6e909e289ee 100644 --- a/dlls/winex11.drv/x11drv.h +++ b/dlls/winex11.drv/x11drv.h @@ -282,6 +282,8 @@ extern BOOL client_side_with_render; extern BOOL shape_layered_windows; extern const struct gdi_dc_funcs *X11DRV_XRender_Init(void);
+extern BOOL visual_from_pixel_format( int format, XVisualInfo *visual ); + extern UINT X11DRV_OpenGLInit( UINT, const struct opengl_funcs *, const struct opengl_driver_funcs ** ); extern UINT X11DRV_VulkanInit( UINT, void *, const struct vulkan_driver_funcs ** );
@@ -358,7 +360,7 @@ extern BOOL needs_offscreen_rendering( HWND hwnd ); extern void set_dc_drawable( HDC hdc, Drawable drawable, const RECT *rect, int mode ); extern Drawable get_dc_drawable( HDC hdc, RECT *rect ); extern HRGN get_dc_monitor_region( HWND hwnd, HDC hdc ); -extern Window x11drv_client_surface_create( HWND hwnd, const XVisualInfo *visual, Colormap colormap, struct client_surface **client ); +extern Window x11drv_client_surface_create( HWND hwnd, int format, struct client_surface **client );
/************************************************************************** * X11 USER driver