[mutter] monitor-manager: Add a connector-type property



commit d514e8ab41eaa33ec48919cecbc2c760758ef990
Author: Jasper St. Pierre <jstpierre mecheye net>
Date:   Mon Dec 29 16:18:24 2014 -0800

    monitor-manager: Add a connector-type property
    
    This is so gnome-settings-daemon

 src/backends/meta-monitor-manager.c            |   28 +++++
 src/backends/meta-monitor-manager.h            |   23 ++++
 src/backends/native/meta-monitor-manager-kms.c |    3 +
 src/backends/x11/meta-monitor-manager-xrandr.c |  142 ++++++++++++++++++++++++
 4 files changed, 196 insertions(+), 0 deletions(-)
---
diff --git a/src/backends/meta-monitor-manager.c b/src/backends/meta-monitor-manager.c
index 59c7154..c6d1682 100644
--- a/src/backends/meta-monitor-manager.c
+++ b/src/backends/meta-monitor-manager.c
@@ -396,6 +396,32 @@ make_display_name (MetaMonitorManager *manager,
   return ret;
 }
 
+static const char *
+get_connector_type_name (MetaConnectorType connector_type)
+{
+  switch (connector_type)
+    {
+    case META_CONNECTOR_TYPE_Unknown: return "Unknown";
+    case META_CONNECTOR_TYPE_VGA: return "VGA";
+    case META_CONNECTOR_TYPE_DVII: return "DVII";
+    case META_CONNECTOR_TYPE_DVID: return "DVID";
+    case META_CONNECTOR_TYPE_DVIA: return "DVIA";
+    case META_CONNECTOR_TYPE_Composite: return "Composite";
+    case META_CONNECTOR_TYPE_SVIDEO: return "SVIDEO";
+    case META_CONNECTOR_TYPE_LVDS: return "LVDS";
+    case META_CONNECTOR_TYPE_Component: return "Component";
+    case META_CONNECTOR_TYPE_9PinDIN: return "9PinDIN";
+    case META_CONNECTOR_TYPE_DisplayPort: return "DisplayPort";
+    case META_CONNECTOR_TYPE_HDMIA: return "HDMIA";
+    case META_CONNECTOR_TYPE_HDMIB: return "HDMIB";
+    case META_CONNECTOR_TYPE_TV: return "TV";
+    case META_CONNECTOR_TYPE_eDP: return "eDP";
+    case META_CONNECTOR_TYPE_VIRTUAL: return "VIRTUAL";
+    case META_CONNECTOR_TYPE_DSI: return "DSI";
+    default: g_assert_not_reached ();
+    }
+}
+
 static gboolean
 meta_monitor_manager_handle_get_resources (MetaDBusDisplayConfig *skeleton,
                                            GDBusMethodInvocation *invocation)
@@ -476,6 +502,8 @@ meta_monitor_manager_handle_get_resources (MetaDBusDisplayConfig *skeleton,
                              g_variant_new_boolean (output->is_primary));
       g_variant_builder_add (&properties, "{sv}", "presentation",
                              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)));
 
       edid_file = manager_class->get_edid_file (manager, output);
       if (edid_file)
diff --git a/src/backends/meta-monitor-manager.h b/src/backends/meta-monitor-manager.h
index 102759f..8ba3b46 100644
--- a/src/backends/meta-monitor-manager.h
+++ b/src/backends/meta-monitor-manager.h
@@ -69,6 +69,27 @@ typedef enum {
   META_MONITOR_TRANSFORM_FLIPPED_270,
 } MetaMonitorTransform;
 
