xwayland: Use fractional scale with rootful
Implement fractional scale with Xwayland rootful by scaling the content to the desired fractional scale using a viewport. For now this applies to Xwayland rootful only. Signed-off-by: Olivier Fourdan <ofourdan@redhat.com> Reviewed-By: Kenny Levinsen <kl@kl.wtf> Acked-by: Peter Hutterer <peter.hutterer@who-t.net> Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/1197>
This commit is contained in:
		
							parent
							
								
									3e77c1699a
								
							
						
					
					
						commit
						821d3d5789
					
				|  | @ -27,6 +27,7 @@ | ||||||
| #include <dix-config.h> | #include <dix-config.h> | ||||||
| #endif | #endif | ||||||
| 
 | 
 | ||||||
|  | #include <float.h> | ||||||
| #include <math.h> | #include <math.h> | ||||||
| #include <sys/mman.h> | #include <sys/mman.h> | ||||||
| 
 | 
 | ||||||
|  | @ -53,6 +54,7 @@ | ||||||
| #include "viewporter-client-protocol.h" | #include "viewporter-client-protocol.h" | ||||||
| #include "xdg-shell-client-protocol.h" | #include "xdg-shell-client-protocol.h" | ||||||
| #include "xwayland-shell-v1-client-protocol.h" | #include "xwayland-shell-v1-client-protocol.h" | ||||||
|  | #include "fractional-scale-v1-client-protocol.h" | ||||||
| 
 | 
 | ||||||
| #define DELAYED_WL_SURFACE_DESTROY 1000 /* ms */ | #define DELAYED_WL_SURFACE_DESTROY 1000 /* ms */ | ||||||
| 
 | 
 | ||||||
|  | @ -61,6 +63,8 @@ | ||||||
| #define MIN_ROOTFUL_WIDTH 320 | #define MIN_ROOTFUL_WIDTH 320 | ||||||
| #define MIN_ROOTFUL_HEIGHT 200 | #define MIN_ROOTFUL_HEIGHT 200 | ||||||
| 
 | 
 | ||||||
|  | #define FRACTIONAL_SCALE_DENOMINATOR 120 | ||||||
|  | 
 | ||||||
