xf86-video-ati: Branch 'master'

Dave Airlie airlied at kemper.freedesktop.org
Tue Sep 8 21:25:37 PDT 2009


 src/drmmode_display.c |  169 ++++++++++++++++++++++++++++++++++++++++++++++++++
 src/drmmode_display.h |   10 ++
 2 files changed, 179 insertions(+)

New commits:
commit 10a58d54857484b6e89763ecf463f54dc290c702
Author: Dave Airlie <airlied at redhat.com>
Date:   Wed Sep 9 14:24:49 2009 +1000

    kms: add property support.
    
    this adds support to the userspace DDX to get properties from the kernel
    and expose them over randr. Its most liberated from the Intel driver.

diff --git a/src/drmmode_display.c b/src/drmmode_display.c
index 1b4985d..e6b948c 100644
--- a/src/drmmode_display.c
+++ b/src/drmmode_display.c
@@ -587,9 +587,15 @@ static void
 drmmode_output_destroy(xf86OutputPtr output)
 {
 	drmmode_output_private_ptr drmmode_output = output->driver_private;
+	int i;
 
 	if (drmmode_output->edid_blob)
 		drmModeFreePropertyBlob(drmmode_output->edid_blob);
+	for (i = 0; i < drmmode_output->num_props; i++) {
+	    drmModeFreeProperty(drmmode_output->props[i].mode_prop);
+	    xfree(drmmode_output->props[i].atoms);
+	}
+	xfree(drmmode_output->props);
 	drmModeFreeConnector(drmmode_output->mode_output);
 	xfree(drmmode_output);
 	output->driver_private = NULL;
@@ -607,8 +613,171 @@ drmmode_output_dpms(xf86OutputPtr output, int mode)
 	return;
 }
 
