[Spice-devel] [PATCH spice-gtk 7/7] Add auto_usbredir property to spice-widget

Hans de Goede hdegoede at redhat.com
Tue Aug 30 05:52:28 PDT 2011


---
 gtk/spice-widget-priv.h |    1 +
 gtk/spice-widget.c      |   38 ++++++++++++++++++++++++++++++++++++++
 gtk/spicy.c             |   41 ++++++++++++++++++++++++++++++++++++++++-
 3 files changed, 79 insertions(+), 1 deletions(-)

diff --git a/gtk/spice-widget-priv.h b/gtk/spice-widget-priv.h
index a567f1b..bd6dedb 100644
--- a/gtk/spice-widget-priv.h
+++ b/gtk/spice-widget-priv.h
@@ -51,6 +51,7 @@ struct _SpiceDisplayPrivate {
     bool                    mouse_grab_enable;
     bool                    resize_guest_enable;
     bool                    auto_clipboard_enable;
+    bool                    auto_usbredir_enable;
 
     /* state */
     enum SpiceSurfaceFmt    format;
diff --git a/gtk/spice-widget.c b/gtk/spice-widget.c
index 9ba9be0..2beea73 100644
--- a/gtk/spice-widget.c
+++ b/gtk/spice-widget.c
@@ -87,6 +87,7 @@ enum {
     PROP_MOUSE_GRAB,
     PROP_RESIZE_GUEST,
     PROP_AUTO_CLIPBOARD,
+    PROP_AUTO_USBREDIR,
     PROP_SCALING,
 };
 
@@ -117,6 +118,7 @@ static void disconnect_display(SpiceDisplay *display);
 static void channel_new(SpiceSession *s, SpiceChannel *channel, gpointer data);
 static void channel_destroy(SpiceSession *s, SpiceChannel *channel, gpointer data);
 static void sync_keyboard_lock_modifiers(SpiceDisplay *display);
+static void update_auto_usbredir(SpiceDisplay *display);
 
 /* ---------------------------------------------------------------- */
 
@@ -141,6 +143,9 @@ static void spice_display_get_property(GObject    *object,
     case PROP_AUTO_CLIPBOARD:
         g_value_set_boolean(value, d->auto_clipboard_enable);
         break;
+    case PROP_AUTO_USBREDIR:
+        g_value_set_boolean(value, d->auto_usbredir_enable);
+        break;
     case PROP_SCALING:
         g_value_set_boolean(value, d->allow_scaling);
 	break;
@@ -195,6 +200,10 @@ static void spice_display_set_property(GObject      *object,
     case PROP_AUTO_CLIPBOARD:
         d->auto_clipboard_enable = g_value_get_boolean(value);
         break;
+    case PROP_AUTO_USBREDIR:
+        d->auto_usbredir_enable = g_value_get_boolean(value);
+        update_auto_usbredir(display);
+        break;
     default:
         G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
         break;
@@ -572,6 +581,22 @@ static void recalc_geometry(GtkWidget *widget, gboolean set_display)
     }
 }
 
+static void update_auto_usbredir(SpiceDisplay *display)
+{
+    SpiceDisplayPrivate *d = SPICE_DISPLAY_GET_PRIVATE(display);
+    SpiceUsbDeviceManager *manager;
+    gboolean auto_connect = FALSE;
+
+    if (d->auto_usbredir_enable && d->keyboard_have_focus)
+        auto_connect = TRUE;
+
+    /* FIXME: allow specifying a different GMainContext then the default */
+    manager = spice_usb_device_manager_get(NULL /* FIXME */, NULL);
+    if (manager) {
+        g_object_set(manager, "auto-connect", auto_connect, NULL);
+    }
+}
+
 /* ---------------------------------------------------------------- */
 
 #define CONVERT_0565_TO_0888(s)                                         \
@@ -857,6 +882,7 @@ static gboolean focus_in_event(GtkWidget *widget, GdkEventFocus *focus G_GNUC_UN
     sync_keyboard_lock_modifiers(display);
     d->keyboard_have_focus = true;
     try_keyboard_grab(display);
+    update_auto_usbredir(display);
 #ifdef WIN32
     focus_window = GDK_WINDOW_HWND(gtk_widget_get_window(widget));
     g_return_val_if_fail(focus_window != NULL, true);
@@ -880,6 +906,7 @@ static gboolean focus_out_event(GtkWidget *widget, GdkEventFocus *focus G_GNUC_U
 
     release_keys(display);
     d->keyboard_have_focus = false;
+    update_auto_usbredir(display);
     return true;
 }
 
@@ -1299,6 +1326,17 @@ static void spice_display_class_init(SpiceDisplayClass *klass)
                               G_PARAM_STATIC_STRINGS));
 
     g_object_class_install_property
