summaryrefslogtreecommitdiffstats
path: root/src/gallium/state_trackers
diff options
context:
space:
mode:
authorLucas Stach <[email protected]>2012-07-18 16:07:29 +0200
committerMichel Dänzer <[email protected]>2012-07-18 17:19:16 +0200
commitfb18ec4f2775f96982a39247efd1c70cccbc46fc (patch)
tree02631fb681733cbbff7d17c397c66e2d4c6fae60 /src/gallium/state_trackers
parent9de16ac0a838a98d71e6abf1f82ccee642073f40 (diff)
st/xorg: attach EDID to outputs
Allows tools like GNOME's monitor configuration to show meaningful names. v2: fix resource leak Signed-off-by: Lucas Stach <[email protected]>
Diffstat (limited to 'src/gallium/state_trackers')
-rw-r--r--src/gallium/state_trackers/xorg/xorg_output.c37
1 files changed, 36 insertions, 1 deletions
diff --git a/src/gallium/state_trackers/xorg/xorg_output.c b/src/gallium/state_trackers/xorg/xorg_output.c
index 5555b51131c..b183cdf9dc1 100644
--- a/src/gallium/state_trackers/xorg/xorg_output.c
+++ b/src/gallium/state_trackers/xorg/xorg_output.c
@@ -32,6 +32,7 @@
#include <xf86.h>
#include <xf86i2c.h>
#include <xf86Crtc.h>
+#include <xf86DDC.h>
#include <errno.h>
#include <fcntl.h>
#include <unistd.h>
@@ -54,7 +55,8 @@
struct output_private
{
drmModeConnectorPtr drm_connector;
-
+ drmModePropertyBlobPtr edid_blob;
+ int fd;
int c;
};
@@ -122,9 +124,39 @@ output_get_modes(xf86OutputPtr output)
struct output_private *priv = output->driver_private;
drmModeConnectorPtr drm_connector = priv->drm_connector;
drmModeModeInfoPtr drm_mode = NULL;
+ drmModePropertyPtr props = NULL;
+ xf86MonPtr ddc_mon = NULL;
DisplayModePtr modes = NULL, mode = NULL;
int i;
+ for (i = 0; i < drm_connector->count_props; i++) {
+ props = drmModeGetProperty(priv->fd, drm_connector->props[i]);
+ if (!props)
+ continue;
+
+ if (!(props->flags & DRM_MODE_PROP_BLOB))
+ goto out_free;
+
+ if (!strcmp(props->name, "EDID")) {
+ if (priv->edid_blob)
+ drmModeFreePropertyBlob(priv->edid_blob);
+ priv->edid_blob = drmModeGetPropertyBlob(priv->fd,
+ drm_connector->prop_values[i]);
+ }
+
+ out_free:
+ drmModeFreeProperty(props);
+ }
+
+ if (priv->edid_blob) {
+ ddc_mon = xf86InterpretEDID(output->scrn->scrnIndex,
+ priv->edid_blob->data);
+
+ if (ddc_mon && priv->edid_blob->length > 128)
+ ddc_mon->flags |= MONITOR_EDID_COMPLETE_RAWDATA;
+ }
+ xf86OutputSetEDID(output, ddc_mon);
+
for (i = 0; i < drm_connector->count_modes; i++) {
drm_mode = &drm_connector->modes[i];
if (drm_mode) {
@@ -194,6 +226,8 @@ static void
output_destroy(xf86OutputPtr output)
{
struct output_private *priv = output->driver_private;
+ if (priv->edid_blob)
+ drmModeFreePropertyBlob(priv->edid_blob);
drmModeFreeConnector(priv->drm_connector);
free(priv);
output->driver_private = NULL;
@@ -283,6 +317,7 @@ xorg_output_init(ScrnInfoPtr pScrn)
}
priv->c = c;
priv->drm_connector = drm_connector;
+ priv->fd = ms->fd;
output->driver_private = priv;
output->subpixel_order = SubPixelHorizontalRGB;
output->interlaceAllowed = FALSE;