diff --git a/glfw/wl_init.c b/glfw/wl_init.c index e7f93c0a4..7c2db6858 100644 --- a/glfw/wl_init.c +++ b/glfw/wl_init.c @@ -681,7 +681,6 @@ static const struct wl_registry_listener registryListener = { registryHandleGlobalRemove }; - GLFWAPI GLFWColorScheme glfwGetCurrentSystemColorTheme(bool query_if_unintialized) { return glfw_current_system_color_theme(query_if_unintialized); } @@ -776,6 +775,25 @@ get_compositor_missing_capabilities(void) { GLFWAPI const char* glfwWaylandMissingCapabilities(void) { return get_compositor_missing_capabilities(); } +static void +image_description_failed(void *data UNUSED, struct wp_image_description_v1 *d, uint32_t cause, const char *msg) { + wp_image_description_v1_destroy(d); + _glfwInputError(GLFW_PLATFORM_ERROR, "Failed to create color mamagement profile description with cause: %d and error: %s", cause, msg); + _glfw.wl.color_manager.image_description_done = true; +} + +static void +image_description_ready(void *data UNUSED, struct wp_image_description_v1 *d, uint32_t identity UNUSED) { + _glfw.wl.color_manager.image_description_done = true; + _glfw.wl.color_manager.image_description = d; +} + +static const struct wp_image_description_v1_listener image_description_listener = { + .failed = image_description_failed, + .ready = image_description_ready, +}; + + int _glfwPlatformInit(bool *supports_window_occlusion) { int i; @@ -835,7 +853,18 @@ int _glfwPlatformInit(bool *supports_window_occlusion) wl_display_roundtrip(_glfw.wl.display); // Sync so we get all color manager capabilities - while(_glfw.wl.wp_color_manager_v1 != NULL && !_glfw.wl.color_manager.capabilities_reported) wl_display_roundtrip(_glfw.wl.display); + if (_glfw.wl.wp_color_manager_v1) { + while (!_glfw.wl.color_manager.capabilities_reported) wl_display_roundtrip(_glfw.wl.display); + _glfw.wl.color_manager.has_needed_capabilities = _glfw.wl.color_manager.supported_transfer_functions.gamma22 && _glfw.wl.color_manager.supported_primaries.srgb; + if (_glfw.wl.color_manager.has_needed_capabilities) { + struct wp_image_description_creator_params_v1 *c = wp_color_manager_v1_create_parametric_creator( + _glfw.wl.wp_color_manager_v1); + wp_image_description_creator_params_v1_set_tf_named(c, WP_COLOR_MANAGER_V1_TRANSFER_FUNCTION_GAMMA22); + wp_image_description_creator_params_v1_set_primaries_named(c, WP_COLOR_MANAGER_V1_PRIMARIES_SRGB); + wp_image_description_v1_add_listener(wp_image_description_creator_params_v1_create(c), + &image_description_listener, NULL); + } + } for (i = 0; i < _glfw.monitorCount; ++i) { @@ -950,8 +979,11 @@ void _glfwPlatformTerminate(void) xdg_system_bell_v1_destroy(_glfw.wl.xdg_system_bell_v1); if (_glfw.wl.xdg_toplevel_tag_manager_v1) xdg_toplevel_tag_manager_v1_destroy(_glfw.wl.xdg_toplevel_tag_manager_v1); - if (_glfw.wl.wp_color_manager_v1) + if (_glfw.wl.wp_color_manager_v1) { + if (_glfw.wl.color_manager.image_description) + wp_image_description_v1_destroy(_glfw.wl.color_manager.image_description); wp_color_manager_v1_destroy(_glfw.wl.wp_color_manager_v1); + } if (_glfw.wl.wp_single_pixel_buffer_manager_v1) wp_single_pixel_buffer_manager_v1_destroy(_glfw.wl.wp_single_pixel_buffer_manager_v1); if (_glfw.wl.wp_cursor_shape_manager_v1) diff --git a/glfw/wl_platform.h b/glfw/wl_platform.h index 1a4f165d0..caa4f6bdf 100644 --- a/glfw/wl_platform.h +++ b/glfw/wl_platform.h @@ -399,7 +399,8 @@ typedef struct _GLFWlibraryWayland struct { struct { bool gamma22, ext_linear; } supported_transfer_functions; struct { bool srgb; } supported_primaries; - bool capabilities_reported; + bool capabilities_reported, image_description_done, has_needed_capabilities; + struct wp_image_description_v1 *image_description; } color_manager; struct { diff --git a/glfw/wl_window.c b/glfw/wl_window.c index e6ada06d7..aaf58e8c9 100644 --- a/glfw/wl_window.c +++ b/glfw/wl_window.c @@ -571,6 +571,13 @@ static const struct wp_fractional_scale_v1_listener fractional_scale_listener = .preferred_scale = &fractional_scale_preferred_scale, }; +static void +ensure_color_manager_ready(void) { + if (_glfw.wl.wp_color_manager_v1 && !_glfw.wl.color_manager.image_description_done) { + while (!_glfw.wl.color_manager.image_description_done) wl_display_roundtrip(_glfw.wl.display); + } +} + static bool createSurface(_GLFWwindow* window, const _GLFWwndconfig* wndconfig) { @@ -583,8 +590,11 @@ static bool createSurface(_GLFWwindow* window, window); wl_surface_set_user_data(window->wl.surface, window); - if (_glfw.wl.wp_color_manager_v1 != NULL) { - window->wl.color_management = wp_color_manager_v1_get_surface(_glfw.wl.wp_color_manager_v1, window->wl.surface); + if (_glfw.wl.color_manager.has_needed_capabilities) { + ensure_color_manager_ready(); + if (_glfw.wl.color_manager.image_description) { + window->wl.color_management = wp_color_manager_v1_get_surface(_glfw.wl.wp_color_manager_v1, window->wl.surface); + } } // If we already have been notified of the primary monitor scale, assume