[mutter] MonitorManager: Add support for overscan compensation



commit cc53d48fa85a7efab2deeddea0a4a439784b20cf
Author: Tomeu Vizoso <tomeu vizoso collabora com>
Date:   Wed Apr 16 10:20:55 2014 +0200

    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.

 src/backends/meta-monitor-config.c             |   14 ++++-
 src/backends/meta-monitor-manager-private.h    |    2 +
 src/backends/meta-monitor-manager.c            |    7 ++-
 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 6cc42fd..c067bd2 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 5a6740c..04ffcf4 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 7fa5139..4ebe800 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 d950592..8eaffb1 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 */


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]