[Spice-devel] [PATCH spice-gtk 09/10] usbredir: Drop our embeddied GUsb copy

Hans de Goede hdegoede at redhat.com
Mon Dec 19 03:24:42 PST 2011


No that we no longer use GUsbSource we're hardly using any code from GUsb,
so drop our embeddied GUsb copy and do the last few things (device
enumeration through gudev) ourselves.

Signed-off-by: Hans de Goede <hdegoede at redhat.com>
---
 gtk/Makefile.am                 |   21 ---
 gtk/channel-usbredir-priv.h     |   10 +-
 gtk/channel-usbredir.c          |   42 +++---
 gtk/gusb/README.txt             |    5 -
 gtk/gusb/gusb-context-private.h |   35 ----
 gtk/gusb/gusb-context.c         |  290 -------------------------------
 gtk/gusb/gusb-context.h         |   63 -------
 gtk/gusb/gusb-device-list.c     |  358 ---------------------------------------
 gtk/gusb/gusb-device-list.h     |   72 --------
 gtk/gusb/gusb-device-private.h  |   34 ----
 gtk/gusb/gusb-device.c          |  232 -------------------------
 gtk/gusb/gusb-device.h          |   71 --------
 gtk/gusb/gusb-marshal.h         |    7 -
 gtk/gusb/gusb-source.c          |  307 ---------------------------------
 gtk/gusb/gusb-source.h          |   58 -------
 gtk/gusb/gusb-util.c            |   65 -------
 gtk/gusb/gusb-util.h            |   32 ----
 gtk/usb-device-manager-priv.h   |    2 +
 gtk/usb-device-manager.c        |  270 +++++++++++++++++++++--------
 19 files changed, 224 insertions(+), 1750 deletions(-)
 delete mode 100644 gtk/gusb/README.txt
 delete mode 100644 gtk/gusb/gusb-context-private.h
 delete mode 100644 gtk/gusb/gusb-context.c
 delete mode 100644 gtk/gusb/gusb-context.h
 delete mode 100644 gtk/gusb/gusb-device-list.c
 delete mode 100644 gtk/gusb/gusb-device-list.h
 delete mode 100644 gtk/gusb/gusb-device-private.h
 delete mode 100644 gtk/gusb/gusb-device.c
 delete mode 100644 gtk/gusb/gusb-device.h
 delete mode 100644 gtk/gusb/gusb-marshal.h
 delete mode 100644 gtk/gusb/gusb-source.c
 delete mode 100644 gtk/gusb/gusb-source.h
 delete mode 100644 gtk/gusb/gusb-util.c
 delete mode 100644 gtk/gusb/gusb-util.h

diff --git a/gtk/Makefile.am b/gtk/Makefile.am
index 9f208cc..8e05c04 100644
--- a/gtk/Makefile.am
+++ b/gtk/Makefile.am
@@ -15,7 +15,6 @@ EXTRA_DIST =					\
 	generated_demarshallers1.c		\
 	generated_marshallers.c			\
 	generated_marshallers1.c		\
-	gusb/README.txt				\
 	spice-client-gtk.override		\
 	spice-client-gtk-manual.defs		\
 	$(NULL)
@@ -174,25 +173,6 @@ libspice_client_glib_2_0_la_LIBADD =	\
 	$(LIBUSBREDIRHOST_LIBS)		\
 	$(NULL)
 
-if WITH_USBREDIR
-GUSB_SRCS =				\
-	gusb/gusb-context.c		\
-	gusb/gusb-context.h		\
-	gusb/gusb-context-private.h	\
-	gusb/gusb-device.c		\
-	gusb/gusb-device.h		\
-	gusb/gusb-device-private.h	\
-	gusb/gusb-device-list.c		\
-	gusb/gusb-device-list.h		\
-	gusb/gusb-marshal.h		\
-	gusb/gusb-source.c		\
-	gusb/gusb-source.h		\
-	gusb/gusb-util.c		\
-	gusb/gusb-util.h
-else
-GUSB_SRCS =
-endif
-
 if WITH_POLKIT
 USB_ACL_HELPER_SRCS = \
 	usb-acl-helper.c		\
@@ -237,7 +217,6 @@ libspice_client_glib_2_0_la_SOURCES =	\
 	smartcard-manager-priv.h	\
 	usb-device-manager.c		\
 	usb-device-manager-priv.h	\
-	$(GUSB_SRCS)			\
 	$(USB_ACL_HELPER_SRCS)		\
 	\
 	decode.h			\
diff --git a/gtk/channel-usbredir-priv.h b/gtk/channel-usbredir-priv.h
index 305e897..5d75e26 100644
--- a/gtk/channel-usbredir-priv.h
+++ b/gtk/channel-usbredir-priv.h
@@ -21,16 +21,14 @@
 #ifndef __SPICE_CLIENT_USBREDIR_CHANNEL_PRIV_H__
 #define __SPICE_CLIENT_USBREDIR_CHANNEL_PRIV_H__
 
-#include <gusb/gusb-context.h>
-#include <gusb/gusb-device.h>
-
+#include <libusb.h>
 #include "spice-client.h"
 
 G_BEGIN_DECLS
 
 void spice_usbredir_channel_connect_async(SpiceUsbredirChannel *channel,
-                                          GUsbContext          *context,
-                                          GUsbDevice           *device,
+                                          libusb_context       *context,
+                                          libusb_device        *device,
                                           GCancellable         *cancellable,
                                           GAsyncReadyCallback   callback,
                                           gpointer              user_data);
