From dcf38e3ea96ce91a1e3162e8e865181cf2f3cffc Mon Sep 17 00:00:00 2001 From: Simon Ser Date: Wed, 22 Jan 2025 21:32:21 +0100 Subject: [PATCH] color-management-v1: add wlr_surface_get_image_description_v1_data() --- include/wlr/types/wlr_color_management_v1.h | 5 ++ types/wlr_color_management_v1.c | 66 ++++++++++++++++++--- 2 files changed, 64 insertions(+), 7 deletions(-) diff --git a/include/wlr/types/wlr_color_management_v1.h b/include/wlr/types/wlr_color_management_v1.h index 16c3fc6a8..1be842eb6 100644 --- a/include/wlr/types/wlr_color_management_v1.h +++ b/include/wlr/types/wlr_color_management_v1.h @@ -13,6 +13,8 @@ #include "color-management-v1-protocol.h" +struct wlr_surface; + struct wlr_image_description_v1_data { uint32_t tf_named; // enum wp_color_manager_v1_transfer_function, zero if unset uint32_t primaries_named; // enum wp_color_manager_v1_primaries, zero if unset @@ -70,4 +72,7 @@ struct wlr_color_manager_v1 { struct wlr_color_manager_v1 *wlr_color_manager_v1_create(struct wl_display *display, uint32_t version, const struct wlr_color_manager_v1_options *options); +const struct wlr_image_description_v1_data * +wlr_surface_get_image_description_v1_data(struct wlr_surface *surface); + #endif diff --git a/types/wlr_color_management_v1.c b/types/wlr_color_management_v1.c index 100b0d921..d9892d3b5 100644 --- a/types/wlr_color_management_v1.c +++ b/types/wlr_color_management_v1.c @@ -19,12 +19,20 @@ struct wlr_color_management_output_v1 { struct wl_listener output_destroy; }; +struct wlr_color_management_surface_v1_state { + bool has_image_desc_data; + struct wlr_image_description_v1_data image_desc_data; +}; + struct wlr_color_management_surface_v1 { struct wl_resource *resource; struct wlr_surface *surface; struct wlr_color_manager_v1 *manager; struct wlr_addon addon; + struct wlr_surface_synced synced; + + struct wlr_color_management_surface_v1_state current, pending; }; struct wlr_color_management_surface_feedback_v1 { @@ -37,6 +45,7 @@ struct wlr_color_management_surface_feedback_v1 { struct wlr_image_description_v1 { struct wl_resource *resource; + bool get_info_allowed; struct wlr_image_description_v1_data data; // immutable }; @@ -95,6 +104,13 @@ static void image_desc_handle_get_information(struct wl_client *client, return; } + if (!image_desc->get_info_allowed) { + wl_resource_post_error(image_desc_resource, + WP_IMAGE_DESCRIPTION_V1_ERROR_NO_INFORMATION, + "get_information not allowed"); + return; + } + uint32_t version = wl_resource_get_version(image_desc_resource); struct wl_resource *resource = wl_resource_create(client, &wp_image_description_info_v1_interface, version, id); @@ -153,7 +169,8 @@ static struct wl_resource *image_desc_create_resource( static void image_desc_create_ready(struct wlr_color_manager_v1 *manager, struct wl_resource *parent_resource, uint32_t id, - const struct wlr_image_description_v1_data *data) { + const struct wlr_image_description_v1_data *data, + bool get_info_allowed) { struct wlr_image_description_v1 *image_desc = calloc(1, sizeof(*image_desc)); if (image_desc == NULL) { wl_resource_post_no_memory(parent_resource); @@ -161,6 +178,7 @@ static void image_desc_create_ready(struct wlr_color_manager_v1 *manager, } image_desc->data = *data; + image_desc->get_info_allowed = get_info_allowed; image_desc->resource = image_desc_create_resource(parent_resource, id); if (!image_desc->resource) { @@ -209,7 +227,7 @@ static void cm_output_handle_get_image_description(struct wl_client *client, .tf_named = WP_COLOR_MANAGER_V1_TRANSFER_FUNCTION_SRGB, .primaries_named = WP_COLOR_MANAGER_V1_PRIMARIES_SRGB, }; - image_desc_create_ready(cm_output->manager, cm_output_resource, id, &data); + image_desc_create_ready(cm_output->manager, cm_output_resource, id, &data, true); } static const struct wp_color_management_output_v1_interface cm_output_impl = { @@ -242,10 +260,15 @@ static void cm_surface_destroy(struct wlr_color_management_surface_v1 *cm_surfac return; } wl_resource_set_user_data(cm_surface->resource, NULL); // make inert + wlr_surface_synced_finish(&cm_surface->synced); wlr_addon_finish(&cm_surface->addon); free(cm_surface); } +static const struct wlr_surface_synced_impl cm_surface_synced_impl = { + .state_size = sizeof(struct wlr_color_management_surface_v1_state), +}; + static void cm_surface_handle_addon_destroy(struct wlr_addon *addon) { struct wlr_color_management_surface_v1 *cm_surface = wl_container_of(addon, cm_surface, addon); cm_surface_destroy(cm_surface); @@ -274,6 +297,8 @@ static void cm_surface_handle_set_image_description(struct wl_client *client, return; } + struct wlr_image_description_v1 *image_desc = image_desc_from_resource(image_desc_resource); + bool found = false; for (size_t i = 0; i < cm_surface->manager->render_intents_len; i++) { if (cm_surface->manager->render_intents[i] == render_intent) { @@ -288,7 +313,8 @@ static void cm_surface_handle_set_image_description(struct wl_client *client, return; } - // TODO + cm_surface->pending.has_image_desc_data = true; + cm_surface->pending.image_desc_data = image_desc->data; } static void cm_surface_handle_unset_image_description(struct wl_client *client, @@ -301,7 +327,7 @@ static void cm_surface_handle_unset_image_description(struct wl_client *client, return; } - // TODO + cm_surface->pending.has_image_desc_data = false; } static const struct wp_color_management_surface_v1_interface cm_surface_impl = { @@ -339,7 +365,7 @@ static void surface_feedback_handle_get_preferred(struct wl_client *client, .primaries_named = WP_COLOR_MANAGER_V1_PRIMARIES_SRGB, }; image_desc_create_ready(surface_feedback->manager, - surface_feedback_resource, id, &data); + surface_feedback_resource, id, &data, true); } static const struct wp_color_management_surface_feedback_v1_interface surface_feedback_impl = { @@ -404,7 +430,7 @@ static void image_desc_creator_params_handle_create(struct wl_client *client, return; } - image_desc_create_ready(params->manager, params_resource, id, ¶ms->data); + image_desc_create_ready(params->manager, params_resource, id, ¶ms->data, false); } static void image_desc_creator_params_handle_set_tf_named(struct wl_client *client, @@ -576,13 +602,22 @@ static void manager_handle_get_output(struct wl_client *client, wl_list_insert(&manager->outputs, &cm_output->link); } +static struct wlr_color_management_surface_v1 *cm_surface_from_surface(struct wlr_surface *surface) { + struct wlr_addon *addon = wlr_addon_find(&surface->addons, NULL, &cm_surface_addon_impl); + if (addon == NULL) { + return NULL; + } + struct wlr_color_management_surface_v1 *cm_surface = wl_container_of(addon, cm_surface, addon); + return cm_surface; +} + static void manager_handle_get_surface(struct wl_client *client, struct wl_resource *manager_resource, uint32_t id, struct wl_resource *surface_resource) { struct wlr_color_manager_v1 *manager = manager_from_resource(manager_resource); struct wlr_surface *surface = wlr_surface_from_resource(surface_resource); - if (wlr_addon_find(&surface->addons, NULL, &cm_surface_addon_impl) != NULL) { + if (cm_surface_from_surface(surface) != NULL) { wl_resource_post_error(manager_resource, WP_COLOR_MANAGER_V1_ERROR_SURFACE_EXISTS, "wp_color_management_surface_v1 already constructed for this surface"); @@ -595,11 +630,19 @@ static void manager_handle_get_surface(struct wl_client *client, return; } + if (!wlr_surface_synced_init(&cm_surface->synced, surface, &cm_surface_synced_impl, + &cm_surface->pending, &cm_surface->current)) { + wl_client_post_no_memory(client); + free(cm_surface); + return; + } + uint32_t version = wl_resource_get_version(manager_resource); cm_surface->resource = wl_resource_create(client, &wp_color_management_surface_v1_interface, version, id); if (!cm_surface->resource) { wl_client_post_no_memory(client); + wlr_surface_synced_finish(&cm_surface->synced); free(cm_surface); return; } @@ -822,3 +865,12 @@ err_options: free(manager); return NULL; } + +const struct wlr_image_description_v1_data * +wlr_surface_get_image_description_v1_data(struct wlr_surface *surface) { + struct wlr_color_management_surface_v1 *cm_surface = cm_surface_from_surface(surface); + if (cm_surface == NULL || !cm_surface->current.has_image_desc_data) { + return NULL; + } + return &cm_surface->current.image_desc_data; +}