Hi: I am puzzled by some functions calling in the function : "spice_usb_device_manager_initable_init"
At this block: /* 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"); ... ... libusb_free_device_list(priv->coldplug_list, 1); priv->coldplug_list = NULL; My questions are as follows: 1. Well, it seems that there are two routines to gather information of the already connected devices : "libusb_get_device_list" and " g_udev_client_query_by_subsystem " , which is the really for wok one ? "g_udev_client_query_by_subsystem" seems to be , am I right ? 2. So, the second question is, why we gather info to "priv->coldplug_list", as the codes above, it just be freed, and has never been used! *list : * I type the descriptions of these two lists, as you can see that the ids of them are very different, Why??? desc Linux 3.2.0-23-generic-pae ehci_hcd EHCI Host Controller [1d6b:0002] at 1-1 desc Linux 3.2.0-23-generic-pae uhci_hcd UHCI Host Controller [1d6b:0001] at 2-1 desc Linux 3.2.0-23-generic-pae uhci_hcd UHCI Host Controller [1d6b:0001] at 3-1 desc Linux 3.2.0-23-generic-pae uhci_hcd UHCI Host Controller [1d6b:0001] at 4-1 desc Linux 3.2.0-23-generic-pae uhci_hcd UHCI Host Controller [1d6b:0001] at 5-1 desc NEC Corp. HighSpeed Hub [0409:005a] at 1-4 desc Alcor Micro Corp. USB Hub [058f:6254] at 1-5 desc USB Keykoard [1a2c:0021] at 3-2 desc Logitech USB-PS/2 Optical Mouse [046d:c045] at 3-3 desc USB 2.0 Peripheral Switch USB 2.0 Peripheral Switch [0557:2407] at 1-6 *priv->coldplug_list : * name usb2 name 2-0:1.0 name usb3 name 3-0:1.0 name 3-1 name 3-1:1.0 name 3-1:1.1 name 3-2 name 3-2:1.0 name usb4 name 4-0:1.0 name usb5 name 5-0:1.0 name usb1 name 1-0:1.0 name 1-5 name 1-5.2 name 1-5.2:1.0 name 1-5.2:1.1 name hiddev0 name 1-5:1.0 name 1-8 name 1-8:1.0 and the codes I get the log above are attached. Thanks a lot! Looking forward to you !!! 2012/6/14 Hans de Goede <hdego...@redhat.com> > Signed-off-by: Hans de Goede <hdego...@redhat.com> > --- > doc/reference/spice-gtk-sections.txt | 2 + > gtk/map-file | 2 + > gtk/usb-device-manager.c | 130 > ++++++++++++++++++++++++++++++++-- > gtk/usb-device-manager.h | 5 ++ > 4 files changed, 132 insertions(+), 7 deletions(-) > > diff --git a/doc/reference/spice-gtk-sections.txt > b/doc/reference/spice-gtk-sections.txt > index a339d32..7eea1fb 100644 > --- a/doc/reference/spice-gtk-sections.txt > +++ b/doc/reference/spice-gtk-sections.txt > @@ -293,6 +293,8 @@ spice_usb_device_manager_disconnect_device > spice_usb_device_manager_can_redirect_device > spice_usb_device_manager_connect_device_async > spice_usb_device_manager_connect_device_finish > +spice_usb_device_manager_disable_automounting > +spice_usb_device_manager_restore_automounting > <SUBSECTION> > SpiceUsbDevice > spice_usb_device_get_description > diff --git a/gtk/map-file b/gtk/map-file > index 32ead37..dd3495c 100644 > --- a/gtk/map-file > +++ b/gtk/map-file > @@ -89,11 +89,13 @@ spice_usb_device_get_type; > spice_usb_device_manager_can_redirect_device; > spice_usb_device_manager_connect_device_async; > spice_usb_device_manager_connect_device_finish; > +spice_usb_device_manager_disable_automounting; > spice_usb_device_manager_disconnect_device; > spice_usb_device_manager_get; > spice_usb_device_manager_get_devices; > spice_usb_device_manager_get_type; > spice_usb_device_manager_is_device_connected; > +spice_usb_device_manager_restore_automounting; > spice_usb_device_widget_get_type; > spice_usb_device_widget_new; > spice_usbredir_channel_get_type; > diff --git a/gtk/usb-device-manager.c b/gtk/usb-device-manager.c > index 25cb14a..bf08b95 100644 > --- a/gtk/usb-device-manager.c > +++ b/gtk/usb-device-manager.c > @@ -34,6 +34,7 @@ > #include "usbutil.h" > #endif > > +#include "desktop-integration.h" > #include "spice-session-priv.h" > #include "spice-client.h" > #include "spice-marshal.h" > @@ -96,6 +97,8 @@ struct _SpiceUsbDeviceManagerPrivate { > libusb_device **coldplug_list; /* Avoid needless reprobing during > init */ > struct usbredirfilter_rule *auto_conn_filter_rules; > int auto_conn_filter_rules_count; > + int disable_automount; > + guint update_automount_id; > #endif > GPtrArray *devices; > GPtrArray *channels; > @@ -284,9 +287,17 @@ static void > spice_usb_device_manager_set_property(GObject *gobject, > case PROP_SESSION: > priv->session = g_value_get_object(value); > break; > - case PROP_AUTO_CONNECT: > - priv->auto_connect = g_value_get_boolean(value); > + case PROP_AUTO_CONNECT: { > + gboolean new_val = g_value_get_boolean(value); > + if (priv->auto_connect != new_val) { > + priv->auto_connect = new_val; > + if (priv->auto_connect) > + spice_usb_device_manager_disable_automounting(self); > + else > + spice_usb_device_manager_restore_automounting(self); > + } > break; > + } > case PROP_AUTO_CONNECT_FILTER: { > const gchar *filter = g_value_get_string(value); > #ifdef USE_USBREDIR > @@ -341,6 +352,15 @@ static void > spice_usb_device_manager_class_init(SpiceUsbDeviceManagerClass *klas > > /** > * SpiceUsbDeviceManager:auto-connect: > + * > + * Set this to TRUE to automatically redirect newly plugged in device. > + * > + * When this property changes from FALSE to TRUE, > #SpiceUsbDeviceManager > + * calls spice_usb_device_manager_disable_automounting() once, and on > TRUE > + * to FALSE it calls spice_usb_device_manager_restore_automounting(). > + * > + * Note when #SpiceGtkSession's auto-usbredir property is TRUE, this > + * property is controlled by #SpiceGtkSession. > */ > pspec = g_param_spec_boolean("auto-connect", "Auto Connect", > "Auto connect plugged in USB devices", > @@ -642,19 +662,33 @@ static void > spice_usb_device_manager_uevent_cb(GUdevClient *client, > spice_usb_device_manager_remove_dev(self, udevice); > } > > +struct channel_connect_cb_data { > + GSimpleAsyncResult *result; > + gboolean restore_automount; > +}; > + > static void spice_usb_device_manager_channel_connect_cb( > GObject *gobject, GAsyncResult *channel_res, gpointer user_data) > { > SpiceUsbredirChannel *channel = SPICE_USBREDIR_CHANNEL(gobject); > - GSimpleAsyncResult *result = G_SIMPLE_ASYNC_RESULT(user_data); > + struct channel_connect_cb_data *data = user_data; > + SpiceUsbDeviceManager *self; > GError *err = NULL; > > spice_usbredir_channel_connect_device_finish(channel, channel_res, > &err); > if (err) { > - g_simple_async_result_take_error(result, err); > + g_simple_async_result_take_error(data->result, err); > } > - g_simple_async_result_complete(result); > - g_object_unref(result); > + > + if (data->restore_automount) { > + self = SPICE_USB_DEVICE_MANAGER(g_async_result_get_source_object( > + > G_ASYNC_RESULT(data->result))); > + spice_usb_device_manager_restore_automounting(self); > + } > + > + g_simple_async_result_complete(data->result); > + g_object_unref(data->result); > + g_free(data); > } > > /* ------------------------------------------------------------------ */ > @@ -848,6 +882,7 @@ void > spice_usb_device_manager_connect_device_async(SpiceUsbDeviceManager *self, > > #ifdef USE_USBREDIR > SpiceUsbDeviceManagerPrivate *priv = self->priv; > + struct channel_connect_cb_data *data; > guint i; > > if (spice_usb_device_manager_is_device_connected(self, device)) { > @@ -863,11 +898,18 @@ void > spice_usb_device_manager_connect_device_async(SpiceUsbDeviceManager *self, > if (spice_usbredir_channel_get_device(channel)) > continue; /* Skip already used channels */ > > + data = g_new0(struct channel_connect_cb_data, 1); > + data->result = result; > + /* If automount is disabled, ensure it stays disabled while we > run */ > + if (priv->disable_automount) { > + spice_usb_device_manager_disable_automounting(self); > + data->restore_automount = TRUE; > + } > spice_usbredir_channel_connect_device_async(channel, > (libusb_device *)device, > cancellable, > > spice_usb_device_manager_channel_connect_cb, > - result); > + data); > return; > } > #endif > @@ -1047,3 +1089,77 @@ gchar > *spice_usb_device_get_description(SpiceUsbDevice *_device, const gchar *fo > return NULL; > #endif > } > + > +/* ------------------------------------------------------------------ */ > +/* Automount disable helper functions */ > + > +static gboolean spice_usb_device_manager_update_automount(gpointer > user_data) > +{ > + SpiceUsbDeviceManager *self = SPICE_USB_DEVICE_MANAGER(user_data); > + SpiceUsbDeviceManagerPrivate *priv = self->priv; > + SpiceDesktopIntegration *di = > spice_desktop_integration_get(priv->session); > + > + if (priv->disable_automount == 0) > + spice_desktop_integration_restore_automount(di); > + > + priv->update_automount_id = 0; > + return FALSE; > +} > + > +/** > + * spice_usb_device_manager_disable_automounting: > + * @manager: the #SpiceUsbDeviceManager manager > + * > + * Disables automounting of newly plugged in devices by the client OS, to > avoid > + * newly plugged in devices getting mounted by the client OS, before they > can > + * be redirected. > + * > + * When this function gets called multiple times, > + * spice_usb_device_manager_restore_automounting() must be called the same > + * amount of times, before automounting gets restored. > + */ > +void spice_usb_device_manager_disable_automounting(SpiceUsbDeviceManager > *self) > +{ > +#ifdef USE_USBREDIR > + SpiceUsbDeviceManagerPrivate *priv = self->priv; > + SpiceDesktopIntegration *di = > spice_desktop_integration_get(priv->session); > + > + priv->disable_automount++; > + if (priv->disable_automount == 1) > + spice_desktop_integration_disable_automount(di); > +#endif > +} > + > +/** > + * spice_usb_device_manager_restore_automounting: > + * @manager: the #SpiceUsbDeviceManager manager > + * > + * Restores automounting of newly plugged in devices by the client OS, to > its > + * original state. If it was disabled already before calling > + * spice_usb_device_manager_disable_automounting() this is a no-op. > + * > + * If spice_usb_device_manager_disable_automounting() has been called > multiple > + * times, this function will not restore automounting until it has been > called > + * the same amount of times. > + */ > +void spice_usb_device_manager_restore_automounting(SpiceUsbDeviceManager > *self) > +{ > +#ifdef USE_USBREDIR > + SpiceUsbDeviceManagerPrivate *priv = self->priv; > + > + g_return_if_fail(priv->disable_automount > 0); > + > + priv->disable_automount--; > + if (priv->disable_automount) > + return; > + > + /* > + * Re-enable automount from a timer, to avoid unnecessary ping-ponging > + * automount when switching between the windows of a multi monitor vm. > + */ > + if (priv->update_automount_id) > + g_source_remove(priv->update_automount_id); > + priv->update_automount_id = > + g_timeout_add(50, spice_usb_device_manager_update_automount, > self); > +#endif > +} > diff --git a/gtk/usb-device-manager.h b/gtk/usb-device-manager.h > index df138ee..b01fe98 100644 > --- a/gtk/usb-device-manager.h > +++ b/gtk/usb-device-manager.h > @@ -114,6 +114,11 @@ > spice_usb_device_manager_can_redirect_device(SpiceUsbDeviceManager *self, > SpiceUsbDevice > *device, > GError **err); > > +void spice_usb_device_manager_disable_automounting( > + SpiceUsbDeviceManager > *manager); > +void spice_usb_device_manager_restore_automounting( > + SpiceUsbDeviceManager > *manager); > + > G_END_DECLS > > #endif /* __SPICE_USB_DEVICE_MANAGER_H__ */ > -- > 1.7.10.2 > > _______________________________________________ > Spice-devel mailing list > Spice-devel@lists.freedesktop.org > http://lists.freedesktop.org/mailman/listinfo/spice-devel >
/* Do coldplug (detection of already connected devices) */ int cnt = 0; cnt = libusb_get_device_list(priv->context, &priv->coldplug_list); if(cnt > 0) { size_t i = 0; struct libusb_device *dev = NULL; while((dev = priv->coldplug_list[i++]) != NULL) { gchar *desc = spice_usb_device_get_description((SpiceUsbDevice *)dev, NULL); g_print(" desc %s \n", desc); } } 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_print(" name %s \n", g_udev_device_get_name(it->data)); g_object_unref(it->data); } g_list_free(list); libusb_free_device_list(priv->coldplug_list, 1); priv->coldplug_list = NULL;
_______________________________________________ Spice-devel mailing list Spice-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/spice-devel