[Spice-devel] [PATCH v2 4/6] Make start redirection asynchronous
Kirill Moizik
kirill at daynix.com
Mon Jul 6 10:59:04 PDT 2015
1)grey out usbredirection widget
2)start async redirection
3)on finish callback update state, update list of devices (we need to do it since we cant query device list while redirecting, so we could miss device changes)
4)ungrey widget
Signed-off-by: Kirill Moizik <kmoizik at redhat.com>
---
src/channel-usbredir.c | 34 ++++++++++++++++++++++++----------
src/usb-device-manager.c | 10 +++++-----
src/usb-device-widget.c | 30 +++++++++++++++++++++++++-----
3 files changed, 54 insertions(+), 20 deletions(-)
diff --git a/src/channel-usbredir.c b/src/channel-usbredir.c
index 292b82f..e7d5949 100644
--- a/src/channel-usbredir.c
+++ b/src/channel-usbredir.c
@@ -308,6 +308,25 @@ static void spice_usbredir_channel_open_acl_cb(
}
#endif
+#ifndef USE_POLKIT
+static void
+spice_usbredir_channel_open_device_async(GSimpleAsyncResult *simple,
+ GObject *object,
+ GCancellable *cancellable)
+{
+ GError *err = NULL;
+ SpiceUsbredirChannel *channel= (SpiceUsbredirChannel *)object;
+ SpiceUsbredirChannelPrivate *priv = channel->priv;
+ if (!spice_usbredir_channel_open_device(channel, &err)) {
+ g_simple_async_result_take_error(simple, err);
+ libusb_unref_device(priv->device);
+ priv->device = NULL;
+ g_boxed_free(spice_usb_device_get_type(), priv->spice_device);
+ priv->spice_device = NULL;
+ }
+}
+#endif
+
G_GNUC_INTERNAL
void spice_usbredir_channel_connect_device_async(
SpiceUsbredirChannel *channel,
@@ -319,9 +338,6 @@ void spice_usbredir_channel_connect_device_async(
{
SpiceUsbredirChannelPrivate *priv = channel->priv;
GSimpleAsyncResult *result;
-#if ! USE_POLKIT
- GError *err = NULL;
-#endif
g_return_if_fail(SPICE_IS_USBREDIR_CHANNEL(channel));
g_return_if_fail(device != NULL);
@@ -362,13 +378,11 @@ void spice_usbredir_channel_connect_device_async(
channel);
return;
#else
- if (!spice_usbredir_channel_open_device(channel, &err)) {
- g_simple_async_result_take_error(result, err);
- libusb_unref_device(priv->device);
- priv->device = NULL;
- g_boxed_free(spice_usb_device_get_type(), priv->spice_device);
- priv->spice_device = NULL;
- }
+ g_simple_async_result_run_in_thread(result,
+ spice_usbredir_channel_open_device_async,
+ G_PRIORITY_DEFAULT,
+ cancellable);
+ return;
#endif
done:
diff --git a/src/usb-device-manager.c b/src/usb-device-manager.c
index 1b334d3..c07ba03 100644
--- a/src/usb-device-manager.c
+++ b/src/usb-device-manager.c
@@ -1455,6 +1455,7 @@ gboolean spice_usb_device_manager_is_device_connected(SpiceUsbDeviceManager *sel
return !!spice_usb_device_manager_get_channel_for_dev(self, device);
}
+#ifdef USE_USBREDIR
/**
* spice_usb_device_manager_connect_device_async:
* @manager: the #SpiceUsbDeviceManager manager
@@ -1480,7 +1481,6 @@ _spice_usb_device_manager_connect_device_async(SpiceUsbDeviceManager *self,
result = g_simple_async_result_new(G_OBJECT(self), callback, user_data,
spice_usb_device_manager_connect_device_async);
-#ifdef USE_USBREDIR
SpiceUsbDeviceManagerPrivate *priv = self->priv;
libusb_device *libdev;
guint i;
@@ -1526,18 +1526,16 @@ _spice_usb_device_manager_connect_device_async(SpiceUsbDeviceManager *self,
libusb_unref_device(libdev);
return;
}
-#endif
g_simple_async_result_set_error(result,
SPICE_CLIENT_ERROR, SPICE_CLIENT_ERROR_FAILED,
_("No free USB channel"));
-#ifdef USE_USBREDIR
done:
-#endif
g_simple_async_result_complete_in_idle(result);
g_object_unref(result);
}
+#endif
void spice_usb_device_manager_connect_device_async(SpiceUsbDeviceManager *self,
SpiceUsbDevice *device,
@@ -1545,8 +1543,9 @@ void spice_usb_device_manager_connect_device_async(SpiceUsbDeviceManager *self,
GAsyncReadyCallback callback,
gpointer user_data)
{
+#ifdef USE_USBREDIR
if (self->priv->use_usbclerk) {
-#if defined(USE_USBREDIR) && defined(G_OS_WIN32)
+#ifdef G_OS_WIN32
SpiceWinUsbDriver *installer;
UsbInstallCbInfo *cbinfo;
@@ -1576,6 +1575,7 @@ void spice_usb_device_manager_connect_device_async(SpiceUsbDeviceManager *self,
callback,
user_data);
}
+#endif
}
gboolean spice_usb_device_manager_connect_device_finish(
diff --git a/src/usb-device-widget.c b/src/usb-device-widget.c
index 72f3b34..a3e89f6 100644
--- a/src/usb-device-widget.c
+++ b/src/usb-device-widget.c
@@ -26,6 +26,17 @@
#include "spice-marshal.h"
#include "usb-device-widget.h"
+#ifdef USE_USBREDIR
+#if defined(USE_GUDEV)
+#include <gudev/gudev.h>
+#elif defined(G_OS_WIN32)
+#include "win-usb-dev.h"
+#define USE_GUDEV /* win-usb-dev.h provides a fake gudev interface */
+#elif !defined USE_LIBUSB_HOTPLUG
+#error "Expecting one of USE_GUDEV or USE_LIBUSB_HOTPLUG to be defined"
+#endif
+#endif
+
/**
* SECTION:usb-device-widget
* @short_description: USB device selection widget
@@ -406,6 +417,12 @@ static gboolean spice_usb_device_widget_update_status(gpointer user_data)
SpiceUsbDeviceWidgetPrivate *priv = self->priv;
priv->device_count = 0;
+ gboolean redirecting;
+ g_object_get(priv->manager, "redirecting", &redirecting, NULL);
+
+ if (redirecting) {
+ return FALSE;
+ }
gtk_container_foreach(GTK_CONTAINER(self), check_can_redirect, self);
if (priv->err_msg) {
@@ -477,9 +494,9 @@ static void connect_cb(GObject *gobject, GAsyncResult *res, gpointer user_data)
g_error_free(err);
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(data->check), FALSE);
- spice_usb_device_widget_update_status(self);
- }
+ }
+ spice_usb_device_widget_update_status(self);
g_object_unref(data->check);
g_object_unref(data->self);
g_free(data);
@@ -492,11 +509,12 @@ static void checkbox_clicked_cb(GtkWidget *check, gpointer user_data)
SpiceUsbDevice *device;
device = g_object_get_data(G_OBJECT(check), "usb-device");
+ connect_cb_data *data = g_new(connect_cb_data, 1);
+ data->check = g_object_ref(check);
+ data->self = g_object_ref(self);
+ set_redirecting(self, TRUE);
if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(check))) {
- connect_cb_data *data = g_new(connect_cb_data, 1);
- data->check = g_object_ref(check);
- data->self = g_object_ref(self);
spice_usb_device_manager_connect_device_async(priv->manager,
device,
NULL,
@@ -521,6 +539,8 @@ static void device_added_cb(SpiceUsbDeviceManager *manager,
SpiceUsbDeviceWidgetPrivate *priv = self->priv;
GtkWidget *align, *check;
gchar *desc;
+ gboolean redirecting;
+ g_object_get(priv->manager, "redirecting", &redirecting, NULL);
desc = spice_usb_device_get_description(device,
priv->device_format_string);
--
2.1.0
More information about the Spice-devel
mailing list