@@ -40,7 +38,7 @@ gboolean spice_usbredir_channel_connect_finish(SpiceUsbredirChannel *channel,
 
 void spice_usbredir_channel_disconnect(SpiceUsbredirChannel *channel);
 
-GUsbDevice *spice_usbredir_channel_get_device(SpiceUsbredirChannel *channel);
+libusb_device *spice_usbredir_channel_get_device(SpiceUsbredirChannel *channel);
 
 G_END_DECLS
 
diff --git a/gtk/channel-usbredir.c b/gtk/channel-usbredir.c
index 6896aab..0069895 100644
--- a/gtk/channel-usbredir.c
+++ b/gtk/channel-usbredir.c
@@ -23,9 +23,6 @@
 
 #ifdef USE_USBREDIR
 #include <usbredirhost.h>
-#include <gusb/gusb-context-private.h>
-#include <gusb/gusb-device-private.h>
-#include <gusb/gusb-util.h>
 #if USE_POLKIT
 #include "usb-acl-helper.h"
 #endif
@@ -66,8 +63,8 @@ enum SpiceUsbredirChannelState {
 };
 
 struct _SpiceUsbredirChannelPrivate {
-    GUsbContext *context;
-    GUsbDevice *device;
+    libusb_context *context;
+    libusb_device *device;
     struct usbredirhost *host;
     /* To catch usbredirhost error messages and report them as a GError */
     GError **catch_error;
@@ -176,17 +173,17 @@ static gboolean spice_usbredir_channel_open_device(
 #endif
                          , FALSE);
 
-    rc = libusb_open(_g_usb_device_get_device(priv->device), &handle);
+    rc = libusb_open(priv->device, &handle);
     if (rc != 0) {
         g_set_error(err, SPICE_CLIENT_ERROR, SPICE_CLIENT_ERROR_FAILED,
                     "Could not open usb device: %s [%i]",
-                    gusb_strerror(rc), rc);
+                    spice_usb_device_manager_libusb_strerror(rc), rc);
         return FALSE;
     }
 
     priv->catch_error = err;
     priv->host = usbredirhost_open_full(
-                                   _g_usb_context_get_context(priv->context),
+                                   priv->context,
                                    handle, usbredir_log,
                                    usbredir_read_callback,
                                    usbredir_write_callback,
@@ -242,8 +239,9 @@ static void spice_usbredir_channel_open_acl_cb(
     }
     if (err) {
         g_simple_async_result_take_error(priv->result, err);
-        g_clear_object(&priv->context);
-        g_clear_object(&priv->device);
+        libusb_unref_device(priv->device);
+        priv->device  = NULL;
+        priv->context = NULL;
         priv->state = STATE_DISCONNECTED;
     }
 
@@ -259,8 +257,8 @@ static void spice_usbredir_channel_open_acl_cb(
 
 G_GNUC_INTERNAL
 void spice_usbredir_channel_connect_async(SpiceUsbredirChannel *channel,
-                                          GUsbContext          *context,
-                                          GUsbDevice           *device,
+                                          libusb_context       *context,
+                                          libusb_device        *device,
                                           GCancellable         *cancellable,
                                           GAsyncReadyCallback   callback,
                                           gpointer              user_data)
@@ -284,8 +282,8 @@ void spice_usbredir_channel_connect_async(SpiceUsbredirChannel *channel,
         goto done;
     }
 
-    priv->context = g_object_ref(context);
-    priv->device  = g_object_ref(device);
+    priv->context = context;
+    priv->device  = libusb_ref_device(device);
 #if USE_POLKIT
     priv->result = result;
     priv->state = STATE_WAITING_FOR_ACL_HELPER;
@@ -293,8 +291,8 @@ void spice_usbredir_channel_connect_async(SpiceUsbredirChannel *channel,
     g_object_set(spice_channel_get_session(SPICE_CHANNEL(channel)),
                  "inhibit-keyboard-grab", TRUE, NULL);
     spice_usb_acl_helper_open_acl(priv->acl_helper,
-                                  g_usb_device_get_bus(device),
-                                  g_usb_device_get_address(device),
+                                  libusb_get_bus_number(device),
+                                  libusb_get_device_address(device),
                                   cancellable,
                                   spice_usbredir_channel_open_acl_cb,
                                   channel);
@@ -303,8 +301,9 @@ void spice_usbredir_channel_connect_async(SpiceUsbredirChannel *channel,
     GError *err = NULL;
     if (!spice_usbredir_channel_open_device(channel, &err)) {
         g_simple_async_result_take_error(result, err);
-        g_clear_object(&priv->context);
-        g_clear_object(&priv->device);
+        libusb_unref_device(priv->device);
+        priv->device  = NULL;
+        priv->context = NULL;
     }
 #endif
 
@@ -362,15 +361,16 @@ void spice_usbredir_channel_disconnect(SpiceUsbredirChannel *channel)
         /* This also closes the libusb handle we passed to its _open */
         usbredirhost_close(priv->host);
         priv->host = NULL;
-        g_clear_object(&priv->device);
-        g_clear_object(&priv->context);
+        libusb_unref_device(priv->device);
+        priv->device  = NULL;
+        priv->context = NULL;
         priv->state = STATE_DISCONNECTED;
         break;
     }
 }
 
 G_GNUC_INTERNAL
-GUsbDevice *spice_usbredir_channel_get_device(SpiceUsbredirChannel *channel)
+libusb_device *spice_usbredir_channel_get_device(SpiceUsbredirChannel *channel)
 {
     return channel->priv->device;
 }
diff --git a/gtk/gusb/README.txt b/gtk/gusb/README.txt
deleted file mode 100644
index 8d76ed7..0000000
--- a/gtk/gusb/README.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-HDG: this is a private copy of gusb, from:
-https://gitorious.org/gusb
-
-This is a temporary solution until gusb upstream has a stable release out
-the door.
diff --git a/gtk/gusb/gusb-context-private.h b/gtk/gusb/gusb-context-private.h
deleted file mode 100644
index 4069a4d..0000000
--- a/gtk/gusb/gusb-context-private.h
+++ /dev/null
@@ -1,35 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
- *
- * Copyright (C) 2011 Richard Hughes <richard at hughsie.com>
- *
- * Licensed under the GNU Lesser General Public License Version 2.1
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA
- */
-
-#ifndef __GUSB_CONTEXT_PRIVATE_H__
-#define __GUSB_CONTEXT_PRIVATE_H__
-
-#include <libusb-1.0/libusb.h>
-
-#include <gusb/gusb-context.h>
-
-G_BEGIN_DECLS
-
-libusb_context	*_g_usb_context_get_context	(GUsbContext	*context);
-
-G_END_DECLS
-
-#endif /* __GUSB_CONTEXT_PRIVATE_H__ */
diff --git a/gtk/gusb/gusb-context.c b/gtk/gusb/gusb-context.c
deleted file mode 100644
index 01eac06..0000000
--- a/gtk/gusb/gusb-context.c
+++ /dev/null
@@ -1,290 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
- *
- * Copyright (C) 2011 Richard Hughes <richard at hughsie.com>
- * Copyright (C) 2011 Hans de Goede <hdegoede at redhat.com>
- *
- * Licensed under the GNU Lesser General Public License Version 2.1
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, see <http://www.gnu.org/licenses/>.
- */
-
-/**
- * SECTION:gusb-context
- * @short_description: Per-thread instance integration for libusb
- *
- * This object is used to get a context that is thread safe.
- */
-
-#include "config.h"
-
-#include <libusb-1.0/libusb.h>
-
-#include "gusb-util.h"
-#include "gusb-context.h"
-#include "gusb-context-private.h"
-
-static void g_usb_context_finalize (GObject *object);
-
-#define G_USB_CONTEXT_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), G_USB_TYPE_CONTEXT, GUsbContextPrivate))
-
-enum {
-	PROP_0,
-	PROP_LIBUSB_CONTEXT,
-	PROP_DEBUG_LEVEL,
-};
-
-/**
- * GUsbContextPrivate:
- *
- * Private #GUsbContext data
- **/
-struct _GUsbContextPrivate
-{
-	libusb_context		*context;
-	int			 debug_level;
-};
-
-G_DEFINE_TYPE (GUsbContext, g_usb_context, G_TYPE_OBJECT)
-
-/**
- * usb_context_get_property:
- **/
-static void
-g_usb_context_get_property (GObject		*object,
-			    guint		 prop_id,
-			    GValue		*value,
-			    GParamSpec		*pspec)
-{
-	GUsbContext *context = G_USB_CONTEXT (object);
-	GUsbContextPrivate *priv = context->priv;
-
-	switch (prop_id) {
-	case PROP_LIBUSB_CONTEXT:
-		g_value_set_pointer (value, priv->context);
-		break;
-	case PROP_DEBUG_LEVEL:
-		g_value_set_int (value, priv->debug_level);
-		break;
-	default:
-		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
-		break;
-	}
-}
-
-/**
- * usb_context_set_property:
- **/
-static void
-g_usb_context_set_property (GObject		*object,
-			   guint		 prop_id,
-			   const GValue		*value,
-			   GParamSpec		*pspec)
-{
-	GUsbContext *context = G_USB_CONTEXT (object);
-	GUsbContextPrivate *priv = context->priv;
-
-	switch (prop_id) {
-	case PROP_LIBUSB_CONTEXT:
-		priv->context = g_value_get_pointer (value);
-		break;
-	case PROP_DEBUG_LEVEL:
-		priv->debug_level = g_value_get_int (value);
-		libusb_set_debug (priv->context, priv->debug_level);
-		break;
-	default:
-		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
-		break;
-	}
-}
-
-static GObject *
-g_usb_context_constructor (GType			 gtype,
-			   guint			 n_properties,
-			   GObjectConstructParam	*properties)
-{
-	GObject *obj;
-	GUsbContext *context;
-	GUsbContextPrivate *priv;
-
-	{
-		/* Always chain up to the parent constructor */
-		GObjectClass *parent_class;
-		parent_class = G_OBJECT_CLASS (g_usb_context_parent_class);
-		obj = parent_class->constructor (gtype, n_properties,
-						 properties);
-	}
-
-	context = G_USB_CONTEXT (obj);
-	priv = context->priv;
-
-	/*
-	 * Yes you're reading this right the sole reason for this constructor
-	 * is to check the context has been set (for now).
-	 */
-	if (!priv->context)
-		g_error("constructed without a context");
-
-	return obj;
-}
-
-/**
- * usb_context_class_init:
- **/
-static void
-g_usb_context_class_init (GUsbContextClass *klass)
-{
-	GParamSpec *pspec;
-	GObjectClass *object_class = G_OBJECT_CLASS (klass);
-
-	object_class->constructor	= g_usb_context_constructor;
-	object_class->finalize		= g_usb_context_finalize;
-	object_class->get_property	= g_usb_context_get_property;
-	object_class->set_property	= g_usb_context_set_property;
-
-	/**
-	 * GUsbContext:libusb_context:
-	 */
-	pspec = g_param_spec_pointer ("libusb_context", NULL, NULL,
-				      G_PARAM_CONSTRUCT_ONLY|
-				      G_PARAM_READWRITE);
-	g_object_class_install_property (object_class, PROP_LIBUSB_CONTEXT,
-					 pspec);
-
-	/**
-	 * GUsbContext:debug_level:
-	 */
-	pspec = g_param_spec_int ("debug_level", NULL, NULL,
-				  0, 3, 0,
-				  G_PARAM_READWRITE);
-	g_object_class_install_property (object_class, PROP_DEBUG_LEVEL,
-					 pspec);
-
-	g_type_class_add_private (klass, sizeof (GUsbContextPrivate));
-}
-
-/**
- * g_usb_context_init:
- **/
-static void
-g_usb_context_init (GUsbContext *context)
-{
-	context->priv = G_USB_CONTEXT_GET_PRIVATE (context);
-}
-
-/**
- * g_usb_context_finalize:
- **/
-static void
-g_usb_context_finalize (GObject *object)
-{
-	GUsbContext *context = G_USB_CONTEXT (object);
-	GUsbContextPrivate *priv = context->priv;
-
-	libusb_exit (priv->context);
-
-	G_OBJECT_CLASS (g_usb_context_parent_class)->finalize (object);
-}
-
-/**
- * g_usb_context_error_quark:
- *
- * Return value: Our personal error quark.
- *
- * Since: 0.0.1
- **/
-GQuark
-g_usb_context_error_quark (void)
-{
-	static GQuark quark = 0;
-	if (!quark)
-		quark = g_quark_from_static_string ("g_usb_context_error");
-	return quark;
-}
-
-/**
- * _g_usb_context_get_context:
- * @context: a #GUsbContext
- *
- * Gets the internal libusb_context.
- *
- * Return value: (transfer none): the libusb_context
- *
- * Since: 0.0.1
- **/
-libusb_context *
-_g_usb_context_get_context (GUsbContext *context)
-{
-	return context->priv->context;
-}
-
-/**
- * g_usb_context_set_debug:
- * @context: a #GUsbContext
- * @flags: a GLogLevelFlags such as %G_LOG_LEVEL_ERROR | %G_LOG_LEVEL_INFO, or 0
- *
- * Sets the debug flags which control what is logged to the console.
- *
- * Using %G_LOG_LEVEL_INFO will output to standard out, and everything
- * else logs to standard error.
- *
- * Since: 0.0.1
- **/
-void
-g_usb_context_set_debug (GUsbContext *context, GLogLevelFlags flags)
-{
-	GUsbContextPrivate *priv = context->priv;
-
-	if (flags & (G_LOG_LEVEL_DEBUG | G_LOG_LEVEL_INFO))
-		priv->debug_level = 3;
-	else if (flags & (G_LOG_LEVEL_MESSAGE | G_LOG_LEVEL_WARNING))
-		priv->debug_level = 2;
-	else if (flags & (G_LOG_LEVEL_CRITICAL | G_LOG_LEVEL_ERROR))
-		priv->debug_level = 1;
-	else
-		priv->debug_level = 0;
-
-	libusb_set_debug (priv->context, priv->debug_level);
-}
-
-/**
- * g_usb_context_new:
- * @error: a #GError, or %NULL
- *
- * Creates a new context for accessing USB devices.
- *
- * Return value: a new %GUsbContext object or %NULL on error.
- *
- * Since: 0.0.1
- **/
-GUsbContext *
-g_usb_context_new (GError **error)
-{
-	gint rc;
-	GObject *obj;
-	libusb_context *context;
-
-	rc = libusb_init (&context);
-	if (rc < 0) {
-		g_set_error (error,
-			     G_USB_CONTEXT_ERROR,
-			     G_USB_CONTEXT_ERROR_INTERNAL,
-			     "failed to init libusb: %s [%i]",
-			     gusb_strerror (rc), rc);
-		return NULL;
-	}
-
-	obj = g_object_new (G_USB_TYPE_CONTEXT, "libusb_context", context,
-			    NULL);
-	return G_USB_CONTEXT (obj);
-}
diff --git a/gtk/gusb/gusb-context.h b/gtk/gusb/gusb-context.h
deleted file mode 100644
index ca9d28c..0000000
--- a/gtk/gusb/gusb-context.h
+++ /dev/null
@@ -1,63 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
- *
- * Copyright (C) 2011 Richard Hughes <richard at hughsie.com>
- * Copyright (C) 2011 Hans de Goede <hdegoede at redhat.com>
- *
- * Licensed under the GNU Lesser General Public License Version 2.1
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef __GUSB_CONTEXT_H__
-#define __GUSB_CONTEXT_H__
-
-#include <glib-object.h>
-
-G_BEGIN_DECLS
-
-#define G_USB_TYPE_CONTEXT		(g_usb_context_get_type ())
-#define G_USB_CONTEXT(o)		(G_TYPE_CHECK_INSTANCE_CAST ((o), G_USB_TYPE_CONTEXT, GUsbContext))
-#define G_USB_IS_CONTEXT(o)		(G_TYPE_CHECK_INSTANCE_TYPE ((o), G_USB_TYPE_CONTEXT))
-#define G_USB_CONTEXT_ERROR		(g_usb_context_error_quark ())
-
-typedef struct _GUsbContextPrivate	GUsbContextPrivate;
-typedef struct _GUsbContext		GUsbContext;
-typedef struct _GUsbContextClass	GUsbContextClass;
-
-struct _GUsbContext
-{
-	 GObject			 parent;
-	 GUsbContextPrivate		*priv;
-};
-
-struct _GUsbContextClass
-{
-	GObjectClass			 parent_class;
-};
-
-typedef enum {
-	G_USB_CONTEXT_ERROR_INTERNAL
-} GUsbContextError;
-
-GType		 g_usb_context_get_type		(void);
-GQuark		 g_usb_context_error_quark	(void);
-
-GUsbContext	*g_usb_context_new		(GError		**error);
-
-void		 g_usb_context_set_debug	(GUsbContext	*context,
-						 GLogLevelFlags	 flags);
-
-G_END_DECLS
-
-#endif /* __GUSB_CONTEXT_H__ */
diff --git a/gtk/gusb/gusb-device-list.c b/gtk/gusb/gusb-device-list.c
deleted file mode 100644
index dbe73f8..0000000
--- a/gtk/gusb/gusb-device-list.c
+++ /dev/null
@@ -1,358 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
- *
- * Copyright (C) 2011 Hans de Goede <hdegoede at redhat.com>
- *
- * Licensed under the GNU Lesser General Public License Version 2.1
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <string.h>
-#include <stdlib.h>
-#include <gudev/gudev.h>
-#include <libusb-1.0/libusb.h>
-
-#include "gusb-marshal.h"
-#include "gusb-context.h"
-#include "gusb-context-private.h"
-#include "gusb-device.h"
-#include "gusb-device-private.h"
-
-#include "gusb-device-list.h"
-
-#define G_USB_DEVICE_LIST_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), G_USB_TYPE_DEVICE_LIST, GUsbDeviceListPrivate))
-
-enum {
-	PROP_0,
-	PROP_CONTEXT,
-};
-
-enum
-{
-	DEVICE_ADDED_SIGNAL,
-	DEVICE_REMOVED_SIGNAL,
-	LAST_SIGNAL,
-};
-
-struct _GUsbDeviceListPrivate {
-	GUsbContext	 *context;
-	GUdevClient	 *udev;
-	GPtrArray	 *devices;
-	libusb_device	**coldplug_list;
-};
-
-static void g_usb_device_list_uevent_cb (GUdevClient	*client,
-					const gchar	*action,
-					GUdevDevice	*udevice,
-					gpointer	 user_data);
-
-static guint signals[LAST_SIGNAL] = { 0, };
-
-G_DEFINE_TYPE (GUsbDeviceList, g_usb_device_list, G_TYPE_OBJECT);
-
-static void
-g_usb_device_list_finalize (GObject *object)
-{
-	GUsbDeviceList *list = G_USB_DEVICE_LIST (object);
-	GUsbDeviceListPrivate *priv = list->priv;
-
-	g_object_unref (priv->udev);
-	g_ptr_array_unref (priv->devices);
-}
-
-/**
- * g_usb_device_list_get_property:
- **/
-static void
-g_usb_device_list_get_property (GObject		*object,
-				guint		 prop_id,
-				GValue		*value,
-				GParamSpec	*pspec)
-{
-	GUsbDeviceList *list = G_USB_DEVICE_LIST (object);
-	GUsbDeviceListPrivate *priv = list->priv;
-
-	switch (prop_id) {
-	case PROP_CONTEXT:
-		g_value_set_object (value, priv->context);
-		break;
-	default:
-		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
-		break;
-	}
-}
-
-/**
- * usb_device_list_set_property:
- **/
-static void
-g_usb_device_list_set_property (GObject		*object,
-				guint		 prop_id,
-				const GValue	*value,
-				GParamSpec	*pspec)
-{
-	GUsbDeviceList *list = G_USB_DEVICE_LIST (object);
-	GUsbDeviceListPrivate *priv = list->priv;
-
-	switch (prop_id) {
-	case PROP_CONTEXT:
-		priv->context = g_value_get_object (value);
-		break;
-	default:
-		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
-		break;
-	}
-}
-
-static GObject *
-g_usb_device_list_constructor (GType			 gtype,
-			       guint			 n_properties,
-			       GObjectConstructParam	*properties)
-{
-	GObject *obj;
-	GUsbDeviceList *list;
-	GUsbDeviceListPrivate *priv;
-	const gchar *const subsystems[] = {"usb", NULL};
-
-	{
-		/* Always chain up to the parent constructor */
-		GObjectClass *parent_class;
-		parent_class = G_OBJECT_CLASS (g_usb_device_list_parent_class);
-		obj = parent_class->constructor (gtype, n_properties,
-						 properties);
-	}
-
-	list = G_USB_DEVICE_LIST (obj);
-	priv = list->priv;
-
-	if (!priv->context)
-		g_error("constructed without a context");
-
-	priv->udev = g_udev_client_new (subsystems);
-	g_signal_connect (G_OBJECT (priv->udev), "uevent",
-			  G_CALLBACK (g_usb_device_list_uevent_cb), list);
-
-	priv->devices = g_ptr_array_new_with_free_func ((GDestroyNotify)
-							g_object_unref);
-
-	priv->coldplug_list = NULL;
-
-	return obj;
-}
-
-/**
- * g_usb_device_list_class_init:
- **/
-static void
-g_usb_device_list_class_init (GUsbDeviceListClass *klass)
-{
-	GParamSpec *pspec;
-	GObjectClass *object_class = (GObjectClass *) klass;
-
-	object_class->constructor	= g_usb_device_list_constructor;
-	object_class->finalize		= g_usb_device_list_finalize;
-	object_class->get_property	= g_usb_device_list_get_property;
-	object_class->set_property	= g_usb_device_list_set_property;
-
-	/**
-	 * GUsbDeviceList:context:
-	 */
-	pspec = g_param_spec_object ("context", NULL, NULL,
-				     G_USB_TYPE_CONTEXT,
-				     G_PARAM_CONSTRUCT_ONLY|
-				     G_PARAM_READWRITE);
-	g_object_class_install_property (object_class, PROP_CONTEXT, pspec);
-
-	signals[DEVICE_ADDED_SIGNAL] = g_signal_new ("device_added",
-			G_TYPE_FROM_CLASS (klass),
-			G_SIGNAL_RUN_LAST,
-			G_STRUCT_OFFSET (GUsbDeviceListClass, device_added),
-			NULL,
-			NULL,
-			g_cclosure_user_marshal_VOID__OBJECT_OBJECT,
-			G_TYPE_NONE,
-			2,
-			G_TYPE_OBJECT,
-			G_TYPE_OBJECT);
-
-	signals[DEVICE_REMOVED_SIGNAL] = g_signal_new ("device_removed",
-			G_TYPE_FROM_CLASS (klass),
-			G_SIGNAL_RUN_LAST,
-			G_STRUCT_OFFSET (GUsbDeviceListClass, device_removed),
-			NULL,
-			NULL,
-			g_cclosure_user_marshal_VOID__OBJECT_OBJECT,
-			G_TYPE_NONE,
-			2,
-			G_TYPE_OBJECT,
-			G_TYPE_OBJECT);
-
-	g_type_class_add_private (klass, sizeof (GUsbDeviceListPrivate));
-}
-
-static void
-g_usb_device_list_init (GUsbDeviceList *list)
-{
-	list->priv = G_USB_DEVICE_LIST_GET_PRIVATE (list);
-}
-
-static gboolean
-g_usb_device_list_get_bus_n_address (GUdevDevice	*udev,
-				     gint		*bus,
-				     gint		*address)
-{
-	const gchar *bus_str, *address_str;
-
-	*bus = *address = 0;
-
-	bus_str = g_udev_device_get_property (udev, "BUSNUM");
-	address_str = g_udev_device_get_property (udev, "DEVNUM");
-	if (bus_str)
-		*bus = atoi(bus_str);
-	if (address_str)
-		*address = atoi(address_str);
-
-	return *bus && *address;
-}
-
-static void
-g_usb_device_list_add_dev (GUsbDeviceList *list, GUdevDevice *udev)
-{
-	GUsbDeviceListPrivate *priv = list->priv;
-	GUsbDevice *device = NULL;
-	libusb_device **dev_list = NULL;
-	const gchar *devtype, *devclass;
-	gint i, bus, address;
-	libusb_context *ctx = _g_usb_context_get_context (priv->context);
-
-	devtype = g_udev_device_get_property (udev, "DEVTYPE");
-	/* Check if this is a usb device (and not an interface) */
-	if (!devtype || strcmp(devtype, "usb_device"))
-		return;
-
-	/* Skip hubs */
-	devclass = g_udev_device_get_sysfs_attr(udev, "bDeviceClass");
-	if (!devclass || !strcmp(devclass, "09"))
-		return;
-
-	if (!g_usb_device_list_get_bus_n_address (udev, &bus, &address)) {
-		g_warning ("usb-device without bus number or device address");
-		return;
-	}
-
-	if (priv->coldplug_list)
-		dev_list = priv->coldplug_list;
-	else
-		libusb_get_device_list(ctx, &dev_list);
-
-	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 = _g_usb_device_new (dev_list[i]);
-			break;
-		}
-	}
-
-	if (!priv->coldplug_list)
-		libusb_free_device_list (dev_list, 1);
-
-	if (!device) {
-		g_warning ("Could not find usb dev at busnum %d devaddr %d",
-			   bus, address);
-		return;
-	}
-
-	g_ptr_array_add (priv->devices, device);
-	g_signal_emit (list, signals[DEVICE_ADDED_SIGNAL], 0, device, udev);
-}
-
-static void
-g_usb_device_list_remove_dev (GUsbDeviceList *list, GUdevDevice *udev)
-{
-	GUsbDeviceListPrivate *priv = list->priv;
-	GUsbDevice *device;
-	gint bus, address;
-
-	if (!g_usb_device_list_get_bus_n_address (udev, &bus, &address))
-		return;
-
-	device = g_usb_device_list_get_dev_by_bus_n_address (list, bus,
-							     address);
-	if (!device)
-		return;
-
-	g_signal_emit (list, signals[DEVICE_REMOVED_SIGNAL], 0, device, udev);
-	g_ptr_array_remove (priv->devices, device);
-}
-
-static void
-g_usb_device_list_uevent_cb (GUdevClient		*client,
-			     const gchar		*action,
-			     GUdevDevice		*udevice,
-			     gpointer			 user_data)
-{
-	GUsbDeviceList *list = G_USB_DEVICE_LIST (user_data);
-
-	if (g_str_equal (action, "add"))
-		g_usb_device_list_add_dev (list, udevice);
-	else if (g_str_equal (action, "remove"))
-		g_usb_device_list_remove_dev (list, udevice);
-}
-
-void
-g_usb_device_list_coldplug (GUsbDeviceList *list)
-{
-	GUsbDeviceListPrivate *priv = list->priv;
-	GList *devices, *elem;
-	libusb_context *ctx = _g_usb_context_get_context (priv->context);
-
-	libusb_get_device_list(ctx, &priv->coldplug_list);
-	devices = g_udev_client_query_by_subsystem (priv->udev, "usb");
-	for (elem = g_list_first (devices); elem; elem = g_list_next (elem)) {
-		g_usb_device_list_add_dev (list, elem->data);
-		g_object_unref (elem->data);
-	}
-	g_list_free (devices);
-	libusb_free_device_list (priv->coldplug_list, 1);
-	priv->coldplug_list = NULL;
-}
-
-GUsbDevice *
-g_usb_device_list_get_dev_by_bus_n_address (GUsbDeviceList	*list,
-					    guint8		 bus,
-					    guint8		 address)
-{
-	GUsbDeviceListPrivate *priv = list->priv;
-	GUsbDevice *device = NULL;
-	guint i;
-
-	for (i = 0; i < priv->devices->len; i++) {
-		GUsbDevice *curr = g_ptr_array_index (priv->devices, i);
-		if (g_usb_device_get_bus (curr) == bus &&
-		    g_usb_device_get_address (curr) == address) {
-			device = curr;
-			break;
-                }
-	}
-
-	return device;
-}
-
-GUsbDeviceList *
-g_usb_device_list_new (GUsbContext *context)
-{
-	GObject *obj;
-	obj = g_object_new (G_USB_TYPE_DEVICE_LIST, "context", context, NULL);
-	return G_USB_DEVICE_LIST (obj);
-}
diff --git a/gtk/gusb/gusb-device-list.h b/gtk/gusb/gusb-device-list.h
deleted file mode 100644
index 430984f..0000000
--- a/gtk/gusb/gusb-device-list.h
+++ /dev/null
@@ -1,72 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
- *
- * Copyright (C) 2011 Hans de Goede <hdegoede at redhat.com>
- *
- * Licensed under the GNU Lesser General Public License Version 2.1
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef __GUSB_DEVICE_LIST_H__
-#define __GUSB_DEVICE_LIST_H__
-
-#include <glib-object.h>
-#include <gudev/gudev.h>
-
-#include <gusb/gusb-context.h>
-#include <gusb/gusb-device.h>
-
-G_BEGIN_DECLS
-
-#define G_USB_TYPE_DEVICE_LIST		(g_usb_device_list_get_type ())
-#define G_USB_DEVICE_LIST(o)		(G_TYPE_CHECK_INSTANCE_CAST ((o), G_USB_TYPE_DEVICE_LIST, GUsbDeviceList))
-#define G_USB_IS_DEVICE_LIST(o)		(G_TYPE_CHECK_INSTANCE_TYPE ((o), G_USB_TYPE_DEVICE_LIST))
-
-typedef struct _GUsbDeviceListPrivate	GUsbDeviceListPrivate;
-typedef struct _GUsbDeviceList		GUsbDeviceList;
-typedef struct _GUsbDeviceListClass	GUsbDeviceListClass;
-
-struct _GUsbDeviceList
-{
-	 GObject			 parent;
-	 GUsbDeviceListPrivate		*priv;
-};
-
-struct _GUsbDeviceListClass
-{
-	GObjectClass			 parent_class;
-	/* Signals */
-	void (*device_added)		(GUsbDeviceList		*list,
-					 GUsbDevice		*device,
-					 GUdevDevice		*udev);
-	void (*device_removed)		(GUsbDeviceList		*list,
-					 GUsbDevice		*device,
-					 GUdevDevice		*udev);
-};
-
-GType			 g_usb_device_list_get_type (void);
-
-GUsbDeviceList		*g_usb_device_list_new (GUsbContext *context);
-
-void			 g_usb_device_list_coldplug (GUsbDeviceList *list);
-
-GUsbDevice		*g_usb_device_list_get_dev_by_bus_n_address (
-					GUsbDeviceList	*list,
-					guint8		 bus,
-					guint8		 address);
-
-
-G_END_DECLS
-
-#endif /* __GUSB_DEVICE_LIST_H__ */
diff --git a/gtk/gusb/gusb-device-private.h b/gtk/gusb/gusb-device-private.h
deleted file mode 100644
index c93b51a..0000000
--- a/gtk/gusb/gusb-device-private.h
+++ /dev/null
@@ -1,34 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
- *
- * Copyright (C) 2011 Hans de Goede <hdegoede at redhat.com>
- *
- * Licensed under the GNU Lesser General Public License Version 2.1
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef __GUSB_DEVICE_PRIVATE_H__
-#define __GUSB_DEVICE_PRIVATE_H__
-
-#include <gusb/gusb-device.h>
-
-G_BEGIN_DECLS
-
-GUsbDevice	*_g_usb_device_new		(libusb_device	*device);
-
-libusb_device	*_g_usb_device_get_device	(GUsbDevice	*device);
-
-G_END_DECLS
-
-#endif /* __GUSB_DEVICE_PRIVATE_H__ */
diff --git a/gtk/gusb/gusb-device.c b/gtk/gusb/gusb-device.c
deleted file mode 100644
index 26a25f3..0000000
--- a/gtk/gusb/gusb-device.c
+++ /dev/null
@@ -1,232 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
- *
- * Copyright (C) 2010-2011 Richard Hughes <richard at hughsie.com>
- * Copyright (C) 2011 Hans de Goede <hdegoede at redhat.com>
- *
- * Licensed under the GNU Lesser General Public License Version 2.1
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, see <http://www.gnu.org/licenses/>.
- */
-
-/**
- * SECTION:usb-device
- * @short_description: GLib device integration for libusb
- *
- * This object is a thin glib wrapper around a libusb_device
- */
-
-#include "config.h"
-
-#include <libusb-1.0/libusb.h>
-
-#include "gusb-device.h"
-#include "gusb-device-private.h"
-
-static void     g_usb_device_finalize	(GObject     *object);
-
-#define G_USB_DEVICE_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), G_USB_TYPE_DEVICE, GUsbDevicePrivate))
-
-/**
- * GUsbDevicePrivate:
- *
- * Private #GUsbDevice data
- **/
-struct _GUsbDevicePrivate
-{
-	libusb_device		*device;
-};
-
-enum {
-	PROP_0,
-	PROP_LIBUSB_DEVICE,
-};
-
-G_DEFINE_TYPE (GUsbDevice, g_usb_device, G_TYPE_OBJECT)
-
-
-/**
- * g_usb_device_error_quark:
- *
- * Return value: Our personal error quark.
- *
- * Since: 0.0.1
- **/
-GQuark
-g_usb_device_error_quark (void)
-{
-	static GQuark quark = 0;
-	if (!quark)
-		quark = g_quark_from_static_string ("g_usb_device_error");
-	return quark;
-}
-
-/**
- * usb_device_get_property:
- **/
-static void
-g_usb_device_get_property (GObject		*object,
-			   guint		 prop_id,
-			   GValue		*value,
-			   GParamSpec		*pspec)
-{
-	GUsbDevice *device = G_USB_DEVICE (object);
-	GUsbDevicePrivate *priv = device->priv;
-
-	switch (prop_id) {
-	case PROP_LIBUSB_DEVICE:
-		g_value_set_pointer (value, priv->device);
-		break;
-	default:
-		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
-		break;
-	}
-}
-
-/**
- * usb_device_set_property:
- **/
-static void
-g_usb_device_set_property (GObject		*object,
-			   guint		 prop_id,
-			   const GValue		*value,
-			   GParamSpec		*pspec)
-{
-	GUsbDevice *device = G_USB_DEVICE (object);
-	GUsbDevicePrivate *priv = device->priv;
-
-	switch (prop_id) {
-	case PROP_LIBUSB_DEVICE:
-		priv->device = g_value_get_pointer (value);
-		break;
-	default:
-		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
-		break;
-	}
-}
-
-static GObject *
-g_usb_device_constructor (GType			 gtype,
-			  guint			 n_properties,
-			  GObjectConstructParam	*properties)
-{
-	GObject *obj;
-	GUsbDevice *device;
-	GUsbDevicePrivate *priv;
-
-	{
-		/* Always chain up to the parent constructor */
-		GObjectClass *parent_class;
-		parent_class = G_OBJECT_CLASS (g_usb_device_parent_class);
-		obj = parent_class->constructor (gtype, n_properties,
-						 properties);
-	}
-
-	device = G_USB_DEVICE (obj);
-	priv = device->priv;
-
-	if (!priv->device)
-		g_error("constructed without a libusb_device");
-
-	libusb_ref_device(priv->device);
-
-	return obj;
-}
-
-/**
- * usb_device_class_init:
- **/
-static void
-g_usb_device_class_init (GUsbDeviceClass *klass)
-{
-	GParamSpec *pspec;
-	GObjectClass *object_class = G_OBJECT_CLASS (klass);
-
-	object_class->constructor	= g_usb_device_constructor;
-	object_class->finalize		= g_usb_device_finalize;
-	object_class->get_property	= g_usb_device_get_property;
-	object_class->set_property	= g_usb_device_set_property;
-
-	/**
-	 * GUsbDevice:libusb_device:
-	 */
-	pspec = g_param_spec_pointer ("libusb_device", NULL, NULL,
-				     G_PARAM_CONSTRUCT_ONLY|
-				     G_PARAM_READWRITE);
-	g_object_class_install_property (object_class, PROP_LIBUSB_DEVICE,
-					 pspec);
-
-	g_type_class_add_private (klass, sizeof (GUsbDevicePrivate));
-}
-
-/**
- * g_usb_device_init:
- **/
-static void
-g_usb_device_init (GUsbDevice *device)
-{
-	device->priv = G_USB_DEVICE_GET_PRIVATE (device);
-}
-
-/**
- * g_usb_device_finalize:
- **/
-static void
-g_usb_device_finalize (GObject *object)
-{
-	GUsbDevice *device = G_USB_DEVICE (object);
-	GUsbDevicePrivate *priv = device->priv;
-
-	libusb_unref_device(priv->device);
-
-	G_OBJECT_CLASS (g_usb_device_parent_class)->finalize (object);
-}
-
-/**
- * _g_usb_device_new:
- *
- * Return value: a new #GUsbDevice object.
- **/
-GUsbDevice *
-_g_usb_device_new (libusb_device	*device)
-{
-	GObject *obj;
-	obj = g_object_new (G_USB_TYPE_DEVICE, "libusb_device", device, NULL);
-	return G_USB_DEVICE (obj);
-}
-
-/**
- * _g_usb_device_get_device:
- * @device: a #GUsbDevice instance
- *
- * Gets the low-level libusb_device
- *
- * Return value: The #libusb_device or %NULL. Do not unref this value.
- **/
-libusb_device *
-_g_usb_device_get_device (GUsbDevice	*device)
-{
-	return device->priv->device;
-}
-
-guint8
-g_usb_device_get_bus (GUsbDevice	*device)
-{
-	return libusb_get_bus_number (device->priv->device);
-}
-
-guint8
-g_usb_device_get_address (GUsbDevice	*device)
-{
-	return libusb_get_device_address (device->priv->device);
-}
diff --git a/gtk/gusb/gusb-device.h b/gtk/gusb/gusb-device.h
deleted file mode 100644
index a504182..0000000
--- a/gtk/gusb/gusb-device.h
+++ /dev/null
@@ -1,71 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
- *
- * Copyright (C) 2010-2011 Richard Hughes <richard at hughsie.com>
- * Copyright (C) 2011 Hans de Goede <hdegoede at redhat.com>
- *
- * Licensed under the GNU Lesser General Public License Version 2.1
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef __GUSB_DEVICE_H__
-#define __GUSB_DEVICE_H__
-
-#include <glib-object.h>
-
-G_BEGIN_DECLS
-
-#define G_USB_TYPE_DEVICE		(g_usb_device_get_type ())
-#define G_USB_DEVICE(o)			(G_TYPE_CHECK_INSTANCE_CAST ((o), G_USB_TYPE_DEVICE, GUsbDevice))
-#define G_USB_IS_DEVICE(o)		(G_TYPE_CHECK_INSTANCE_TYPE ((o), G_USB_TYPE_DEVICE))
-#define G_USB_DEVICE_ERROR		(g_usb_device_error_quark ())
-
-typedef struct _GUsbDevicePrivate	GUsbDevicePrivate;
-typedef struct _GUsbDevice		GUsbDevice;
-typedef struct _GUsbDeviceClass		GUsbDeviceClass;
-
-/**
- * GUsbDeviceError:
- *
- * The error code.
- **/
-typedef enum {
-	G_USB_DEVICE_ERROR_INTERNAL
-} GUsbDeviceError;
-
-struct _GUsbDevice
-{
-	 GObject			 parent;
-	 GUsbDevicePrivate		*priv;
-};
-
-struct _GUsbDeviceClass
-{
-	GObjectClass			 parent_class;
-};
-
-GType			 g_usb_device_get_type		(void);
-GQuark			 g_usb_device_error_quark	(void);
-
-guint8			 g_usb_device_get_bus		(GUsbDevice      *device);
-guint8			 g_usb_device_get_address	(GUsbDevice      *device);
-
-#if 0 /* TODO */
-GUsbDeviceHandle 	*g_usb_device_get_device_handle	(GUsbDevice	 *device,
-							 GError		**err);
-#endif
-
-G_END_DECLS
-
-#endif /* __GUSB_DEVICE_H__ */
diff --git a/gtk/gusb/gusb-marshal.h b/gtk/gusb/gusb-marshal.h
deleted file mode 100644
index b00fd65..0000000
--- a/gtk/gusb/gusb-marshal.h
+++ /dev/null
@@ -1,7 +0,0 @@
-/*
- * HDG: hack
- * Important: Don't forget to remove VOID:OBJECT,OBJECT from spice-marshal.txt
- * when we remove our bundled gusb.
- */
-
-#include "spice-marshal.h"
diff --git a/gtk/gusb/gusb-source.c b/gtk/gusb/gusb-source.c
deleted file mode 100644
index bb0af49..0000000
--- a/gtk/gusb/gusb-source.c
+++ /dev/null
@@ -1,307 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
- *
- * Copyright (C) 2010-2011 Richard Hughes <richard at hughsie.com>
- * Copyright (C) 2011 Hans de Goede <hdegoede at redhat.com>
- *
- * Licensed under the GNU Lesser General Public License Version 2.1
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA
- */
-
-/**
- * SECTION:gusb-source
- * @short_description: GSource integration for libusb
- *
- * This object can be used to integrate libusb into the GLib main loop.
- */
-
-#include "config.h"
-
-#include <libusb-1.0/libusb.h>
-#include <poll.h>
-#include <stdlib.h>
-
-#include "gusb-util.h"
-#include "gusb-context.h"
-#include "gusb-context-private.h"
-#include "gusb-source.h"
-
-/**
- * g_usb_source_error_quark:
- *
- * Return value: Our personal error quark.
- *
- * Since: 0.0.1
- **/
-GQuark
-g_usb_source_error_quark (void)
-{
-	static GQuark quark = 0;
-	if (!quark)
-		quark = g_quark_from_static_string ("g_usb_source_error");
-	return quark;
-}
-
-struct _GUsbSource {
-	GSource		 source;
-	GSList		*pollfds;
-	GUsbContext	*usbcontext;
-	libusb_context	*ctx;
-};
-
-static void
-g_usb_source_pollfd_add (GUsbSource *source, int fd, short events)
-{
-	GPollFD *pollfd = g_slice_new(GPollFD);
-	pollfd->fd = fd;
-	pollfd->events = 0;
-	pollfd->revents = 0;
-	if (events & POLLIN)
-		pollfd->events |= G_IO_IN;
-	if (events & POLLOUT)
-		pollfd->events |= G_IO_OUT;
-
-	source->pollfds = g_slist_prepend(source->pollfds, pollfd);
-	g_source_add_poll((GSource *)source, pollfd);
-}
-
-static void
-g_usb_source_pollfd_added_cb (int fd, short events, void *user_data)
-{
-	GUsbSource *source = user_data;
-	g_usb_source_pollfd_add (source, fd, events);
-}
-
-static void
-g_usb_source_pollfd_remove (GUsbSource *source, int fd)
-{
-	GPollFD *pollfd;
-	GSList *elem = source->pollfds;
-
-	/* nothing to see here, move along */
-	if (elem == NULL) {
-		g_warning("cannot remove from list as list is empty?");
-		return;
-	}
-
-	/* find the pollfd in the list */
-	do {
-		pollfd = elem->data;
-		if (pollfd->fd != fd)
-			continue;
-
-		g_source_remove_poll((GSource *)source, pollfd);
-		g_slice_free(GPollFD, pollfd);
-		source->pollfds = g_slist_delete_link(source->pollfds, elem);
-		return;
-	} while ((elem = g_slist_next(elem)));
-	g_warning ("couldn't find fd %d in list", fd);
-}
-
-static void
-g_usb_source_pollfd_removed_cb(int fd, void *user_data)
-{
-	GUsbSource *source = user_data;
-
-	g_usb_source_pollfd_remove (source, fd);
-}
-
-static void
-g_usb_source_pollfd_remove_all (GUsbSource *source)
-{
-	GPollFD *pollfd;
-	GSList *curr, *next;
-
-	next = source->pollfds;
-	while (next) {
-		curr = next;
-		next = g_slist_next(curr);
-		pollfd = curr->data;
-		g_source_remove_poll((GSource *)source, pollfd);
-		g_slice_free (GPollFD, pollfd);
-		source->pollfds = g_slist_delete_link(source->pollfds, curr);
-	}
-}
-
-/**
- * g_usb_source_prepare:
- *
- * Called before all the file descriptors are polled.
- * As we are a file descriptor source, the prepare function returns FALSE.
- * It sets the returned timeout to -1 to indicate that it doesn't mind
- * how long the poll() call blocks.
- *
- * No, we're not going to support FreeBSD.
- **/
-static gboolean
-g_usb_source_prepare (GSource *source, gint *timeout)
-{
-	*timeout = -1;
-	return FALSE;
-}
-
-/**
- * g_usb_source_check:
- *
- * In the check function, it tests the results of the poll() call to see
- * if the required condition has been met, and returns TRUE if so.
- **/
-static gboolean
-g_usb_source_check (GSource *source)
-{
-	GUsbSource *usb_source = (GUsbSource *)source;
-	GPollFD *pollfd;
-	GSList *elem = usb_source->pollfds;
-
-	/* no fds */
-	if (elem == NULL)
-		return FALSE;
-
-	/* check each pollfd */
-	do {
-		pollfd = elem->data;
-		if (pollfd->revents)
-			return TRUE;
-	} while ((elem = g_slist_next(elem)));
-
-	return FALSE;
-}
-
-static gboolean
-g_usb_source_dispatch (GSource *source,
-		       GSourceFunc callback,
-		       gpointer user_data)
-{
-	GUsbSource *usb_source = (GUsbSource *)source;
-	struct timeval tv = { 0, 0 };
-	gint rc;
-
-	rc = libusb_handle_events_timeout (usb_source->ctx, &tv);
-	if (rc < 0) {
-		g_warning ("failed to handle event: %s [%i]",
-			   gusb_strerror (rc), rc);
-	}
-
-	if (callback)
-		callback(user_data);
-
-	return TRUE;
-}
-
-static void
-g_usb_source_finalize (GSource *source)
-{
-	GUsbSource *usb_source = (GUsbSource *)source;
-	g_object_unref (usb_source->usbcontext);
-	g_slist_free (usb_source->pollfds);
-}
-
-static GSourceFuncs usb_source_funcs = {
-	g_usb_source_prepare,
-	g_usb_source_check,
-	g_usb_source_dispatch,
-	g_usb_source_finalize,
-	NULL, NULL
-};
-
-/**
- * g_usb_source_new:
- * @main_ctx: a #GMainContext, or %NULL
- * @gusb_ctx: a #GUsbContext
- * @error: a #GError, or %NULL
- *
- * Creates a source for integration into libusb1.
- *
- * Return value: (transfer none): the #GUsbSource, or %NULL. Use g_usb_source_destroy() to unref.
- *
- * Since: 0.0.1
- **/
-GUsbSource *
-g_usb_source_new (GMainContext *main_ctx,
-		  GUsbContext *gusb_ctx,
-		  GError **error)
-{
-	guint i;
-	const struct libusb_pollfd **pollfds;
-	GUsbSource *gusb_source;
-
-	gusb_source = (GUsbSource *)g_source_new (&usb_source_funcs,
-						  sizeof(GUsbSource));
-	gusb_source->pollfds = NULL;
-	gusb_source->usbcontext = g_object_ref (gusb_ctx);
-	gusb_source->ctx = _g_usb_context_get_context (gusb_ctx);
-
-	/* watch the fd's already created */
-	pollfds = libusb_get_pollfds (gusb_source->ctx);
-	if (pollfds == NULL) {
-		g_set_error_literal (error,
-				     G_USB_SOURCE_ERROR,
-				     G_USB_SOURCE_ERROR_INTERNAL,
-				     "failed to allocate memory");
-		g_free (gusb_source);
-		gusb_source = NULL;
-		goto out;
-	}
-	for (i=0; pollfds[i] != NULL; i++)
-		g_usb_source_pollfd_add (gusb_source,
-					 pollfds[i]->fd,
-					 pollfds[i]->events);
-	free (pollfds);
-
-	/* watch for PollFD changes */
-	g_source_attach ((GSource *)gusb_source, main_ctx);
-	libusb_set_pollfd_notifiers (gusb_source->ctx,
-				     g_usb_source_pollfd_added_cb,
-				     g_usb_source_pollfd_removed_cb,
-				     gusb_source);
-out:
-	return gusb_source;
-}
-
-/**
- * g_usb_source_destroy:
- * @source: a #GUsbSource
- *
- * Destroys a #GUsbSource
- *
- * Since: 0.0.1
- **/
-void
-g_usb_source_destroy (GUsbSource *source)
-{
-	libusb_set_pollfd_notifiers (source->ctx, NULL, NULL, NULL);
-	g_usb_source_pollfd_remove_all (source);
-	g_source_destroy ((GSource *)source);
-}
-
-/**
- * g_usb_source_set_callback:
- * @source: a #GUsbSource
- * @func: a function to call
- * @data: data to pass to @func
- * @notify: a #GDestroyNotify
- *
- * Set a callback to be called when the source is dispatched.
- *
- * Since: 0.0.1
- **/
-void
-g_usb_source_set_callback (GUsbSource *source,
-			   GSourceFunc func,
-			   gpointer data,
-			   GDestroyNotify notify)
-{
-	g_source_set_callback ((GSource *)source, func, data, notify);
-}
diff --git a/gtk/gusb/gusb-source.h b/gtk/gusb/gusb-source.h
deleted file mode 100644
index 40f6880..0000000
--- a/gtk/gusb/gusb-source.h
+++ /dev/null
@@ -1,58 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
- *
- * Copyright (C) 2010-2011 Richard Hughes <richard at hughsie.com>
- * Copyright (C) 2011 Hans de Goede <hdegoede at redhat.com>
- *
- * Licensed under the GNU Lesser General Public License Version 2.1
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA
- */
-
-#ifndef __GUSB_SOURCE_H__
-#define __GUSB_SOURCE_H__
-
-#include <glib.h>
-
-#include <gusb/gusb-context.h>
-
-G_BEGIN_DECLS
-
-#define G_USB_SOURCE_ERROR			(g_usb_source_error_quark ())
-
-typedef struct _GUsbSource GUsbSource;
-
-/**
- * GUsbSourceError:
- *
- * The error code.
- **/
-typedef enum {
-	G_USB_SOURCE_ERROR_INTERNAL
-} GUsbSourceError;
-
-GQuark		 g_usb_source_error_quark	(void);
-GUsbSource	*g_usb_source_new		(GMainContext	*main_ctx,
-						 GUsbContext	*gusb_ctx,
-						 GError		**error);
-void		 g_usb_source_destroy		(GUsbSource	*source);
-
-void		 g_usb_source_set_callback	(GUsbSource	*source,
-						 GSourceFunc	 func,
-						 gpointer	 data,
-						 GDestroyNotify	 notify);
-
-G_END_DECLS
-
-#endif /* __GUSB_SOURCE_H__ */
diff --git a/gtk/gusb/gusb-util.c b/gtk/gusb/gusb-util.c
deleted file mode 100644
index ca91700..0000000
--- a/gtk/gusb/gusb-util.c
+++ /dev/null
@@ -1,65 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
- *
- * Copyright (C) 2011 Hans de Goede <hdegoede at redhat.com>
- *
- * Licensed under the GNU Lesser General Public License Version 2.1
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "config.h"
-
-#include <libusb-1.0/libusb.h>
-
-#include "gusb-util.h"
-
-/* libusb_strerror is not going upstream in the forseeable future because of
-   i18n worries, provide our own implementation for now, later this can
-   hopefully became just a wrapper of the upstream version */
-const gchar* gusb_strerror(gint error_code)
-{
-    enum libusb_error error = error_code;
-
-    switch (error) {
-    case LIBUSB_SUCCESS:
-        return "Success";
-    case LIBUSB_ERROR_IO:
-        return "Input/output error";
-    case LIBUSB_ERROR_INVALID_PARAM:
-        return "Invalid parameter";
-    case LIBUSB_ERROR_ACCESS:
-        return "Access denied (insufficient permissions)";
-    case LIBUSB_ERROR_NO_DEVICE:
-        return "No such device (it may have been disconnected)";
-    case LIBUSB_ERROR_NOT_FOUND:
-        return "Entity not found";
-    case LIBUSB_ERROR_BUSY:
-        return "Resource busy";
-    case LIBUSB_ERROR_TIMEOUT:
-        return "Operation timed out";
-    case LIBUSB_ERROR_OVERFLOW:
-        return "Overflow";
-    case LIBUSB_ERROR_PIPE:
-        return "Pipe error";
-    case LIBUSB_ERROR_INTERRUPTED:
-        return "System call interrupted (perhaps due to signal)";
-    case LIBUSB_ERROR_NO_MEM:
-        return "Insufficient memory";
-    case LIBUSB_ERROR_NOT_SUPPORTED:
-        return "Operation not supported or unimplemented on this platform";
-    case LIBUSB_ERROR_OTHER:
-        return "Other error";
-    }
-    return "Unknown error";
-}
diff --git a/gtk/gusb/gusb-util.h b/gtk/gusb/gusb-util.h
deleted file mode 100644
index c270853..0000000
--- a/gtk/gusb/gusb-util.h
+++ /dev/null
@@ -1,32 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
- *
- * Copyright (C) 2011 Hans de Goede <hdegoede at redhat.com>
- *
- * Licensed under the GNU Lesser General Public License Version 2.1
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef __GUSB_UTIL_H__
-#define __GUSB_UTIL_H__
-
-#include <glib.h>
-
-G_BEGIN_DECLS
-
-const gchar* gusb_strerror(gint error_code);
-
-G_END_DECLS
-
-#endif /* __GUSB_UTIL_H__ */
diff --git a/gtk/usb-device-manager-priv.h b/gtk/usb-device-manager-priv.h
index 841c725..e6e116c 100644
--- a/gtk/usb-device-manager-priv.h
+++ b/gtk/usb-device-manager-priv.h
@@ -25,6 +25,8 @@
 
 G_BEGIN_DECLS
 
+const char *spice_usb_device_manager_libusb_strerror(enum libusb_error error_code);
+
 gboolean spice_usb_device_manager_start_event_listening(
     SpiceUsbDeviceManager *manager, GError **err);
 
diff --git a/gtk/usb-device-manager.c b/gtk/usb-device-manager.c
index dc0dddd..69ba108 100644
--- a/gtk/usb-device-manager.c
+++ b/gtk/usb-device-manager.c
@@ -26,8 +26,8 @@
 #include "glib-compat.h"
 
 #ifdef USE_USBREDIR
-#include <gusb/gusb-device-list.h>
-#include <gusb/gusb-context-private.h>
+#include <libusb.h>
+#include <gudev/gudev.h>
 #include "channel-usbredir-priv.h"
 #endif
 
@@ -87,25 +87,24 @@ struct _SpiceUsbDeviceManagerPrivate {
     SpiceSession *session;
     gboolean auto_connect;
 #ifdef USE_USBREDIR
-    GUsbContext *context;
-    GUsbDeviceList *devlist;
+    libusb_context *context;
+    GUdevClient *udev;
     int event_listeners;
     GThread *event_thread;
     gboolean event_thread_run;
+    libusb_device **coldplug_list; /* Avoid needless reprobing during init */
 #endif
     GPtrArray *devices;
     GPtrArray *channels;
 };
 
 #ifdef USE_USBREDIR
-static void spice_usb_device_manager_dev_added(GUsbDeviceList *devlist,
-                                               GUsbDevice     *device,
-                                               GUdevDevice    *udev,
-                                               gpointer        user_data);
-static void spice_usb_device_manager_dev_removed(GUsbDeviceList *devlist,
-                                                 GUsbDevice     *device,
-                                                 GUdevDevice    *udev,
-                                                 gpointer        user_data);
+static void spice_usb_device_manager_uevent_cb(GUdevClient     *client,
+                                               const gchar     *action,
+                                               GUdevDevice     *udevice,
+                                               gpointer         user_data);
+static void spice_usb_device_manager_add_dev(SpiceUsbDeviceManager  *self,
+                                             GUdevDevice            *udev);
 #endif
 static void spice_usb_device_manager_initable_iface_init(GInitableIface *iface);
 
@@ -114,7 +113,9 @@ 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));
 
-G_DEFINE_BOXED_TYPE(SpiceUsbDevice, spice_usb_device, g_object_ref, g_object_unref)
+G_DEFINE_BOXED_TYPE(SpiceUsbDevice, spice_usb_device,
+                    (GBoxedCopyFunc)libusb_ref_device,
+                    (GBoxedFreeFunc)libusb_unref_device)
 
 static void spice_usb_device_manager_init(SpiceUsbDeviceManager *self)
 {
@@ -125,7 +126,7 @@ static void spice_usb_device_manager_init(SpiceUsbDeviceManager *self)
 
     priv->channels = g_ptr_array_new();
     priv->devices  = g_ptr_array_new_with_free_func((GDestroyNotify)
-                                                    g_object_unref);
+                                                    libusb_unref_device);
 }
 
 static gboolean spice_usb_device_manager_initable_init(GInitable  *initable,
@@ -137,7 +138,8 @@ static gboolean spice_usb_device_manager_initable_init(GInitable  *initable,
     SpiceUsbDeviceManager *self;
     SpiceUsbDeviceManagerPrivate *priv;
 #ifdef USE_USBREDIR
-    GError *my_err = NULL;
+    int rc;
+    const gchar *const subsystems[] = {"usb", NULL};
 #endif
 
     g_return_val_if_fail(SPICE_IS_USB_DEVICE_MANAGER(initable), FALSE);
@@ -169,26 +171,30 @@ static gboolean spice_usb_device_manager_initable_init(GInitable  *initable,
     g_list_free(list);
 
 #ifdef USE_USBREDIR
-    priv->context = g_usb_context_new(&my_err);
-    if (priv->context == NULL) {
-        g_warning("Could not get a GUsbContext, disabling USB support: %s",
-                  my_err->message);
-        if (err) {
-            *err = my_err;
-        } else {
-            g_error_free(my_err);
-        }
+    rc = libusb_init(&priv->context);
+    if (rc < 0) {
+        const char *desc = spice_usb_device_manager_libusb_strerror(rc);
+        g_warning("Error initializing USB support: %s [%i]", desc, rc);
+        g_set_error(err, SPICE_CLIENT_ERROR, SPICE_CLIENT_ERROR_FAILED,
+                    "Error initializing USB support: %s [%i]", desc, rc);
         return FALSE;
     }
 
-    priv->devlist = g_usb_device_list_new(priv->context);
-    g_signal_connect(G_OBJECT(priv->devlist), "device_added",
-                     G_CALLBACK(spice_usb_device_manager_dev_added),
-                     self);
-    g_signal_connect(G_OBJECT(priv->devlist), "device_removed",
-                     G_CALLBACK(spice_usb_device_manager_dev_removed),
-                     self);
-    g_usb_device_list_coldplug(priv->devlist);
+    priv->udev = g_udev_client_new(subsystems);
+    g_signal_connect(G_OBJECT(priv->udev), "uevent",
+                     G_CALLBACK(spice_usb_device_manager_uevent_cb), self);
+
+    /* Do coldplug (detection of already connected devices) */
+    libusb_get_device_list(priv->context, &priv->coldplug_list);
+    list = g_udev_client_query_by_subsystem(priv->udev, "usb");
+    for (it = g_list_first(list); it; it = g_list_next(it)) {
+        spice_usb_device_manager_add_dev(self, it->data);
+        g_object_unref(it->data);
+    }
+    g_list_free(list);
+    libusb_free_device_list(priv->coldplug_list, 1);
+    priv->coldplug_list = NULL;
+
     return TRUE;
 #else
     g_set_error_literal(err, SPICE_CLIENT_ERROR, SPICE_CLIENT_ERROR_FAILED,
@@ -202,19 +208,17 @@ static void spice_usb_device_manager_finalize(GObject *gobject)
     SpiceUsbDeviceManager *self = SPICE_USB_DEVICE_MANAGER(gobject);
     SpiceUsbDeviceManagerPrivate *priv = self->priv;
 
+    g_ptr_array_unref(priv->channels);
+    g_ptr_array_unref(priv->devices);
+
 #ifdef USE_USBREDIR
+    g_clear_object(&priv->udev);
+    if (priv->context)
+        libusb_exit(priv->context);
     if (priv->event_thread)
         g_thread_join(priv->event_thread);
-
-    if (priv->devlist) {
-        g_object_unref(priv->devlist);
-        g_object_unref(priv->context);
-    }
 #endif
 
-    g_ptr_array_unref(priv->channels);
-    g_ptr_array_unref(priv->devices);
-
     /* Chain up to the parent class */
     if (G_OBJECT_CLASS(spice_usb_device_manager_parent_class)->finalize)
         G_OBJECT_CLASS(spice_usb_device_manager_parent_class)->finalize(gobject);
@@ -364,6 +368,63 @@ static void spice_usb_device_manager_class_init(SpiceUsbDeviceManagerClass *klas
 }
 
 /* ------------------------------------------------------------------ */
+/* gudev / libusb Helper functions                                    */
+
+#ifdef USE_USBREDIR
+static gboolean spice_usb_device_manager_get_udev_bus_n_address(
+    GUdevDevice *udev, int *bus, int *address)
+{
+    const gchar *bus_str, *address_str;
+
+    *bus = *address = 0;
+
+    bus_str = g_udev_device_get_property(udev, "BUSNUM");
+    address_str = g_udev_device_get_property(udev, "DEVNUM");
+    if (bus_str)
+        *bus = atoi(bus_str);
+    if (address_str)
+        *address = atoi(address_str);
+
+    return *bus && *address;
+}
+
+const char *spice_usb_device_manager_libusb_strerror(enum libusb_error error_code)
+{
+    switch (error_code) {
+    case LIBUSB_SUCCESS:
+        return "Success";
+    case LIBUSB_ERROR_IO:
+        return "Input/output error";
+    case LIBUSB_ERROR_INVALID_PARAM:
+        return "Invalid parameter";
+    case LIBUSB_ERROR_ACCESS:
+        return "Access denied (insufficient permissions)";
+    case LIBUSB_ERROR_NO_DEVICE:
+        return "No such device (it may have been disconnected)";
+    case LIBUSB_ERROR_NOT_FOUND:
+        return "Entity not found";
+    case LIBUSB_ERROR_BUSY:
+        return "Resource busy";
+    case LIBUSB_ERROR_TIMEOUT:
+        return "Operation timed out";
+    case LIBUSB_ERROR_OVERFLOW:
+        return "Overflow";
+    case LIBUSB_ERROR_PIPE:
+        return "Pipe error";
+    case LIBUSB_ERROR_INTERRUPTED:
+        return "System call interrupted (perhaps due to signal)";
+    case LIBUSB_ERROR_NO_MEM:
+        return "Insufficient memory";
+    case LIBUSB_ERROR_NOT_SUPPORTED:
+        return "Operation not supported or unimplemented on this platform";
+    case LIBUSB_ERROR_OTHER:
+        return "Other error";
+    }
+    return "Unknown error";
+}
+#endif
+
+/* ------------------------------------------------------------------ */
 /* callbacks                                                          */
 
 static void channel_new(SpiceSession *session, SpiceChannel *channel,
@@ -390,12 +451,12 @@ static void spice_usb_device_manager_auto_connect_cb(GObject      *gobject,
                                                      gpointer      user_data)
 {
     SpiceUsbDeviceManager *self = SPICE_USB_DEVICE_MANAGER(gobject);
-    SpiceUsbDevice *device = user_data;
+    libusb_device *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(device);
+        gchar *desc = spice_usb_device_get_description((SpiceUsbDevice *)device);
         g_prefix_error(&err, "Could not auto-redirect %s: ", desc);
         g_free(desc);
 
@@ -403,46 +464,109 @@ 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);
     }
-    g_object_unref(device);
+    libusb_unref_device(device);
 }
 
-static void spice_usb_device_manager_dev_added(GUsbDeviceList *devlist,
-                                               GUsbDevice     *_device,
-                                               GUdevDevice    *udev,
-                                               gpointer        user_data)
+static void spice_usb_device_manager_add_dev(SpiceUsbDeviceManager  *self,
+                                             GUdevDevice            *udev)
 {
-    SpiceUsbDeviceManager *manager = user_data;
-    SpiceUsbDeviceManagerPrivate *priv = manager->priv;
-    SpiceUsbDevice *device = (SpiceUsbDevice *)_device;
+    SpiceUsbDeviceManagerPrivate *priv = self->priv;
+    libusb_device *device = NULL, **dev_list = NULL;
+    const gchar *devtype, *devclass;
+    int i, bus, address;
+
+    devtype = g_udev_device_get_property(udev, "DEVTYPE");
+    /* Check if this is a usb device (and not an interface) */
+    if (!devtype || strcmp(devtype, "usb_device"))
+        return;
+
+    /* Skip hubs */
+    devclass = g_udev_device_get_sysfs_attr(udev, "bDeviceClass");
+    if (!devclass || !strcmp(devclass, "09"))
+        return;
+
+    if (!spice_usb_device_manager_get_udev_bus_n_address(udev, &bus, &address)) {
+        g_warning("USB device without bus number or device address");
+        return;
+    }
 
-    g_ptr_array_add(priv->devices, g_object_ref(device));
+    if (priv->coldplug_list)
+        dev_list = priv->coldplug_list;
+    else
+        libusb_get_device_list(priv->context, &dev_list);
+
+    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]);
+            break;
+        }
+    }
+
+    if (!priv->coldplug_list)
+        libusb_free_device_list(dev_list, 1);
+
+    if (!device) {
+        g_warning("Could not find USB device at busnum %d devaddr %d",
+                  bus, address);
+        return;
+    }
+
+    g_ptr_array_add(priv->devices, device);
 
     if (priv->auto_connect) {
-        spice_usb_device_manager_connect_device_async(manager, device, NULL,
+        spice_usb_device_manager_connect_device_async(self,
+                                   (SpiceUsbDevice *)device, NULL,
                                    spice_usb_device_manager_auto_connect_cb,
-                                   g_object_ref(device));
+                                   libusb_ref_device(device));
     }
 
     SPICE_DEBUG("device added %p", device);
-    g_signal_emit(manager, signals[DEVICE_ADDED], 0, device);
+    g_signal_emit(self, signals[DEVICE_ADDED], 0, device);
 }
 
-static void spice_usb_device_manager_dev_removed(GUsbDeviceList *devlist,
-                                                 GUsbDevice     *device,
-                                                 GUdevDevice    *udev,
-                                                 gpointer        user_data)
+static void spice_usb_device_manager_remove_dev(SpiceUsbDeviceManager  *self,
+                                                GUdevDevice            *udev)
 {
-    SpiceUsbDeviceManager *manager = user_data;
-    SpiceUsbDeviceManagerPrivate *priv = manager->priv;
+    SpiceUsbDeviceManagerPrivate *priv = self->priv;
+    libusb_device *curr, *device = NULL;
+    int bus, address;
+    guint i;
 
-    spice_usb_device_manager_disconnect_device(manager,
-                                               (SpiceUsbDevice *)device);
+    if (!spice_usb_device_manager_get_udev_bus_n_address(udev, &bus, &address))
+        return;
+
+    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) {
+            device = curr;
+            break;
+        }
+    }
+    if (!device)
+        return;
+
+    spice_usb_device_manager_disconnect_device(self, (SpiceUsbDevice *)device);
 
     SPICE_DEBUG("device removed %p", device);
-    g_signal_emit(manager, signals[DEVICE_REMOVED], 0, device);
+    g_signal_emit(self, signals[DEVICE_REMOVED], 0, device);
     g_ptr_array_remove(priv->devices, device);
 }
 
