[PATCH xserver 02/10] xf86-video-modesetting: Update property values at detect and uevent time

Keith Packard keithp at keithp.com
Fri Dec 22 02:54:34 UTC 2017


We were updating the link-status property when a uevent came in, but
we also want to update the non-desktop property, and potentially
others as well. We also want to check at detect time in case we don't
get a hotplug event.

This patch updates every property provided by the kernel, sending
changes to DIX so it can track things as well.

Signed-off-by: Keith Packard <keithp at keithp.com>
---
 hw/xfree86/drivers/modesetting/drmmode_display.c | 111 ++++++++++++++++++-----
 1 file changed, 86 insertions(+), 25 deletions(-)

diff --git a/hw/xfree86/drivers/modesetting/drmmode_display.c b/hw/xfree86/drivers/modesetting/drmmode_display.c
index 5b8e4fa1b..9c3856378 100644
--- a/hw/xfree86/drivers/modesetting/drmmode_display.c
+++ b/hw/xfree86/drivers/modesetting/drmmode_display.c
@@ -1132,6 +1132,67 @@ drmmode_crtc_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, drmModeResPtr mode_res
     return 1;
 }
 
+/*
+ * Update all of the property values for an output
+ */
+static void
+drmmode_output_update_properties(xf86OutputPtr output)
+{
+    drmmode_output_private_ptr drmmode_output = output->driver_private;
+    int i, j, k;
+    int err;
+    drmModeConnectorPtr koutput;
+
+    /* Use the most recently fetched values from the kernel */
+    koutput = drmmode_output->mode_output;
+
+    if (!koutput)
+        return;
+
+    for (i = 0; i < drmmode_output->num_props; i++) {
+        drmmode_prop_ptr p = &drmmode_output->props[i];
+
+        for (j = 0; koutput && j < koutput->count_props; j++) {
+            if (koutput->props[j] == p->mode_prop->prop_id) {
+
+                /* Check to see if the property value has changed */
+                if (koutput->prop_values[j] != p->value) {
+
+                    p->value = koutput->prop_values[j];
+
+                    if (p->mode_prop->flags & DRM_MODE_PROP_RANGE) {
+                        INT32 value = p->value;
+
+                        err = RRChangeOutputProperty(output->randr_output, p->atoms[0],
+                                                     XA_INTEGER, 32, PropModeReplace, 1,
+                                                     &value, FALSE, TRUE);
+
+                        if (err != 0) {
+                            xf86DrvMsg(output->scrn->scrnIndex, X_ERROR,
+                                       "RRChangeOutputProperty error, %d\n", err);
+                        }
+                    }
+                    else if (p->mode_prop->flags & DRM_MODE_PROP_ENUM) {
+                        for (k = 0; k < p->mode_prop->count_enums; k++)
+                            if (p->mode_prop->enums[k].value == p->value)
+                                break;
+                        if (k < p->mode_prop->count_enums) {
+                            err = RRChangeOutputProperty(output->randr_output, p->atoms[0],
+                                                         XA_ATOM, 32, PropModeReplace, 1,
+                                                         &p->atoms[k + 1], FALSE, TRUE);
+                            if (err != 0) {
+                                xf86DrvMsg(output->scrn->scrnIndex, X_ERROR,
+                                           "RRChangeOutputProperty error, %d\n", err);
+                            }
+                        }
+                    }
+                }
+                break;
+            }
+        }
+    }
+}
+
 static xf86OutputStatus
 drmmode_output_detect(xf86OutputPtr output)
 {
@@ -1147,11 +1208,14 @@ drmmode_output_detect(xf86OutputPtr output)
 
     drmmode_output->mode_output =
         drmModeGetConnector(drmmode->fd, drmmode_output->output_id);
+
     if (!drmmode_output->mode_output) {
         drmmode_output->output_id = -1;
         return XF86OutputStatusDisconnected;
     }
 
+    drmmode_output_update_properties(output);
+
     switch (drmmode_output->mode_output->connection) {
     case DRM_MODE_CONNECTED:
         status = XF86OutputStatusConnected;
@@ -2244,38 +2308,35 @@ drmmode_handle_uevents(int fd, void *closure)
      */
     for (i = 0; i < config->num_output; i++) {
         xf86OutputPtr output = config->output[i];
-        xf86CrtcPtr crtc = output->crtc;
         drmmode_output_private_ptr drmmode_output = output->driver_private;
-        uint32_t con_id, idx;
-        drmModeConnectorPtr koutput;
 
-        if (crtc == NULL || drmmode_output->mode_output == NULL)
-            continue;
+        drmmode_output_detect(output);
 
-        con_id = drmmode_output->mode_output->connector_id;
         /* Get an updated view of the properties for the current connector and
          * look for the link-status property
          */
-        koutput = drmModeGetConnectorCurrent(drmmode->fd, con_id);
-        if (!koutput)
-            continue;
-
-        idx = koutput_get_prop_idx(drmmode->fd, koutput,
-                DRM_MODE_PROP_ENUM, "link-status");
-
-        if ((idx > -1) &&
-                (koutput->prop_values[idx] == DRM_MODE_LINK_STATUS_BAD)) {
-            /* the connector got a link failure, re-set the current mode */
-            drmmode_set_mode_major(crtc, &crtc->mode, crtc->rotation,
-                                   crtc->x, crtc->y);
-
-            xf86DrvMsg(scrn->scrnIndex, X_WARNING,
-                       "hotplug event: connector %u's link-state is BAD, "
-                       "tried resetting the current mode. You may be left"
-                       "with a black screen if this fails...\n", con_id);
+        for (j = 0; j < drmmode_output->num_props; j++) {
+            drmmode_prop_ptr p = &drmmode_output->props[j];
+
+            if (!strcmp(p->mode_prop->name, "link-status")) {
+                if (p->value == DRM_MODE_LINK_STATUS_BAD) {
+                    xf86CrtcPtr crtc = output->crtc;
+                    if (!crtc)
+                        continue;
+
+                    /* the connector got a link failure, re-set the current mode */
+                    drmmode_set_mode_major(crtc, &crtc->mode, crtc->rotation,
+                                           crtc->x, crtc->y);
+
+                    xf86DrvMsg(scrn->scrnIndex, X_WARNING,
+                               "hotplug event: connector %u's link-state is BAD, "
+                               "tried resetting the current mode. You may be left"
+                               "with a black screen if this fails...\n",
+                               drmmode_output->mode_output->connector_id);
+                }
+                break;
+            }
         }
-
-        drmModeFreeConnector(koutput);
     }
 
     mode_res = drmModeGetResources(drmmode->fd);
-- 
2.15.1



More information about the xorg-devel mailing list