Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Add uevent support

When a hotplug event is received from the kernel we should notify the
client side to reconfigure the display.

Ported to nouveau from radeon driver, based on work by ajax in intel driver.
  • Loading branch information...
commit 6ff8ade0c7cd835b4172257ea310a8d88f28e757 1 parent 4063616
Ben Skeggs authored
View
8 configure.ac
@@ -81,6 +81,14 @@ sdkdir=$(pkg-config --variable=sdkdir xorg-server)
# Checks for libraries.
PKG_CHECK_MODULES([PCIACCESS], [pciaccess >= 0.10])
+PKG_CHECK_MODULES(LIBUDEV, [libudev], [LIBUDEV=yes], [LIBUDEV=no])
+if test "x$LIBUDEV" = xyes; then
+ AC_DEFINE(HAVE_LIBUDEV, 1, [libudev support])
+fi
+AM_CONDITIONAL(LIBUDEV, [ test "x$LIBUDEV" = "xyes" ] )
+AC_SUBST([LIBUDEV_CFLAGS])
+AC_SUBST([LIBUDEV_LIBS])
+
# Checks for header files.
AC_HEADER_STDC
View
5 src/Makefile.am
@@ -23,9 +23,10 @@
# -avoid-version prevents gratuitous .0.0.0 version numbers on the end
# _ladir passes a dummy rpath to libtool so the thing will actually link
# TODO: -nostdlib/-Bstatic/-lgcc platform magic, not installing the .a, etc.
-AM_CFLAGS = @XORG_CFLAGS@ @LIBDRM_NOUVEAU_CFLAGS@
+AM_CFLAGS = @XORG_CFLAGS@ @LIBUDEV_CFLAGS@ @LIBDRM_NOUVEAU_CFLAGS@
nouveau_drv_la_LTLIBRARIES = nouveau_drv.la
-nouveau_drv_la_LDFLAGS = -module -avoid-version @LIBDRM_NOUVEAU_LIBS@
+nouveau_drv_la_LDFLAGS = -module -avoid-version @LIBDRM_NOUVEAU_LIBS@ \
+ @LIBUDEV_LIBS@
nouveau_drv_ladir = @moduledir@/drivers
nouveau_drv_la_SOURCES = \
View
83 src/drmmode_display.c
@@ -38,12 +38,19 @@
#include "X11/Xatom.h"
#include <sys/ioctl.h>
+#ifdef HAVE_LIBUDEV
+#include "libudev.h"
+#endif
typedef struct {
int fd;
uint32_t fb_id;
drmModeResPtr mode_res;
int cpp;
+#ifdef HAVE_LIBUDEV
+ struct udev_monitor *uevent_monitor;
+ InputHandlerProc uevent_handler;
+#endif
} drmmode_rec, *drmmode_ptr;
typedef struct {
@@ -1169,3 +1176,79 @@ drmmode_cursor_init(ScreenPtr pScreen)
return xf86_cursors_init(pScreen, size, size, flags);
}
+#ifdef HAVE_LIBUDEV
+static drmmode_ptr
+drmmode_from_scrn(ScrnInfoPtr scrn)
+{
+ xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
+ drmmode_crtc_private_ptr drmmode_crtc;
+
+ drmmode_crtc = xf86_config->crtc[0]->driver_private;
+ return drmmode_crtc->drmmode;
+}
+
+static void
+drmmode_handle_uevents(int fd, void *closure)
+{
+ ScrnInfoPtr scrn = closure;
+ drmmode_ptr drmmode = drmmode_from_scrn(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)
+{
+#ifdef HAVE_LIBUDEV
+ drmmode_ptr drmmode = drmmode_from_scrn(scrn);
+ 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, scrn);
+
+ drmmode->uevent_monitor = mon;
+#endif
+}
+
+void
+drmmode_uevent_fini(ScrnInfoPtr scrn)
+{
+#ifdef HAVE_LIBUDEV
+ drmmode_ptr drmmode = drmmode_from_scrn(scrn);
+
+ 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
+}
View
3  src/nv_driver.c
@@ -411,6 +411,8 @@ NVCloseScreen(int scrnIndex, ScreenPtr pScreen)
ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
NVPtr pNv = NVPTR(pScrn);
+ drmmode_uevent_fini(pScrn);
+
nouveau_dri2_fini(pScreen);
if (pScrn->vtSema) {
@@ -1167,6 +1169,7 @@ NVScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
if (serverGeneration == 1)
xf86ShowUnusedOptions(pScrn->scrnIndex, pScrn->options);
+ drmmode_uevent_init(pScrn);
return TRUE;
}
View
2  src/nv_proto.h
@@ -7,6 +7,8 @@ void drmmode_adjust_frame(ScrnInfoPtr pScrn, int x, int y, int flags);
void drmmode_remove_fb(ScrnInfoPtr pScrn);
Bool drmmode_cursor_init(ScreenPtr pScreen);
void drmmode_fbcon_copy(ScreenPtr pScreen);
+void drmmode_uevent_init(ScrnInfoPtr);
+void drmmode_uevent_fini(ScrnInfoPtr);
/* in nv_accel_common.c */
Bool NVAccelCommonInit(ScrnInfoPtr pScrn);
Please sign in to comment.
Something went wrong with that request. Please try again.