| static DevPrivateKeyRec xwl_window_private_key; | static DevPrivateKeyRec xwl_window_private_key; | ||||||
| static DevPrivateKeyRec xwl_damage_private_key; | static DevPrivateKeyRec xwl_damage_private_key; | ||||||
| static const char *xwl_surface_tag = "xwl-surface"; | static const char *xwl_surface_tag = "xwl-surface"; | ||||||
|  | @ -246,6 +250,24 @@ unregister_damage(WindowPtr window) | ||||||
|     dixSetPrivate(&window->devPrivates, &xwl_damage_private_key, NULL); |     dixSetPrivate(&window->devPrivates, &xwl_damage_private_key, NULL); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | static Bool | ||||||
|  | xwl_window_update_fractional_scale(struct xwl_window *xwl_window, | ||||||
|  |                                    int fractional_scale_numerator) | ||||||
|  | { | ||||||
|  |     int old_scale_numerator = xwl_window->fractional_scale_numerator; | ||||||
|  | 
 | ||||||
|  |     xwl_window->fractional_scale_numerator = fractional_scale_numerator; | ||||||
|  | 
 | ||||||
|  |     return (old_scale_numerator != fractional_scale_numerator); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static double | ||||||
|  | xwl_window_get_fractional_scale_factor(struct xwl_window *xwl_window) | ||||||
|  | { | ||||||
|  |     return (double) xwl_window->fractional_scale_numerator / | ||||||
|  |            (double) FRACTIONAL_SCALE_DENOMINATOR; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| static Bool | static Bool | ||||||
| xwl_window_has_viewport_enabled(struct xwl_window *xwl_window) | xwl_window_has_viewport_enabled(struct xwl_window *xwl_window) | ||||||
| { | { | ||||||
|  | @ -264,6 +286,42 @@ xwl_window_disable_viewport(struct xwl_window *xwl_window) | ||||||
|     xwl_window->viewport_scale_y = 1.0; |     xwl_window->viewport_scale_y = 1.0; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | /* Enable the viewport for fractional scale support with Xwayland rootful.
 | ||||||
|  |  * Fractional scale support is not used with Xwayland rootful fullscreen (which | ||||||
|  |  * sets its own XRandR resolution) so we can use the viewport for either | ||||||
|  |  * fullscreen mode or fractional scale. | ||||||
|  |  */ | ||||||
|  | static void | ||||||
|  | xwl_window_enable_viewport_for_fractional_scale(struct xwl_window *xwl_window, | ||||||
|  |                                                 int width, int height) | ||||||
|  | { | ||||||
|  |     struct xwl_screen *xwl_screen = xwl_window->xwl_screen; | ||||||
|  |     int buffer_width, buffer_height; | ||||||
|  |     double scale; | ||||||
|  | 
 | ||||||
|  |     scale = xwl_window_get_fractional_scale_factor(xwl_window); | ||||||
|  |     buffer_width = round((double) width / scale); | ||||||
|  |     buffer_height = round((double) height / scale); | ||||||
|  | 
 | ||||||
|  |     if (!xwl_window_has_viewport_enabled(xwl_window)) | ||||||
|  |         xwl_window->viewport = wp_viewporter_get_viewport(xwl_screen->viewporter, | ||||||
|  |                                                           xwl_window->surface); | ||||||
|  | 
 | ||||||
|  |     DebugF("XWAYLAND: enabling viewport for fractional scale %dx%d -> %dx%d\n", | ||||||
|  |            width, height, buffer_width, buffer_height); | ||||||
|  |     wp_viewport_set_source(xwl_window->viewport, | ||||||
|  |                            wl_fixed_from_int(0), | ||||||
|  |                            wl_fixed_from_int(0), | ||||||
|  |                            wl_fixed_from_int(width), | ||||||
|  |                            wl_fixed_from_int(height)); | ||||||
|  |     wp_viewport_set_destination(xwl_window->viewport, | ||||||
|  |                                 buffer_width, | ||||||
|  |                                 buffer_height); | ||||||
|  | 
 | ||||||
|  |     xwl_window->viewport_scale_x = scale; | ||||||
|  |     xwl_window->viewport_scale_y = scale; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| /* Enable the viewport for Xwayland rootful fullscreen, to match the XRandR
 | /* Enable the viewport for Xwayland rootful fullscreen, to match the XRandR
 | ||||||
|  * resolution with the actual output size. |  * resolution with the actual output size. | ||||||
|  */ |  */ | ||||||
|  | @ -434,6 +492,35 @@ xwl_window_should_enable_viewport(struct xwl_window *xwl_window, | ||||||
|     return FALSE; |     return FALSE; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | static Bool | ||||||
|  | xwl_window_should_enable_fractional_scale_viewport(struct xwl_window *xwl_window) | ||||||
|  | { | ||||||
|  |     struct xwl_screen *xwl_screen = xwl_window->xwl_screen; | ||||||
|  |     double scale; | ||||||
|  | 
 | ||||||
|  |     if (!xwl_screen_should_use_fractional_scale(xwl_screen)) | ||||||
|  |         return FALSE; | ||||||
|  | 
 | ||||||
|  |     scale = xwl_window_get_fractional_scale_factor(xwl_window); | ||||||
|  | 
 | ||||||
|  |     return fabs(scale - 1.00) > FLT_EPSILON; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static void | ||||||
|  | xwl_window_check_fractional_scale_viewport(struct xwl_window *xwl_window, | ||||||
|  |                                            int width, int height) | ||||||
|  | { | ||||||
|  |     struct xwl_screen *xwl_screen = xwl_window->xwl_screen; | ||||||
|  | 
 | ||||||
|  |     if (!xwl_screen_should_use_fractional_scale(xwl_screen)) | ||||||
|  |         return; | ||||||
|  | 
 | ||||||
|  |     if (xwl_window_should_enable_fractional_scale_viewport(xwl_window)) | ||||||
|  |         xwl_window_enable_viewport_for_fractional_scale(xwl_window, width, height); | ||||||
|  |     else if (xwl_window_has_viewport_enabled(xwl_window)) | ||||||
|  |         xwl_window_disable_viewport(xwl_window); | ||||||
|  | } | ||||||
|  | 
 | ||||||
| void | void | ||||||
| xwl_window_check_resolution_change_emulation(struct xwl_window *xwl_window) | xwl_window_check_resolution_change_emulation(struct xwl_window *xwl_window) | ||||||
| { | { | ||||||
|  | @ -442,6 +529,8 @@ xwl_window_check_resolution_change_emulation(struct xwl_window *xwl_window) | ||||||
| 
 | 
 | ||||||
|     if (xwl_window_should_enable_viewport(xwl_window, &xwl_output, &emulated_mode)) |     if (xwl_window_should_enable_viewport(xwl_window, &xwl_output, &emulated_mode)) | ||||||
|         xwl_window_enable_viewport_for_output(xwl_window, xwl_output, &emulated_mode); |         xwl_window_enable_viewport_for_output(xwl_window, xwl_output, &emulated_mode); | ||||||
|  |     else if (xwl_window_should_enable_fractional_scale_viewport(xwl_window)) | ||||||
|  |         return; | ||||||
|     else if (xwl_window_has_viewport_enabled(xwl_window)) |     else if (xwl_window_has_viewport_enabled(xwl_window)) | ||||||
|         xwl_window_disable_viewport(xwl_window); |         xwl_window_disable_viewport(xwl_window); | ||||||
| } | } | ||||||
|  | @ -673,6 +762,13 @@ xwl_window_maybe_resize(struct xwl_window *xwl_window, double width, double heig | ||||||
|     xwl_screen->width = width; |     xwl_screen->width = width; | ||||||
|     xwl_screen->height = height; |     xwl_screen->height = height; | ||||||
| 
 | 
 | ||||||
|  |     /* When fractional scale is used, the global surface scale is 1, and vice
 | ||||||
|  |      * versa, so we can multiply the two here, and have the resulting scale | ||||||
|  |      * apply for both cases, the legacy wl_surface buffer scale and fractional | ||||||
|  |      * scaling. | ||||||
|  |      */ | ||||||
|  |     scale *= xwl_window_get_fractional_scale_factor(xwl_window); | ||||||
|  | 
 | ||||||
|     xwl_output = xwl_screen_get_fixed_or_first_output(xwl_screen); |     xwl_output = xwl_screen_get_fixed_or_first_output(xwl_screen); | ||||||
|     if (!xwl_randr_add_modes_fixed(xwl_output, round(width / scale), round(height / scale))) |     if (!xwl_randr_add_modes_fixed(xwl_output, round(width / scale), round(height / scale))) | ||||||
|         return; |         return; | ||||||
|  | @ -707,9 +803,12 @@ xwl_window_update_libdecor_size(struct xwl_window *xwl_window, | ||||||
|                                 int width, int height) |                                 int width, int height) | ||||||
| { | { | ||||||
|     struct libdecor_state *state; |     struct libdecor_state *state; | ||||||
|  |     double scale; | ||||||
| 
 | 
 | ||||||
|     if (xwl_window->libdecor_frame) { |     if (xwl_window->libdecor_frame) { | ||||||
| 	state = libdecor_state_new(width, height); | 	scale = xwl_window_get_fractional_scale_factor(xwl_window); | ||||||
|  | 	state = libdecor_state_new(round((double) width / scale), | ||||||
|  | 	                           round((double) height / scale)); | ||||||
| 	libdecor_frame_commit(xwl_window->libdecor_frame, state, configuration); | 	libdecor_frame_commit(xwl_window->libdecor_frame, state, configuration); | ||||||
| 	libdecor_state_free(state); | 	libdecor_state_free(state); | ||||||
|     } |     } | ||||||
|  | @ -724,6 +823,7 @@ handle_libdecor_configure(struct libdecor_frame *frame, | ||||||
|     struct xwl_screen *xwl_screen = xwl_window->xwl_screen; |     struct xwl_screen *xwl_screen = xwl_window->xwl_screen; | ||||||
|     int width, height; |     int width, height; | ||||||
|     double new_width, new_height; |     double new_width, new_height; | ||||||
|  |     double scale; | ||||||
| 
 | 
 | ||||||
|     if (libdecor_configuration_get_content_size(configuration, frame, &width, &height)) { |     if (libdecor_configuration_get_content_size(configuration, frame, &width, &height)) { | ||||||
|         new_width = (double) width; |         new_width = (double) width; | ||||||
|  | @ -737,6 +837,10 @@ handle_libdecor_configure(struct libdecor_frame *frame, | ||||||
|     new_width *= xwl_screen->global_surface_scale; |     new_width *= xwl_screen->global_surface_scale; | ||||||
|     new_height *= xwl_screen->global_surface_scale; |     new_height *= xwl_screen->global_surface_scale; | ||||||
| 
 | 
 | ||||||
|  |     scale = xwl_window_get_fractional_scale_factor(xwl_window); | ||||||
|  |     new_width *= scale; | ||||||
|  |     new_height *= scale; | ||||||
|  | 
 | ||||||
|     xwl_window_maybe_resize(xwl_window, new_width, new_height); |     xwl_window_maybe_resize(xwl_window, new_width, new_height); | ||||||
| 
 | 
 | ||||||
|     new_width = xwl_screen->width / xwl_screen->global_surface_scale; |     new_width = xwl_screen->width / xwl_screen->global_surface_scale; | ||||||
|  | @ -941,15 +1045,20 @@ xdg_toplevel_handle_configure(void *data, | ||||||
|     struct xwl_screen *xwl_screen = xwl_window->xwl_screen; |     struct xwl_screen *xwl_screen = xwl_window->xwl_screen; | ||||||
|     uint32_t *p; |     uint32_t *p; | ||||||
|     Bool old_active = xwl_screen->active; |     Bool old_active = xwl_screen->active; | ||||||
|     int new_width, new_height; |     double scale, new_width, new_height; | ||||||
| 
 | 
 | ||||||
|     /* Maintain our current size if no dimensions are requested */ |     /* Maintain our current size if no dimensions are requested */ | ||||||
|     if (width == 0 && height == 0) |     if (width == 0 && height == 0) | ||||||
|         return; |         return; | ||||||
| 
 | 
 | ||||||
|     if (!xwl_screen->fullscreen) { |     if (!xwl_screen->fullscreen) { | ||||||
|         new_width = width * xwl_screen->global_surface_scale; |         new_width = (double) (width * xwl_screen->global_surface_scale); | ||||||
|         new_height = height * xwl_screen->global_surface_scale; |         new_height = (double) (height * xwl_screen->global_surface_scale); | ||||||
|  | 
 | ||||||
|  |         scale = xwl_window_get_fractional_scale_factor(xwl_window); | ||||||
|  |         new_width *= scale; | ||||||
|  |         new_height *= scale; | ||||||
|  | 
 | ||||||
|         /* This will be committed by the xdg_surface.configure handler */ |         /* This will be committed by the xdg_surface.configure handler */ | ||||||
|         xwl_window_maybe_resize(xwl_window, new_width, new_height); |         xwl_window_maybe_resize(xwl_window, new_width, new_height); | ||||||
|     } |     } | ||||||
|  | @ -982,6 +1091,58 @@ static const struct xdg_toplevel_listener xdg_toplevel_listener = { | ||||||
|     xdg_toplevel_handle_close, |     xdg_toplevel_handle_close, | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
|  | static void | ||||||
|  | xwl_window_update_rootful_scale(struct xwl_window *xwl_window, double previous_scale) | ||||||
|  | { | ||||||
|  |     struct xwl_screen *xwl_screen = xwl_window->xwl_screen; | ||||||
|  |     double new_scale, new_width, new_height; | ||||||
|  | 
 | ||||||
|  |     new_scale = xwl_window_get_fractional_scale_factor(xwl_window); | ||||||
|  |     new_width = xwl_screen->width / previous_scale * new_scale; | ||||||
|  |     new_height = xwl_screen->height / previous_scale * new_scale; | ||||||
|  | 
 | ||||||
|  |     DebugF("XWAYLAND: Fractional scale is now %.2f (was %.2f)\n", | ||||||
|  |            new_scale, previous_scale); | ||||||
|  | 
 | ||||||
|  |     xwl_output_set_xscale(xwl_screen->fixed_output, new_scale); | ||||||
|  |     xwl_window_maybe_resize(xwl_window, new_width, new_height); | ||||||
|  |     xwl_window_check_fractional_scale_viewport(xwl_window, | ||||||
|  |                                                xwl_screen_get_width(xwl_screen), | ||||||
|  |                                                xwl_screen_get_height(xwl_screen)); | ||||||
|  | 
 | ||||||
|  | #ifdef XWL_HAS_LIBDECOR | ||||||
|  |     if (xwl_window->libdecor_frame) { | ||||||
|  |         xwl_window_libdecor_set_size_limits(xwl_window); | ||||||
|  |         xwl_window_update_libdecor_size(xwl_window, | ||||||
|  |                                         NULL, | ||||||
|  |                                         xwl_screen_get_width(xwl_screen), | ||||||
|  |                                         xwl_screen_get_height(xwl_screen)); | ||||||
|  |     } | ||||||
|  |     else | ||||||
|  | #endif | ||||||
|  |         wl_surface_commit(xwl_window->surface); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static void | ||||||
|  | wp_fractional_scale_preferred_scale(void *data, | ||||||
|  |                                     struct wp_fractional_scale_v1 *fractional_scale, | ||||||
|  |                                     uint32_t scale_numerator) | ||||||
|  | { | ||||||
|  |     struct xwl_window *xwl_window = data; | ||||||
|  |     struct xwl_screen *xwl_screen = xwl_window->xwl_screen; | ||||||
|  |     double previous_scale = xwl_window_get_fractional_scale_factor(xwl_window); | ||||||
|  | 
 | ||||||
|  |     if (xwl_window_update_fractional_scale(xwl_window, scale_numerator)) { | ||||||
|  |         if (xwl_screen->fixed_output) { /* We're running rootful */ | ||||||
|  |             xwl_window_update_rootful_scale(xwl_window, previous_scale); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static const struct wp_fractional_scale_v1_listener fractional_scale_listener = { | ||||||
|  |    wp_fractional_scale_preferred_scale, | ||||||
|  | }; | ||||||
|  | 
 | ||||||
| static Bool | static Bool | ||||||
| xwl_create_root_surface(struct xwl_window *xwl_window) | xwl_create_root_surface(struct xwl_window *xwl_window) | ||||||
| { | { | ||||||
|  | @ -1028,6 +1189,14 @@ xwl_create_root_surface(struct xwl_window *xwl_window) | ||||||
|     wl_surface_add_listener(xwl_window->surface, |     wl_surface_add_listener(xwl_window->surface, | ||||||
|                             &surface_listener, xwl_window); |                             &surface_listener, xwl_window); | ||||||
| 
 | 
 | ||||||
|  |     if (xwl_screen_should_use_fractional_scale(xwl_screen)) { | ||||||
|  |         xwl_window->fractional_scale = | ||||||
|  |             wp_fractional_scale_manager_v1_get_fractional_scale(xwl_screen->fractional_scale_manager, | ||||||
|  |                                                                 xwl_window->surface); | ||||||
|  |         wp_fractional_scale_v1_add_listener(xwl_window->fractional_scale, | ||||||
|  |                                             &fractional_scale_listener, xwl_window); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     xwl_window_rootful_update_title(xwl_window); |     xwl_window_rootful_update_title(xwl_window); | ||||||
|     xwl_window_rootful_set_app_id(xwl_window); |     xwl_window_rootful_set_app_id(xwl_window); | ||||||
|     wl_surface_commit(xwl_window->surface); |     wl_surface_commit(xwl_window->surface); | ||||||
|  | @ -1083,8 +1252,10 @@ ensure_surface_for_window(WindowPtr window) | ||||||
| 
 | 
 | ||||||
|     xwl_window->xwl_screen = xwl_screen; |     xwl_window->xwl_screen = xwl_screen; | ||||||
|     xwl_window->window = window; |     xwl_window->window = window; | ||||||
|  |     xwl_window->fractional_scale_numerator = FRACTIONAL_SCALE_DENOMINATOR; | ||||||
|     xwl_window->viewport_scale_x = 1.0; |     xwl_window->viewport_scale_x = 1.0; | ||||||
|     xwl_window->viewport_scale_y = 1.0; |     xwl_window->viewport_scale_y = 1.0; | ||||||
|  |     xwl_window->surface_scale = 1; | ||||||
|     xorg_list_init(&xwl_window->xwl_output_list); |     xorg_list_init(&xwl_window->xwl_output_list); | ||||||
|     xwl_window->surface = wl_compositor_create_surface(xwl_screen->compositor); |     xwl_window->surface = wl_compositor_create_surface(xwl_screen->compositor); | ||||||
|     if (xwl_window->surface == NULL) { |     if (xwl_window->surface == NULL) { | ||||||
|  | @ -1322,6 +1493,9 @@ xwl_unrealize_window(WindowPtr window) | ||||||
|     if (xwl_window->tearing_control) |     if (xwl_window->tearing_control) | ||||||
|         wp_tearing_control_v1_destroy(xwl_window->tearing_control); |         wp_tearing_control_v1_destroy(xwl_window->tearing_control); | ||||||
| 
 | 
 | ||||||
|  |     if (xwl_window->fractional_scale) | ||||||
|  |         wp_fractional_scale_v1_destroy(xwl_window->fractional_scale); | ||||||
|  | 
 | ||||||
|     release_wl_surface_for_window(xwl_window); |     release_wl_surface_for_window(xwl_window); | ||||||
|     xorg_list_del(&xwl_window->link_damage); |     xorg_list_del(&xwl_window->link_damage); | ||||||
|     xorg_list_del(&xwl_window->link_window); |     xorg_list_del(&xwl_window->link_window); | ||||||
|  | @ -1419,16 +1593,17 @@ xwl_resize_window(WindowPtr window, | ||||||
|     if (xwl_window) { |     if (xwl_window) { | ||||||
|         if (xwl_window_get(window) || xwl_window_is_toplevel(window)) |         if (xwl_window_get(window) || xwl_window_is_toplevel(window)) | ||||||
|             xwl_window_check_resolution_change_emulation(xwl_window); |             xwl_window_check_resolution_change_emulation(xwl_window); | ||||||
| #ifdef XWL_HAS_LIBDECOR |  | ||||||
|         if (window == screen->root) { |         if (window == screen->root) { | ||||||
|  | #ifdef XWL_HAS_LIBDECOR | ||||||
|             unsigned int decor_width, decor_height; |             unsigned int decor_width, decor_height; | ||||||
| 
 | 
 | ||||||
|             decor_width = width / xwl_screen->global_surface_scale; |             decor_width = width / xwl_screen->global_surface_scale; | ||||||
|             decor_height = height / xwl_screen->global_surface_scale; |             decor_height = height / xwl_screen->global_surface_scale; | ||||||
|             xwl_window_update_libdecor_size(xwl_window, NULL, |             xwl_window_update_libdecor_size(xwl_window, NULL, | ||||||
|                                             decor_width, decor_height); |                                             decor_width, decor_height); | ||||||
|         } |  | ||||||
| #endif | #endif | ||||||
|  |             xwl_window_check_fractional_scale_viewport(xwl_window, width, height); | ||||||
|  |         } | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -82,6 +82,8 @@ struct xwl_window { | ||||||
|     /* If TRUE, the window buffer format supports scanout with implicit modifier */ |     /* If TRUE, the window buffer format supports scanout with implicit modifier */ | ||||||
|     Bool has_implicit_scanout_support; |     Bool has_implicit_scanout_support; | ||||||
|     struct wp_tearing_control_v1 *tearing_control; |     struct wp_tearing_control_v1 *tearing_control; | ||||||
|  |     struct wp_fractional_scale_v1 *fractional_scale; | ||||||
|  |     int fractional_scale_numerator; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| struct xwl_window *xwl_window_get(WindowPtr window); | struct xwl_window *xwl_window_get(WindowPtr window); | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue