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 @@ + + + + + + + + + + + + + + + + + +