<div dir="ltr"><br><div class="gmail_extra"><br><div class="gmail_quote">On Fri, Jul 3, 2015 at 3:58 PM, Christophe Fergeau <span dir="ltr"><<a href="mailto:cfergeau@redhat.com" target="_blank">cfergeau@redhat.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><span class="">On Thu, Jul 02, 2015 at 04:41:33PM +0300, Kirill Moizik wrote:<br>
> 1)grey out usbredirection widget<br>
> 2)start async redirection<br>
> 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)<br>
> 4) ungrey widget<br>
<br>
</span>I'd tend to move the UI updates in a separate commit<br>
<span class=""><br>
><br>
> Signed-off-by: Kirill Moizik <<a href="mailto:kirill@daynix.com">kirill@daynix.com</a>><br>
> ---<br>
>  src/channel-usbredir.c  | 32 ++++++++++++++++++++---------<br>
>  src/usb-device-widget.c | 54 ++++++++++++++++++++++++++++++++++++++++++++-----<br>
>  2 files changed, 71 insertions(+), 15 deletions(-)<br>
><br>
> diff --git a/src/channel-usbredir.c b/src/channel-usbredir.c<br>
> index 292b82f..97003dc 100644<br>
> --- a/src/channel-usbredir.c<br>
> +++ b/src/channel-usbredir.c<br>
> @@ -308,6 +308,23 @@ static void spice_usbredir_channel_open_acl_cb(<br>
>  }<br>
>  #endif<br>
><br>
> +static void<br>
> +spice_usbredir_channel_open_device_async(GSimpleAsyncResult *simple,<br>
> +                                         GObject *object,<br>
> +                                         GCancellable *cancellable)<br>
> +{<br>
> +    GError *err = NULL;<br>
<br>
</span>This was wrapped in a #ifdef ! USE_POLKIT, any reason for dropping this?<br></blockquote><div><br></div><div>We do not need   GError *err  in this function, since before the change we were calling spice_usbredir_channel_open_device synchronously  with GError  err as output parameter, and then we  were propagating error to GSimpleAsyncResult ( g_simple_async_result_take_error() call )to deal with it in cb  after g_simple_async_result_complete_in_idle was called. After the change we are starting new thread ( g_simple_async_result_run_in_thread() call) , so error will be handled in cb as before ,  but we will provide error to GSimpleAsyncResult inside new thread.</div><div><br></div><div>PS sorry for broken Linux build, i'll do my best to send fixed version with all your comments  today</div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">
<span class=""><br>
> +    SpiceUsbredirChannel *channel= (SpiceUsbredirChannel *)object;<br>
> +    SpiceUsbredirChannelPrivate *priv = channel->priv;<br>
> +    if (!spice_usbredir_channel_open_device(channel, &err)) {<br>
> +        g_simple_async_result_take_error(simple, err);<br>
> +        libusb_unref_device(priv->device);<br>
> +        priv->device = NULL;<br>
> +        g_boxed_free(spice_usb_device_get_type(), priv->spice_device);<br>
> +        priv->spice_device = NULL;<br>
> +     }<br>
> +}<br>
<br>
</span>This is running in thread context, have you checked that this shared<br>
context (priv, channel) and all these methods are thread-safe/cannot be<br>
called concurrently to this code?<br>
<div><div class="h5"><br>
> +<br>
>  G_GNUC_INTERNAL<br>
>  void spice_usbredir_channel_connect_device_async(<br>
>                                            SpiceUsbredirChannel *channel,<br>
> @@ -319,9 +336,6 @@ void spice_usbredir_channel_connect_device_async(<br>
>  {<br>
>      SpiceUsbredirChannelPrivate *priv = channel->priv;<br>
>      GSimpleAsyncResult *result;<br>
> -#if ! USE_POLKIT<br>
> -    GError *err = NULL;<br>
> -#endif<br>
><br>
>      g_return_if_fail(SPICE_IS_USBREDIR_CHANNEL(channel));<br>
>      g_return_if_fail(device != NULL);<br>
> @@ -362,13 +376,11 @@ void spice_usbredir_channel_connect_device_async(<br>
>                                    channel);<br>
>      return;<br>
>  #else<br>
> -    if (!spice_usbredir_channel_open_device(channel, &err)) {<br>
> -        g_simple_async_result_take_error(result, err);<br>
> -        libusb_unref_device(priv->device);<br>
> -        priv->device = NULL;<br>
> -        g_boxed_free(spice_usb_device_get_type(), priv->spice_device);<br>
> -        priv->spice_device = NULL;<br>
> -    }<br>
> +    g_simple_async_result_run_in_thread(result,<br>
> +                                        spice_usbredir_channel_open_device_async,<br>
> +                                        G_PRIORITY_DEFAULT,<br>
> +                                        cancellable);<br>
> +    return;<br>
>  #endif<br>
><br>
>  done:<br>
> diff --git a/src/usb-device-widget.c b/src/usb-device-widget.c<br>
> index 1ec30e3..4c466ca 100644<br>
> --- a/src/usb-device-widget.c<br>
> +++ b/src/usb-device-widget.c<br>
> @@ -25,6 +25,7 @@<br>
>  #include "spice-client.h"<br>
>  #include "spice-marshal.h"<br>
>  #include "usb-device-widget.h"<br>
> +#include "win-usb-dev.h"<br>
><br>
>  /**<br>
>   * SECTION:usb-device-widget<br>
> @@ -52,6 +53,9 @@ static gboolean spice_usb_device_widget_update_status(gpointer user_data);<br>
>  /* ------------------------------------------------------------------ */<br>
>  /* gobject glue                                                       */<br>
><br>
> +<br>
> +static void set_sensitive_all(GtkWidget *widget, gpointer user_data);<br>
> +<br>
>  #define SPICE_USB_DEVICE_WIDGET_GET_PRIVATE(obj) \<br>
>      (G_TYPE_INSTANCE_GET_PRIVATE((obj), SPICE_TYPE_USB_DEVICE_WIDGET, \<br>
>                                   SpiceUsbDeviceWidgetPrivate))<br>
> @@ -401,6 +405,10 @@ static gboolean spice_usb_device_widget_update_status(gpointer user_data)<br>
>      SpiceUsbDeviceWidgetPrivate *priv = self->priv;<br>
><br>
>      priv->device_count = 0;<br>
> +<br>
> +    if (spice_usb_device_manager_get_redirecting(priv->manager)) {<br>
> +        return FALSE;<br>
> +    }<br>
>      gtk_container_foreach(GTK_CONTAINER(self), check_can_redirect, self);<br>
><br>
>      if (priv->err_msg) {<br>
> @@ -425,6 +433,23 @@ typedef struct _connect_cb_data {<br>
>      SpiceUsbDeviceWidget *self;<br>
>  } connect_cb_data;<br>
><br>
> +static void set_redirecting(SpiceUsbDeviceWidget *self, gboolean val)<br>
> +{<br>
> +    spice_usb_device_manager_set_redirecting(self->priv->manager , val);<br>
> +    spice_g_udev_set_redirecting(val);<br>
> +    gboolean sensitive = !val;<br>
> +    if (val == TRUE) {<br>
> +        spice_usb_device_widget_show_info_bar(self, _("Redirecting Usb Device"),<br>
> +                                     GTK_MESSAGE_INFO,<br>
> +                                     GTK_STOCK_DIALOG_INFO);<br>
> +    } else {<br>
> +        spice_g_udev_handle_device_change();<br>
> +        spice_usb_device_widget_hide_info_bar(self);<br>
> +    }<br>
> +    gtk_container_foreach(GTK_CONTAINER(self),<br>
> +                          set_sensitive_all, (gpointer) &sensitive);<br>
> +}<br>
> +<br>
>  static void connect_cb(GObject *gobject, GAsyncResult *res, gpointer user_data)<br>
>  {<br>
>      SpiceUsbDeviceManager *manager = SPICE_USB_DEVICE_MANAGER(gobject);<br>
> @@ -435,6 +460,7 @@ static void connect_cb(GObject *gobject, GAsyncResult *res, gpointer user_data)<br>
>      GError *err = NULL;<br>
>      gchar *desc;<br>
><br>
> +    set_redirecting (self,FALSE);<br>
>      spice_usb_device_manager_connect_device_finish(manager, res, &err);<br>
>      if (err) {<br>
>          device = g_object_get_data(G_OBJECT(data->check), "usb-device");<br>
> @@ -448,9 +474,9 @@ static void connect_cb(GObject *gobject, GAsyncResult *res, gpointer user_data)<br>
>          g_error_free(err);<br>
><br>
>          gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(data->check), FALSE);<br>
> -        spice_usb_device_widget_update_status(self);<br>
> -    }<br>
><br>
> +    }<br>
> +    spice_usb_device_widget_update_status(self);<br>
>      g_object_unref(data->check);<br>
>      g_object_unref(data->self);<br>
>      g_free(data);<br>
> @@ -463,11 +489,12 @@ static void checkbox_clicked_cb(GtkWidget *check, gpointer user_data)<br>
>      SpiceUsbDevice *device;<br>
><br>
>      device = g_object_get_data(G_OBJECT(check), "usb-device");<br>
> +    connect_cb_data *data = g_new(connect_cb_data, 1);<br>
> +    data->check = g_object_ref(check);<br>
> +    data->self  = g_object_ref(self);<br>
> +    set_redirecting(self, TRUE);<br>
><br>
>      if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(check))) {<br>
> -        connect_cb_data *data = g_new(connect_cb_data, 1);<br>
> -        data->check = g_object_ref(check);<br>
> -        data->self  = g_object_ref(self);<br>
>          spice_usb_device_manager_connect_device_async(priv->manager,<br>
>                                                        device,<br>
>                                                        NULL,<br>
> @@ -502,6 +529,10 @@ static void device_added_cb(SpiceUsbDeviceManager *manager,<br>
>                                                       device))<br>
>          gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check), TRUE);<br>
><br>
> +<br>
> +    if (spice_usb_device_manager_get_redirecting(priv->manager)) {<br>
> +        gtk_widget_set_sensitive(check, FALSE);<br>
> +    }<br>
>      g_object_set_data_full(<br>
>              G_OBJECT(check), "usb-device",<br>
>              g_boxed_copy(spice_usb_device_get_type(), device),<br>
> @@ -542,6 +573,19 @@ static void set_inactive_by_usb_device(GtkWidget *widget, gpointer user_data)<br>
>      }<br>
>  }<br>
><br>
> +static void set_sensitive_all(GtkWidget *widget, gpointer user_data)<br>
> +{<br>
> +    gboolean sensitive = *((gboolean *)user_data);<br>
> +    SpiceUsbDevice *device;<br>
> +    if (GTK_IS_BIN(widget)) {<br>
> +        GtkWidget *check = gtk_bin_get_child(GTK_BIN(widget));<br>
> +        device = get_usb_device(widget);<br>
> +        if (!device)<br>
> +            return; /* Non device widget, ie the info_bar */<br>
> +        gtk_widget_set_sensitive(check, sensitive);<br>
> +    }<br>
> +}<br>
> +<br>
>  static void device_error_cb(SpiceUsbDeviceManager *manager,<br>
>      SpiceUsbDevice *device, GError *err, gpointer user_data)<br>
>  {<br>
> --<br>
> 2.1.0<br>
><br>
</div></div>> _______________________________________________<br>
> Spice-devel mailing list<br>
> <a href="mailto:Spice-devel@lists.freedesktop.org">Spice-devel@lists.freedesktop.org</a><br>
> <a href="http://lists.freedesktop.org/mailman/listinfo/spice-devel" rel="noreferrer" target="_blank">http://lists.freedesktop.org/mailman/listinfo/spice-devel</a><br>
</blockquote></div><br></div></div>