diff options
author | Keith Packard <keithp@keithp.com> | 2017-12-21 18:54:34 -0800 |
---|---|---|
committer | Adam Jackson <ajax@redhat.com> | 2018-01-22 17:22:21 -0500 |
commit | a12485ed846b852ca14d17d1e58c8b0f2399e577 (patch) | |
tree | 8e84b87b7bc1a4a091e6799c422737d82775f2b7 | |
parent | 44d5f2eb8a2f92571698adec39ac569b71da5a1b (diff) |
xf86-video-modesetting: Update property values at detect and uevent time
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.
Reviewed-by: Adam Jackson <ajax@redhat.com>
Signed-off-by: Keith Packard <keithp@keithp.com>
-rw-r--r-- | hw/xfree86/drivers/modesetting/drmmode_display.c | 111 |
1 files 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); |