summaryrefslogtreecommitdiff
path: root/xserver/hw
diff options
context:
space:
mode:
authorRobert Nagy <robert@cvs.openbsd.org>2018-01-15 15:30:37 +0000
committerRobert Nagy <robert@cvs.openbsd.org>2018-01-15 15:30:37 +0000
commit8e432d651570775c9a7758b6a3aceee8d1f48080 (patch)
tree490a217a7587663a0c334b9982849032a6dd9ade /xserver/hw
parente061c608afa92f61481071786f2cde0a40cb9aac (diff)
watch for events sent by drm(4) over kevent using EVFILT_DEVICE
and NOTE_CHANGE to notify the desktop environment to deal with the change (e.g. after plugging in an HDMI cable) with this change there is no need to manually do any randr commands if your desktop environment supports it (gnome, mate, kde, etc.) ok matthieu@, kettenis@
Diffstat (limited to 'xserver/hw')
-rw-r--r--xserver/hw/xfree86/drivers/modesetting/drmmode_display.c39
-rw-r--r--xserver/hw/xfree86/drivers/modesetting/drmmode_display.h5
2 files changed, 42 insertions, 2 deletions
diff --git a/xserver/hw/xfree86/drivers/modesetting/drmmode_display.c b/xserver/hw/xfree86/drivers/modesetting/drmmode_display.c
index 7981665a3..21703d2c7 100644
--- a/xserver/hw/xfree86/drivers/modesetting/drmmode_display.c
+++ b/xserver/hw/xfree86/drivers/modesetting/drmmode_display.c
@@ -32,6 +32,9 @@
#include <errno.h>
#include <sys/ioctl.h>
#include <sys/mman.h>
+#if defined(CONFIG_KEVENT_KMS)
+#include <sys/event.h>
+#endif
#include <unistd.h>
#include "dumb_bo.h"
#include "xf86str.h"
@@ -2308,7 +2311,7 @@ drmmode_setup_colormap(ScreenPtr pScreen, ScrnInfoPtr pScrn)
return TRUE;
}
-#ifdef CONFIG_UDEV_KMS
+#if defined(CONFIG_UDEV_KMS) || defined(CONFIG_KEVENT_KMS)
#define DRM_MODE_LINK_STATUS_GOOD 0
#define DRM_MODE_LINK_STATUS_BAD 1
@@ -2318,17 +2321,26 @@ drmmode_handle_uevents(int fd, void *closure)
{
drmmode_ptr drmmode = closure;
ScrnInfoPtr scrn = drmmode->scrn;
+#ifdef CONFIG_UDEV_KMS
struct udev_device *dev;
+#endif
drmModeResPtr mode_res;
xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn);
int i, j;
Bool found = FALSE;
Bool changed = FALSE;
+#ifdef CONFIG_UDEV_KMS
while ((dev = udev_monitor_receive_device(drmmode->uevent_monitor))) {
udev_device_unref(dev);
found = TRUE;
}
+#else
+ struct kevent ev;
+ if ((kevent(fd, NULL, 0, &ev, 1, NULL)) && ev.fflags & NOTE_CHANGE)
+ found = TRUE;
+#endif
+
if (!found)
return;
@@ -2478,6 +2490,23 @@ drmmode_uevent_init(ScrnInfoPtr scrn, drmmode_ptr drmmode)
drmmode_handle_uevents, drmmode);
drmmode->uevent_monitor = mon;
+#elif CONFIG_KEVENT_KMS
+ int kq;
+ struct kevent ev;
+
+ if (drmmode->kevent_handler)
+ return;
+
+ if ((kq = kqueue()) <= 0)
+ return;
+
+ EV_SET(&ev, drmmode->fd, EVFILT_DEVICE, EV_ADD | EV_ENABLE | EV_CLEAR,
+ NOTE_CHANGE, 0, NULL);
+ if (kevent(kq, &ev, 1, NULL, 0, NULL) < 0)
+ return;
+
+ drmmode->kevent_handler = xf86AddGeneralHandler(kq,
+ drmmode_handle_uevents, drmmode);
#endif
}
@@ -2493,6 +2522,14 @@ drmmode_uevent_fini(ScrnInfoPtr scrn, drmmode_ptr drmmode)
udev_monitor_unref(drmmode->uevent_monitor);
udev_unref(u);
}
+#elif CONFIG_KEVENT_KMS
+ int kq;
+
+ if (drmmode->kevent_handler) {
+ kq = xf86RemoveGeneralHandler(drmmode->kevent_handler);
+ close(kq);
+ drmmode->kevent_handler = NULL;
+ }
#endif
}
diff --git a/xserver/hw/xfree86/drivers/modesetting/drmmode_display.h b/xserver/hw/xfree86/drivers/modesetting/drmmode_display.h
index 50976b849..0412b3553 100644
--- a/xserver/hw/xfree86/drivers/modesetting/drmmode_display.h
+++ b/xserver/hw/xfree86/drivers/modesetting/drmmode_display.h
@@ -53,10 +53,13 @@ typedef struct {
struct gbm_device *gbm;
-#ifdef CONFIG_UDEV_KMS
+#if defined(CONFIG_UDEV_KMS)
struct udev_monitor *uevent_monitor;
InputHandlerProc uevent_handler;
#endif
+#if defined(CONFIG_KEVENT_KMS)
+ InputHandlerProc kevent_handler;
+#endif
drmEventContext event_context;
drmmode_bo front_bo;
Bool sw_cursor;