+/* This matches the values in drm_mode.h */
+typedef enum {
+  META_CONNECTOR_TYPE_Unknown = 0,
+  META_CONNECTOR_TYPE_VGA = 1,
+  META_CONNECTOR_TYPE_DVII = 2,
+  META_CONNECTOR_TYPE_DVID = 3,
+  META_CONNECTOR_TYPE_DVIA = 4,
+  META_CONNECTOR_TYPE_Composite = 5,
+  META_CONNECTOR_TYPE_SVIDEO = 6,
+  META_CONNECTOR_TYPE_LVDS = 7,
+  META_CONNECTOR_TYPE_Component = 8,
+  META_CONNECTOR_TYPE_9PinDIN = 9,
+  META_CONNECTOR_TYPE_DisplayPort = 10,
+  META_CONNECTOR_TYPE_HDMIA = 11,
+  META_CONNECTOR_TYPE_HDMIB = 12,
+  META_CONNECTOR_TYPE_TV = 13,
+  META_CONNECTOR_TYPE_eDP = 14,
+  META_CONNECTOR_TYPE_VIRTUAL = 15,
+  META_CONNECTOR_TYPE_DSI = 16,
+} MetaConnectorType;
+
 struct _MetaOutput
 {
   /* The CRTC driving this output, NULL if the output is not enabled */
@@ -84,6 +105,8 @@ struct _MetaOutput
   CoglSubpixelOrder subpixel_order;
   int scale;
 
+  MetaConnectorType connector_type;
+
   MetaMonitorMode *preferred_mode;
   MetaMonitorMode **modes;
   unsigned int n_modes;
diff --git a/src/backends/native/meta-monitor-manager-kms.c b/src/backends/native/meta-monitor-manager-kms.c
index aa949ab..564bc50 100644
--- a/src/backends/native/meta-monitor-manager-kms.c
+++ b/src/backends/native/meta-monitor-manager-kms.c
@@ -537,6 +537,9 @@ meta_monitor_manager_kms_read_current (MetaMonitorManager *manager)
               meta_output->serial = g_strdup ("unknown");
             }
 
