xf86-video-intel: 4 commits - src/compat-api.h src/sna/sna_display.c src/sna/sna_driver.c src/sna/sna.h
Chris Wilson
ickle at kemper.freedesktop.org
Fri May 2 09:16:44 PDT 2014
src/compat-api.h | 1
src/sna/sna.h | 3
src/sna/sna_display.c | 309 +++++++++++++++++++++++++++++++++++++-------------
src/sna/sna_driver.c | 33 +++--
4 files changed, 254 insertions(+), 92 deletions(-)
New commits:
commit 828bd9e250b7d9dd1dc4185c0179237e9b21d8bf
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Fri May 2 17:13:29 2014 +0100
sna: Reorder cursor initialisation
It helps to initialise the cursors after we setup one of the values we
depend on.
Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
diff --git a/src/sna/sna_display.c b/src/sna/sna_display.c
index 47a36d8..70fbc8d 100644
--- a/src/sna/sna_display.c
+++ b/src/sna/sna_display.c
@@ -3802,6 +3802,9 @@ sna_cursor_pre_init(struct sna *sna)
uint64_t value;
} cap;
+ if (sna->mode.num_real_crtc == 0)
+ return;
+
#define LOCAL_IOCTL_GET_CAP DRM_IOWR(0x0c, struct local_get_cap)
#define DRM_CAP_CURSOR_WIDTH 8
#define DRM_CAP_CURSOR_HEIGHT 9
@@ -4392,8 +4395,6 @@ bool sna_mode_pre_init(ScrnInfoPtr scrn, struct sna *sna)
assert(res->count_crtcs);
assert(res->count_connectors);
- sna_cursor_pre_init(sna);
-
xf86CrtcConfigInit(scrn, &sna_mode_funcs);
xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
@@ -4417,6 +4418,8 @@ bool sna_mode_pre_init(ScrnInfoPtr scrn, struct sna *sna)
sna->mode.max_crtc_height = res->max_height;
drmModeFreeResources(res);
+
+ sna_cursor_pre_init(sna);
} else {
if (num_fake == 0)
num_fake = 1;
commit 38f82655e0bc8f26250f56e9a25aedd30b46360c
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Fri May 2 12:30:43 2014 +0100
sna: Remove incorrect cursor assertion
Ideally, we want to assert that we have sufficient stashed cursors to
allocate for the unused CRTCS, so something like
assert(num_stash + num_active_cursors >= 0);
Reported-by: Zdenek Kabelac <zkabelac at redhat.com>
Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
diff --git a/src/sna/sna_display.c b/src/sna/sna_display.c
index a66ca09..47a36d8 100644
--- a/src/sna/sna_display.c
+++ b/src/sna/sna_display.c
@@ -3765,10 +3765,8 @@ sna_use_hw_cursor(ScreenPtr screen, CursorPtr cursor)
cursor->bits->width, cursor->bits->height));
/* cursors are invariant */
- if (cursor == sna->cursor.ref) {
- assert(sna->cursor.num_stash >= 0);
+ if (cursor == sna->cursor.ref)
return TRUE;
- }
if (sna->cursor.ref) {
FreeCursor(sna->cursor.ref, None);
commit 430152da82f496ac47f33ce1eca65d154af38752
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Fri May 2 16:57:27 2014 +0100
compat: Add missing wrapper for RegionSubtract
Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
diff --git a/src/compat-api.h b/src/compat-api.h
index 244a486..c7b0aae 100644
--- a/src/compat-api.h
+++ b/src/compat-api.h
@@ -121,6 +121,7 @@
#define RegionCopy(res, r) REGION_COPY(NULL, res, r)
#define RegionIntersect(res, r1, r2) REGION_INTERSECT(NULL, res, r1, r2)
#define RegionUnion(res, r1, r2) REGION_UNION(NULL, res, r1, r2)
+#define RegionSubtract(res, r1, r2) REGION_SUBTRACT(NULL, res, r1, r2)
#define RegionTranslate(r, x, y) REGION_TRANSLATE(NULL, r, x, y)
#define RegionUninit(r) REGION_UNINIT(NULL, r)
#define region_from_bitmap BITMAP_TO_REGION
commit add84cd8a8dc6d285912d0ea3a3a3e7faa9e0942
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Fri May 2 13:21:02 2014 +0100
sna: Perform dynamic connector discovery
One of the side-effects of MST is that we need to support dynamic
attachment and removal of displays as the branch hierachy changes.
Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
diff --git a/src/sna/sna.h b/src/sna/sna.h
index cf9a4d5..cc086d7 100644
--- a/src/sna/sna.h
+++ b/src/sna/sna.h
@@ -242,6 +242,7 @@ struct sna {
#define SNA_IS_HOSTED 0x80
#define SNA_PERFORMANCE 0x100
#define SNA_POWERSAVE 0x200
+#define SNA_REDISCOVER 0x40000000
#define SNA_REPROBE 0x80000000
unsigned cpu_features;
@@ -281,6 +282,7 @@ struct sna {
unsigned num_real_crtc;
unsigned num_real_output;
unsigned num_fake;
+ unsigned serial;
} mode;
struct {
@@ -378,6 +380,7 @@ struct sna {
bool sna_mode_pre_init(ScrnInfoPtr scrn, struct sna *sna);
bool sna_mode_fake_init(struct sna *sna, int num_fake);
void sna_mode_adjust_frame(struct sna *sna, int x, int y);
+extern void sna_mode_discover(struct sna *sna);
extern void sna_mode_update(struct sna *sna);
extern void sna_mode_reset(struct sna *sna);
extern void sna_mode_wakeup(struct sna *sna);
diff --git a/src/sna/sna_display.c b/src/sna/sna_display.c
index ae07252..a66ca09 100644
--- a/src/sna/sna_display.c
+++ b/src/sna/sna_display.c
@@ -47,6 +47,7 @@
#include "backlight.h"
#include <xf86Crtc.h>
+#include <xf86RandR12.h>
#include <cursorstr.h>
#if XF86_CRTC_VERSION >= 3
@@ -128,7 +129,8 @@ struct sna_property {
struct sna_output {
int id;
- int encoder_idx;
+ int encoder_id, encoder_idx;
+ int serial;
unsigned int is_panel : 1;
@@ -743,14 +745,15 @@ sna_crtc_apply(xf86CrtcPtr crtc)
if (output->crtc != crtc)
continue;
- assert(output->possible_crtcs & (1 << sna_crtc->pipe) ||
- xf86IsEntityShared(crtc->scrn->entityList[0]));
-
DBG(("%s: attaching output '%s' %d [%d] to crtc:%d (pipe %d) (possible crtc:%x, possible clones:%x)\n",
__FUNCTION__, output->name, i, to_connector_id(output),
sna_crtc->id, sna_crtc->pipe,
(uint32_t)output->possible_crtcs,
(uint32_t)output->possible_clones));
+
+ assert(output->possible_crtcs & (1 << sna_crtc->pipe) ||
+ xf86IsEntityShared(crtc->scrn->entityList[0]));
+
output_ids[output_count] = to_connector_id(output);
if (++output_count == ARRAY_SIZE(output_ids))
return false;
@@ -1799,7 +1802,7 @@ sna_crtc_init__cursor(struct sna *sna, struct sna_crtc *crtc)
}
static bool
-sna_crtc_init(ScrnInfoPtr scrn, int id)
+sna_crtc_add(ScrnInfoPtr scrn, int id)
{
struct sna *sna = to_sna(scrn);
xf86CrtcPtr crtc;
@@ -2634,24 +2637,98 @@ output_ignored(ScrnInfoPtr scrn, const char *name)
return xf86CheckBoolOption(conf->mon_option_lst, "Ignore", 0);
}
-static bool
-sna_output_init(ScrnInfoPtr scrn, int id, drmModeResPtr res)
+/* We need to map from kms encoder based possible_clones mask to X output based
+ * possible clones masking. Note that for SDVO and on Haswell with DP/HDMI we
+ * can have more than one output hanging off the same encoder.
+ */
+static void
+sna_mode_compute_possible_outputs(struct sna *sna, drmModeResPtr res)
{
- struct sna *sna = to_sna(scrn);
- xf86OutputPtr output;
+ xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(sna->scrn);
+ int i, j;
+
+ assert(sna->mode.num_real_output < 32);
+ assert(sna->mode.num_real_crtc < 32);
+
+ for (i = 0; i < sna->mode.num_real_output; i++) {
+ xf86OutputPtr output = config->output[i];
+ struct sna_output *sna_output = to_sna_output(output);
+ struct drm_mode_get_encoder enc;
+
+ assert(to_sna_output(output));
+
+ sna_output->encoder_idx = -1;
+ output->possible_clones = 0;
+
+ VG_CLEAR(enc);
+ enc.encoder_id = sna_output->encoder_id;
+
+ if (drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_GETENCODER, &enc)) {
+ DBG(("%s: GETENCODER failed, ret=%d\n", __FUNCTION__, errno));
+ continue;
+ }
+
+ for (j = 0; j < res->count_encoders; j++) {
+ if (enc.encoder_id == res->encoders[j]) {
+ sna_output->encoder_idx = j;
+ break;
+ }
+ }
+ assert(sna_output->encoder_idx != -1);
+
+ output->possible_clones = enc.possible_clones;
+ }
+
+ /* Convert from encoder numbering to output numbering */
+ for (i = 0; i < sna->mode.num_real_output; i++) {
+ xf86OutputPtr output = config->output[i];
+ unsigned mask = output->possible_clones;
+ unsigned clones = 0;
+
+ assert(to_sna_output(output));
+ if (output->possible_clones == 0)
+ continue;
+
+ for (j = 0; j < sna->mode.num_real_output; j++) {
+ struct sna_output *sna_output = to_sna_output(config->output[j]);
+
+ if (i == j)
+ continue;
+
+ if (sna_output->encoder_idx == -1)
+ continue;
+
+ if (mask & (1 << sna_output->encoder_idx))
+ clones |= 1 << j;
+ }
+
+ output->possible_clones = clones;
+
+ DBG(("%s: updated output '%s' %d [%d] (possible crtc:%x, possible clones:%x)\n",
+ __FUNCTION__, output->name, i, to_connector_id(output),
+ (uint32_t)output->possible_crtcs,
+ (uint32_t)output->possible_clones));
+ }
+}
+
+static int
+sna_output_add(struct sna *sna, int id, drmModeResPtr res, int serial)
+{
+ ScrnInfoPtr scrn = sna->scrn;
+ xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn);
union compat_mode_get_connector compat_conn;
struct drm_mode_get_encoder enc;
struct drm_mode_modeinfo dummy;
struct sna_output *sna_output;
+ xf86OutputPtr *outputs, output;
const char *output_name;
char name[32];
- bool ret = false;
- int i;
-
- COMPILE_TIME_ASSERT(sizeof(struct drm_mode_get_connector) <= sizeof(compat_conn.pad));
+ int len, i, ret = -1;
DBG(("%s(%d)\n", __FUNCTION__, id));
+ COMPILE_TIME_ASSERT(sizeof(struct drm_mode_get_connector) <= sizeof(compat_conn.pad));
+
VG_CLEAR(compat_conn);
VG_CLEAR(enc);
@@ -2664,23 +2741,23 @@ sna_output_init(ScrnInfoPtr scrn, int id, drmModeResPtr res)
if (drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_GETCONNECTOR, &compat_conn.conn)) {
DBG(("%s: GETCONNECTOR failed, ret=%d\n", __FUNCTION__, errno));
- return false;
+ return -1;
}
if (compat_conn.conn.count_encoders != 1) {
DBG(("%s: unexpected number [%d] of encoders attached\n",
__FUNCTION__, compat_conn.conn.count_encoders));
- return false;
+ return 0;
}
if (drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_GETENCODER, &enc)) {
DBG(("%s: GETENCODER failed, ret=%d\n", __FUNCTION__, errno));
- return false;
+ return 0;
}
sna_output = calloc(sizeof(struct sna_output), 1);
if (!sna_output)
- return false;
+ return -1;
sna_output->num_props = compat_conn.conn.count_props;
sna_output->prop_ids = malloc(sizeof(uint32_t)*compat_conn.conn.count_props);
@@ -2710,7 +2787,9 @@ sna_output_init(ScrnInfoPtr scrn, int id, drmModeResPtr res)
output_name = output_names[compat_conn.conn.connector_type];
else
output_name = "UNKNOWN";
- snprintf(name, 32, "%s%d", output_name, compat_conn.conn.connector_type_id);
+ len = snprintf(name, 32, "%s%d", output_name, compat_conn.conn.connector_type_id);
+ if (output_ignored(scrn, name))
+ return 0;
if (xf86IsEntityShared(scrn->entityList[0])) {
const char *str;
@@ -2718,7 +2797,7 @@ sna_output_init(ScrnInfoPtr scrn, int id, drmModeResPtr res)
str = xf86GetOptValString(sna->Options, OPTION_ZAPHOD);
if (str && !sna_zaphod_match(str, name)) {
DBG(("%s: zaphod mismatch, want %s, have %s\n", __FUNCTION__, str, name));
- ret = true;
+ ret = 0;
goto cleanup;
}
@@ -2732,22 +2811,39 @@ sna_output_init(ScrnInfoPtr scrn, int id, drmModeResPtr res)
}
enc.possible_crtcs = 1;
- enc.possible_clones = 0;
}
- output = xf86OutputCreate(scrn, &sna_output_funcs, name);
- if (!output) {
- /* xf86OutputCreate does not differentiate between
- * a failure to allocate the output, and a user request
- * to ignore the output. So reconstruct whether the user
- * explicitly ignored the output.
- */
- ret = output_ignored(scrn, name);
- DBG(("%s: create failed, ignored? %d\n", __FUNCTION__, ret));
+ output = calloc(1, sizeof(*output) + len + 1);
+ if (!output)
goto cleanup;
+
+ outputs = realloc(config->output, (config->num_output + 1) * sizeof(output));
+ if (outputs == NULL) {
+ free(output);
+ goto cleanup;
+ }
+
+ for (i = config->num_output; i > sna->mode.num_real_output; i--) {
+ outputs[i] = outputs[i-1];
+ assert(outputs[i]->driver_private == NULL);
+ outputs[i]->possible_clones <<= 1;
}
+ outputs[i] = output;
+ sna->mode.num_real_output++;
+ config->num_output++;
+ config->output = outputs;
+
+ output->scrn = scrn;
+ output->funcs = &sna_output_funcs;
+ output->name = (char *)(output + 1);
+ memcpy(output->name, name, len + 1);
+
+ output->use_screen_monitor = config->num_output;
+ xf86OutputUseScreenMonitor(output, !config->num_output);
sna_output->id = compat_conn.conn.connector_id;
+ sna_output->encoder_id = enc.encoder_id;
+ sna_output->encoder_idx = -1;
sna_output->is_panel = is_panel(compat_conn.conn.connector_type);
sna_output->edid_idx = find_property(sna, sna_output, "EDID");
sna_output->dpms_id = find_property_id(sna, sna_output, "DPMS");
@@ -2760,33 +2856,34 @@ sna_output_init(ScrnInfoPtr scrn, int id, drmModeResPtr res)
output->subpixel_order = subpixel_conv_table[compat_conn.conn.subpixel];
output->driver_private = sna_output;
- for (i = 0; i < res->count_encoders; i++) {
- if (enc.encoder_id == res->encoders[i]) {
- sna_output->encoder_idx = i;
- break;
- }
- }
-
if (sna_output->is_panel)
sna_output_backlight_init(output);
- output->possible_crtcs = enc.possible_crtcs;
- output->possible_clones = enc.possible_clones;
+ output->possible_crtcs = enc.possible_crtcs & ((1 << sna->mode.num_real_crtc) - 1);
output->interlaceAllowed = TRUE;
- /* stash the active CRTC id for our probe function */
- output->crtc = NULL;
- if (compat_conn.conn.connection != DRM_MODE_DISCONNECTED)
- output->crtc = (void *)(uintptr_t)enc.crtc_id;
+ if (serial) {
+ output->randr_output = RROutputCreate(xf86ScrnToScreen(scrn), name, len, output);
+ if (output->randr_output == NULL)
+ goto cleanup;
+
+ sna_output_create_resources(output);
+ RRPostPendingProperties(output->randr_output);
+
+ sna_output->serial = serial;
+ } else {
+ /* stash the active CRTC id for our probe function */
+ if (compat_conn.conn.connection != DRM_MODE_DISCONNECTED)
+ output->crtc = (void *)(uintptr_t)enc.crtc_id;
+ }
- DBG(("%s: created output '%s' %d (possible crtc:%x, possible clones:%x), edid=%d, dpms=%d, crtc=%lu\n",
+ DBG(("%s: created output '%s' %d (possible crtc:%x), serial=%d, edid=%d, dpms=%d, crtc=%lu\n",
__FUNCTION__, name, id,
(uint32_t)output->possible_crtcs,
- (uint32_t)output->possible_clones,
- sna_output->edid_idx, sna_output->dpms_id,
+ serial, sna_output->edid_idx, sna_output->dpms_id,
(unsigned long)(uintptr_t)output->crtc));
- return true;
+ return 1;
cleanup:
free(sna_output->prop_ids);
@@ -2795,41 +2892,92 @@ cleanup:
return ret;
}
-/* We need to map from kms encoder based possible_clones mask to X output based
- * possible clones masking. Note that for SDVO and on Haswell with DP/HDMI we
- * can have more than one output hanging off the same encoder.
- */
-static void
-sna_mode_compute_possible_outputs(ScrnInfoPtr scrn)
+static void sna_output_del(xf86OutputPtr output)
{
+ ScrnInfoPtr scrn = output->scrn;
xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn);
- unsigned crtc_mask;
- int i, j;
+ int i;
- assert(config->num_output < 32);
- assert(config->num_crtc < 32);
+ assert(to_sna_output(output));
- crtc_mask = (1 << config->num_crtc) - 1;
+ RROutputDestroy(output->randr_output);
+ sna_output_destroy(output);
- /* Convert from encoder numbering to output numbering */
+ while (output->probed_modes)
+ xf86DeleteMode(&output->probed_modes, output->probed_modes);
+
+ free(output);
+
+ for (i = 0; i < config->num_output; i++)
+ if (config->output[i] == output)
+ break;
+ assert(i < to_sna(scrn)->mode.num_real_output);
+
+ for (; i < config->num_output; i++) {
+ config->output[i] = config->output[i+1];
+ config->output[i]->possible_clones >>= 1;
+ }
+ config->num_output--;
+ to_sna(scrn)->mode.num_real_output--;
+}
+
+static void sort_randr_outputs(struct sna *sna, ScreenPtr screen)
+{
+ xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(sna->scrn);
+ rrScrPriv(screen);
+ int i;
+
+ assert(pScrPriv->numOutputs = config->num_output);
for (i = 0; i < config->num_output; i++) {
- xf86OutputPtr output = config->output[i];
- unsigned mask = output->possible_clones;
- unsigned clones = 0;
+ assert(config->output[i]->randr_output);
+ pScrPriv->outputs[i] = config->output[i]->randr_output;
+ }
+}
- for (j = 0; j < config->num_output; j++) {
- if (mask & (1 << to_sna_output(config->output[j])->encoder_idx))
- clones |= 1 << j;
+void sna_mode_discover(struct sna *sna)
+{
+ ScreenPtr screen = xf86ScrnToScreen(sna->scrn);
+ xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(sna->scrn);
+ drmModeResPtr res;
+ int i, j, serial = ++sna->mode.serial;
+ bool changed = false;
+
+ res = drmModeGetResources(sna->kgem.fd);
+ if (res == NULL)
+ return;
+
+ assert(res->count_crtcs == sna->mode.num_real_crtc);
+ assert(sna->mode.max_crtc_width == res->max_width);
+ assert(sna->mode.max_crtc_height == res->max_height);
+
+ for (i = 0; i < res->count_connectors; i++) {
+ for (j = 0; j < sna->mode.num_real_output; j++) {
+ if (to_sna_output(config->output[j])->id == res->connectors[i]) {
+ to_sna_output(config->output[j])->serial = serial;
+ break;
+ }
}
+ if (j == sna->mode.num_real_output)
+ changed |= sna_output_add(sna, res->connectors[i], res, serial) > 0;
+ }
- output->possible_clones = clones;
- output->possible_crtcs &= crtc_mask;
+ for (i = 0; i < sna->mode.num_real_output; i++) {
+ xf86OutputPtr output = config->output[i];
+ if (to_sna_output(output)->serial != serial) {
+ sna_output_del(output);
+ changed = true;
+ }
+ }
- DBG(("%s: updated output '%s' %d [%d] (possible crtc:%x, possible clones:%x)\n",
- __FUNCTION__, output->name, i, to_connector_id(output),
- (uint32_t)output->possible_crtcs,
- (uint32_t)output->possible_clones));
+ if (changed) {
+ sna_mode_compute_possible_outputs(sna, res);
+
+ /* Reorder user visible listing */
+ sort_randr_outputs(sna, screen);
+ xf86RandR12TellChanged(screen);
}
+
+ drmModeFreeResources(res);
}
static void copy_front(struct sna *sna, PixmapPtr old, PixmapPtr new)
@@ -4254,18 +4402,18 @@ bool sna_mode_pre_init(ScrnInfoPtr scrn, struct sna *sna)
xf86_config->xf86_crtc_notify = sna_crtc_config_notify;
for (i = 0; i < res->count_crtcs; i++)
- if (!sna_crtc_init(scrn, res->crtcs[i]))
+ if (!sna_crtc_add(scrn, res->crtcs[i]))
return false;
+ sna->mode.num_real_crtc = xf86_config->num_crtc;
+
for (i = 0; i < res->count_connectors; i++)
- if (!sna_output_init(scrn, res->connectors[i], res))
+ if (sna_output_add(sna, res->connectors[i], res, 0) < 0)
return false;
- sna->mode.num_real_crtc = xf86_config->num_crtc;
sna->mode.num_real_output = xf86_config->num_output;
- if (!xf86IsEntityShared(scrn->entityList[0]))
- sna_mode_compute_possible_outputs(scrn);
+ sna_mode_compute_possible_outputs(sna, res);
sna->mode.max_crtc_width = res->max_width;
sna->mode.max_crtc_height = res->max_height;
diff --git a/src/sna/sna_driver.c b/src/sna/sna_driver.c
index 673e2a5..80ff33b 100644
--- a/src/sna/sna_driver.c
+++ b/src/sna/sna_driver.c
@@ -689,7 +689,7 @@ sna_handle_uevents(int fd, void *closure)
ScrnInfoPtr scrn = closure;
struct sna *sna = to_sna(scrn);
struct udev_device *dev;
- const char *hotplug;
+ const char *str;
struct stat s;
dev_t udev_devnum;
@@ -700,21 +700,13 @@ sna_handle_uevents(int fd, void *closure)
return;
udev_devnum = udev_device_get_devnum(dev);
- if (fstat(sna->kgem.fd, &s)) {
+ if (fstat(sna->kgem.fd, &s) || memcmp(&s.st_rdev, &udev_devnum, sizeof (dev_t))) {
udev_device_unref(dev);
return;
}
- /*
- * Check to make sure this event is directed at our
- * device (by comparing dev_t values), then make
- * sure it's a hotplug event (HOTPLUG=1)
- */
-
- hotplug = udev_device_get_property_value(dev, "HOTPLUG");
-
- if (memcmp(&s.st_rdev, &udev_devnum, sizeof (dev_t)) == 0 &&
- hotplug && atoi(hotplug) == 1) {
+ str = udev_device_get_property_value(dev, "HOTPLUG");
+ if (str && atoi(str) == 1) {
DBG(("%s: hotplug event (vtSema?=%d)\n",
__FUNCTION__, sna->scrn->vtSema));
if (sna->scrn->vtSema) {
@@ -724,6 +716,16 @@ sna_handle_uevents(int fd, void *closure)
sna->flags |= SNA_REPROBE;
}
+ str = udev_device_get_property_value(dev, "DISCOVER");
+ if (str && atoi(str) == 1) {
+ DBG(("%s: discover event (vtSema?=%d)\n",
+ __FUNCTION__, sna->scrn->vtSema));
+ if (sna->scrn->vtSema)
+ sna_mode_discover(sna);
+ else
+ sna->flags |= SNA_REDISCOVER;
+ }
+
udev_device_unref(dev);
}
@@ -1094,6 +1096,13 @@ static Bool sna_enter_vt(VT_FUNC_ARGS_DECL)
if (!sna_set_desired_mode(sna))
return FALSE;
+ if (sna->flags & SNA_REDISCOVER) {
+ DBG(("%s: reporting deferred discover event\n",
+ __FUNCTION__));
+ sna_mode_discover(sna);
+ sna->flags &= ~SNA_REDISCOVER;
+ }
+
if (sna->flags & SNA_REPROBE) {
DBG(("%s: reporting deferred hotplug event\n",
__FUNCTION__));
More information about the xorg-commit
mailing list