From 8325f0eda53c354f05c1463a484e0f4a42581af7 Mon Sep 17 00:00:00 2001 From: Giovanni Campagna Date: Fri, 26 Jul 2013 15:57:34 +0200 Subject: [PATCH] MonitorManager: add gamma support Add GetCrtcGamma() and SetCrtcGamma(), that wrap the similarly named XRandR API. These are used by GnomeRR inside the color plugin of the control center (and may go away if the color plugin decides to do something different under wayland) --- src/core/monitor.c | 180 +++++++++++++++++++++++++++++++++++++++++++++ src/xrandr.xml | 37 +++++++++- 2 files changed, 216 insertions(+), 1 deletion(-) diff --git a/src/core/monitor.c b/src/core/monitor.c index 3e74e2789..edeadae9a 100644 --- a/src/core/monitor.c +++ b/src/core/monitor.c @@ -1867,12 +1867,192 @@ meta_monitor_manager_handle_change_backlight (MetaDBusDisplayConfig *skeleton, return TRUE; } +#ifdef HAVE_RANDR +static void +handle_get_crtc_gamma_xrandr (MetaMonitorManager *manager, + MetaCRTC *crtc, + gsize *size, + unsigned short **red, + unsigned short **green, + unsigned short **blue) +{ + XRRCrtcGamma *gamma; + + gamma = XRRGetCrtcGamma (manager->xdisplay, (XID)crtc->crtc_id); + + *size = gamma->size; + *red = g_memdup (gamma->red, sizeof (unsigned short) * gamma->size); + *green = g_memdup (gamma->green, sizeof (unsigned short) * gamma->size); + *blue = g_memdup (gamma->blue, sizeof (unsigned short) * gamma->size); + + XRRFreeGamma (gamma); +} +#endif + +static void +handle_get_crtc_gamma_dummy (MetaMonitorManager *manager, + MetaCRTC *crtc, + gsize *size, + unsigned short **red, + unsigned short **green, + unsigned short **blue) +{ + *size = 0; + *red = g_new0 (unsigned short, 0); + *green = g_new0 (unsigned short, 0); + *blue = g_new0 (unsigned short, 0); +} + +static gboolean +meta_monitor_manager_handle_get_crtc_gamma (MetaDBusDisplayConfig *skeleton, + GDBusMethodInvocation *invocation, + guint serial, + guint crtc_id) +{ + MetaMonitorManager *manager = META_MONITOR_MANAGER (skeleton); + MetaCRTC *crtc; + gsize size; + unsigned short *red; + unsigned short *green; + unsigned short *blue; + GBytes *red_bytes, *green_bytes, *blue_bytes; + GVariant *red_v, *green_v, *blue_v; + + if (serial != manager->serial) + { + g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR, + G_DBUS_ERROR_ACCESS_DENIED, + "The requested configuration is based on stale information"); + return TRUE; + } + + if (crtc_id < 0 || crtc_id >= manager->n_crtcs) + { + g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR, + G_DBUS_ERROR_INVALID_ARGS, + "Invalid crtc id"); + return TRUE; + } + crtc = &manager->crtcs[crtc_id]; + + if (manager->backend == META_BACKEND_XRANDR) + handle_get_crtc_gamma_xrandr (manager, crtc, &size, &red, &green, &blue); + else + handle_get_crtc_gamma_dummy (manager, crtc, &size, &red, &green, &blue); + + red_bytes = g_bytes_new_take (red, size * sizeof (unsigned short)); + green_bytes = g_bytes_new_take (green, size * sizeof (unsigned short)); + blue_bytes = g_bytes_new_take (blue, size * sizeof (unsigned short)); + + red_v = g_variant_new_from_bytes (G_VARIANT_TYPE ("aq"), red_bytes, TRUE); + green_v = g_variant_new_from_bytes (G_VARIANT_TYPE ("aq"), green_bytes, TRUE); + blue_v = g_variant_new_from_bytes (G_VARIANT_TYPE ("aq"), blue_bytes, TRUE); + + meta_dbus_display_config_complete_get_crtc_gamma (skeleton, invocation, + red_v, green_v, blue_v); + + g_bytes_unref (red_bytes); + g_bytes_unref (green_bytes); + g_bytes_unref (blue_bytes); + + return TRUE; +} + +#ifdef HAVE_RANDR +static void +handle_set_crtc_gamma_xrandr (MetaMonitorManager *manager, + MetaCRTC *crtc, + gsize size, + unsigned short *red, + unsigned short *green, + unsigned short *blue) +{ + XRRCrtcGamma gamma; + + gamma.size = size; + gamma.red = red; + gamma.green = green; + gamma.blue = blue; + + XRRSetCrtcGamma (manager->xdisplay, (XID)crtc->crtc_id, &gamma); +} +#endif + +static void +handle_set_crtc_gamma_dummy (MetaMonitorManager *manager, + MetaCRTC *crtc, + gsize size, + unsigned short *red, + unsigned short *green, + unsigned short *blue) +{ +} + +static gboolean +meta_monitor_manager_handle_set_crtc_gamma (MetaDBusDisplayConfig *skeleton, + GDBusMethodInvocation *invocation, + guint serial, + guint crtc_id, + GVariant *red_v, + GVariant *green_v, + GVariant *blue_v) +{ + MetaMonitorManager *manager = META_MONITOR_MANAGER (skeleton); + MetaCRTC *crtc; + gsize size, dummy; + unsigned short *red; + unsigned short *green; + unsigned short *blue; + GBytes *red_bytes, *green_bytes, *blue_bytes; + + if (serial != manager->serial) + { + g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR, + G_DBUS_ERROR_ACCESS_DENIED, + "The requested configuration is based on stale information"); + return TRUE; + } + + if (crtc_id < 0 || crtc_id >= manager->n_crtcs) + { + g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR, + G_DBUS_ERROR_INVALID_ARGS, + "Invalid crtc id"); + return TRUE; + } + crtc = &manager->crtcs[crtc_id]; + + red_bytes = g_variant_get_data_as_bytes (red_v); + green_bytes = g_variant_get_data_as_bytes (green_v); + blue_bytes = g_variant_get_data_as_bytes (blue_v); + + size = g_bytes_get_size (red_bytes) / sizeof (unsigned short); + red = (unsigned short*) g_bytes_get_data (red_bytes, &dummy); + green = (unsigned short*) g_bytes_get_data (green_bytes, &dummy); + blue = (unsigned short*) g_bytes_get_data (blue_bytes, &dummy); + + if (manager->backend == META_BACKEND_XRANDR) + handle_set_crtc_gamma_xrandr (manager, crtc, size, red, green, blue); + else + handle_set_crtc_gamma_dummy (manager, crtc, size, red, green, blue); + + meta_dbus_display_config_complete_set_crtc_gamma (skeleton, invocation); + + g_bytes_unref (red_bytes); + g_bytes_unref (green_bytes); + g_bytes_unref (blue_bytes); + + return TRUE; +} + static void meta_monitor_manager_display_config_init (MetaDBusDisplayConfigIface *iface) { iface->handle_get_resources = meta_monitor_manager_handle_get_resources; iface->handle_apply_configuration = meta_monitor_manager_handle_apply_configuration; iface->handle_change_backlight = meta_monitor_manager_handle_change_backlight; + iface->handle_get_crtc_gamma = meta_monitor_manager_handle_get_crtc_gamma; + iface->handle_set_crtc_gamma = meta_monitor_manager_handle_set_crtc_gamma; } static void diff --git a/src/xrandr.xml b/src/xrandr.xml index 02255361b..b0db9a0da 100644 --- a/src/xrandr.xml +++ b/src/xrandr.xml @@ -62,7 +62,6 @@ CRTC; they are not necessarily reflected in the hardware. No property is specified in this version of the API. - FIXME: gamma? Note: all geometry information refers to the untransformed display. @@ -215,6 +214,42 @@ + + + + + + + + + + + + + + + + + +