[PATCH xserver] xf86-video-modesetting: Update all property values at uevent time
Keith Packard
keithp at keithp.com
Fri Dec 8 01:08:14 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. This patch just 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 | 117 ++++++++++++++++++-----
1 file changed, 92 insertions(+), 25 deletions(-)
diff --git a/hw/xfree86/drivers/modesetting/drmmode_display.c b/hw/xfree86/drivers/modesetting/drmmode_display.c
index a51722b58..52b8e4a53 100644
--- a/hw/xfree86/drivers/modesetting/drmmode_display.c
+++ b/hw/xfree86/drivers/modesetting/drmmode_display.c
@@ -2213,6 +2213,76 @@ drmmode_setup_colormap(ScreenPtr pScreen, ScrnInfoPtr pScrn)
return TRUE;
}
+/*
+ * 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;
+ drmmode_ptr drmmode = drmmode_output->drmmode;
+ int i, j, k;
+ int err;
+
+ drmModeConnectorPtr koutput;
+
+ if (drmmode_output->mode_output == NULL)
+ return;
+
+ /* Get an updated view of the properties for the current connector and
+ * update the server's copy of them.
+ */
+ koutput = drmModeGetConnector(drmmode->fd,
+ drmmode_output->mode_output->connector_id);
+
+ 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;
+ }
+ }
+ }
+ drmModeFreeConnector(koutput);
+}
+
#ifdef CONFIG_UDEV_KMS
#define DRM_MODE_LINK_STATUS_GOOD 0
@@ -2248,38 +2318,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_update_properties(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.0.rc0
More information about the xorg-devel
mailing list