mirror of
https://gitlab.freedesktop.org/wlroots/wlroots.git
synced 2025-10-29 05:40:12 -04:00
color-management-v1: add struct wlr_image_description_v1
This commit is contained in:
parent
0ab3c1d060
commit
6d4737a7f6
2 changed files with 110 additions and 17 deletions
|
|
@ -13,6 +13,13 @@
|
|||
|
||||
#include "color-management-v1-protocol.h"
|
||||
|
||||
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
|
||||
|
||||
uint32_t max_cll, max_fall; // cd/m², zero if unset
|
||||
};
|
||||
|
||||
struct wlr_color_manager_v1_features {
|
||||
bool icc_v2_v4;
|
||||
bool parametric;
|
||||
|
|
@ -54,6 +61,8 @@ struct wlr_color_manager_v1 {
|
|||
|
||||
struct wl_list outputs; // wlr_color_management_output_v1.link
|
||||
|
||||
uint32_t last_image_desc_identity;
|
||||
|
||||
struct wl_listener display_destroy;
|
||||
} WLR_PRIVATE;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@
|
|||
struct wlr_color_management_output_v1 {
|
||||
struct wl_resource *resource;
|
||||
struct wlr_output *output;
|
||||
struct wlr_color_manager_v1 *manager;
|
||||
struct wl_list link;
|
||||
|
||||
struct wl_listener output_destroy;
|
||||
|
|
@ -29,10 +30,16 @@ struct wlr_color_management_surface_v1 {
|
|||
struct wlr_color_management_surface_feedback_v1 {
|
||||
struct wl_resource *resource;
|
||||
struct wlr_surface *surface;
|
||||
struct wlr_color_manager_v1 *manager;
|
||||
|
||||
struct wl_listener surface_destroy;
|
||||
};
|
||||
|
||||
struct wlr_image_description_v1 {
|
||||
struct wl_resource *resource;
|
||||
struct wlr_image_description_v1_data data; // immutable
|
||||
};
|
||||
|
||||
static void resource_handle_destroy(struct wl_client *client, struct wl_resource *resource) {
|
||||
wl_resource_destroy(resource);
|
||||
}
|
||||
|
|
@ -65,8 +72,23 @@ static int32_t encode_cie1931_coord(float value) {
|
|||
return round(value * 1000 * 1000);
|
||||
}
|
||||
|
||||
static const struct wp_image_description_v1_interface image_desc_impl;
|
||||
|
||||
static struct wlr_image_description_v1 *image_desc_from_resource(struct wl_resource *resource) {
|
||||
assert(wl_resource_instance_of(resource, &wp_image_description_v1_interface, &image_desc_impl));
|
||||
return wl_resource_get_user_data(resource);
|
||||
}
|
||||
|
||||
static void image_desc_handle_get_information(struct wl_client *client,
|
||||
struct wl_resource *image_desc_resource, uint32_t id) {
|
||||
struct wlr_image_description_v1 *image_desc = image_desc_from_resource(image_desc_resource);
|
||||
if (image_desc == NULL) {
|
||||
wl_resource_post_error(image_desc_resource,
|
||||
WP_IMAGE_DESCRIPTION_V1_ERROR_NOT_READY,
|
||||
"image description is in failed state");
|
||||
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);
|
||||
|
|
@ -75,24 +97,19 @@ static void image_desc_handle_get_information(struct wl_client *client,
|
|||
return;
|
||||
}
|
||||
|
||||
enum wp_color_manager_v1_primaries primaries_named =
|
||||
WP_COLOR_MANAGER_V1_PRIMARIES_SRGB;
|
||||
enum wp_color_manager_v1_transfer_function transfer_function =
|
||||
WP_COLOR_MANAGER_V1_TRANSFER_FUNCTION_SRGB;
|
||||
|
||||
struct wlr_color_primaries primaries;
|
||||
wlr_color_primaries_from_named(&primaries, named_primaries_to_wlr(primaries_named));
|
||||
wlr_color_primaries_from_named(&primaries, named_primaries_to_wlr(image_desc->data.primaries_named));
|
||||
|
||||
struct wlr_color_luminances luminances;
|
||||
wlr_color_transfer_function_get_default_luminance(transfer_function_to_wlr(transfer_function), &luminances);
|
||||
wlr_color_transfer_function_get_default_luminance(transfer_function_to_wlr(image_desc->data.tf_named), &luminances);
|
||||
|
||||
wp_image_description_info_v1_send_primaries_named(resource, primaries_named);
|
||||
wp_image_description_info_v1_send_primaries_named(resource, image_desc->data.primaries_named);
|
||||
wp_image_description_info_v1_send_primaries(resource,
|
||||
encode_cie1931_coord(primaries.red.x), encode_cie1931_coord(primaries.red.y),
|
||||
encode_cie1931_coord(primaries.green.x), encode_cie1931_coord(primaries.green.y),
|
||||
encode_cie1931_coord(primaries.blue.x), encode_cie1931_coord(primaries.blue.y),
|
||||
encode_cie1931_coord(primaries.white.x), encode_cie1931_coord(primaries.white.y));
|
||||
wp_image_description_info_v1_send_tf_named(resource, transfer_function);
|
||||
wp_image_description_info_v1_send_tf_named(resource, image_desc->data.tf_named);
|
||||
wp_image_description_info_v1_send_luminances(resource,
|
||||
round(luminances.min * 10000), round(luminances.max),
|
||||
round(luminances.reference));
|
||||
|
|
@ -115,18 +132,54 @@ static const struct wp_image_description_v1_interface image_desc_impl = {
|
|||
.get_information = image_desc_handle_get_information,
|
||||
};
|
||||
|
||||
static void image_desc_create_ready(struct wl_resource *parent_resource, uint32_t id) {
|
||||
static void image_desc_handle_resource_destroy(struct wl_resource *resource) {
|
||||
struct wlr_image_description_v1 *image_desc = image_desc_from_resource(resource);
|
||||
free(image_desc);
|
||||
}
|
||||
|
||||
static struct wl_resource *image_desc_create_resource(
|
||||
struct wl_resource *parent_resource, uint32_t id) {
|
||||
struct wl_client *client = wl_resource_get_client(parent_resource);
|
||||
uint32_t version = wl_resource_get_version(parent_resource);
|
||||
struct wl_resource *resource = wl_resource_create(client,
|
||||
&wp_image_description_v1_interface, version, id);
|
||||
if (!resource) {
|
||||
wl_client_post_no_memory(client);
|
||||
return wl_resource_create(client, &wp_image_description_v1_interface,
|
||||
version, id);
|
||||
}
|
||||
|
||||
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) {
|
||||
struct wlr_image_description_v1 *image_desc = calloc(1, sizeof(*image_desc));
|
||||
if (image_desc == NULL) {
|
||||
wl_resource_post_no_memory(parent_resource);
|
||||
return;
|
||||
}
|
||||
|
||||
image_desc->data = *data;
|
||||
|
||||
image_desc->resource = image_desc_create_resource(parent_resource, id);
|
||||
if (!image_desc->resource) {
|
||||
wl_resource_post_no_memory(parent_resource);
|
||||
free(image_desc);
|
||||
return;
|
||||
}
|
||||
wl_resource_set_implementation(image_desc->resource, &image_desc_impl,
|
||||
image_desc, image_desc_handle_resource_destroy);
|
||||
|
||||
// TODO: de-duplicate identity
|
||||
uint32_t identity = ++manager->last_image_desc_identity;
|
||||
wp_image_description_v1_send_ready(image_desc->resource, identity);
|
||||
}
|
||||
|
||||
static void image_desc_create_failed(struct wl_resource *parent_resource, uint32_t id,
|
||||
enum wp_image_description_v1_cause cause, const char *msg) {
|
||||
struct wl_resource *resource = image_desc_create_resource(parent_resource, id);
|
||||
if (resource == NULL) {
|
||||
wl_resource_post_no_memory(parent_resource);
|
||||
return;
|
||||
}
|
||||
wl_resource_set_implementation(resource, &image_desc_impl, NULL, NULL);
|
||||
|
||||
wp_image_description_v1_send_ready(resource, 1);
|
||||
wp_image_description_v1_send_failed(resource, cause, msg);
|
||||
}
|
||||
|
||||
static const struct wp_color_management_output_v1_interface cm_output_impl;
|
||||
|
|
@ -138,7 +191,19 @@ static struct wlr_color_management_output_v1 *cm_output_from_resource(struct wl_
|
|||
|
||||
static void cm_output_handle_get_image_description(struct wl_client *client,
|
||||
struct wl_resource *cm_output_resource, uint32_t id) {
|
||||
image_desc_create_ready(cm_output_resource, id);
|
||||
struct wlr_color_management_output_v1 *cm_output = cm_output_from_resource(cm_output_resource);
|
||||
if (cm_output == NULL) {
|
||||
image_desc_create_failed(cm_output_resource, id,
|
||||
WP_IMAGE_DESCRIPTION_V1_CAUSE_NO_OUTPUT,
|
||||
"output has been destroyed");
|
||||
return;
|
||||
}
|
||||
|
||||
struct wlr_image_description_v1_data data = {
|
||||
.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);
|
||||
}
|
||||
|
||||
static const struct wp_color_management_output_v1_interface cm_output_impl = {
|
||||
|
|
@ -254,7 +319,21 @@ static struct wlr_color_management_surface_feedback_v1 *surface_feedback_from_re
|
|||
|
||||
static void surface_feedback_handle_get_preferred(struct wl_client *client,
|
||||
struct wl_resource *surface_feedback_resource, uint32_t id) {
|
||||
image_desc_create_ready(surface_feedback_resource, id);
|
||||
struct wlr_color_management_surface_feedback_v1 *surface_feedback =
|
||||
surface_feedback_from_resource(surface_feedback_resource);
|
||||
if (surface_feedback == NULL) {
|
||||
wl_resource_post_error(surface_feedback_resource,
|
||||
WP_COLOR_MANAGEMENT_SURFACE_FEEDBACK_V1_ERROR_INERT,
|
||||
"get_preferred sent on inert feedback surface");
|
||||
return;
|
||||
}
|
||||
|
||||
struct wlr_image_description_v1_data data = {
|
||||
.tf_named = WP_COLOR_MANAGER_V1_TRANSFER_FUNCTION_SRGB,
|
||||
.primaries_named = WP_COLOR_MANAGER_V1_PRIMARIES_SRGB,
|
||||
};
|
||||
image_desc_create_ready(surface_feedback->manager,
|
||||
surface_feedback_resource, id, &data);
|
||||
}
|
||||
|
||||
static const struct wp_color_management_surface_feedback_v1_interface surface_feedback_impl = {
|
||||
|
|
@ -302,6 +381,8 @@ static void manager_handle_get_output(struct wl_client *client,
|
|||
return;
|
||||
}
|
||||
|
||||
cm_output->manager = manager;
|
||||
|
||||
uint32_t version = wl_resource_get_version(manager_resource);
|
||||
cm_output->resource = wl_resource_create(client,
|
||||
&wp_color_management_output_v1_interface, version, id);
|
||||
|
|
@ -357,6 +438,7 @@ static void manager_handle_get_surface(struct wl_client *client,
|
|||
static void manager_handle_get_surface_feedback(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);
|
||||
|
||||
struct wlr_color_management_surface_feedback_v1 *surface_feedback =
|
||||
|
|
@ -366,6 +448,8 @@ static void manager_handle_get_surface_feedback(struct wl_client *client,
|
|||
return;
|
||||
}
|
||||
|
||||
surface_feedback->manager = manager;
|
||||
|
||||
uint32_t version = wl_resource_get_version(manager_resource);
|
||||
surface_feedback->resource = wl_resource_create(client,
|
||||
&wp_color_management_surface_feedback_v1_interface, version, id);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue