[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