diff options
author | Dave Airlie <airlied@redhat.com> | 2010-04-16 13:58:54 +1000 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2010-04-16 13:58:54 +1000 |
commit | a69e749d0562887af6bd236c38802472e54640c4 (patch) | |
tree | 2b2ddc0be5e2c10bc64d96ceff997caf06c5a705 /src/drmmode_display.c | |
parent | 22a46dddd375b2b9399e12fdf168fa5292ff17a4 (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.c | 64 |
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 |