diff options
author | Robert Nagy <robert@cvs.openbsd.org> | 2018-01-15 15:30:37 +0000 |
---|---|---|
committer | Robert Nagy <robert@cvs.openbsd.org> | 2018-01-15 15:30:37 +0000 |
commit | 8e432d651570775c9a7758b6a3aceee8d1f48080 (patch) | |
tree | 490a217a7587663a0c334b9982849032a6dd9ade /xserver/hw | |
parent | e061c608afa92f61481071786f2cde0a40cb9aac (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.c | 39 | ||||
-rw-r--r-- | xserver/hw/xfree86/drivers/modesetting/drmmode_display.h | 5 |
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; |