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

Christophe Fergeau cfergeau at redhat.com
Fri Dec 23 10:07:40 PST 2011


On Mon, Dec 19, 2011 at 12:24:42PM +0100, Hans de Goede wrote:
> 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.

Ah, I was starting to worry about the libusb/gusb mix in the code, and
about embedding a copy of gusb instead of using the system one, so ACK on
this one even though I haven't looked at it carefully

Christophe
> 
> 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
> 
> _______________________________________________
> Spice-devel mailing list
> Spice-devel at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/spice-devel
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 198 bytes
Desc: not available
URL: <http://lists.freedesktop.org/archives/spice-devel/attachments/20111223/2d9f066c/attachment-0001.pgp>


More information about the Spice-devel mailing list