[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