monitor-manager: Add a connector-type property

This is so gnome-settings-daemon
This commit is contained in:
Jasper St. Pierre 2014-12-29 16:18:24 -08:00
parent 44a60eb7e9
commit d514e8ab41
4 changed files with 196 additions and 0 deletions

View File

@ -396,6 +396,32 @@ make_display_name (MetaMonitorManager *manager,
return ret; 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 static gboolean
meta_monitor_manager_handle_get_resources (MetaDBusDisplayConfig *skeleton, meta_monitor_manager_handle_get_resources (MetaDBusDisplayConfig *skeleton,
GDBusMethodInvocation *invocation) GDBusMethodInvocation *invocation)
@ -476,6 +502,8 @@ meta_monitor_manager_handle_get_resources (MetaDBusDisplayConfig *skeleton,
g_variant_new_boolean (output->is_primary)); g_variant_new_boolean (output->is_primary));
g_variant_builder_add (&properties, "{sv}", "presentation", g_variant_builder_add (&properties, "{sv}", "presentation",
g_variant_new_boolean (output->is_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); edid_file = manager_class->get_edid_file (manager, output);
if (edid_file) if (edid_file)

View File

@ -69,6 +69,27 @@ typedef enum {
META_MONITOR_TRANSFORM_FLIPPED_270, META_MONITOR_TRANSFORM_FLIPPED_270,
} MetaMonitorTransform; } 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 struct _MetaOutput
{ {
/* The CRTC driving this output, NULL if the output is not enabled */ /* The CRTC driving this output, NULL if the output is not enabled */
@ -84,6 +105,8 @@ struct _MetaOutput
CoglSubpixelOrder subpixel_order; CoglSubpixelOrder subpixel_order;
int scale; int scale;
MetaConnectorType connector_type;
MetaMonitorMode *preferred_mode; MetaMonitorMode *preferred_mode;
MetaMonitorMode **modes; MetaMonitorMode **modes;
unsigned int n_modes; unsigned int n_modes;

View File

@ -537,6 +537,9 @@ meta_monitor_manager_kms_read_current (MetaMonitorManager *manager)
meta_output->serial = g_strdup ("unknown"); 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, /* FIXME: backlight is a very driver specific thing unfortunately,
every DDX does its own thing, and the dumb KMS API does not include it. every DDX does its own thing, and the dumb KMS API does not include it.

View File

@ -406,6 +406,147 @@ output_get_suggested_y (MetaMonitorManagerXrandr *manager_xrandr,
return -1; 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 * static char *
get_xmode_name (XRRModeInfo *xmode) 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->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_x = output_get_suggested_x (manager_xrandr, meta_output);
meta_output->suggested_y = output_get_suggested_y (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->n_modes = output->nmode;
meta_output->modes = g_new0 (MetaMonitorMode *, meta_output->n_modes); meta_output->modes = g_new0 (MetaMonitorMode *, meta_output->n_modes);