[Spice-devel] [spice-gtk Win32 v3 05/12] Make SpiceUsbDevice a gobject, instead of a box for libusb_device
Uri Lublin
uril at redhat.com
Wed Jun 27 18:46:34 PDT 2012
Note that this change may affect performance a bit, as we now need to look
for the libusb_device if we need it. Likely it's negligible.
---
gtk/Makefile.am | 4 +
gtk/channel-usbredir-priv.h | 4 +-
gtk/channel-usbredir.c | 46 +++++-----
gtk/map-file | 7 ++
gtk/usb-device-manager-priv.h | 3 +
gtk/usb-device-manager.c | 194 +++++++++++++++++++++++++++++------------
gtk/usb-device-manager.h | 5 +-
gtk/usb-device-widget.c | 9 +--
spice-common | 2 +-
9 files changed, 182 insertions(+), 92 deletions(-)
diff --git a/gtk/Makefile.am b/gtk/Makefile.am
index 0327d65..e79abae 100644
--- a/gtk/Makefile.am
+++ b/gtk/Makefile.am
@@ -228,6 +228,9 @@ libspice_client_glib_2_0_la_SOURCES = \
channel-usbredir-priv.h \
smartcard-manager.c \
smartcard-manager-priv.h \
+ spice-usb-device.c \
+ spice-usb-device.h \
+ spice-usb-device-priv.h \
usb-device-manager.c \
usb-device-manager-priv.h \
usbutil.c \
@@ -266,6 +269,7 @@ libspice_client_glibinclude_HEADERS = \
channel-record.h \
channel-smartcard.h \
channel-usbredir.h \
+ spice-usb-device.h \
usb-device-manager.h \
smartcard-manager.h \
$(NULL)
diff --git a/gtk/channel-usbredir-priv.h b/gtk/channel-usbredir-priv.h
index 5d28c79..e6cd538 100644
--- a/gtk/channel-usbredir-priv.h
+++ b/gtk/channel-usbredir-priv.h
@@ -37,7 +37,7 @@ void spice_usbredir_channel_set_context(SpiceUsbredirChannel *channel,
(through spice_channel_connect()), before calling this. */
void spice_usbredir_channel_connect_device_async(
SpiceUsbredirChannel *channel,
- libusb_device *device,
+ SpiceUsbDevice *device,
GCancellable *cancellable,
GAsyncReadyCallback callback,
gpointer user_data);
@@ -48,7 +48,7 @@ gboolean spice_usbredir_channel_connect_device_finish(
void spice_usbredir_channel_disconnect_device(SpiceUsbredirChannel *channel);
-libusb_device *spice_usbredir_channel_get_device(SpiceUsbredirChannel *channel);
+SpiceUsbDevice *spice_usbredir_channel_get_device(SpiceUsbredirChannel *channel);
void spice_usbredir_channel_get_guest_filter(
SpiceUsbredirChannel *channel,
diff --git a/gtk/channel-usbredir.c b/gtk/channel-usbredir.c
index 3d57152..63efb77 100644
--- a/gtk/channel-usbredir.c
+++ b/gtk/channel-usbredir.c
@@ -35,6 +35,7 @@
#include "spice-client.h"
#include "spice-common.h"
+#include "spice-usb-device-priv.h"
#include "spice-channel-priv.h"
#include "glib-compat.h"
@@ -65,7 +66,7 @@ enum SpiceUsbredirChannelState {
};
struct _SpiceUsbredirChannelPrivate {
- libusb_device *device;
+ SpiceUsbDevice *device;
struct usbredirhost *host;
/* To catch usbredirhost error messages and report them as a GError */
GError **catch_error;
@@ -211,6 +212,7 @@ static gboolean spice_usbredir_channel_open_device(
SpiceUsbredirChannel *channel, GError **err)
{
SpiceUsbredirChannelPrivate *priv = channel->priv;
+ SpiceUsbDeviceManager *manager;
libusb_device_handle *handle = NULL;
int rc, status;
@@ -220,7 +222,11 @@ static gboolean spice_usbredir_channel_open_device(
#endif
, FALSE);
- rc = libusb_open(priv->device, &handle);
+ manager = spice_usb_device_manager_get(
+ spice_channel_get_session(SPICE_CHANNEL(channel)), err);
+ if (!manager)
+ return FALSE;
+ rc = spice_usb_device_libusb_open(manager, priv->device, &handle);
if (rc != 0) {
g_set_error(err, SPICE_CLIENT_ERROR, SPICE_CLIENT_ERROR_FAILED,
"Could not open usb device: %s [%i]",
@@ -236,10 +242,7 @@ static gboolean spice_usbredir_channel_open_device(
return FALSE;
}
- if (!spice_usb_device_manager_start_event_listening(
- spice_usb_device_manager_get(
- spice_channel_get_session(SPICE_CHANNEL(channel)), NULL),
- err)) {
+ if (!spice_usb_device_manager_start_event_listening(manager, err)) {
usbredirhost_set_device(priv->host, NULL);
return FALSE;
}
@@ -272,7 +275,7 @@ static void spice_usbredir_channel_open_acl_cb(
}
if (err) {
g_simple_async_result_take_error(priv->result, err);
- libusb_unref_device(priv->device);
+ g_object_unref(priv->device);
priv->device = NULL;
priv->state = STATE_DISCONNECTED;
}
@@ -290,7 +293,7 @@ static void spice_usbredir_channel_open_acl_cb(
G_GNUC_INTERNAL
void spice_usbredir_channel_connect_device_async(
SpiceUsbredirChannel *channel,
- libusb_device *device,
+ SpiceUsbDevice *device,
GCancellable *cancellable,
GAsyncReadyCallback callback,
gpointer user_data)
@@ -302,7 +305,7 @@ void spice_usbredir_channel_connect_device_async(
#endif
g_return_if_fail(SPICE_IS_USBREDIR_CHANNEL(channel));
- g_return_if_fail(device != NULL);
+ g_return_if_fail(SPICE_IS_USB_DEVICE(device));
SPICE_DEBUG("connecting usb channel %p", channel);
@@ -323,7 +326,7 @@ void spice_usbredir_channel_connect_device_async(
goto done;
}
- priv->device = libusb_ref_device(device);
+ priv->device = g_object_ref(device);
#if USE_POLKIT
priv->result = result;
priv->state = STATE_WAITING_FOR_ACL_HELPER;
@@ -331,8 +334,8 @@ void spice_usbredir_channel_connect_device_async(
g_object_set(spice_channel_get_session(SPICE_CHANNEL(channel)),
"inhibit-keyboard-grab", TRUE, NULL);
spice_usb_acl_helper_open_acl(priv->acl_helper,
- libusb_get_bus_number(device),
- libusb_get_device_address(device),
+ spice_usb_device_get_busnum(device),
+ spice_usb_device_get_devaddr(device),
cancellable,
spice_usbredir_channel_open_acl_cb,
channel);
@@ -340,7 +343,7 @@ void spice_usbredir_channel_connect_device_async(
#else
if (!spice_usbredir_channel_open_device(channel, &err)) {
g_simple_async_result_take_error(result, err);
- libusb_unref_device(priv->device);
+ g_object_unref(priv->device);
priv->device = NULL;
}
#endif
@@ -398,7 +401,7 @@ void spice_usbredir_channel_disconnect_device(SpiceUsbredirChannel *channel)
spice_channel_get_session(SPICE_CHANNEL(channel)), NULL));
/* This also closes the libusb handle we passed from open_device */
usbredirhost_set_device(priv->host, NULL);
- libusb_unref_device(priv->device);
+ g_object_unref(priv->device);
priv->device = NULL;
priv->state = STATE_DISCONNECTED;
break;
@@ -406,7 +409,7 @@ void spice_usbredir_channel_disconnect_device(SpiceUsbredirChannel *channel)
}
G_GNUC_INTERNAL
-libusb_device *spice_usbredir_channel_get_device(SpiceUsbredirChannel *channel)
+SpiceUsbDevice *spice_usbredir_channel_get_device(SpiceUsbredirChannel *channel)
{
return channel->priv->device;
}
@@ -550,7 +553,7 @@ enum {
};
struct DEVICE_ERROR {
- libusb_device *device;
+ SpiceUsbDevice *device;
GError *error;
};
@@ -569,7 +572,7 @@ static void do_emit_main_context(GObject *object, int event, gpointer params)
spice_usb_device_manager_device_error(
spice_usb_device_manager_get(
spice_channel_get_session(SPICE_CHANNEL(channel)), NULL),
- (SpiceUsbDevice *)p->device, p->error);
+ p->device, p->error);
}
break;
}
@@ -624,14 +627,13 @@ static void usbredir_handle_msg(SpiceChannel *c, SpiceMsgIn *in)
r = usbredirhost_read_guest_data(priv->host);
if (r != 0) {
- libusb_device *device = priv->device;
+ SpiceUsbDevice *device = priv->device;
gchar *desc;
GError *err;
g_return_if_fail(device != NULL);
- desc = spice_usb_device_get_description((SpiceUsbDevice *)device,
- NULL);
+ desc = spice_usb_device_get_description(device, NULL);
switch (r) {
case usbredirhost_read_parse_error:
err = g_error_new(SPICE_CLIENT_ERROR, SPICE_CLIENT_ERROR_FAILED,
@@ -655,9 +657,9 @@ static void usbredir_handle_msg(SpiceChannel *c, SpiceMsgIn *in)
SPICE_DEBUG("%s", err->message);
- g_boxed_copy(spice_usb_device_get_type(), device);
+ g_object_ref(device);
emit_main_context(channel, DEVICE_ERROR, device, err);
- g_boxed_free(spice_usb_device_get_type(), device);
+ g_object_unref(device);
g_error_free(err);
}
diff --git a/gtk/map-file b/gtk/map-file
index 32ead37..7f18d19 100644
--- a/gtk/map-file
+++ b/gtk/map-file
@@ -100,6 +100,13 @@ spice_usbredir_channel_get_type;
spice_util_get_debug;
spice_util_get_version_string;
spice_util_set_debug;
+spice_usb_device_get_type;
+spice_usb_device_new;
+spice_usb_device_set_info;
+spice_usb_device_get_busnum;
+spice_usb_device_get_devaddr;
+spice_usb_device_get_vid;
+spice_usb_device_get_pid;
local:
*;
};
diff --git a/gtk/usb-device-manager-priv.h b/gtk/usb-device-manager-priv.h
index 912e3bf..6da890c 100644
--- a/gtk/usb-device-manager-priv.h
+++ b/gtk/usb-device-manager-priv.h
@@ -34,6 +34,9 @@ void spice_usb_device_manager_stop_event_listening(
void spice_usb_device_manager_device_error(
SpiceUsbDeviceManager *manager, SpiceUsbDevice *device, GError *err);
+int spice_usb_device_libusb_open(SpiceUsbDeviceManager *self,
+ SpiceUsbDevice *device,
+ struct libusb_device_handle **handle);
G_END_DECLS
#endif /* __SPICE_USB_DEVICE_MANAGER_PRIV_H__ */
diff --git a/gtk/usb-device-manager.c b/gtk/usb-device-manager.c
index 25cb14a..4448a74 100644
--- a/gtk/usb-device-manager.c
+++ b/gtk/usb-device-manager.c
@@ -38,6 +38,8 @@
#include "spice-client.h"
#include "spice-marshal.h"
#include "usb-device-manager-priv.h"
+#include "spice-usb-device.h"
+#include "spice-usb-device-priv.h"
#include <glib/gi18n.h>
@@ -112,14 +114,11 @@ static void spice_usb_device_manager_uevent_cb(GUdevClient *client,
gpointer user_data);
static void spice_usb_device_manager_add_dev(SpiceUsbDeviceManager *self,
GUdevDevice *udev);
+static
+libusb_device *spice_usb_device_find_libusb_device(SpiceUsbDeviceManager *self,
+ SpiceUsbDevice *device);
+#endif /* ifdef USBREDIR */
-G_DEFINE_BOXED_TYPE(SpiceUsbDevice, spice_usb_device,
- (GBoxedCopyFunc)libusb_ref_device,
- (GBoxedFreeFunc)libusb_unref_device)
-
-#else
-G_DEFINE_BOXED_TYPE(SpiceUsbDevice, spice_usb_device, g_object_ref, g_object_unref)
-#endif
static void spice_usb_device_manager_initable_iface_init(GInitableIface *iface);
static guint signals[LAST_SIGNAL] = { 0, };
@@ -127,6 +126,8 @@ static guint signals[LAST_SIGNAL] = { 0, };
G_DEFINE_TYPE_WITH_CODE(SpiceUsbDeviceManager, spice_usb_device_manager, G_TYPE_OBJECT,
G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE, spice_usb_device_manager_initable_iface_init));
+
+
static void spice_usb_device_manager_init(SpiceUsbDeviceManager *self)
{
SpiceUsbDeviceManagerPrivate *priv;
@@ -137,7 +138,7 @@ static void spice_usb_device_manager_init(SpiceUsbDeviceManager *self)
priv->channels = g_ptr_array_new();
#ifdef USE_USBREDIR
priv->devices = g_ptr_array_new_with_free_func((GDestroyNotify)
- libusb_unref_device);
+ g_object_unref);
#endif
}
@@ -395,7 +396,7 @@ static void spice_usb_device_manager_class_init(SpiceUsbDeviceManagerClass *klas
g_cclosure_marshal_VOID__BOXED,
G_TYPE_NONE,
1,
- SPICE_TYPE_USB_DEVICE);
+ G_TYPE_POINTER);
/**
* SpiceUsbDeviceManager::device-removed:
@@ -414,7 +415,7 @@ static void spice_usb_device_manager_class_init(SpiceUsbDeviceManagerClass *klas
g_cclosure_marshal_VOID__BOXED,
G_TYPE_NONE,
1,
- SPICE_TYPE_USB_DEVICE);
+ G_TYPE_POINTER);
/**
* SpiceUsbDeviceManager::auto-connect-failed:
@@ -435,7 +436,7 @@ static void spice_usb_device_manager_class_init(SpiceUsbDeviceManagerClass *klas
g_cclosure_user_marshal_VOID__BOXED_BOXED,
G_TYPE_NONE,
2,
- SPICE_TYPE_USB_DEVICE,
+ G_TYPE_POINTER,
G_TYPE_ERROR);
/**
@@ -457,7 +458,7 @@ static void spice_usb_device_manager_class_init(SpiceUsbDeviceManagerClass *klas
g_cclosure_user_marshal_VOID__BOXED_BOXED,
G_TYPE_NONE,
2,
- SPICE_TYPE_USB_DEVICE,
+ G_TYPE_POINTER,
G_TYPE_ERROR);
g_type_class_add_private(klass, sizeof(SpiceUsbDeviceManagerPrivate));
@@ -515,12 +516,12 @@ static void spice_usb_device_manager_auto_connect_cb(GObject *gobject,
gpointer user_data)
{
SpiceUsbDeviceManager *self = SPICE_USB_DEVICE_MANAGER(gobject);
- libusb_device *device = user_data;
+ SpiceUsbDevice *device = user_data;
GError *err = NULL;
spice_usb_device_manager_connect_device_finish(self, res, &err);
if (err) {
- gchar *desc = spice_usb_device_get_description((SpiceUsbDevice *)device, NULL);
+ gchar *desc = spice_usb_device_get_description(device, NULL);
g_prefix_error(&err, "Could not auto-redirect %s: ", desc);
g_free(desc);
@@ -528,16 +529,18 @@ static void spice_usb_device_manager_auto_connect_cb(GObject *gobject,
g_signal_emit(self, signals[AUTO_CONNECT_FAILED], 0, device, err);
g_error_free(err);
}
- libusb_unref_device(device);
+ g_object_unref(device);
}
static void spice_usb_device_manager_add_dev(SpiceUsbDeviceManager *self,
GUdevDevice *udev)
{
SpiceUsbDeviceManagerPrivate *priv = self->priv;
- libusb_device *device = NULL, **dev_list = NULL;
+ libusb_device **dev_list = NULL;
+ SpiceUsbDevice *device = NULL;
const gchar *devtype, *devclass;
int i, bus, address;
+ gboolean filter_ok = FALSE;
devtype = g_udev_device_get_property(udev, "DEVTYPE");
/* Check if this is a usb device (and not an interface) */
@@ -562,7 +565,12 @@ static void spice_usb_device_manager_add_dev(SpiceUsbDeviceManager *self,
for (i = 0; dev_list && dev_list[i]; i++) {
if (libusb_get_bus_number(dev_list[i]) == bus &&
libusb_get_device_address(dev_list[i]) == address) {
- device = libusb_ref_device(dev_list[i]);
+ device = spice_usb_device_new();
+ spice_usb_device_set_info(device, dev_list[i]);
+ filter_ok = usbredirhost_check_device_filter(
+ priv->auto_conn_filter_rules,
+ priv->auto_conn_filter_rules_count,
+ dev_list[i], 0) == 0;
break;
}
}
@@ -579,21 +587,17 @@ static void spice_usb_device_manager_add_dev(SpiceUsbDeviceManager *self,
g_ptr_array_add(priv->devices, device);
if (priv->auto_connect) {
- gboolean can_redirect, auto_ok;
+ gboolean can_redirect;
can_redirect = spice_usb_device_manager_can_redirect_device(
- self, (SpiceUsbDevice *)device, NULL);
-
- auto_ok = usbredirhost_check_device_filter(
- priv->auto_conn_filter_rules,
- priv->auto_conn_filter_rules_count,
- device, 0) == 0;
+ self, device, NULL);
- if (can_redirect && auto_ok)
+ if (can_redirect && filter_ok) {
spice_usb_device_manager_connect_device_async(self,
- (SpiceUsbDevice *)device, NULL,
+ device, NULL,
spice_usb_device_manager_auto_connect_cb,
- libusb_ref_device(device));
+ g_object_ref(device));
+ }
}
SPICE_DEBUG("device added %p", device);
@@ -604,7 +608,7 @@ static void spice_usb_device_manager_remove_dev(SpiceUsbDeviceManager *self,
GUdevDevice *udev)
{
SpiceUsbDeviceManagerPrivate *priv = self->priv;
- libusb_device *curr, *device = NULL;
+ SpiceUsbDevice *curr, *device = NULL;
int bus, address;
guint i;
@@ -613,8 +617,8 @@ static void spice_usb_device_manager_remove_dev(SpiceUsbDeviceManager *self,
for (i = 0; i < priv->devices->len; i++) {
curr = g_ptr_array_index(priv->devices, i);
- if (libusb_get_bus_number(curr) == bus &&
- libusb_get_device_address(curr) == address) {
+ if (spice_usb_device_get_busnum(curr) == bus &&
+ spice_usb_device_get_devaddr(curr) == address) {
device = curr;
break;
}
@@ -727,11 +731,10 @@ void spice_usb_device_manager_device_error(
#endif
static SpiceUsbredirChannel *spice_usb_device_manager_get_channel_for_dev(
- SpiceUsbDeviceManager *manager, SpiceUsbDevice *_device)
+ SpiceUsbDeviceManager *manager, SpiceUsbDevice *device)
{
#ifdef USE_USBREDIR
SpiceUsbDeviceManagerPrivate *priv = manager->priv;
- libusb_device *device = (libusb_device *)_device;
guint i;
for (i = 0; i < priv->channels->len; i++) {
@@ -796,10 +799,10 @@ GPtrArray* spice_usb_device_manager_get_devices(SpiceUsbDeviceManager *self)
guint i;
devices_copy = g_ptr_array_new_with_free_func((GDestroyNotify)
- libusb_unref_device);
+ g_object_unref);
for (i = 0; i < priv->devices->len; i++) {
- libusb_device *device = g_ptr_array_index(priv->devices, i);
- g_ptr_array_add(devices_copy, libusb_ref_device(device));
+ SpiceUsbDevice *device = g_ptr_array_index(priv->devices, i);
+ g_ptr_array_add(devices_copy, g_object_ref(device));
}
#endif
@@ -864,7 +867,7 @@ void spice_usb_device_manager_connect_device_async(SpiceUsbDeviceManager *self,
continue; /* Skip already used channels */
spice_usbredir_channel_connect_device_async(channel,
- (libusb_device *)device,
+ device,
cancellable,
spice_usb_device_manager_channel_connect_cb,
result);
@@ -959,13 +962,20 @@ spice_usb_device_manager_can_redirect_device(SpiceUsbDeviceManager *self,
g_ptr_array_index(priv->channels, 0),
&guest_filter_rules, &guest_filter_rules_count);
- if (guest_filter_rules &&
- usbredirhost_check_device_filter(
+ if (guest_filter_rules) {
+ gboolean filter_ok;
+ libusb_device *ldev;
+ ldev = spice_usb_device_find_libusb_device(self, device);
+ g_return_val_if_fail(ldev != NULL, FALSE);
+ filter_ok = (usbredirhost_check_device_filter(
guest_filter_rules, guest_filter_rules_count,
- (libusb_device *)device, 0) != 0) {
- g_set_error_literal(err, SPICE_CLIENT_ERROR, SPICE_CLIENT_ERROR_FAILED,
- _("Some USB devices are blocked by host policy"));
- return FALSE;
+ ldev, 0) == 0);
+ libusb_unref_device(ldev);
+ if (!filter_ok) {
+ g_set_error_literal(err, SPICE_CLIENT_ERROR, SPICE_CLIENT_ERROR_FAILED,
+ _("Some USB devices are blocked by host policy"));
+ return FALSE;
+ }
}
/* Check if there are free channels */
@@ -1009,34 +1019,32 @@ spice_usb_device_manager_can_redirect_device(SpiceUsbDeviceManager *self,
*
* Returns: a newly-allocated string holding the description, or %NULL if failed
*/
-gchar *spice_usb_device_get_description(SpiceUsbDevice *_device, const gchar *format)
+gchar *spice_usb_device_get_description(SpiceUsbDevice *device, const gchar *format)
{
#ifdef USE_USBREDIR
- libusb_device *device = (libusb_device *)_device;
- struct libusb_device_descriptor desc;
- int bus, address;
+ int bus, addr, vid, pid;
gchar *description, *descriptor, *manufacturer = NULL, *product = NULL;
- g_return_val_if_fail(device != NULL, NULL);
+ g_return_val_if_fail(SPICE_IS_USB_DEVICE(device), NULL);
- bus = libusb_get_bus_number(device);
- address = libusb_get_device_address(device);
+ bus = spice_usb_device_get_busnum(device);
+ addr = spice_usb_device_get_devaddr(device);
+ vid = spice_usb_device_get_vid(device);
+ pid = spice_usb_device_get_pid(device);
- if (libusb_get_device_descriptor(device, &desc) == LIBUSB_SUCCESS) {
- spice_usb_util_get_device_strings(bus, address,
- desc.idVendor, desc.idProduct,
- &manufacturer, &product);
- descriptor = g_strdup_printf("[%04x:%04x]", desc.idVendor, desc.idProduct);
+ if ((vid > 0) && (pid > 0)) {
+ descriptor = g_strdup_printf("[%04x:%04x]", vid, pid);
} else {
- spice_usb_util_get_device_strings(bus, address, -1, -1,
- &manufacturer, &product);
descriptor = g_strdup("");
}
+ spice_usb_util_get_device_strings(bus, addr, vid, pid,
+ &manufacturer, &product);
+
if (!format)
format = _("%s %s %s at %d-%d");
- description = g_strdup_printf(format, manufacturer, product, descriptor, bus, address);
+ description = g_strdup_printf(format, manufacturer, product, descriptor, bus, addr);
g_free(manufacturer);
g_free(descriptor);
@@ -1047,3 +1055,75 @@ gchar *spice_usb_device_get_description(SpiceUsbDevice *_device, const gchar *fo
return NULL;
#endif
}
+
+
+
+/*
+ * Caller must libusb_unref_device the libusb_device returned by this function.
+ * Returns a libusb_device, or NULL upon failure
+ */
+static
+libusb_device *spice_usb_device_find_libusb_device(SpiceUsbDeviceManager *self,
+ SpiceUsbDevice *device)
+{
+ libusb_device *d, **devlist;
+ guint8 bus, addr;
+ int i;
+
+ g_return_val_if_fail(SPICE_IS_USB_DEVICE_MANAGER(self), NULL);
+ g_return_val_if_fail(SPICE_IS_USB_DEVICE(device), NULL);
+ g_return_val_if_fail(self->priv != NULL, NULL);
+ g_return_val_if_fail(self->priv->context != NULL, NULL);
+
+ bus = spice_usb_device_get_busnum(device);
+ addr = spice_usb_device_get_devaddr(device);
+
+ libusb_get_device_list(self->priv->context, &devlist);
+ if (!devlist)
+ return NULL;
+
+ for (i = 0; (d = devlist[i]) != NULL; i++) {
+ if ((libusb_get_bus_number(d) == bus) &&
+ (libusb_get_device_address(d) == addr)) {
+ libusb_ref_device(d);
+ break;
+ }
+ }
+
+ libusb_free_device_list(devlist, 1);
+
+ return d;
+}
+
+int spice_usb_device_libusb_open(SpiceUsbDeviceManager *self,
+ SpiceUsbDevice *device,
+ struct libusb_device_handle **handle)
+{
+ libusb_device *ldev;
+ guint8 bus, addr;
+ int rc;
+
+ g_return_val_if_fail(SPICE_IS_USB_DEVICE_MANAGER(self), -1);
+ g_return_val_if_fail(SPICE_IS_USB_DEVICE(device), -2);
+
+ bus = spice_usb_device_get_busnum(device);
+ addr = spice_usb_device_get_devaddr(device);
+
+ ldev = spice_usb_device_find_libusb_device(self, device);
+ if (ldev) {
+ rc = libusb_open(ldev, handle);
+ if (rc) {
+ const gchar *errstr = spice_usbutil_libusb_strerror(rc);
+ g_warning("Failed to open usb device %d.%d -- %s (%i)",
+ bus, addr, errstr, rc);
+ }
+ libusb_unref_device(ldev);
+ } else {
+ rc = -3;
+ g_warning("Did not find device %d.%d to open", bus, addr);
+ }
+
+
+
+ return rc;
+}
diff --git a/gtk/usb-device-manager.h b/gtk/usb-device-manager.h
index df138ee..e5577d8 100644
--- a/gtk/usb-device-manager.h
+++ b/gtk/usb-device-manager.h
@@ -23,6 +23,7 @@
#include "spice-client.h"
#include <gio/gio.h>
+#include "spice-usb-device.h"
G_BEGIN_DECLS
@@ -33,13 +34,12 @@ G_BEGIN_DECLS
#define SPICE_IS_USB_DEVICE_MANAGER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SPICE_TYPE_USB_DEVICE_MANAGER))
#define SPICE_USB_DEVICE_MANAGER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), SPICE_TYPE_USB_DEVICE_MANAGER, SpiceUsbDeviceManagerClass))
-#define SPICE_TYPE_USB_DEVICE (spice_usb_device_get_type())
+
typedef struct _SpiceUsbDeviceManager SpiceUsbDeviceManager;
typedef struct _SpiceUsbDeviceManagerClass SpiceUsbDeviceManagerClass;
typedef struct _SpiceUsbDeviceManagerPrivate SpiceUsbDeviceManagerPrivate;
-typedef struct _SpiceUsbDevice SpiceUsbDevice;
/**
* SpiceUsbDeviceManager:
@@ -85,7 +85,6 @@ struct _SpiceUsbDeviceManagerClass
gchar _spice_reserved[SPICE_RESERVED_PADDING];
};
-GType spice_usb_device_get_type(void);
GType spice_usb_device_manager_get_type(void);
gchar *spice_usb_device_get_description(SpiceUsbDevice *device, const gchar *format);
diff --git a/gtk/usb-device-widget.c b/gtk/usb-device-widget.c
index 3ed81e4..c342981 100644
--- a/gtk/usb-device-widget.c
+++ b/gtk/usb-device-widget.c
@@ -465,11 +465,6 @@ static void checkbox_clicked_cb(GtkWidget *check, gpointer user_data)
spice_usb_device_widget_update_status(self);
}
-static void checkbox_usb_device_destroy_notify(gpointer data)
-{
- g_boxed_free(spice_usb_device_get_type(), data);
-}
-
static void device_added_cb(SpiceUsbDeviceManager *manager,
SpiceUsbDevice *device, gpointer user_data)
{
@@ -489,8 +484,8 @@ static void device_added_cb(SpiceUsbDeviceManager *manager,
g_object_set_data_full(
G_OBJECT(check), "usb-device",
- g_boxed_copy(spice_usb_device_get_type(), device),
- checkbox_usb_device_destroy_notify);
+ g_object_ref(device),
+ g_object_unref);
g_signal_connect(G_OBJECT(check), "clicked",
G_CALLBACK(checkbox_clicked_cb), self);
diff --git a/spice-common b/spice-common
index 5f44094..22fc0b0 160000
--- a/spice-common
+++ b/spice-common
@@ -1 +1 @@
-Subproject commit 5f4409494066b5f59df58d6207fdbb0441aa9e90
+Subproject commit 22fc0b0145876b90385c1c88923bcd72a6380812
--
1.7.7.6
More information about the Spice-devel
mailing list