+          /* MetaConnectorType matches DRM's connector types */
+          meta_output->connector_type = (MetaConnectorType) connector->connector_type;
+
           /* FIXME: backlight is a very driver specific thing unfortunately,
              every DDX does its own thing, and the dumb KMS API does not include it.
 
diff --git a/src/backends/x11/meta-monitor-manager-xrandr.c b/src/backends/x11/meta-monitor-manager-xrandr.c
index 6abe6e0..96781a9 100644
--- a/src/backends/x11/meta-monitor-manager-xrandr.c
+++ b/src/backends/x11/meta-monitor-manager-xrandr.c
@@ -406,6 +406,147 @@ output_get_suggested_y (MetaMonitorManagerXrandr *manager_xrandr,
   return -1;
 }
 
+static MetaConnectorType
+connector_type_from_atom (MetaMonitorManagerXrandr *manager_xrandr,
+                          Atom                      atom)
+{
+  Display *xdpy = manager_xrandr->xdisplay;
+
+  if (atom == XInternAtom (xdpy, "HDMI", True))
+    return META_CONNECTOR_TYPE_HDMIA;
+  if (atom == XInternAtom (xdpy, "VGA", True))
+    return META_CONNECTOR_TYPE_VGA;
+  /* Doesn't have a DRM equivalent, but means an internal panel.
+   * We could pick either LVDS or eDP here. */
+  if (atom == XInternAtom (xdpy, "Panel", True))
+    return META_CONNECTOR_TYPE_LVDS;
+  if (atom == XInternAtom (xdpy, "DVI", True) || atom == XInternAtom (xdpy, "DVI-I", True))
+    return META_CONNECTOR_TYPE_DVII;
+  if (atom == XInternAtom (xdpy, "DVI-A", True))
+    return META_CONNECTOR_TYPE_DVIA;
+  if (atom == XInternAtom (xdpy, "DVI-D", True))
+    return META_CONNECTOR_TYPE_DVID;
+  if (atom == XInternAtom (xdpy, "DisplayPort", True))
+    return META_CONNECTOR_TYPE_DisplayPort;
+
+  if (atom == XInternAtom (xdpy, "TV", True))
+    return META_CONNECTOR_TYPE_TV;
+  if (atom == XInternAtom (xdpy, "TV-Composite", True))
+    return META_CONNECTOR_TYPE_Composite;
+  if (atom == XInternAtom (xdpy, "TV-SVideo", True))
+    return META_CONNECTOR_TYPE_SVIDEO;
+  /* Another set of mismatches. */
+  if (atom == XInternAtom (xdpy, "TV-SCART", True))
+    return META_CONNECTOR_TYPE_TV;
+  if (atom == XInternAtom (xdpy, "TV-C4", True))
+    return META_CONNECTOR_TYPE_TV;
+
+  return META_CONNECTOR_TYPE_Unknown;
+}
+
+static MetaConnectorType
+output_get_connector_type_from_prop (MetaMonitorManagerXrandr *manager_xrandr,
+                                     MetaOutput               *output)
+{
+  MetaConnectorType ret = META_CONNECTOR_TYPE_Unknown;
+  Atom atom, actual_type, connector_type_atom;
+  int actual_format;
+  unsigned long nitems, bytes_after;
+  unsigned char *buffer;
+
+  atom = XInternAtom (manager_xrandr->xdisplay, "ConnectorType", 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;
+
+  connector_type_atom = ((Atom *) buffer)[0];
+  ret = connector_type_from_atom (manager_xrandr, connector_type_atom);
+
+ out:
+  meta_XFree (buffer);
+  return ret;
+}
+
+static MetaConnectorType
+output_get_connector_type_from_name (MetaMonitorManagerXrandr *manager_xrandr,
+                                     MetaOutput               *output)
+{
+  const char *name = output->name;
+
+  /* drmmode_display.c, which was copy/pasted across all the FOSS
+   * xf86-video-* drivers, seems to name its outputs based on the
+   * connector type, so look for that....
+   *
+   * SNA has its own naming scheme, because what else did you expect
+   * from SNA, but it's not too different, so we can thankfully use
+   * that with minor changes.
+   *
+   * http://cgit.freedesktop.org/xorg/xserver/tree/hw/xfree86/drivers/modesetting/drmmode_display.c#n953
+   * http://cgit.freedesktop.org/xorg/driver/xf86-video-intel/tree/src/sna/sna_display.c#n3486
+   */
+
+  if (g_str_has_prefix (name, "DVI"))
+    return META_CONNECTOR_TYPE_DVII;
+  if (g_str_has_prefix (name, "LVDS"))
+    return META_CONNECTOR_TYPE_LVDS;
+  if (g_str_has_prefix (name, "HDMI"))
+    return META_CONNECTOR_TYPE_HDMIA;
+  if (g_str_has_prefix (name, "VGA"))
+    return META_CONNECTOR_TYPE_VGA;
+  /* SNA uses DP, not DisplayPort. Test for both. */
+  if (g_str_has_prefix (name, "DP") || g_str_has_prefix (name, "DisplayPort"))
+    return META_CONNECTOR_TYPE_DisplayPort;
+  if (g_str_has_prefix (name, "eDP"))
+    return META_CONNECTOR_TYPE_eDP;
+  if (g_str_has_prefix (name, "Virtual"))
+    return META_CONNECTOR_TYPE_VIRTUAL;
+  if (g_str_has_prefix (name, "Composite"))
+    return META_CONNECTOR_TYPE_VGA;
+  if (g_str_has_prefix (name, "S-video"))
+    return META_CONNECTOR_TYPE_SVIDEO;
+  if (g_str_has_prefix (name, "TV"))
+    return META_CONNECTOR_TYPE_TV;
+  if (g_str_has_prefix (name, "CTV"))
+    return META_CONNECTOR_TYPE_Composite;
+  if (g_str_has_prefix (name, "DSI"))
+    return META_CONNECTOR_TYPE_DSI;
+  if (g_str_has_prefix (name, "DIN"))
+    return META_CONNECTOR_TYPE_9PinDIN;
+
+  return META_CONNECTOR_TYPE_Unknown;
+}
+
+static MetaConnectorType
+output_get_connector_type (MetaMonitorManagerXrandr *manager_xrandr,
+                           MetaOutput               *output)
+{
+  MetaConnectorType ret;
+
+  /* The "ConnectorType" property is considered mandatory since RandR 1.3,
+   * but none of the FOSS drivers support it, because we're a bunch of
+   * professional software developers.
+   *
+   * Try poking it first, without any expectations that it will work.
+   * If it's not there, we thankfully have other bonghits to try next.
+   */
+  ret = output_get_connector_type_from_prop (manager_xrandr, output);
+  if (ret != META_CONNECTOR_TYPE_Unknown)
+    return ret;
+
+  /* Fall back to heuristics based on the output name. */
+  ret = output_get_connector_type_from_name (manager_xrandr, output);
+  if (ret != META_CONNECTOR_TYPE_Unknown)
+    return ret;
+
+  return META_CONNECTOR_TYPE_Unknown;
+}
+
 static char *
 get_xmode_name (XRRModeInfo *xmode)
 {
@@ -595,6 +736,7 @@ meta_monitor_manager_xrandr_read_current (MetaMonitorManager *manager)
           meta_output->hotplug_mode_update = output_get_hotplug_mode_update (manager_xrandr, meta_output);
          meta_output->suggested_x = output_get_suggested_x (manager_xrandr, meta_output);
          meta_output->suggested_y = output_get_suggested_y (manager_xrandr, meta_output);
+          meta_output->connector_type = output_get_connector_type (manager_xrandr, meta_output);
 
          meta_output->n_modes = output->nmode;
          meta_output->modes = g_new0 (MetaMonitorMode *, meta_output->n_modes);


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