Atlas - SDL_waylandcolor.c

Home / ext / SDL / src / video / wayland Lines: 1 | Size: 14348 bytes [Download] [Show on GitHub] [Search similar files] [Raw] [Raw (proxy)]
[FILE BEGIN]
1/* 2 Simple DirectMedia Layer 3 Copyright (C) 1997-2025 Sam Lantinga <[email protected]> 4 5 This software is provided 'as-is', without any express or implied 6 warranty. In no event will the authors be held liable for any damages 7 arising from the use of this software. 8 9 Permission is granted to anyone to use this software for any purpose, 10 including commercial applications, and to alter it and redistribute it 11 freely, subject to the following restrictions: 12 13 1. The origin of this software must not be misrepresented; you must not 14 claim that you wrote the original software. If you use this software 15 in a product, an acknowledgment in the product documentation would be 16 appreciated but is not required. 17 2. Altered source versions must be plainly marked as such, and must not be 18 misrepresented as being the original software. 19 3. This notice may not be removed or altered from any source distribution. 20*/ 21 22#include "SDL_internal.h" 23 24#ifdef SDL_VIDEO_DRIVER_WAYLAND 25 26#include "SDL_waylandcolor.h" 27#include "SDL_waylandvideo.h" 28#include "SDL_waylandwindow.h" 29#include "color-management-v1-client-protocol.h" 30#include "../../events/SDL_windowevents_c.h" 31 32typedef struct Wayland_ColorInfoState 33{ 34 struct wp_image_description_v1 *wp_image_description; 35 struct wp_image_description_info_v1 *wp_image_description_info; 36 struct wl_event_queue *queue; 37 38 union 39 { 40 SDL_WindowData *window_data; 41 SDL_DisplayData *display_data; 42 }; 43 44 enum 45 { 46 WAYLAND_COLOR_OBJECT_TYPE_WINDOW, 47 WAYLAND_COLOR_OBJECT_TYPE_DISPLAY 48 } object_type; 49 50 SDL_HDROutputProperties HDR; 51 52 // The ICC fd is only valid if the size is non-zero. 53 int icc_fd; 54 Uint32 icc_size; 55 56 bool deferred_event_processing; 57} Wayland_ColorInfoState; 58 59static void Wayland_CancelColorInfoRequest(Wayland_ColorInfoState *state) 60{ 61 if (state) { 62 if (state->wp_image_description_info) { 63 wp_image_description_info_v1_destroy(state->wp_image_description_info); 64 state->wp_image_description_info = NULL; 65 } 66 if (state->wp_image_description) { 67 wp_image_description_v1_destroy(state->wp_image_description); 68 state->wp_image_description = NULL; 69 } 70 } 71} 72 73void Wayland_FreeColorInfoState(Wayland_ColorInfoState *state) 74{ 75 if (state) { 76 Wayland_CancelColorInfoRequest(state); 77 if (state->queue) { 78 WAYLAND_wl_event_queue_destroy(state->queue); 79 } 80 81 switch (state->object_type) { 82 case WAYLAND_COLOR_OBJECT_TYPE_WINDOW: 83 state->window_data->color_info_state = NULL; 84 break; 85 case WAYLAND_COLOR_OBJECT_TYPE_DISPLAY: 86 state->display_data->color_info_state = NULL; 87 break; 88 } 89 90 SDL_free(state); 91 } 92} 93 94static void image_description_info_handle_done(void *data, 95 struct wp_image_description_info_v1 *wp_image_description_info_v1) 96{ 97 Wayland_ColorInfoState *state = (Wayland_ColorInfoState *)data; 98 Wayland_CancelColorInfoRequest(state); 99 100 switch (state->object_type) { 101 case WAYLAND_COLOR_OBJECT_TYPE_WINDOW: 102 { 103 SDL_SetWindowHDRProperties(state->window_data->sdlwindow, &state->HDR, true); 104 if (state->icc_size) { 105 state->window_data->icc_fd = state->icc_fd; 106 state->window_data->icc_size = state->icc_size; 107 SDL_SendWindowEvent(state->window_data->sdlwindow, SDL_EVENT_WINDOW_ICCPROF_CHANGED, 0, 0); 108 } 109 } break; 110 case WAYLAND_COLOR_OBJECT_TYPE_DISPLAY: 111 { 112 SDL_copyp(&state->display_data->HDR, &state->HDR); 113 114 if (state->display_data->display) { 115 SDL_VideoDisplay *disp = SDL_GetVideoDisplay(state->display_data->display); 116 if (disp) { 117 SDL_SetDisplayHDRProperties(disp, &state->HDR); 118 } 119 } else { 120 SDL_copyp(&state->display_data->placeholder.HDR, &state->HDR); 121 } 122 } break; 123 } 124} 125 126static void image_description_info_handle_icc_file(void *data, 127 struct wp_image_description_info_v1 *wp_image_description_info_v1, 128 int32_t icc, uint32_t icc_size) 129{ 130 Wayland_ColorInfoState *state = (Wayland_ColorInfoState *)data; 131 132 state->icc_fd = icc; 133 state->icc_size = icc_size; 134} 135 136static void image_description_info_handle_primaries(void *data, 137 struct wp_image_description_info_v1 *wp_image_description_info_v1, 138 int32_t r_x, int32_t r_y, 139 int32_t g_x, int32_t g_y, 140 int32_t b_x, int32_t b_y, 141 int32_t w_x, int32_t w_y) 142{ 143 // NOP 144} 145 146static void image_description_info_handle_primaries_named(void *data, 147 struct wp_image_description_info_v1 *wp_image_description_info_v1, 148 uint32_t primaries) 149{ 150 // NOP 151} 152 153static void image_description_info_handle_tf_power(void *data, 154 struct wp_image_description_info_v1 *wp_image_description_info_v1, 155 uint32_t eexp) 156{ 157 // NOP 158} 159 160static void image_description_info_handle_tf_named(void *data, 161 struct wp_image_description_info_v1 *wp_image_description_info_v1, 162 uint32_t tf) 163{ 164 // NOP 165} 166 167static void image_description_info_handle_luminances(void *data, 168 struct wp_image_description_info_v1 *wp_image_description_info_v1, 169 uint32_t min_lum, 170 uint32_t max_lum, 171 uint32_t reference_lum) 172{ 173 Wayland_ColorInfoState *state = (Wayland_ColorInfoState *)data; 174 state->HDR.HDR_headroom = (float)max_lum / (float)reference_lum; 175} 176 177static void image_description_info_handle_target_primaries(void *data, 178 struct wp_image_description_info_v1 *wp_image_description_info_v1, 179 int32_t r_x, int32_t r_y, 180 int32_t g_x, int32_t g_y, 181 int32_t b_x, int32_t b_y, 182 int32_t w_x, int32_t w_y) 183{ 184 // NOP 185} 186 187static void image_description_info_handle_target_luminance(void *data, 188 struct wp_image_description_info_v1 *wp_image_description_info_v1, 189 uint32_t min_lum, 190 uint32_t max_lum) 191{ 192 // NOP 193} 194 195static void image_description_info_handle_target_max_cll(void *data, 196 struct wp_image_description_info_v1 *wp_image_description_info_v1, 197 uint32_t max_cll) 198{ 199 // NOP 200} 201 202static void image_description_info_handle_target_max_fall(void *data, 203 struct wp_image_description_info_v1 *wp_image_description_info_v1, 204 uint32_t max_fall) 205{ 206 // NOP 207} 208 209static const struct wp_image_description_info_v1_listener image_description_info_listener = { 210 image_description_info_handle_done, 211 image_description_info_handle_icc_file, 212 image_description_info_handle_primaries, 213 image_description_info_handle_primaries_named, 214 image_description_info_handle_tf_power, 215 image_description_info_handle_tf_named, 216 image_description_info_handle_luminances, 217 image_description_info_handle_target_primaries, 218 image_description_info_handle_target_luminance, 219 image_description_info_handle_target_max_cll, 220 image_description_info_handle_target_max_fall 221}; 222 223static void PumpColorspaceEvents(Wayland_ColorInfoState *state) 224{ 225 SDL_VideoData *vid = SDL_GetVideoDevice()->internal; 226 227 // Run the image description sequence to completion in its own queue. 228 while (state->wp_image_description) { 229 WAYLAND_wl_display_dispatch_queue(vid->display, state->queue); 230 } 231 232 Wayland_FreeColorInfoState(state); 233} 234 235static void image_description_handle_failed(void *data, 236 struct wp_image_description_v1 *wp_image_description_v1, 237 uint32_t cause, 238 const char *msg) 239{ 240 Wayland_ColorInfoState *state = (Wayland_ColorInfoState *)data; 241 Wayland_CancelColorInfoRequest(state); 242 243 if (state->deferred_event_processing) { 244 Wayland_FreeColorInfoState(state); 245 } 246} 247 248static void image_description_handle_ready2(void *data, 249 struct wp_image_description_v1 *wp_image_description_v1, 250 uint32_t identity_hi, uint32_t identity_lo) 251{ 252 Wayland_ColorInfoState *state = (Wayland_ColorInfoState *)data; 253 254 /* If event processing was deferred, then the image description is on the default queue. 255 * Otherwise, it will inherit the queue from the image description object. 256 */ 257 if (state->deferred_event_processing) { 258 SDL_VideoData *vid = SDL_GetVideoDevice()->internal; 259 state->queue = Wayland_DisplayCreateQueue(vid->display, "SDL Color Management Queue"); 260 261 struct wl_proxy *image_desc_wrapper = WAYLAND_wl_proxy_create_wrapper(state->wp_image_description); 262 WAYLAND_wl_proxy_set_queue(image_desc_wrapper, state->queue); 263 state->wp_image_description_info = wp_image_description_v1_get_information((struct wp_image_description_v1 *)image_desc_wrapper); 264 WAYLAND_wl_proxy_wrapper_destroy(image_desc_wrapper); 265 } else { 266 state->wp_image_description_info = wp_image_description_v1_get_information(state->wp_image_description); 267 } 268 wp_image_description_info_v1_add_listener(state->wp_image_description_info, &image_description_info_listener, data); 269 270 if (state->deferred_event_processing) { 271 PumpColorspaceEvents(state); 272 } 273} 274 275static void image_description_handle_ready(void *data, 276 struct wp_image_description_v1 *wp_image_description_v1, 277 uint32_t identity) 278{ 279 image_description_handle_ready2(data, wp_image_description_v1, 0, identity); 280} 281 282static const struct wp_image_description_v1_listener image_description_listener = { 283 image_description_handle_failed, 284 image_description_handle_ready, 285 image_description_handle_ready2 286}; 287 288void Wayland_GetColorInfoForWindow(SDL_WindowData *window_data, bool defer_event_processing) 289{ 290 // Cancel any pending request, as it is out-of-date. 291 Wayland_FreeColorInfoState(window_data->color_info_state); 292 Wayland_ColorInfoState *state = SDL_calloc(1, sizeof(Wayland_ColorInfoState)); 293 294 if (state) { 295 window_data->color_info_state = state; 296 state->window_data = window_data; 297 state->object_type = WAYLAND_COLOR_OBJECT_TYPE_WINDOW; 298 state->deferred_event_processing = defer_event_processing; 299 300 if (!defer_event_processing) { 301 state->queue = Wayland_DisplayCreateQueue(window_data->waylandData->display, "SDL Color Management Queue"); 302 303 struct wl_proxy *surface_feedback_wrapper = WAYLAND_wl_proxy_create_wrapper(window_data->wp_color_management_surface_feedback); 304 WAYLAND_wl_proxy_set_queue(surface_feedback_wrapper, state->queue); 305 state->wp_image_description = wp_color_management_surface_feedback_v1_get_preferred((struct wp_color_management_surface_feedback_v1 *)surface_feedback_wrapper); 306 WAYLAND_wl_proxy_wrapper_destroy(surface_feedback_wrapper); 307 } else { 308 state->wp_image_description = wp_color_management_surface_feedback_v1_get_preferred(window_data->wp_color_management_surface_feedback); 309 } 310 wp_image_description_v1_add_listener(state->wp_image_description, &image_description_listener, state); 311 312 if (!defer_event_processing) { 313 PumpColorspaceEvents(state); 314 } 315 } 316} 317 318void Wayland_GetColorInfoForOutput(SDL_DisplayData *display_data, bool defer_event_processing) 319{ 320 // Cancel any pending request, as it is out-of-date. 321 Wayland_FreeColorInfoState(display_data->color_info_state); 322 Wayland_ColorInfoState *state = SDL_calloc(1, sizeof(Wayland_ColorInfoState)); 323 324 if (state) { 325 display_data->color_info_state = state; 326 state->display_data = display_data; 327 state->object_type = WAYLAND_COLOR_OBJECT_TYPE_DISPLAY; 328 state->deferred_event_processing = defer_event_processing; 329 330 if (!defer_event_processing) { 331 state->queue = Wayland_DisplayCreateQueue(display_data->videodata->display, "SDL Color Management Queue"); 332 333 struct wl_proxy *output_feedback_wrapper = WAYLAND_wl_proxy_create_wrapper(display_data->wp_color_management_output); 334 WAYLAND_wl_proxy_set_queue(output_feedback_wrapper, state->queue); 335 state->wp_image_description = wp_color_management_output_v1_get_image_description((struct wp_color_management_output_v1 *)output_feedback_wrapper); 336 WAYLAND_wl_proxy_wrapper_destroy(output_feedback_wrapper); 337 } else { 338 state->wp_image_description = wp_color_management_output_v1_get_image_description(display_data->wp_color_management_output); 339 } 340 wp_image_description_v1_add_listener(state->wp_image_description, &image_description_listener, state); 341 342 if (!defer_event_processing) { 343 PumpColorspaceEvents(state); 344 } 345 } 346} 347 348#endif // SDL_VIDEO_DRIVER_WAYLAND 349
[FILE END]
(C) 2025 0x4248 (C) 2025 4248 Media and 4248 Systems, All part of 0x4248 See LICENCE files for more information. Not all files are by 0x4248 always check Licencing.