[Spice-commits] 5 commits - doc/reference gtk/map-file gtk/spice-glib-sym-file gtk/usb-device-manager.c gtk/usb-device-manager.h

Hans de Goede jwrdegoede at kemper.freedesktop.org
Wed Apr 24 00:34:51 PDT 2013


 doc/reference/spice-gtk-sections.txt |    1 
 gtk/map-file                         |    1 
 gtk/spice-glib-sym-file              |    1 
 gtk/usb-device-manager.c             |  111 +++++++++++++++++++++++++++--------
 gtk/usb-device-manager.h             |    2 
 5 files changed, 93 insertions(+), 23 deletions(-)

New commits:
commit 12dc919a7a1bd9e12ae0ffe17a0d5da4d82473ec
Author: Hans de Goede <hdegoede at redhat.com>
Date:   Tue Apr 23 14:12:46 2013 +0200

    usb-device-manager: Fix stray '\n'-s in g_warning calls
    
    Signed-off-by: Hans de Goede <hdegoede at redhat.com>

diff --git a/gtk/usb-device-manager.c b/gtk/usb-device-manager.c
index 7575417..b7f24da 100644
--- a/gtk/usb-device-manager.c
+++ b/gtk/usb-device-manager.c
@@ -385,7 +385,7 @@ static void spice_usb_device_manager_set_property(GObject       *gobject,
         if (r) {
             if (r == -ENOMEM)
                 g_error("Failed to allocate memory for auto-connect-filter");
-            g_warning("Error parsing auto-connect-filter string, keeping old filter\n");
+            g_warning("Error parsing auto-connect-filter string, keeping old filter");
             break;
         }
 
@@ -409,7 +409,7 @@ static void spice_usb_device_manager_set_property(GObject       *gobject,
         if (r) {
             if (r == -ENOMEM)
                 g_error("Failed to allocate memory for redirect-on-connect");
-            g_warning("Error parsing redirect-on-connect string, keeping old filter\n");
+            g_warning("Error parsing redirect-on-connect string, keeping old filter");
             break;
         }
 
commit 3ae6117ebae938f6092e39192b9631a5b9434688
Author: Hans de Goede <hdegoede at redhat.com>
Date:   Tue Apr 23 14:12:03 2013 +0200

    usb-device-manager: Fix redirect_on_connect_rules mem-leak
    
    Signed-off-by: Hans de Goede <hdegoede at redhat.com>

diff --git a/gtk/usb-device-manager.c b/gtk/usb-device-manager.c
index 75406a4..7575417 100644
--- a/gtk/usb-device-manager.c
+++ b/gtk/usb-device-manager.c
@@ -314,6 +314,7 @@ static void spice_usb_device_manager_finalize(GObject *gobject)
     if (priv->event_thread)
         g_thread_join(priv->event_thread);
     free(priv->auto_conn_filter_rules);
+    free(priv->redirect_on_connect_rules);
 #ifdef G_OS_WIN32
     if (priv->installer)
         g_object_unref(priv->installer);
commit 0ebcc23c0642d2bddcb05ed4152497c99cb3ca1d
Author: Hans de Goede <hdegoede at redhat.com>
Date:   Tue Apr 23 14:10:02 2013 +0200

    usb-device-manager: Add spice_usb_device_manager_get_devices_with_filter (fdo#63807)
    
    Signed-off-by: Hans de Goede <hdegoede at redhat.com>

diff --git a/doc/reference/spice-gtk-sections.txt b/doc/reference/spice-gtk-sections.txt
index d82a886..b15e4bb 100644
--- a/doc/reference/spice-gtk-sections.txt
+++ b/doc/reference/spice-gtk-sections.txt
@@ -291,6 +291,7 @@ SpiceUsbDeviceManagerClass
 <SUBSECTION>
 spice_usb_device_manager_get
 spice_usb_device_manager_get_devices
+spice_usb_device_manager_get_devices_with_filter
 spice_usb_device_manager_is_device_connected
 spice_usb_device_manager_disconnect_device
 spice_usb_device_manager_can_redirect_device
diff --git a/gtk/map-file b/gtk/map-file
index 386afb1..558a4d7 100644
--- a/gtk/map-file
+++ b/gtk/map-file
@@ -104,6 +104,7 @@ spice_usb_device_manager_connect_device_finish;
 spice_usb_device_manager_disconnect_device;
 spice_usb_device_manager_get;
 spice_usb_device_manager_get_devices;
+spice_usb_device_manager_get_devices_with_filter;
 spice_usb_device_manager_get_type;
 spice_usb_device_manager_is_device_connected;
 spice_usb_device_widget_get_type;
diff --git a/gtk/spice-glib-sym-file b/gtk/spice-glib-sym-file
index ac8ee82..5a580d6 100644
--- a/gtk/spice-glib-sym-file
+++ b/gtk/spice-glib-sym-file
@@ -80,6 +80,7 @@ spice_usb_device_manager_connect_device_finish
 spice_usb_device_manager_disconnect_device
 spice_usb_device_manager_get
 spice_usb_device_manager_get_devices
+spice_usb_device_manager_get_devices_with_filter
 spice_usb_device_manager_get_type
 spice_usb_device_manager_is_device_connected
 spice_usbredir_channel_get_type
diff --git a/gtk/usb-device-manager.c b/gtk/usb-device-manager.c
index dc334bd..75406a4 100644
--- a/gtk/usb-device-manager.c
+++ b/gtk/usb-device-manager.c
@@ -500,7 +500,7 @@ static void spice_usb_device_manager_class_init(SpiceUsbDeviceManagerClass *klas
      * Set a string specifying a filter selecting USB devices to automatically
      * redirect after a Spice connection has been established.
      *
-     * See SpiceUsbDeviceManager:auto-connect-filter: for the filter string
+     * See #SpiceUsbDeviceManager:auto-connect-filter for the filter string
      * format.
      */
     pspec = g_param_spec_string("redirect-on-connect", "Redirect on connect",
@@ -1181,12 +1181,15 @@ SpiceUsbDeviceManager *spice_usb_device_manager_get(SpiceSession *session,
 }
 
 /**
- * spice_usb_device_manager_get_devices:
+ * spice_usb_device_manager_get_devices_with_filter:
  * @manager: the #SpiceUsbDeviceManager manager
+ * @filter: filter string for selecting which devices to return, see
+ *      #SpiceUsbDeviceManager:auto-connect-filter for the filter string format
  *
  * Returns: (element-type SpiceUsbDevice) (transfer full): a %GPtrArray array of %SpiceUsbDevice
  */
-GPtrArray* spice_usb_device_manager_get_devices(SpiceUsbDeviceManager *self)
+GPtrArray* spice_usb_device_manager_get_devices_with_filter(
+    SpiceUsbDeviceManager *self, const gchar *filter)
 {
     GPtrArray *devices_copy = NULL;
 
@@ -1194,20 +1197,57 @@ GPtrArray* spice_usb_device_manager_get_devices(SpiceUsbDeviceManager *self)
 
 #ifdef USE_USBREDIR
     SpiceUsbDeviceManagerPrivate *priv = self->priv;
+    struct usbredirfilter_rule *rules = NULL;;
+    int r, count = 0;
     guint i;
 
+    if (filter) {
+        r = usbredirfilter_string_to_rules(filter, ",", "|", &rules, &count);
+        if (r) {
+            if (r == -ENOMEM)
+                g_error("Failed to allocate memory for filter");
+            g_warning("Error parsing filter, ignoring");
+            rules = NULL;
+            count = 0;
+        }
+    }
+
     devices_copy = g_ptr_array_new_with_free_func((GDestroyNotify)
                                                   spice_usb_device_unref);
     for (i = 0; i < priv->devices->len; i++) {
         SpiceUsbDevice *device = g_ptr_array_index(priv->devices, i);
+
+        if (rules) {
+            libusb_device *libdev =
+                spice_usb_device_manager_device_to_libdev(self, device);
+#ifdef G_OS_WIN32
+            if (libdev == NULL)
+                continue;
+#endif
+            if (usbredirhost_check_device_filter(rules, count, libdev, 0) != 0)
+                continue;
+        }
         g_ptr_array_add(devices_copy, spice_usb_device_ref(device));
     }
+
+    free(rules);
 #endif
 
     return devices_copy;
 }
 
 /**
+ * spice_usb_device_manager_get_devices:
+ * @manager: the #SpiceUsbDeviceManager manager
+ *
+ * Returns: (element-type SpiceUsbDevice) (transfer full): a %GPtrArray array of %SpiceUsbDevice
+ */
+GPtrArray* spice_usb_device_manager_get_devices(SpiceUsbDeviceManager *self)
+{
+    return spice_usb_device_manager_get_devices_with_filter(self, NULL);
+}
+
+/**
  * spice_usb_device_manager_is_device_connected:
  * @manager: the #SpiceUsbDeviceManager manager
  * @device: a #SpiceUsbDevice
diff --git a/gtk/usb-device-manager.h b/gtk/usb-device-manager.h
index df138ee..a7e3515 100644
--- a/gtk/usb-device-manager.h
+++ b/gtk/usb-device-manager.h
@@ -94,6 +94,8 @@ SpiceUsbDeviceManager *spice_usb_device_manager_get(SpiceSession *session,
                                                     GError **err);
 
 GPtrArray *spice_usb_device_manager_get_devices(SpiceUsbDeviceManager *manager);
+GPtrArray* spice_usb_device_manager_get_devices_with_filter(
+    SpiceUsbDeviceManager *manager, const gchar *filter);
 
 gboolean spice_usb_device_manager_is_device_connected(SpiceUsbDeviceManager *manager,
                                                       SpiceUsbDevice *device);
commit ddeec68a4d9a36589a3722845e260602a4204cb6
Author: Hans de Goede <hdegoede at redhat.com>
Date:   Tue Apr 23 12:16:02 2013 +0200

    usb-device-manager: Error check spice_usb_device_manager_device_to_libdev calls
    
    Under Windows all calls to spice_usb_device_manager_device_to_libdev may fail,
    so error check them all.
    
    Signed-off-by: Hans de Goede <hdegoede at redhat.com>

diff --git a/gtk/usb-device-manager.c b/gtk/usb-device-manager.c
index 76f82b2..dc334bd 100644
--- a/gtk/usb-device-manager.c
+++ b/gtk/usb-device-manager.c
@@ -1090,7 +1090,10 @@ static void spice_usb_device_manager_check_redir_on_connect(
             continue;
 
         libdev = spice_usb_device_manager_device_to_libdev(self, device);
-
+#ifdef G_OS_WIN32
+        if (libdev == NULL)
+            continue;
+#endif
         if (usbredirhost_check_device_filter(
                             priv->redirect_on_connect_rules,
                             priv->redirect_on_connect_rules_count,
@@ -1448,7 +1451,13 @@ spice_usb_device_manager_can_redirect_device(SpiceUsbDeviceManager  *self,
         libusb_device *libdev;
 
         libdev = spice_usb_device_manager_device_to_libdev(self, device);
-        g_return_val_if_fail(libdev != NULL, FALSE);
+#ifdef G_OS_WIN32
+        if (libdev == NULL) {
+            g_set_error_literal(err, SPICE_CLIENT_ERROR, SPICE_CLIENT_ERROR_FAILED,
+                                _("Some USB devices were not found"));
+            return FALSE;
+        }
+#endif
         filter_ok = (usbredirhost_check_device_filter(
                             guest_filter_rules, guest_filter_rules_count,
                             libdev, 0) == 0);
commit f90b107c0cece52c15f55d32673351e3188ff3f1
Author: Hans de Goede <hdegoede at redhat.com>
Date:   Tue Apr 23 11:28:48 2013 +0200

    usb-device-manager: Avoid needless re-numeration of usb devs under Linux
    
    libusb_get_device_list() is not exactly a cheap call (lots of sysfs and
    usbfs accesses), so it is worth to avoid it where possible.
    
    This patch restores the old (pre win32 support addition) of dealing with
    libusb-devices under Linux, it keeps the device from the first lookup
    in spice_usb_device_manager_add_dev cached and uses that throughout.
    
    This also means that spice_usb_device_manager_device_to_libdev can no
    longer fail under Linux, so no need to error check it.
    
    Signed-off-by: Hans de Goede <hdegoede at redhat.com>

diff --git a/gtk/usb-device-manager.c b/gtk/usb-device-manager.c
index 92d4615..76f82b2 100644
--- a/gtk/usb-device-manager.c
+++ b/gtk/usb-device-manager.c
@@ -140,8 +140,11 @@ typedef struct _SpiceUsbDeviceInfo {
     guint8  devaddr;
     guint16 vid;
     guint16 pid;
+#ifdef G_OS_WIN32
     guint8  state;
-    guint8  reserved;
+#else
+    libusb_device *libdev;
+#endif
     gint    ref;
 } SpiceUsbDeviceInfo;
 
@@ -1261,8 +1264,8 @@ _spice_usb_device_manager_connect_device_async(SpiceUsbDeviceManager *self,
             continue; /* Skip already used channels */
 
         libdev = spice_usb_device_manager_device_to_libdev(self, device);
-        if (libdev == NULL) {
 #ifdef G_OS_WIN32
+        if (libdev == NULL) {
             /* Most likely, the device was plugged out at driver installation
              * time, and its remove-device event was ignored.
              * So remove the device now
@@ -1272,13 +1275,13 @@ _spice_usb_device_manager_connect_device_async(SpiceUsbDeviceManager *self,
             g_ptr_array_remove(priv->devices, device);
             g_signal_emit(self, signals[DEVICE_REMOVED], 0, device);
             spice_usb_device_unref(device);
-#endif
             g_simple_async_result_set_error(result,
                                             SPICE_CLIENT_ERROR,
                                             SPICE_CLIENT_ERROR_FAILED,
                                             _("Device was not found"));
             goto done;
         }
+#endif
         spice_usbredir_channel_connect_device_async(channel,
                                  libdev,
                                  device,
@@ -1563,6 +1566,9 @@ static SpiceUsbDeviceInfo *spice_usb_device_new(libusb_device *libdev)
     info->vid = vid;
     info->pid = pid;
     info->ref = 1;
+#ifndef G_OS_WIN32
+    info->libdev = libusb_ref_device(libdev);
+#endif
 
     return info;
 }
@@ -1642,26 +1648,24 @@ static void spice_usb_device_unref(SpiceUsbDevice *device)
 
     ref_count_is_0 = g_atomic_int_dec_and_test(&info->ref);
     if (ref_count_is_0) {
+#ifndef G_OS_WIN32
+        libusb_unref_device(info->libdev);
+#endif
         g_free(info);
     }
 }
 
-#ifndef G_OS_WIN32 /* Linux -- compare bus.addr */
+#ifndef G_OS_WIN32 /* Linux -- directly compare libdev */
 static gboolean
 spice_usb_device_equal_libdev(SpiceUsbDevice *device,
                               libusb_device  *libdev)
 {
-    guint8 addr1, addr2, bus1, bus2;
+    SpiceUsbDeviceInfo *info = (SpiceUsbDeviceInfo *)device;
 
     if ((device == NULL) || (libdev == NULL))
         return FALSE;
 
-    bus1  = spice_usb_device_get_busnum(device);
-    addr1 = spice_usb_device_get_devaddr(device);
-    bus2  = libusb_get_bus_number(libdev);
-    addr2 = libusb_get_device_address(libdev);
-
-    return ((bus1 == bus2) && (addr1 == addr2));
+    return info->libdev == libdev;
 }
 #else /* Windows -- compare vid:pid of device and libdev */
 static gboolean
@@ -1692,6 +1696,14 @@ static libusb_device *
 spice_usb_device_manager_device_to_libdev(SpiceUsbDeviceManager *self,
                                           SpiceUsbDevice *device)
 {
+#ifdef G_OS_WIN32
+    /*
+     * On win32 we need to do this the hard and slow way, by asking libusb to
+     * re-enumerate all devices and then finding a matching device.
+     * We cannot cache the libusb_device like we do under Linux since the
+     * driver swap we do under windows invalidates the cached libdev.
+     */
+
     libusb_device *d, **devlist;
     int bus, addr;
     int i;
@@ -1701,13 +1713,9 @@ spice_usb_device_manager_device_to_libdev(SpiceUsbDeviceManager *self,
     g_return_val_if_fail(self->priv != NULL, NULL);
     g_return_val_if_fail(self->priv->context != NULL, NULL);
 
-#ifndef G_OS_WIN32
-    bus  = spice_usb_device_get_busnum(device);
-    addr = spice_usb_device_get_devaddr(device);
-#else
+    /* On windows we match by vid / pid, since the address may change */
     bus  = spice_usb_device_get_vid(device);
     addr = spice_usb_device_get_pid(device);
-#endif
 
     libusb_get_device_list(self->priv->context, &devlist);
     if (!devlist)
@@ -1723,5 +1731,12 @@ spice_usb_device_manager_device_to_libdev(SpiceUsbDeviceManager *self,
     libusb_free_device_list(devlist, 1);
 
     return d;
+
+#else
+    /* Simply return a ref to the cached libdev */
+    SpiceUsbDeviceInfo *info = (SpiceUsbDeviceInfo *)device;
+
+    return libusb_ref_device(info->libdev);
+#endif
 }
 #endif /* USE_USBREDIR */


More information about the Spice-commits mailing list