summaryrefslogtreecommitdiff
path: root/src/drmmode_display.c
diff options
context:
space:
mode:
authorDave Airlie <airlied@redhat.com>2010-04-16 13:58:54 +1000
committerDave Airlie <airlied@redhat.com>2010-04-16 13:58:54 +1000
commita69e749d0562887af6bd236c38802472e54640c4 (patch)
tree2b2ddc0be5e2c10bc64d96ceff997caf06c5a705 /src/drmmode_display.c
parent22a46dddd375b2b9399e12fdf168fa5292ff17a4 (diff)
kms: add uevent support.
When we get a hotplug event from the kernel we should notify the client side to reconfigure displays. based on work by ajax in intel driver. Signed-off-by: Dave Airlie <airlied@redhat.com>
Diffstat (limited to 'src/drmmode_display.c')
-rw-r--r--src/drmmode_display.c64
1 files changed, 64 insertions, 0 deletions
diff --git a/src/drmmode_display.c b/src/drmmode_display.c
index 399a6a73..cadd1763 100644
--- a/src/drmmode_display.c
+++ b/src/drmmode_display.c
@@ -1159,6 +1159,7 @@ Bool drmmode_pre_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, int cpp)
xf86CrtcConfigInit(pScrn, &drmmode_xf86crtc_config_funcs);
xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
+ drmmode->scrn = pScrn;
drmmode->cpp = cpp;
drmmode->mode_res = drmModeGetResources(drmmode->fd);
if (!drmmode->mode_res)
@@ -1347,4 +1348,67 @@ Bool drmmode_setup_colormap(ScreenPtr pScreen, ScrnInfoPtr pScrn)
return FALSE;
return TRUE;
}
+
+#ifdef HAVE_LIBUDEV
+static void
+drmmode_handle_uevents(int fd, void *closure)
+{
+ drmmode_ptr drmmode = closure;
+ ScrnInfoPtr scrn = drmmode->scrn;
+ struct udev_device *dev;
+ dev = udev_monitor_receive_device(drmmode->uevent_monitor);
+ if (!dev)
+ return;
+
+ RRGetInfo(screenInfo.screens[scrn->scrnIndex], TRUE);
+ udev_device_unref(dev);
+}
+#endif
+
+void drmmode_uevent_init(ScrnInfoPtr scrn, drmmode_ptr drmmode)
+{
+#ifdef HAVE_LIBUDEV
+ struct udev *u;
+ struct udev_monitor *mon;
+
+ u = udev_new();
+ if (!u)
+ return;
+ mon = udev_monitor_new_from_netlink(u, "udev");
+ if (!mon) {
+ udev_unref(u);
+ return;
+ }
+
+ if (udev_monitor_filter_add_match_subsystem_devtype(mon,
+ "drm",
+ "drm_minor") < 0 ||
+ udev_monitor_enable_receiving(mon) < 0) {
+ udev_monitor_unref(mon);
+ udev_unref(u);
+ return;
+ }
+
+ drmmode->uevent_handler =
+ xf86AddGeneralHandler(udev_monitor_get_fd(mon),
+ drmmode_handle_uevents,
+ drmmode);
+
+ drmmode->uevent_monitor = mon;
+#endif
+}
+
+void drmmode_uevent_fini(ScrnInfoPtr scrn, drmmode_ptr drmmode)
+{
+#ifdef HAVE_LIBUDEV
+ if (drmmode->uevent_handler) {
+ struct udev *u = udev_monitor_get_udev(drmmode->uevent_monitor);
+ xf86RemoveGeneralHandler(drmmode->uevent_handler);
+
+ udev_monitor_unref(drmmode->uevent_monitor);
+ udev_unref(u);
+ }
+#endif
+}
+
#endif