+        (gobject_class, PROP_AUTO_USBREDIR,
+         g_param_spec_boolean("auto-usbredir",
+                              "Auto USB Redirection",
+                              "Automatically redirect newly plugged in USB"
+                              "Devices to the guest.",
+                              TRUE,
+                              G_PARAM_READWRITE |
+                              G_PARAM_CONSTRUCT |
+                              G_PARAM_STATIC_STRINGS));
+
+    g_object_class_install_property
         (gobject_class, PROP_SCALING,
          g_param_spec_boolean("scaling", "Scaling",
                               "Whether we should use scaling",
diff --git a/gtk/spicy.c b/gtk/spicy.c
index a954085..761e056 100644
--- a/gtk/spicy.c
+++ b/gtk/spicy.c
@@ -686,7 +686,10 @@ static const char *spice_properties[] = {
     "grab-mouse",
     "resize-guest",
     "scaling",
-    "auto-clipboard"
+    "auto-clipboard",
+#ifdef USE_USBREDIR
+    "auto-usbredir",
+#endif
 };
 
 static const GtkToggleActionEntry tentries[] = {
@@ -711,6 +714,12 @@ static const GtkToggleActionEntry tentries[] = {
         .label       = N_("Automagic clipboard sharing between host and guest"),
         .callback    = G_CALLBACK(menu_cb_bool_prop),
     },{
+#ifdef USE_USBREDIR
+        .name        = "auto-usbredir",
+        .label       = N_("Auto redirect newly plugged in USB devices"),
+        .callback    = G_CALLBACK(menu_cb_bool_prop),
+    },{
+#endif
         .name        = "Statusbar",
         .label       = N_("Statusbar"),
         .callback    = G_CALLBACK(menu_cb_statusbar),
@@ -752,6 +761,9 @@ static char ui_xml[] =
 "      <menuitem action='resize-guest'/>\n"
 "      <menuitem action='scaling'/>\n"
 "      <menuitem action='auto-clipboard'/>\n"
+#ifdef USE_USBREDIR
+"      <menuitem action='auto-usbredir'/>\n"
+#endif
 "    </menu>\n"
 "    <menu action='HelpMenu'>\n"
 "      <menuitem action='About'/>\n"
@@ -1304,6 +1316,24 @@ static void display_mark(SpiceChannel *channel, gint mark, spice_window *win)
     }
 }
 
+static void update_auto_usbredir_sensitive(spice_connection *conn)
+{
+#ifdef USE_USBREDIR
+    int i;
+    GtkAction *ac;
+    gboolean sensitive;
+
+    sensitive = spice_session_has_channel_type(conn->session,
+                                               SPICE_CHANNEL_USBREDIR);
+    for (i = 0; i < SPICE_N_ELEMENTS(conn->wins); i++) {
+        if (conn->wins[i] == NULL)
+            continue;
+        ac = gtk_action_group_get_action(conn->wins[i]->ag, "auto-usbredir");
+        gtk_action_set_sensitive(ac, sensitive);
+    }
+#endif
+}
+
 static void channel_new(SpiceSession *s, SpiceChannel *channel, gpointer data)
 {
     spice_connection *conn = data;
@@ -1334,6 +1364,7 @@ static void channel_new(SpiceSession *s, SpiceChannel *channel, gpointer data)
         conn->wins[id] = create_spice_window(conn, id, channel);
         g_signal_connect(channel, "display-mark",
                          G_CALLBACK(display_mark), conn->wins[id]);
+        update_auto_usbredir_sensitive(conn);
     }
 
     if (SPICE_IS_INPUTS_CHANNEL(channel)) {
@@ -1348,6 +1379,10 @@ static void channel_new(SpiceSession *s, SpiceChannel *channel, gpointer data)
         SPICE_DEBUG("new audio channel");
         conn->audio = spice_audio_new(s, NULL, NULL);
     }
+
+    if (SPICE_IS_USBREDIR_CHANNEL(channel)) {
+        update_auto_usbredir_sensitive(conn);
+    }
 }
 
 static void channel_destroy(SpiceSession *s, SpiceChannel *channel, gpointer data)
@@ -1378,6 +1413,10 @@ static void channel_destroy(SpiceSession *s, SpiceChannel *channel, gpointer dat
         }
     }
 
+    if (SPICE_IS_USBREDIR_CHANNEL(channel)) {
+        update_auto_usbredir_sensitive(conn);
+    }
+
     conn->channels--;
     if (conn->channels > 0) {
         return;
-- 
1.7.6.1



More information about the Spice-devel mailing list