+static void spice_usb_device_manager_uevent_cb(GUdevClient     *client,
+                                               const gchar     *action,
+                                               GUdevDevice     *udevice,
+                                               gpointer         user_data)
+{
+    SpiceUsbDeviceManager *self = SPICE_USB_DEVICE_MANAGER(user_data);
+
+    if (g_str_equal(action, "add"))
+        spice_usb_device_manager_add_dev(self, udevice);
+    else if (g_str_equal (action, "remove"))
+        spice_usb_device_manager_remove_dev(self, udevice);
+}
+
 static void spice_usb_device_manager_channel_connect_cb(
     GObject *gobject, GAsyncResult *channel_res, gpointer user_data)
 {
@@ -467,7 +591,7 @@ static gpointer spice_usb_device_magager_usb_ev_thread(gpointer user_data)
     SpiceUsbDeviceManagerPrivate *priv = self->priv;
 
     while (priv->event_thread_run) {
-        libusb_handle_events(_g_usb_context_get_context(priv->context));
+        libusb_handle_events(priv->context);
     }
 
     return NULL;
@@ -516,7 +640,7 @@ static SpiceUsbredirChannel *spice_usb_device_manager_get_channel_for_dev(
 {
 #ifdef USE_USBREDIR
     SpiceUsbDeviceManagerPrivate *priv = manager->priv;
-    GUsbDevice *device = (GUsbDevice *)_device;
+    libusb_device *device = (libusb_device *)_device;
     guint i;
 
     for (i = 0; i < priv->channels->len; i++) {
@@ -580,10 +704,10 @@ GPtrArray* spice_usb_device_manager_get_devices(SpiceUsbDeviceManager *self)
 
     priv = self->priv;
     devices_copy = g_ptr_array_new_with_free_func((GDestroyNotify)
-                                                  g_object_unref);
+                                                  libusb_unref_device);
     for (i = 0; i < priv->devices->len; i++) {
-        SpiceUsbDevice *device = g_ptr_array_index(priv->devices, i);
-        g_ptr_array_add(devices_copy, g_object_ref(device));
+        libusb_device *device = g_ptr_array_index(priv->devices, i);
+        g_ptr_array_add(devices_copy, libusb_ref_device(device));
     }
 
     return devices_copy;
@@ -648,7 +772,7 @@ void spice_usb_device_manager_connect_device_async(SpiceUsbDeviceManager *self,
 
         spice_usbredir_channel_connect_async(channel,
                                  priv->context,
-                                 (GUsbDevice *)device,
+                                 (libusb_device *)device,
                                  cancellable,
                                  spice_usb_device_manager_channel_connect_cb,
                                  result);
@@ -715,16 +839,16 @@ void spice_usb_device_manager_disconnect_device(SpiceUsbDeviceManager *self,
  *
  * Returns: a newly-allocated string holding the description
  */
-gchar *spice_usb_device_get_description(SpiceUsbDevice *device)
+gchar *spice_usb_device_get_description(SpiceUsbDevice *_device)
 {
 #ifdef USE_USBREDIR
-    /* FIXME, extend gusb to get vid:pid + usb descriptor strings, use those */
+    libusb_device *device = (libusb_device *)_device;
     int bus, address;
 
     g_return_val_if_fail(device != NULL, NULL);
 
-    bus = g_usb_device_get_bus((GUsbDevice *)device);
-    address = g_usb_device_get_address((GUsbDevice *)device);
+    bus     = libusb_get_bus_number(device);
+    address = libusb_get_device_address(device);
 
     return g_strdup_printf("USB device at %d-%d", bus, address);
 #else
-- 
1.7.7.4



More information about the Spice-devel mailing list