[Wine-patches] [eterwine 1/2] mountmgr: Add dynamic USB devices support using udev (eterbug #4301).
Alexander Morozov
amorozov на etersoft.ru
Вт Май 15 18:28:46 MSK 2012
---
configure | 71 ++++++++++++++++++++++++++++++++++
configure.ac | 13 +++++++
dlls/mountmgr.sys/Makefile.in | 2 +-
dlls/mountmgr.sys/dbus.c | 8 ++++
dlls/mountmgr.sys/usbhub.c | 84 +++++++++++++++++++++++++++++++++++++++++
include/config.h.in | 3 ++
6 files changed, 180 insertions(+), 1 deletion(-)
diff --git a/configure b/configure
index c3a8273..118793f 100755
--- a/configure
+++ b/configure
@@ -644,6 +644,7 @@ gphoto2port_devel
gphoto2_devel
USBINCL
USBLIBS
+LIBUDEV
SANEINCL
sane_devel
GNUTLSINCL
@@ -811,6 +812,7 @@ with_png
with_pthread
with_sane
with_tiff
+with_udev
with_usb
with_v4l
with_xcomposite
@@ -1502,6 +1504,7 @@ Optional Packages:
--without-pthread do not use the pthread library
--without-sane do not use SANE (scanner support)
--without-tiff do not use TIFF
+ --without-udev do not use libudev
--without-usb do not use USB
--without-v4l do not use v4l1 (v4l support)
--without-xcomposite do not use the Xcomposite extension
@@ -2726,6 +2729,12 @@ if test "${with_tiff+set}" = set; then :
fi
+# Check whether --with-udev was given.
+if test "${with_udev+set}" = set; then :
+ withval=$with_udev;
+fi
+
+
# Check whether --with-usb was given.
if test "${with_usb+set}" = set; then :
withval=$with_usb;
@@ -10143,6 +10152,68 @@ This is an error since --with-v4l was requested." "$LINENO" 5 ;;
esac
fi
+LIBUDEV=""
+
+if test "x$with_udev" != "xno"
+then
+ ac_fn_c_check_header_mongrel "$LINENO" "libudev.h" "ac_cv_header_libudev_h" "$ac_includes_default"
+if test "x$ac_cv_header_libudev_h" = xyes; then :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for udev_new in -ludev" >&5
+$as_echo_n "checking for udev_new in -ludev... " >&6; }
+if ${ac_cv_lib_udev_udev_new+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-ludev $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char udev_new ();
+int
+main ()
+{
+return udev_new ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_udev_udev_new=yes
+else
+ ac_cv_lib_udev_udev_new=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_udev_udev_new" >&5
+$as_echo "$ac_cv_lib_udev_udev_new" >&6; }
+if test "x$ac_cv_lib_udev_udev_new" = xyes; then :
+
+$as_echo "#define HAVE_LIBUDEV 1" >>confdefs.h
+
+ LIBUDEV="-ludev"
+fi
+
+fi
+
+
+fi
+if test "x$ac_cv_lib_udev_udev_new" = "x"; then :
+ case "x$with_udev" in
+ x) as_fn_append wine_notices "|libudev ${notice_platform}development files not found, no dynamic USB device support." ;;
+ xno) ;;
+ *) as_fn_error $? "libudev ${notice_platform}development files not found, no dynamic USB device support.
+This is an error since --with-udev was requested." "$LINENO" 5 ;;
+esac
+fi
+
USBLIBS=""
USBINCL=""
diff --git a/configure.ac b/configure.ac
index eeb3a38..5caa7d5 100644
--- a/configure.ac
+++ b/configure.ac
@@ -78,6 +78,7 @@ AC_ARG_WITH(pthread, AS_HELP_STRING([--without-pthread],[do not use the pthrea
AC_ARG_WITH(sane, AS_HELP_STRING([--without-sane],[do not use SANE (scanner support)]))
AC_ARG_WITH(tiff, AS_HELP_STRING([--without-tiff],[do not use TIFF]),
[if test "x$withval" = "xno"; then ac_cv_header_tiffio_h=no; fi])
+AC_ARG_WITH(udev, AS_HELP_STRING([--without-udev],[do not use libudev]))
AC_ARG_WITH(usb, AS_HELP_STRING([--without-usb],[do not use USB]))
AC_ARG_WITH(v4l, AS_HELP_STRING([--without-v4l],[do not use v4l1 (v4l support)]))
AC_ARG_WITH(xcomposite,AS_HELP_STRING([--without-xcomposite],[do not use the Xcomposite extension]),
@@ -1337,6 +1338,18 @@ fi
WINE_NOTICE_WITH(v4l,[test "x$ac_cv_lib_soname_v4l1" = "x"],
[libv4l ${notice_platform}development files not found.])
+dnl **** Check for libudev ****
+AC_SUBST(LIBUDEV,"")
+if test "x$with_udev" != "xno"
+then
+ AC_CHECK_HEADER(libudev.h,
+ AC_CHECK_LIB(udev, udev_new,
+ [AC_DEFINE(HAVE_LIBUDEV, 1, [Define if you have the libudev library and header])
+ LIBUDEV="-ludev"]))
+fi
+WINE_NOTICE_WITH(udev,[test "x$ac_cv_lib_udev_udev_new" = "x"],
+ [libudev ${notice_platform}development files not found, no dynamic USB device support.])
+
dnl **** Check for LIBUSB ****
AC_SUBST(USBLIBS,"")
AC_SUBST(USBINCL,"")
diff --git a/dlls/mountmgr.sys/Makefile.in b/dlls/mountmgr.sys/Makefile.in
index 41b06ac..03f7857 100644
--- a/dlls/mountmgr.sys/Makefile.in
+++ b/dlls/mountmgr.sys/Makefile.in
@@ -4,7 +4,7 @@ DELAYIMPORTS = user32
EXTRADLLFLAGS = -Wb,--subsystem,native
EXTRADEFS = @DBUSINCL@ @HALINCL@
EXTRAINCL = @USBINCL@
-EXTRALIBS = @DISKARBITRATIONLIB@ @USBLIBS@
+EXTRALIBS = @DISKARBITRATIONLIB@ @USBLIBS@ @LIBUDEV@
C_SRCS = \
dbus.c \
diff --git a/dlls/mountmgr.sys/dbus.c b/dlls/mountmgr.sys/dbus.c
index 8cbba51..635f614 100644
--- a/dlls/mountmgr.sys/dbus.c
+++ b/dlls/mountmgr.sys/dbus.c
@@ -406,7 +406,9 @@ static DBusHandlerResult udisks_filter( DBusConnection *ctx, DBusMessage *msg, v
static void hal_new_device( LibHalContext *ctx, const char *udi )
{
DBusError error;
+#ifndef HAVE_LIBUDEV
char *subsys = NULL;
+#endif
char *parent = NULL;
char *mount_point = NULL;
char *device = NULL;
@@ -417,9 +419,11 @@ static void hal_new_device( LibHalContext *ctx, const char *udi )
p_dbus_error_init( &error );
+#ifndef HAVE_LIBUDEV
if ((subsys = p_libhal_device_get_property_string( ctx, udi, "info.subsystem", NULL )) &&
!strcmp( subsys, "usb_device" ))
add_usb_devices();
+#endif
if (automount_disabled())
goto done;
@@ -454,7 +458,9 @@ static void hal_new_device( LibHalContext *ctx, const char *udi )
else if (guid_ptr) add_volume( udi, device, mount_point, DEVICE_HARDDISK_VOL, guid_ptr );
done:
+#ifndef HAVE_LIBUDEV
if (subsys) p_libhal_free_string( subsys );
+#endif
if (type) p_libhal_free_string( type );
if (parent) p_libhal_free_string( parent );
if (device) p_libhal_free_string( device );
@@ -470,7 +476,9 @@ static void hal_removed_device( LibHalContext *ctx, const char *udi )
TRACE( "removed %s\n", wine_dbgstr_a(udi) );
+#ifndef HAVE_LIBUDEV
remove_usb_devices();
+#endif
if (!remove_dos_device( -1, udi ))
{
p_dbus_error_init( &error );
diff --git a/dlls/mountmgr.sys/usbhub.c b/dlls/mountmgr.sys/usbhub.c
index 1ce0c2b..533c298 100644
--- a/dlls/mountmgr.sys/usbhub.c
+++ b/dlls/mountmgr.sys/usbhub.c
@@ -21,6 +21,12 @@
#include <stdio.h>
#include <stdlib.h>
+#ifdef HAVE_POLL_H
+#include <poll.h>
+#endif
+#ifdef HAVE_SYS_POLL_H
+#include <sys/poll.h>
+#endif
#ifdef HAVE_LIBUSB_1
#include <libusb.h>
@@ -32,6 +38,9 @@
#undef USB_ENDPOINT_TYPE_BULK
#undef USB_ENDPOINT_TYPE_INTERRUPT
#endif
+#ifdef HAVE_LIBUDEV
+#include <libudev.h>
+#endif
#define NONAMELESSUNION
#define NONAMELESSSTRUCT
@@ -1975,6 +1984,77 @@ void remove_usb_devices(void)
#if defined(HAVE_LIBUSB) || defined(HAVE_LIBUSB_1)
+#ifdef HAVE_LIBUDEV
+
+static void *start_udev(void)
+{
+ struct udev *udev;
+ struct udev_monitor *mon;
+ int ret;
+
+ udev = udev_new();
+ if (!udev)
+ return NULL;
+
+ mon = udev_monitor_new_from_netlink( udev, "udev" );
+ if (!mon) goto end;
+ ret = udev_monitor_filter_add_match_subsystem_devtype( mon, "usb", "usb_device" );
+ if (ret < 0) goto end;
+ ret = udev_monitor_enable_receiving( mon );
+ if (ret < 0) goto end;
+ return mon;
+end:
+ udev_monitor_unref( mon );
+ udev_unref( udev );
+ return NULL;
+}
+
+static void loop_udev( void *mon )
+{
+ struct pollfd fds;
+ int ret, fd = udev_monitor_get_fd( mon );
+
+ fds.fd = fd;
+ fds.events = POLLIN;
+
+ for(;;)
+ {
+ fds.revents = 0;
+ ret = poll( &fds, 1, -1 );
+ if (ret == 1 && (fds.revents & POLLIN))
+ {
+ struct udev_device *dev = udev_monitor_receive_device( mon );
+
+ if (dev)
+ {
+ const char *action = udev_device_get_action( dev );
+
+ if (action)
+ {
+ if (!strcmp( action, "add" ))
+ add_usb_devices();
+ else if (!strcmp( action, "remove" ))
+ remove_usb_devices();
+ }
+ udev_device_unref( dev );
+ }
+ }
+ }
+}
+
+#else /* HAVE_LIBUDEV */
+
+static void *start_udev(void)
+{
+ return NULL;
+}
+
+static void loop_udev( void *mon )
+{
+}
+
+#endif /* HAVE_LIBUDEV */
+
static DWORD CALLBACK initialize_usbhub( void *arg )
{
static const WCHAR usbhub_started_eventW[] = {'_','_','w','i','n','e',
@@ -1982,6 +2062,7 @@ static DWORD CALLBACK initialize_usbhub( void *arg )
'S','t','a','r','t','e','d',0};
HANDLE event;
+ void *monitor;
EnterCriticalSection( &usbhub_cs );
if (!enum_reg_usb_devices())
@@ -1991,10 +2072,13 @@ static DWORD CALLBACK initialize_usbhub( void *arg )
else
libusb_initialized = TRUE;
LeaveCriticalSection( &usbhub_cs );
+ monitor = start_udev();
add_usb_devices();
event = CreateEventW( NULL, TRUE, FALSE, usbhub_started_eventW );
SetEvent( event );
CloseHandle( event );
+ if (monitor)
+ loop_udev( monitor );
return 0;
}
diff --git a/include/config.h.in b/include/config.h.in
index f060af9..12bd154 100644
--- a/include/config.h.in
+++ b/include/config.h.in
@@ -356,6 +356,9 @@
/* Define to 1 if you have the `ossaudio' library (-lossaudio). */
#undef HAVE_LIBOSSAUDIO
+/* Define if you have the libudev library and header */
+#undef HAVE_LIBUDEV
+
/* Define if you have the libusb library and header */
#undef HAVE_LIBUSB
--
1.7.9.7
Подробная информация о списке рассылки Wine-patches