<div dir="ltr"><div class="gmail_default" style="font-family:verdana,sans-serif;font-size:small;color:#0000ff">Great!</div><div class="gmail_default" style="font-family:verdana,sans-serif;font-size:small;color:#0000ff">Is there a good way to let it work for windows client?</div><div class="gmail_default" style="font-family:verdana,sans-serif;font-size:small;color:#0000ff">libusb is not fully support for windows...</div><div class="gmail_default" style="font-family:verdana,sans-serif;font-size:small;color:#0000ff">I tried to build libwdi with WDK, but I don't think it's a good way.</div></div><div class="gmail_extra"><br><div class="gmail_quote">On Tue, Nov 11, 2014 at 10:29 PM, Fabiano Fidêncio <span dir="ltr"><<a href="mailto:fidencio@redhat.com" target="_blank">fidencio@redhat.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">As we only can filter USB devices by their Classes and sometimes it is<br>
not enough (eg: I do not want to have Keyboard and Mouse, but want to<br>
have have Joysticks, being all of them part of HID Class), provide to<br>
the applications a way match the device itself with the desired Class,<br>
SubClass and Protocol, so the applications refine the filter provided<br>
by usbredir.<br>
---<br>
This patch was written based on <a href="https://bugzilla.gnome.org/show_bug.cgi?id=698430" target="_blank">https://bugzilla.gnome.org/show_bug.cgi?id=698430</a><br>
Any suggestion to have a shorter short-log is welcome :-)<br>
---<br>
gtk/map-file | 1 +<br>
gtk/spice-glib-sym-file | 1 +<br>
gtk/usb-device-manager.c | 96 ++++++++++++++++++++++++++++++++++++++++++++++++<br>
gtk/usb-device-manager.h | 1 +<br>
4 files changed, 99 insertions(+)<br>
<br>
diff --git a/gtk/map-file b/gtk/map-file<br>
index 9f8d04e..6bbf407 100644<br>
--- a/gtk/map-file<br>
+++ b/gtk/map-file<br>
@@ -124,6 +124,7 @@ spice_usb_device_manager_get_devices;<br>
spice_usb_device_manager_get_devices_with_filter;<br>
spice_usb_device_manager_get_type;<br>
spice_usb_device_manager_is_device_connected;<br>
+spice_usb_device_matches_interface;<br>
spice_usb_device_widget_get_type;<br>
spice_usb_device_widget_new;<br>
spice_usbredir_channel_get_type;<br>
diff --git a/gtk/spice-glib-sym-file b/gtk/spice-glib-sym-file<br>
index 2189fa5..83f7f18 100644<br>
--- a/gtk/spice-glib-sym-file<br>
+++ b/gtk/spice-glib-sym-file<br>
@@ -101,6 +101,7 @@ spice_usb_device_manager_get_devices<br>
spice_usb_device_manager_get_devices_with_filter<br>
spice_usb_device_manager_get_type<br>
spice_usb_device_manager_is_device_connected<br>
+spice_usb_device_matches_interface<br>
spice_usbredir_channel_get_type<br>
spice_util_get_debug<br>
spice_util_get_version_string<br>
diff --git a/gtk/usb-device-manager.c b/gtk/usb-device-manager.c<br>
index 5013b6c..6749b0d 100644<br>
--- a/gtk/usb-device-manager.c<br>
+++ b/gtk/usb-device-manager.c<br>
@@ -706,6 +706,30 @@ static gboolean spice_usb_device_manager_get_device_descriptor(<br>
return TRUE;<br>
}<br>
<br>
+static gboolean spice_usb_device_manager_get_config_descriptor(<br>
+ libusb_device *libdev,<br>
+ struct libusb_config_descriptor **config)<br>
+{<br>
+ int errcode;<br>
+ const gchar *errstr;<br>
+<br>
+ g_return_val_if_fail(libdev != NULL, FALSE);<br>
+ g_return_val_if_fail(config != NULL, FALSE);<br>
+<br>
+ errcode = libusb_get_active_config_descriptor(libdev, config);<br>
+ if (errcode < 0) {<br>
+ int bus, addr;<br>
+<br>
+ bus = libusb_get_bus_number(libdev);<br>
+ addr = libusb_get_device_address(libdev);<br>
+ errstr = spice_usbutil_libusb_strerror(errcode);<br>
+ g_warning("Cannot get config descriptor for (%p) %d.%d -- %s(%d)",<br>
+ libdev, bus, addr, errstr, errcode);<br>
+ return FALSE;<br>
+ }<br>
+ return TRUE;<br>
+}<br>
+<br>
static gboolean spice_usb_device_manager_get_libdev_vid_pid(<br>
libusb_device *libdev, int *vid, int *pid)<br>
{<br>
@@ -1726,7 +1750,79 @@ gchar *spice_usb_device_get_description(SpiceUsbDevice *device, const gchar *for<br>
#endif<br>
}<br>
<br>
+static guint8 spice_usb_device_get_interface_class(libusb_device *libdev)<br>
+{<br>
+ struct libusb_config_descriptor *config;<br>
+ guint8 interface_class;<br>
+<br>
+ g_return_val_if_fail(libdev != NULL, 0);<br>
+<br>
+ config = g_malloc(sizeof(*config));<br>
+ spice_usb_device_manager_get_config_descriptor(libdev, &config);<br>
+ interface_class = config->interface->altsetting->bInterfaceClass;<br>
+ libusb_free_config_descriptor(config);<br>
+<br>
+ return interface_class;<br>
+}<br>
+<br>
+static guint8 spice_usb_device_get_interface_subclass(libusb_device *libdev)<br>
+{<br>
+ struct libusb_config_descriptor *config;<br>
+ guint8 interface_subclass;<br>
+<br>
+ g_return_val_if_fail(libdev != NULL, 0);<br>
+<br>
+ config = g_malloc(sizeof(*config));<br>
+ spice_usb_device_manager_get_config_descriptor(libdev, &config);<br>
+ interface_subclass = config->interface->altsetting->bInterfaceSubClass;<br>
+ libusb_free_config_descriptor(config);<br>
+<br>
+ return interface_subclass;<br>
+}<br>
+<br>
+static guint8 spice_usb_device_get_interface_protocol(libusb_device *libdev)<br>
+{<br>
+ struct libusb_config_descriptor *config;<br>
+ guint8 interface_protocol;<br>
+<br>
+ g_return_val_if_fail(libdev != NULL, 0);<br>
+<br>
+ config = g_malloc(sizeof(*config));<br>
+ spice_usb_device_manager_get_config_descriptor(libdev, &config);<br>
+ interface_protocol = config->interface->altsetting->bInterfaceProtocol;<br>
+ libusb_free_config_descriptor(config);<br>
+<br>
+ return interface_protocol;<br>
+}<br>
+<br>
+/**<br>
+ * spice_usb_device_matches_interface:<br>
+ * @device: #SpiceUsbDevice to check if the interface info matches with<br>
+ * @class: the interface class to be checked<br>
+ * @subclass: the interface usbclass to be checked<br>
+ * @protocol; the interface protocol to be checked<br>
+ *<br>
+ * Compares if the device's interface class, subclass and protocol match with<br>
+ * the received interface class, subclass and protocol.<br>
+ *<br>
+ * Returns: TRUE if the device's interface matches with the receveid one.<br>
+ * FALSE, otherwise.<br>
+ *<br>
+ * Since: 0.27<br>
+ **/<br>
+gboolean spice_usb_device_matches_interface(const SpiceUsbDevice *device, guint8 class, guint8 subclass, guint8 protocol)<br>
+{<br>
+ const SpiceUsbDeviceInfo *info = (const SpiceUsbDeviceInfo *)device;<br>
+<br>
+ g_return_val_if_fail(info != NULL, FALSE);<br>
+<br>
+ if ((spice_usb_device_get_interface_class(info->libdev) == class) &&<br>
+ (spice_usb_device_get_interface_subclass(info->libdev) == subclass) &&<br>
+ (spice_usb_device_get_interface_protocol(info->libdev) == protocol))<br>
+ return TRUE;<br>
<br>
+ return FALSE;<br>
+}<br>
<br>
#ifdef USE_USBREDIR<br>
/*<br>
diff --git a/gtk/usb-device-manager.h b/gtk/usb-device-manager.h<br>
index a7e3515..9959fe5 100644<br>
--- a/gtk/usb-device-manager.h<br>
+++ b/gtk/usb-device-manager.h<br>
@@ -89,6 +89,7 @@ GType spice_usb_device_get_type(void);<br>
GType spice_usb_device_manager_get_type(void);<br>
<br>
gchar *spice_usb_device_get_description(SpiceUsbDevice *device, const gchar *format);<br>
+gboolean spice_usb_device_matches_interface(const SpiceUsbDevice *device, guint8 class, guint8 subclass, guint8 protocol);<br>
<br>
SpiceUsbDeviceManager *spice_usb_device_manager_get(SpiceSession *session,<br>
GError **err);<br>
<span class="HOEnZb"><font color="#888888">--<br>
2.1.0<br>
<br>
_______________________________________________<br>
Spice-devel mailing list<br>
<a href="mailto:Spice-devel@lists.freedesktop.org">Spice-devel@lists.freedesktop.org</a><br>
<a href="http://lists.freedesktop.org/mailman/listinfo/spice-devel" target="_blank">http://lists.freedesktop.org/mailman/listinfo/spice-devel</a><br>
</font></span></blockquote></div><br><br clear="all"><div><br></div>-- <br><div class="gmail_signature"><div dir="ltr"><font color="#cfe2f3">Q</font><font color="#9fc5e8">S</font><font color="#6fa8dc">B</font><font color="#3d85c6">D</font><font color="#0b5394">T</font><font color="#073763">0</font><font color="#0c343d">R</font><font color="#134f5c">F</font><font color="#45818e">U</font><font color="#76a5af">i</font><font color="#a2c4c9">B</font><font color="#d0e0e3">G</font><font color="#d9ead3">U</font><font color="#b6d7a8">k</font><font color="#93c47d">9</font><font color="#6aa84f">N</font><font color="#38761d">I</font><font color="#274e13">F</font><font color="#7f6000">J</font><font color="#bf9000">J</font><font color="#f1c232">R</font><font color="#ffd966">V</font><font color="#ffe599">N</font><font color="#fff2cc">U</font><font color="#fce5cd">I</font><font color="#f9cb9c">E</font><font color="#f6b26b">9</font><font color="#e69138">G</font><font color="#b45f06">I</font><font color="#783f04">E</font><font color="#660000">N</font><font color="#990000">U</font><font color="#cc0000">U</font><font color="#e06666">0V</font><font color="#ea9999">V</font></div></div>
</div>