Send the SPICE_MSG_MAIN_AGENT_FEATURES message containing information
about enabled/disabled agent features when client connects.

Currently supported features:
 * Copy & Paste
 * File transfer

Related:
https://bugzilla.redhat.com/show_bug.cgi?id=1373725
---
 configure.ac                 |  2 +-
 server/main-channel-client.c | 32 ++++++++++++++++++++++++++++++++
 server/main-channel-client.h |  2 ++
 server/main-channel.c        |  5 +++++
 server/main-channel.h        |  1 +
 server/reds.c                | 16 ++++++++++++++++
 spice-common                 |  2 +-
 7 files changed, 58 insertions(+), 2 deletions(-)

diff --git a/configure.ac b/configure.ac
index f8284f6..71da32b 100644
--- a/configure.ac
+++ b/configure.ac
@@ -143,7 +143,7 @@ AS_IF([test x"$have_smartcard" = "xyes"], [
     AS_VAR_APPEND([SPICE_REQUIRES], [" libcacard >= 0.1.2"])
 ])
 
-SPICE_PROTOCOL_MIN_VER=0.12.12
+SPICE_PROTOCOL_MIN_VER=0.12.13
 PKG_CHECK_MODULES([SPICE_PROTOCOL], [spice-protocol >= 
$SPICE_PROTOCOL_MIN_VER])
 AC_SUBST([SPICE_PROTOCOL_MIN_VER])
 
diff --git a/server/main-channel-client.c b/server/main-channel-client.c
index 236a2e7..75c1496 100644
--- a/server/main-channel-client.c
+++ b/server/main-channel-client.c
@@ -122,6 +122,11 @@ typedef struct RedMultiMediaTimePipeItem {
     int time;
 } RedMultiMediaTimePipeItem;
 
+typedef struct RedAgentFeaturesPipeItem {
+    RedPipeItem base;
+    uint32_t flags;
+} RedAgentFeaturesPipeItem;
+
 #define ZERO_BUF_SIZE 4096
 
 static const uint8_t zero_page[ZERO_BUF_SIZE] = {0};
@@ -342,6 +347,18 @@ RedPipeItem 
*main_multi_media_time_item_new(RedChannelClient *rcc,
     return &item->base;
 }
 
+RedPipeItem *main_agent_features_item_new(RedChannelClient *rcc,
+                                          void *data, int num G_GNUC_UNUSED)
+{
+    uint32_t *flags = data;
+    RedAgentFeaturesPipeItem *item;
+
+    item = spice_malloc(sizeof(RedAgentFeaturesPipeItem));
+    red_pipe_item_init(&item->base, RED_PIPE_ITEM_TYPE_MAIN_AGENT_FEATURES);
+    item->flags = *flags;
+    return &item->base;
+}
+
 void main_channel_client_handle_migrate_connected(MainChannelClient *mcc,
                                                   int success,
                                                   int seamless)
@@ -833,6 +850,17 @@ static void 
main_channel_marshall_multi_media_time(RedChannelClient *rcc,
     spice_marshall_msg_main_multi_media_time(m, &time_mes);
 }
 
+static void main_channel_marshall_agent_features(RedChannelClient *rcc,
+                                                 SpiceMarshaller *m,
+                                                 RedAgentFeaturesPipeItem 
*item)
+{
+    SpiceMsgMainAgentFeatures agent_features_msg;
+
+    red_channel_client_init_send_data(rcc, SPICE_MSG_MAIN_AGENT_FEATURES, 
&item->base);
+    agent_features_msg.flags = item->flags;
+    spice_marshall_msg_main_agent_features(m, &agent_features_msg);
+}
+
 static void main_channel_marshall_migrate_switch(SpiceMarshaller *m, 
RedChannelClient *rcc,
                                                  RedPipeItem *item)
 {
@@ -944,6 +972,10 @@ void main_channel_client_send_item(RedChannelClient *rcc, 
RedPipeItem *base)
         case RED_PIPE_ITEM_TYPE_MAIN_AGENT_CONNECTED_TOKENS:
             main_channel_marshall_agent_connected(m, rcc, base);
             break;
+        case RED_PIPE_ITEM_TYPE_MAIN_AGENT_FEATURES:
+            main_channel_marshall_agent_features(rcc, m,
+                                                 
SPICE_UPCAST(RedAgentFeaturesPipeItem, base));
+            break;
         default:
             break;
     };
