[Spice-devel] [PATCH spice-gtk] main: Handle agent features message

Pavel Grunt pgrunt at redhat.com
Thu Sep 15 10:09:00 UTC 2016


The message indicates that some agent features are enabled or disabled.
Currently supported features:
 * Copy & Paste
 * File transfer

It allows to avoid sending unnecessary agent messages.

For compatibility reason all the features are considered enabled by default

Resolves:
https://bugzilla.redhat.com/show_bug.cgi?id=1373725
---
 configure.ac       |  2 +-
 spice-common       |  2 +-
 src/channel-main.c | 51 +++++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 53 insertions(+), 2 deletions(-)

diff --git a/configure.ac b/configure.ac
index f3e7f8d..aa60e91 100644
--- a/configure.ac
+++ b/configure.ac
@@ -69,7 +69,7 @@ AC_CHECK_LIBM
 AC_SUBST(LIBM)
 
 AC_CONFIG_SUBDIRS([spice-common])
-PKG_CHECK_MODULES([SPICE_PROTOCOL], [spice-protocol >= 0.12.12])
+PKG_CHECK_MODULES([SPICE_PROTOCOL], [spice-protocol >= 0.12.13])
 
 COMMON_CFLAGS='-I${top_builddir}/spice-common/ -I${top_srcdir}/spice-common/ ${SPICE_PROTOCOL_CFLAGS}'
 AC_SUBST(COMMON_CFLAGS)
diff --git a/spice-common b/spice-common
index 62f3024..ee8a6c3 160000
--- a/spice-common
+++ b/spice-common
@@ -1 +1 @@
-Subproject commit 62f3024f4220766761269618bf3df143ff5c9956
+Subproject commit ee8a6c3a98ab5aff9f54133c3ec315e5298b34cd
diff --git a/src/channel-main.c b/src/channel-main.c
index 990a06a..341df4f 100644
--- a/src/channel-main.c
+++ b/src/channel-main.c
@@ -105,6 +105,7 @@ struct _SpiceMainChannelPrivate  {
     guint                       agent_msg_pos;
     uint8_t                     agent_msg_size;
     uint32_t                    agent_caps[VD_AGENT_CAPS_SIZE];
+    uint32_t                    agent_features;
     SpiceDisplayConfig          display[MAX_DISPLAY];
     gint                        timer_id;
     GQueue                      *agent_msg_queue;
@@ -447,6 +448,7 @@ static void spice_main_constructed(GObject *object)
 
     /* update default value */
     c->max_clipboard = spice_main_get_max_clipboard(self);
+    c->agent_features = SPICE_AGENT_FEATURES_FLAGS_MASK;
 
     if (G_OBJECT_CLASS(spice_main_channel_parent_class)->constructed)
         G_OBJECT_CLASS(spice_main_channel_parent_class)->constructed(object);
@@ -2099,6 +2101,17 @@ static void main_handle_agent_token(SpiceChannel *channel, SpiceMsgIn *in)
     agent_send_msg_queue(SPICE_MAIN_CHANNEL(channel));
 }
 
