diff options
author | Tomeu Vizoso <tomeu.vizoso@collabora.com> | 2014-04-16 10:20:55 +0200 |
---|---|---|
committer | Jasper St. Pierre <jstpierre@mecheye.net> | 2015-04-27 17:17:15 -0700 |
commit | cc53d48fa85a7efab2deeddea0a4a439784b20cf (patch) | |
tree | 700f5eb969cfde9e7eaaeac745325497b8cf01e6 | |
parent | ca6e799b97a9ec24d3c4b608f4c0ac57eedd3026 (diff) |
MonitorManager: Add support for overscan compensation
Some DRM drivers have added a consistent set of properties that
allow compensating for the overscan that some TVs do, without the
user being able to disable.
-rw-r--r-- | src/backends/meta-monitor-config.c | 14 | ||||
-rw-r--r-- | src/backends/meta-monitor-manager-private.h | 2 | ||||
-rw-r--r-- | src/backends/meta-monitor-manager.c | 7 | ||||
-rw-r--r-- | src/backends/x11/meta-monitor-manager-xrandr.c | 59 |
4 files changed, 78 insertions, 4 deletions
diff --git a/src/backends/meta-monitor-config.c b/src/backends/meta-monitor-config.c index 6cc42fd1..c067bd26 100644 --- a/src/backends/meta-monitor-config.c +++ b/src/backends/meta-monitor-config.c @@ -65,6 +65,7 @@ typedef struct { gboolean is_primary; gboolean is_presentation; + gboolean is_underscanning; } MetaOutputConfig; typedef struct { @@ -403,7 +404,8 @@ handle_start_element (GMarkupParseContext *context, strcmp (element_name, "reflect_x") == 0 || strcmp (element_name, "reflect_y") == 0 || strcmp (element_name, "primary") == 0 || - strcmp (element_name, "presentation") == 0) && parser->unknown_count == 0) + strcmp (element_name, "presentation") == 0 || + strcmp (element_name, "underscanning") == 0) && parser->unknown_count == 0) { parser->state = STATE_OUTPUT_FIELD; @@ -710,6 +712,8 @@ handle_text (GMarkupParseContext *context, parser->output.is_primary = read_bool (text, text_len, error); else if (strcmp (parser->output_field, "presentation") == 0) parser->output.is_presentation = read_bool (text, text_len, error); + else if (strcmp (parser->output_field, "underscanning") == 0) + parser->output.is_underscanning = read_bool (text, text_len, error); else g_assert_not_reached (); return; @@ -1427,6 +1431,7 @@ init_config_from_output (MetaOutputConfig *config, config->transform = output->crtc->transform; config->is_primary = output->is_primary; config->is_presentation = output->is_presentation; + config->is_underscanning = output->is_underscanning; } void @@ -1617,7 +1622,8 @@ meta_monitor_config_save (MetaMonitorConfig *self) " <reflect_x>%s</reflect_x>\n" " <reflect_y>no</reflect_y>\n" " <primary>%s</primary>\n" - " <presentation>%s</presentation>\n", + " <presentation>%s</presentation>\n" + " <underscanning>%s</underscanning>\n", output->rect.width, output->rect.height, refresh_rate, @@ -1626,7 +1632,8 @@ meta_monitor_config_save (MetaMonitorConfig *self) rotation_map[output->transform & 0x3], output->transform >= META_MONITOR_TRANSFORM_FLIPPED ? "yes" : "no", output->is_primary ? "yes" : "no", - output->is_presentation ? "yes" : "no"); + output->is_presentation ? "yes" : "no", + output->is_underscanning ? "yes" : "no"); } g_string_append (buffer, " </output>\n"); @@ -1960,6 +1967,7 @@ meta_monitor_config_assign_crtcs (MetaConfiguration *config, &config->keys[i]); output_info->is_primary = output_config->is_primary; output_info->is_presentation = output_config->is_presentation; + output_info->is_underscanning = output_config->is_underscanning; g_ptr_array_add (outputs, output_info); } diff --git a/src/backends/meta-monitor-manager-private.h b/src/backends/meta-monitor-manager-private.h index 5a6740c9..04ffcf4e 100644 --- a/src/backends/meta-monitor-manager-private.h +++ b/src/backends/meta-monitor-manager-private.h @@ -132,6 +132,7 @@ struct _MetaOutput */ gboolean is_primary; gboolean is_presentation; + gboolean is_underscanning; gpointer driver_private; GDestroyNotify driver_notify; @@ -230,6 +231,7 @@ struct _MetaOutputInfo { MetaOutput *output; gboolean is_primary; gboolean is_presentation; + gboolean is_underscanning; }; #define META_TYPE_MONITOR_MANAGER (meta_monitor_manager_get_type ()) diff --git a/src/backends/meta-monitor-manager.c b/src/backends/meta-monitor-manager.c index 7fa51396..4ebe8002 100644 --- a/src/backends/meta-monitor-manager.c +++ b/src/backends/meta-monitor-manager.c @@ -520,6 +520,8 @@ meta_monitor_manager_handle_get_resources (MetaDBusDisplayConfig *skeleton, g_variant_new_boolean (output->is_presentation)); g_variant_builder_add (&properties, "{sv}", "connector-type", g_variant_new_string (get_connector_type_name (output->connector_type))); + g_variant_builder_add (&properties, "{sv}", "underscanning", + g_variant_new_boolean (output->is_underscanning)); edid_file = manager_class->get_edid_file (manager, output); if (edid_file) @@ -808,7 +810,7 @@ meta_monitor_manager_handle_apply_configuration (MetaDBusDisplayConfig *skeleto while (g_variant_iter_loop (&output_iter, "(u@a{sv})", &output_index, &properties)) { MetaOutputInfo *output_info; - gboolean primary, presentation; + gboolean primary, presentation, underscanning; if (output_index >= manager->n_outputs) { @@ -827,6 +829,9 @@ meta_monitor_manager_handle_apply_configuration (MetaDBusDisplayConfig *skeleto if (g_variant_lookup (properties, "presentation", "b", &presentation)) output_info->is_presentation = presentation; + if (g_variant_lookup (properties, "underscanning", "b", &underscanning)) + output_info->is_underscanning = underscanning; + g_ptr_array_add (output_infos, output_info); } diff --git a/src/backends/x11/meta-monitor-manager-xrandr.c b/src/backends/x11/meta-monitor-manager-xrandr.c index d9505926..8eaffb13 100644 --- a/src/backends/x11/meta-monitor-manager-xrandr.c +++ b/src/backends/x11/meta-monitor-manager-xrandr.c @@ -225,6 +225,38 @@ output_get_presentation_xrandr (MetaMonitorManagerXrandr *manager_xrandr, return output_get_boolean_property (manager_xrandr, output, "_MUTTER_PRESENTATION_OUTPUT"); } +static gboolean +output_get_underscanning_xrandr (MetaMonitorManagerXrandr *manager_xrandr, + MetaOutput *output) +{ + gboolean value = FALSE; + Atom atom, actual_type; + int actual_format; + unsigned long nitems, bytes_after; + unsigned char *buffer; + char *str; + + atom = XInternAtom (manager_xrandr->xdisplay, "underscan", False); + XRRGetOutputProperty (manager_xrandr->xdisplay, + (XID)output->winsys_id, + atom, + 0, G_MAXLONG, False, False, XA_ATOM, + &actual_type, &actual_format, + &nitems, &bytes_after, &buffer); + + if (actual_type != XA_ATOM || actual_format != 32 || + nitems < 1) + goto out; + + str = XGetAtomName (manager_xrandr->xdisplay, *(Atom *)buffer); + value = !strcmp(str, "on"); + XFree (str); + +out: + XFree (buffer); + return value; +} + static int normalize_backlight (MetaOutput *output, int hw_value) @@ -756,6 +788,7 @@ meta_monitor_manager_xrandr_read_current (MetaMonitorManager *manager) meta_output->is_primary = ((XID)meta_output->winsys_id == primary_output); meta_output->is_presentation = output_get_presentation_xrandr (manager_xrandr, meta_output); + meta_output->is_underscanning = output_get_underscanning_xrandr (manager_xrandr, meta_output); output_get_backlight_limits_xrandr (manager_xrandr, meta_output); if (!(meta_output->backlight_min == 0 && meta_output->backlight_max == 0)) @@ -877,6 +910,27 @@ output_set_presentation_xrandr (MetaMonitorManagerXrandr *manager_xrandr, } static void +output_set_underscanning_xrandr (MetaMonitorManagerXrandr *manager_xrandr, + MetaOutput *output, + gboolean underscanning) +{ + Atom prop, valueatom; + const char *value; + + prop = XInternAtom (manager_xrandr->xdisplay, "underscan", False); + + /* XXX: Also implement underscan border */ + value = underscanning ? "on" : "off"; + valueatom = XInternAtom (manager_xrandr->xdisplay, value, False); + + XRRChangeOutputProperty (manager_xrandr->xdisplay, + (XID)output->winsys_id, + prop, + XA_ATOM, 32, PropModeReplace, + (unsigned char*) &valueatom, 1); +} + +static void meta_monitor_manager_xrandr_apply_configuration (MetaMonitorManager *manager, MetaCRTCInfo **crtcs, unsigned int n_crtcs, @@ -1071,8 +1125,13 @@ meta_monitor_manager_xrandr_apply_configuration (MetaMonitorManager *manager, output_info->output, output_info->is_presentation); + output_set_underscanning_xrandr (manager_xrandr, + output_info->output, + output_info->is_underscanning); + output->is_primary = output_info->is_primary; output->is_presentation = output_info->is_presentation; + output->is_underscanning = output_info->is_underscanning; } /* Disable outputs not mentioned in the list */ |