diff --git a/server/main-channel-client.h b/server/main-channel-client.h
index 9f05af3..5254916 100644
--- a/server/main-channel-client.h
+++ b/server/main-channel-client.h
@@ -89,6 +89,7 @@ enum {
     RED_PIPE_ITEM_TYPE_MAIN_NAME,
     RED_PIPE_ITEM_TYPE_MAIN_UUID,
     RED_PIPE_ITEM_TYPE_MAIN_AGENT_CONNECTED_TOKENS,
+    RED_PIPE_ITEM_TYPE_MAIN_AGENT_FEATURES,
 };
 
 typedef struct MainMouseModeItemInfo {
@@ -104,5 +105,6 @@ typedef struct MainMultiMediaTimeItemInfo {
 
 RedPipeItem *main_multi_media_time_item_new(RedChannelClient *rcc,
                                             void *data, int num);
+RedPipeItem *main_agent_features_item_new(RedChannelClient *rcc, void *data, 
int num);
 
 #endif /* __MAIN_CHANNEL_CLIENT_H__ */
diff --git a/server/main-channel.c b/server/main-channel.c
index 4670315..2cc425b 100644
--- a/server/main-channel.c
+++ b/server/main-channel.c
@@ -131,6 +131,11 @@ void main_channel_push_multi_media_time(MainChannel 
*main_chan, int time)
         main_multi_media_time_item_new, &info);
 }
 
+void main_channel_push_agent_features(MainChannel *main_chan, uint32_t flags)
+{
+    red_channel_pipes_new_add_push(&main_chan->base, 
main_agent_features_item_new, &flags);
+}
+
 static void main_channel_fill_mig_target(MainChannel *main_channel, 
RedsMigSpice *mig_target)
 {
     spice_assert(mig_target);
diff --git a/server/main-channel.h b/server/main-channel.h
index 868a14a..4a84079 100644
--- a/server/main-channel.h
+++ b/server/main-channel.h
@@ -61,6 +61,7 @@ void main_channel_push_mouse_mode(MainChannel *main_chan, int 
current_mode, int
 void main_channel_push_agent_connected(MainChannel *main_chan);
 void main_channel_push_agent_disconnected(MainChannel *main_chan);
 void main_channel_push_multi_media_time(MainChannel *main_chan, int time);
+void main_channel_push_agent_features(MainChannel *main_chan, uint32_t flags);
 int main_channel_getsockname(MainChannel *main_chan, struct sockaddr *sa, 
socklen_t *salen);
 int main_channel_getpeername(MainChannel *main_chan, struct sockaddr *sa, 
socklen_t *salen);
 
diff --git a/server/reds.c b/server/reds.c
index 800107b..742d673 100644
--- a/server/reds.c
+++ b/server/reds.c
@@ -731,8 +731,22 @@ static void reds_update_mouse_mode(RedsState *reds)
     }
 }
 
+static void reds_push_agent_features(RedsState *reds)
+{
+    if (reds->config == NULL) {
+        return;
+    }
+
+    if (reds_main_channel_connected(reds)) {
+        uint32_t flags = (reds->config->agent_copypaste ? 
SPICE_AGENT_FEATURE_COPY_PASTE : 0) |
+                         (reds->config->agent_file_xfer ? 
SPICE_AGENT_FEATURE_FILE_TRANSFER : 0);
+        main_channel_push_agent_features(reds->main_channel, flags);
+    }
+}
+
 static void reds_update_agent_properties(RedsState *reds)
 {
+    reds_push_agent_features(reds);
     if (reds->agent_dev == NULL || reds->config == NULL) {
         return;
     }
@@ -1844,6 +1858,8 @@ static void reds_handle_main_link(RedsState *reds, 
RedLinkInfo *link)
             main_channel_client_push_name(mcc, reds->config->spice_name);
         if (reds->config->spice_uuid_is_set)
             main_channel_client_push_uuid(mcc, reds->config->spice_uuid);
+        /* inform new client about agent features */
+        reds_push_agent_features(reds);
     } else {
         reds_mig_target_client_add(reds, client);
     }
diff --git a/spice-common b/spice-common
index 38047fb..ee8a6c3 160000
--- a/spice-common
+++ b/spice-common
@@ -1 +1 @@
-Subproject commit 38047fb46f7e1211bbc20d9a81c8fae19b8f8bf4
+Subproject commit ee8a6c3a98ab5aff9f54133c3ec315e5298b34cd
-- 
2.10.0

_______________________________________________
Spice-devel mailing list
Spice-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/spice-devel

Reply via email to