+/* coroutine context */
+static void main_handle_agent_features(SpiceChannel *channel, SpiceMsgIn *in)
+{
+    SpiceMsgMainAgentFeatures *features = spice_msg_in_parsed(in);
+    SpiceMainChannelPrivate *c = SPICE_MAIN_CHANNEL(channel)->priv;
+
+    CHANNEL_DEBUG(channel, "received agent features: %x", features->flags);
+
+    c->agent_features = features->flags;
+}
+
 /* main context */
 static void migrate_channel_new_cb(SpiceSession *s, SpiceChannel *channel, gpointer data)
 {
@@ -2490,6 +2503,7 @@ static void channel_set_handlers(SpiceChannelClass *klass)
         [ SPICE_MSG_MAIN_AGENT_DISCONNECTED ]  = main_handle_agent_disconnected,
         [ SPICE_MSG_MAIN_AGENT_DATA ]          = main_handle_agent_data,
         [ SPICE_MSG_MAIN_AGENT_TOKEN ]         = main_handle_agent_token,
+        [ SPICE_MSG_MAIN_AGENT_FEATURES ]      = main_handle_agent_features,
 
         [ SPICE_MSG_MAIN_MIGRATE_BEGIN ]       = main_handle_migrate_begin,
         [ SPICE_MSG_MAIN_MIGRATE_END ]         = main_handle_migrate_end,
@@ -2636,9 +2650,16 @@ void spice_main_clipboard_grab(SpiceMainChannel *channel, guint32 *types, int nt
 void spice_main_clipboard_selection_grab(SpiceMainChannel *channel, guint selection,
                                          guint32 *types, int ntypes)
 {
+    SpiceMainChannelPrivate *c;
     g_return_if_fail(channel != NULL);
     g_return_if_fail(SPICE_IS_MAIN_CHANNEL(channel));
 
+    c = channel->priv;
+    if (!(c->agent_features & SPICE_AGENT_FEATURE_COPY_PASTE)) {
+        CHANNEL_DEBUG(channel, "Copy & Paste feature is disabled");
+        return;
+    }
+
     agent_clipboard_grab(channel, selection, types, ntypes);
     spice_channel_wakeup(SPICE_CHANNEL(channel), FALSE);
 }
@@ -2677,6 +2698,11 @@ void spice_main_clipboard_selection_release(SpiceMainChannel *channel, guint sel
     if (!c->agent_connected)
         return;
 
+    if (!(c->agent_features & SPICE_AGENT_FEATURE_COPY_PASTE)) {
+        CHANNEL_DEBUG(channel, "Copy & Paste feature is disabled");
+        return;
+    }
+
     agent_clipboard_release(channel, selection);
     spice_channel_wakeup(SPICE_CHANNEL(channel), FALSE);
 }
@@ -2714,9 +2740,16 @@ void spice_main_clipboard_notify(SpiceMainChannel *channel,
 void spice_main_clipboard_selection_notify(SpiceMainChannel *channel, guint selection,
                                            guint32 type, const guchar *data, size_t size)
 {
+    SpiceMainChannelPrivate *c;
     g_return_if_fail(channel != NULL);
     g_return_if_fail(SPICE_IS_MAIN_CHANNEL(channel));
 
+    c = channel->priv;
+    if (!(c->agent_features & SPICE_AGENT_FEATURE_COPY_PASTE)) {
+        CHANNEL_DEBUG(channel, "Copy & Paste feature is disabled");
+        return;
+    }
+
     agent_clipboard_notify(channel, selection, type, data, size);
     spice_channel_wakeup(SPICE_CHANNEL(channel), FALSE);
 }
@@ -2749,9 +2782,16 @@ void spice_main_clipboard_request(SpiceMainChannel *channel, guint32 type)
  **/
 void spice_main_clipboard_selection_request(SpiceMainChannel *channel, guint selection, guint32 type)
 {
+    SpiceMainChannelPrivate *c;
     g_return_if_fail(channel != NULL);
     g_return_if_fail(SPICE_IS_MAIN_CHANNEL(channel));
 
+    c = channel->priv;
+    if (!(c->agent_features & SPICE_AGENT_FEATURE_COPY_PASTE)) {
+        CHANNEL_DEBUG(channel, "Copy & Paste feature is disabled");
+        return;
+    }
+
     agent_clipboard_request(channel, selection, type);
     spice_channel_wakeup(SPICE_CHANNEL(channel), FALSE);
 }
@@ -3073,6 +3113,17 @@ void spice_main_file_copy_async(SpiceMainChannel *channel,
     g_return_if_fail(sources != NULL);
 
     c = channel->priv;
+    if (!(c->agent_features & SPICE_AGENT_FEATURE_FILE_TRANSFER)) {
+        g_task_report_new_error(channel,
+                                callback,
+                                user_data,
+                                spice_main_file_copy_async,
+                                SPICE_CLIENT_ERROR,
+                                SPICE_CLIENT_ERROR_FAILED,
+                                "The file transfer is disabled on the SPICE server");
+        return;
+    }
+
     if (!c->agent_connected) {
         g_task_report_new_error(channel,
                                 callback,
-- 
2.10.0



More information about the Spice-devel mailing list