+
+static Bool
+drmmode_property_ignore(drmModePropertyPtr prop)
+{
+    if (!prop)
+	return TRUE;
+    /* ignore blob prop */
+    if (prop->flags & DRM_MODE_PROP_BLOB)
+	return TRUE;
+    /* ignore standard property */
+    if (!strcmp(prop->name, "EDID") ||
+	    !strcmp(prop->name, "DPMS"))
+	return TRUE;
+
+    return FALSE;
+}
+
+static void
+drmmode_output_create_resources(xf86OutputPtr output)
+{
+    drmmode_output_private_ptr drmmode_output = output->driver_private;
+    drmModeConnectorPtr mode_output = drmmode_output->mode_output;
+    drmmode_ptr drmmode = drmmode_output->drmmode;
+    drmModePropertyPtr drmmode_prop;
+    int i, j, err;
+
+    drmmode_output->props = xcalloc(mode_output->count_props, sizeof(drmmode_prop_rec));
+    if (!drmmode_output->props)
+	return;
+    
+    drmmode_output->num_props = 0;
+    for (i = 0, j = 0; i < mode_output->count_props; i++) {
+	drmmode_prop = drmModeGetProperty(drmmode->fd, mode_output->props[i]);
+	if (drmmode_property_ignore(drmmode_prop)) {
+	    drmModeFreeProperty(drmmode_prop);
+	    continue;
+	}
+	drmmode_output->props[j].mode_prop = drmmode_prop;
+	drmmode_output->props[j].value = mode_output->prop_values[i];
+	drmmode_output->num_props++;
+	j++;
+    }
+
+    for (i = 0; i < drmmode_output->num_props; i++) {
+	drmmode_prop_ptr p = &drmmode_output->props[i];
+	drmmode_prop = p->mode_prop;
+
+	if (drmmode_prop->flags & DRM_MODE_PROP_RANGE) {
+	    INT32 range[2];
+
+	    p->num_atoms = 1;
+	    p->atoms = xcalloc(p->num_atoms, sizeof(Atom));
+	    if (!p->atoms)
+		continue;
+	    p->atoms[0] = MakeAtom(drmmode_prop->name, strlen(drmmode_prop->name), TRUE);
+	    range[0] = drmmode_prop->values[0];
+	    range[1] = drmmode_prop->values[1];
+	    err = RRConfigureOutputProperty(output->randr_output, p->atoms[0],
+		    FALSE, TRUE,
+		    drmmode_prop->flags & DRM_MODE_PROP_IMMUTABLE ? TRUE : FALSE,
+		    2, range);
+	    if (err != 0) {
+		xf86DrvMsg(output->scrn->scrnIndex, X_ERROR,
+			"RRConfigureOutputProperty error, %d\n", err);
+	    }
+	    err = RRChangeOutputProperty(output->randr_output, p->atoms[0],
+		    XA_INTEGER, 32, PropModeReplace, 1, &p->value, FALSE, TRUE);
+	    if (err != 0) {
+		xf86DrvMsg(output->scrn->scrnIndex, X_ERROR,
+			"RRChangeOutputProperty error, %d\n", err);
+	    }
+	} else if (drmmode_prop->flags & DRM_MODE_PROP_ENUM) {
+	    p->num_atoms = drmmode_prop->count_enums + 1;
+	    p->atoms = xcalloc(p->num_atoms, sizeof(Atom));
+	    if (!p->atoms)
+		continue;
+	    p->atoms[0] = MakeAtom(drmmode_prop->name, strlen(drmmode_prop->name), TRUE);
+	    for (j = 1; j <= drmmode_prop->count_enums; j++) {
+		struct drm_mode_property_enum *e = &drmmode_prop->enums[j-1];
+		p->atoms[j] = MakeAtom(e->name, strlen(e->name), TRUE);
+	    }
+	    err = RRConfigureOutputProperty(output->randr_output, p->atoms[0],
+		    FALSE, FALSE,
+		    drmmode_prop->flags & DRM_MODE_PROP_IMMUTABLE ? TRUE : FALSE,
+		    p->num_atoms - 1, (INT32 *)&p->atoms[1]);
+	    if (err != 0) {
+		xf86DrvMsg(output->scrn->scrnIndex, X_ERROR,
+			"RRConfigureOutputProperty error, %d\n", err);
+	    }
+	    for (j = 0; j < drmmode_prop->count_enums; j++)
+		if (drmmode_prop->enums[j].value == p->value)
+		    break;
+	    /* there's always a matching value */
+	    err = RRChangeOutputProperty(output->randr_output, p->atoms[0],
+		    XA_ATOM, 32, PropModeReplace, 1, &p->atoms[j+1], FALSE, TRUE);
+	    if (err != 0) {
+		xf86DrvMsg(output->scrn->scrnIndex, X_ERROR,
+			"RRChangeOutputProperty error, %d\n", err);
+	    }
+	}
+    }
+}
+
+static Bool
+drmmode_output_set_property(xf86OutputPtr output, Atom property,
+		RRPropertyValuePtr value)
+{
+    drmmode_output_private_ptr drmmode_output = output->driver_private;
+    drmmode_ptr drmmode = drmmode_output->drmmode;
+    int i;
+
+    for (i = 0; i < drmmode_output->num_props; i++) {
+	drmmode_prop_ptr p = &drmmode_output->props[i];
+
+	if (p->atoms[0] != property)
+	    continue;
+
+	if (p->mode_prop->flags & DRM_MODE_PROP_RANGE) {
+	    uint32_t val;
+
+	    if (value->type != XA_INTEGER || value->format != 32 ||
+		    value->size != 1)
+		return FALSE;
+	    val = *(uint32_t *)value->data;
+
+	    drmModeConnectorSetProperty(drmmode->fd, drmmode_output->output_id,
+		    p->mode_prop->prop_id, (uint64_t)val);
+	    return TRUE;
+	} else if (p->mode_prop->flags & DRM_MODE_PROP_ENUM) {
+	    Atom	atom;
+	    const char	*name;
+	    int		j;
+
+	    if (value->type != XA_ATOM || value->format != 32 || value->size != 1)
+		return FALSE;
+	    memcpy(&atom, value->data, 4);
+	    name = NameForAtom(atom);
+
+	    /* search for matching name string, then set its value down */
+	    for (j = 0; j < p->mode_prop->count_enums; j++) {
+		if (!strcmp(p->mode_prop->enums[j].name, name)) {
+		    drmModeConnectorSetProperty(drmmode->fd, drmmode_output->output_id,
+			    p->mode_prop->prop_id, p->mode_prop->enums[j].value);
+		    return TRUE;
+		}
+	    }
+	}
+    }
+
+    return TRUE;
+}
+
+static Bool
+drmmode_output_get_property(xf86OutputPtr output, Atom property)
+{
+    return TRUE;
+}
+
 static const xf86OutputFuncsRec drmmode_output_funcs = {
     .dpms = drmmode_output_dpms,
+    .create_resources = drmmode_output_create_resources,
+#ifdef RANDR_12_INTERFACE
+    .set_property = drmmode_output_set_property,
+    .get_property = drmmode_output_get_property,
+#endif
 #if 0
 
     .save = drmmode_crt_save,
diff --git a/src/drmmode_display.h b/src/drmmode_display.h
index 2713bab..1410afe 100644
--- a/src/drmmode_display.h
+++ b/src/drmmode_display.h
@@ -53,12 +53,22 @@ typedef struct {
 } drmmode_crtc_private_rec, *drmmode_crtc_private_ptr;
 
 typedef struct {
+    drmModePropertyPtr mode_prop;
+    uint64_t value;
+    int num_atoms; /* if range prop, num_atoms == 1; if enum prop, num_atoms == num_enums + 1 */
+    Atom *atoms;
+} drmmode_prop_rec, *drmmode_prop_ptr;
+
+
+typedef struct {
     drmmode_ptr drmmode;
     int output_id;
     drmModeConnectorPtr mode_output;
     drmModeEncoderPtr mode_encoder;
     drmModePropertyBlobPtr edid_blob;
     int dpms_enum_id;
+    int num_props;
+    drmmode_prop_ptr props;
 } drmmode_output_private_rec, *drmmode_output_private_ptr;
 
 


More information about the xorg-commit mailing list