[Spice-commits] Branch 'vdiport_separation' - 7 commits - server/reds.c server/reds-private.h server/vdi.c server/vdi.h

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Sat Feb 9 07:41:19 UTC 2019


 server/reds-private.h |    1 
 server/reds.c         |  133 +++++++++++--------------------------------
 server/vdi.c          |  154 ++++++++++++++++++++++++++++++++++++--------------
 server/vdi.h          |    1 
 4 files changed, 149 insertions(+), 140 deletions(-)

New commits:
commit c51b40211df88db11be98214e726c7d23cf601a5
Author: Frediano Ziglio <fziglio at redhat.com>
Date:   Sat Feb 9 07:20:47 2019 +0000

    COMMENTS

diff --git a/server/vdi.c b/server/vdi.c
index c7e6c132..e1cc496b 100644
--- a/server/vdi.c
+++ b/server/vdi.c
@@ -218,6 +218,7 @@ static RedPipeItem *vdi_port_read_one_msg_from_device(RedCharDevice *self,
 
     reds = red_char_device_get_server(self);
 // XXX    g_assert(RED_CHAR_DEVICE(reds->agent_dev) == sin->st);
+// XXX why reds_get_vdagent ?? maybe move the field ??
     SpiceCharDeviceInstance *vdagent = reds_get_vdagent(reds);
     if (!vdagent) {
         return NULL;
@@ -759,6 +760,7 @@ void vdi_reset(RedCharDeviceVDIPort *dev)
     red_char_device_reset(char_dev);
     red_char_device_reset_dev_instance(char_dev, NULL);
 
+    // XXX this value should be the previous "sin" !!!
     SpiceCharDeviceInstance *vdagent = reds_get_vdagent(reds);
     sif = spice_char_device_get_interface(vdagent);
     if (sif->state) {
commit badb29c185f5e6f6a3c84cb6c98e08ae518bba9b
Author: Frediano Ziglio <fziglio at redhat.com>
Date:   Sat Feb 9 07:11:23 2019 +0000

    MOVE reds_send_device_display_info here

diff --git a/server/reds-private.h b/server/reds-private.h
index e295295c..7159c62a 100644
--- a/server/reds-private.h
+++ b/server/reds-private.h
@@ -80,7 +80,6 @@ struct RedsState {
     SpiceWatch *listen_watch;
     SpiceWatch *secure_listen_watch;
     RedCharDeviceVDIPort *agent_dev;
-    bool pending_device_display_info_message;
     GList *clients;
     MainChannel *main_channel;
     InputsChannel *inputs_channel;
diff --git a/server/reds.c b/server/reds.c
index c465ec08..6215e6a3 100644
--- a/server/reds.c
+++ b/server/reds.c
@@ -557,20 +557,14 @@ void reds_agent_remove(RedsState *reds)
     }
 }
 
-void reds_send_device_display_info(RedsState *reds)
+// XXX put in header
+void reds_marshall_device_display_info(RedsState *reds, SpiceMarshaller *m);
+void reds_marshall_device_display_info(RedsState *reds, SpiceMarshaller *m)
 {
-#if 0
-    if (!reds->agent_dev->priv->agent_attached) {
-        return;
-    }
-    g_debug("Sending device display info to the agent:");
-
     QXLInstance *qxl;
     RedCharDevice *dev;
 
     void *device_count_ptr = spice_marshaller_add_uint32(m, 0);
-    size_t message_size = sizeof(VDAgentGraphicsDeviceInfo);
-    SpiceMarshaller *m = spice_marshaller_new();
     uint32_t device_count = 0;
 
     // add the qxl devices to the message
@@ -627,34 +621,6 @@ void reds_send_device_display_info(RedsState *reds)
         }
     }
     spice_marshaller_set_uint32(m, device_count_ptr, device_count);
-    message_size += spice_marshaller_get_total_size(m);
-
-    RedCharDeviceWriteBuffer *char_dev_buf = vdagent_new_write_buffer(reds->agent_dev,
-                                         VD_AGENT_GRAPHICS_DEVICE_INFO,
-                                         message_size,
-                                         true);
-
-    if (!char_dev_buf) {
-        reds->pending_device_display_info_message = true;
-        return;
-    }
-
-    VDInternalBuf *internal_buf = (VDInternalBuf *)char_dev_buf->buf;
-    VDAgentGraphicsDeviceInfo *graphics_device_info = &internal_buf->u.graphics_device_info;
-    graphics_device_info->count = GUINT32_TO_LE(device_count);
-
-    int free_info;
-    size_t len_info;
-    uint8_t *info = spice_marshaller_linearize(m, 0, &len_info, &free_info);
-    memcpy(graphics_device_info->display_info, info, len_info);
-    if (free_info) {
-        free(info);
-    }
-
-    reds->pending_device_display_info_message = false;
-
-    red_char_device_write_buffer_add(RED_CHAR_DEVICE(reds->agent_dev), char_dev_buf);
-#endif
 }
 
 /****************************************************************************/
diff --git a/server/vdi.c b/server/vdi.c
index 59e0f28a..c7e6c132 100644
--- a/server/vdi.c
+++ b/server/vdi.c
@@ -34,14 +34,14 @@
 // XXX declaration to make code happy
 struct RedsState {
     RedCharDeviceVDIPort *agent_dev;
-    // should be moved to RedCharDeviceVDIPortPrivate
-    bool pending_device_display_info_message;
 };
 
 SpiceCharDeviceInstance *reds_get_vdagent(RedsState *reds);
+// the name of this seems to indicate should be in this file...
 void reds_agent_remove(RedsState *reds);
 gboolean reds_use_client_monitors_config(RedsState *reds);
 void reds_client_monitors_config(RedsState *reds, VDAgentMonitorsConfig *monitors_config);
+void reds_marshall_device_display_info(RedsState *reds, SpiceMarshaller *m);
 // XXX finish
 
 #define REDS_TOKENS_TO_SEND 5
@@ -100,6 +100,7 @@ struct RedCharDeviceVDIPortPrivate {
      * client, being passed to the guest */
     SpiceBuffer client_monitors_config;
     VDAgentMouseState *pending_mouse_state;
+    bool pending_device_display_info_message;
 };
 
 G_DEFINE_TYPE_WITH_PRIVATE(RedCharDeviceVDIPort, red_char_device_vdi_port, RED_TYPE_CHAR_DEVICE)
@@ -391,7 +392,7 @@ static void vdi_port_on_free_self_token(RedCharDevice *self)
         reds_handle_agent_mouse_event(reds, &pending_mouse_state);
     }
 
-    if (reds->pending_device_display_info_message) {
+    if (dev->priv->pending_device_display_info_message) {
         spice_debug("pending device display info message");
         reds_send_device_display_info(reds);
     }
@@ -527,6 +528,7 @@ int vdi_agent_state_restore(RedCharDeviceVDIPort *agent_dev, SpiceMigrateDataMai
     return red_char_device_restore(RED_CHAR_DEVICE(agent_dev), &mig_data->agent_base);
 }
 
+// XXX reds_
 /*
  * Push partial agent data, even if not all the chunk was consumend,
  * in order to avoid the roundtrip (src-server->client->dest-server)
@@ -630,6 +632,7 @@ overflow:
     spice_buffer_free(cmc);
 }
 
+// XXX reds_
 void reds_on_main_agent_data(RedsState *reds, MainChannelClient *mcc, const void *message,
                              size_t size)
 {
@@ -915,4 +918,45 @@ void vdi_update_filters(RedCharDeviceVDIPort *dev, bool clipboard_enabled, bool
     dev->priv->read_filter.file_xfer_enabled = xfer_enabled;
 }
 
+// XXX stll reds_
+// maybe reds should pass the marshaller directly and
+// we should save the message like for the mouse ?
+void reds_send_device_display_info(RedsState *reds)
+{
+    RedCharDeviceVDIPort *dev = reds->agent_dev;
+    if (!dev->priv->agent_attached) {
+        return;
+    }
+    g_debug("Sending device display info to the agent:");
+
+    SpiceMarshaller *m = spice_marshaller_new();
+    reds_marshall_device_display_info(reds, m);
+
+    RedCharDeviceWriteBuffer *char_dev_buf = vdagent_new_write_buffer(dev,
+                                         VD_AGENT_GRAPHICS_DEVICE_INFO,
+                                         spice_marshaller_get_total_size(m),
+                                         true);
+
+    if (!char_dev_buf) {
+        spice_marshaller_destroy(m);
+        dev->priv->pending_device_display_info_message = true;
+        return;
+    }
+
+    VDInternalBuf *internal_buf = (VDInternalBuf *)char_dev_buf->buf;
+
+    int free_info;
+    size_t len_info;
+    uint8_t *info = spice_marshaller_linearize(m, 0, &len_info, &free_info);
+    memcpy(&internal_buf->u.graphics_device_info, info, len_info);
+    if (free_info) {
+        free(info);
+    }
+    spice_marshaller_destroy(m);
+
+    dev->priv->pending_device_display_info_message = false;
+
+    red_char_device_write_buffer_add(RED_CHAR_DEVICE(dev), char_dev_buf);
+}
+
 // TODO look as XXX comments
commit a1f5e4e0add6c9a8331d59333ea4f57a22abe10d
Author: Frediano Ziglio <fziglio at redhat.com>
Date:   Sat Feb 9 07:10:37 2019 +0000

    XXX merge to previous patch
    
    TODO, factor out a function, add the previous decouple test
    TODO release marshaller
    TODO better message_size, remove

diff --git a/server/reds.c b/server/reds.c
index 60a58410..c465ec08 100644
--- a/server/reds.c
+++ b/server/reds.c
@@ -568,11 +568,12 @@ void reds_send_device_display_info(RedsState *reds)
     QXLInstance *qxl;
     RedCharDevice *dev;
 
+    void *device_count_ptr = spice_marshaller_add_uint32(m, 0);
     size_t message_size = sizeof(VDAgentGraphicsDeviceInfo);
     SpiceMarshaller *m = spice_marshaller_new();
     uint32_t device_count = 0;
 
-    // size for the qxl device info
+    // add the qxl devices to the message
     FOREACH_QXL_INSTANCE(reds, qxl) {
         const char *const device_address = red_qxl_get_device_address(qxl);
         const size_t device_address_len = strlen(device_address) + 1;
@@ -594,7 +595,7 @@ void reds_send_device_display_info(RedsState *reds)
         }
     }
 
-    // size for the stream device info
+    // add the stream devices to the message
     GLIST_FOREACH(reds->char_devices, RedCharDevice, dev) {
         if (IS_STREAM_DEVICE(dev)) {
             StreamDevice *stream_dev = STREAM_DEVICE(dev);
@@ -625,6 +626,7 @@ void reds_send_device_display_info(RedsState *reds)
                     info->device_display_id);
         }
     }
+    spice_marshaller_set_uint32(m, device_count_ptr, device_count);
     message_size += spice_marshaller_get_total_size(m);
 
     RedCharDeviceWriteBuffer *char_dev_buf = vdagent_new_write_buffer(reds->agent_dev,
commit aa4d89bd8ac2771bfb3daac3960cea08626a21aa
Author: Frediano Ziglio <fziglio at redhat.com>
Date:   Fri Feb 8 11:48:23 2019 +0000

    XXX reduce code duplication

diff --git a/server/reds.c b/server/reds.c
index 8a18a2f7..60a58410 100644
--- a/server/reds.c
+++ b/server/reds.c
@@ -569,78 +569,39 @@ void reds_send_device_display_info(RedsState *reds)
     RedCharDevice *dev;
 
     size_t message_size = sizeof(VDAgentGraphicsDeviceInfo);
+    SpiceMarshaller *m = spice_marshaller_new();
+    uint32_t device_count = 0;
 
     // size for the qxl device info
     FOREACH_QXL_INSTANCE(reds, qxl) {
-        message_size +=
-            (sizeof(VDAgentDeviceDisplayInfo) + strlen(red_qxl_get_device_address(qxl)) + 1) *
-            red_qxl_get_monitors_count(qxl);
-    }
-
-    // size for the stream device info
-    GLIST_FOREACH(reds->char_devices, RedCharDevice, dev) {
-        if (IS_STREAM_DEVICE(dev)) {
-            size_t device_address_len =
-                strlen(stream_device_get_device_display_info(STREAM_DEVICE(dev))->device_address);
-
-            if (device_address_len == 0) {
-                // the device info wasn't set (yet), don't send it
-                continue;
-            }
-
-            message_size += (sizeof(VDAgentDeviceDisplayInfo) + device_address_len + 1);
+        const char *const device_address = red_qxl_get_device_address(qxl);
+        const size_t device_address_len = strlen(device_address) + 1;
+        if (device_address_len == 1) {
+            continue;
         }
-    }
-
-    RedCharDeviceWriteBuffer *char_dev_buf = vdagent_new_write_buffer(reds->agent_dev,
-                                         VD_AGENT_GRAPHICS_DEVICE_INFO,
-                                         message_size,
-                                         true);
-
-    if (!char_dev_buf) {
-        reds->pending_device_display_info_message = true;
-        return;
-    }
-
-    VDInternalBuf *internal_buf = (VDInternalBuf *)char_dev_buf->buf;
-    VDAgentGraphicsDeviceInfo *graphics_device_info = &internal_buf->u.graphics_device_info;
-    graphics_device_info->count = 0;
-
-    VDAgentDeviceDisplayInfo *device_display_info = graphics_device_info->display_info;
-
-    // add the qxl devices to the message
-    FOREACH_QXL_INSTANCE(reds, qxl) {
         for (size_t i = 0; i < red_qxl_get_monitors_count(qxl); ++i) {
-            device_display_info->channel_id = qxl->id;
-            device_display_info->monitor_id = i;
-            device_display_info->device_display_id = red_qxl_get_device_display_ids(qxl)[i];
-
-            strcpy((char*) device_display_info->device_address, red_qxl_get_device_address(qxl));
+            spice_marshaller_add_uint32(m, qxl->id);
+            spice_marshaller_add_uint32(m, i);
+            spice_marshaller_add_uint32(m, red_qxl_get_device_display_ids(qxl)[i]);
+            spice_marshaller_add_uint32(m, device_address_len);
+            spice_marshaller_add(m, (void*) device_address, device_address_len);
+            ++device_count;
 
-            device_display_info->device_address_len =
-                strlen((char*) device_display_info->device_address) + 1;
-
-            g_debug("   (qxl)    channel_id: %u monitor_id: %u, device_address: %s, device_display_id: %u",
-                    device_display_info->channel_id,
-                    device_display_info->monitor_id,
-                    device_display_info->device_address,
-                    device_display_info->device_display_id);
-
-            device_display_info = (VDAgentDeviceDisplayInfo*) ((char*) device_display_info +
-                    sizeof(VDAgentDeviceDisplayInfo) + device_display_info->device_address_len);
-
-            graphics_device_info->count++;
+            g_debug("   (qxl)    channel_id: %u monitor_id: %zu, device_address: %s, "
+                    "device_display_id: %u",
+                    qxl->id, i, device_address,
+                    red_qxl_get_device_display_ids(qxl)[i]);
         }
     }
 
-    // add the stream devices to the message
+    // size for the stream device info
     GLIST_FOREACH(reds->char_devices, RedCharDevice, dev) {
         if (IS_STREAM_DEVICE(dev)) {
             StreamDevice *stream_dev = STREAM_DEVICE(dev);
             const StreamDeviceDisplayInfo *info = stream_device_get_device_display_info(stream_dev);
-            size_t device_address_len = strlen(info->device_address);
+            size_t device_address_len = strlen(info->device_address) + 1;
 
-            if (device_address_len == 0) {
+            if (device_address_len == 1) {
                 // the device info wasn't set (yet), don't send it
                 continue;
             }
@@ -651,24 +612,41 @@ void reds_send_device_display_info(RedsState *reds)
                 continue;
             }
 
-            device_display_info->channel_id = channel_id;
-            device_display_info->monitor_id = info->stream_id;
-            device_display_info->device_display_id = info->device_display_id;
+            spice_marshaller_add_uint32(m, channel_id);
+            spice_marshaller_add_uint32(m, info->stream_id);
+            spice_marshaller_add_uint32(m, info->device_display_id);
+            spice_marshaller_add_uint32(m, device_address_len);
+            spice_marshaller_add(m, (void*) info->device_address, device_address_len);
+            ++device_count;
 
-            strcpy((char*) device_display_info->device_address, info->device_address);
-            device_display_info->device_address_len = device_address_len + 1;
+            g_debug("   (stream) channel_id: %u monitor_id: %u, device_address: %s, "
+                    "device_display_id: %u",
+                    channel_id, info->stream_id, info->device_address,
+                    info->device_display_id);
+        }
+    }
+    message_size += spice_marshaller_get_total_size(m);
 
-            g_debug("   (stream) channel_id: %u monitor_id: %u, device_address: %s, device_display_id: %u",
-                    device_display_info->channel_id,
-                    device_display_info->monitor_id,
-                    device_display_info->device_address,
-                    device_display_info->device_display_id);
+    RedCharDeviceWriteBuffer *char_dev_buf = vdagent_new_write_buffer(reds->agent_dev,
+                                         VD_AGENT_GRAPHICS_DEVICE_INFO,
+                                         message_size,
+                                         true);
 
-            device_display_info = (VDAgentDeviceDisplayInfo*) ((char*) device_display_info +
-                    sizeof(VDAgentDeviceDisplayInfo) + device_display_info->device_address_len);
+    if (!char_dev_buf) {
+        reds->pending_device_display_info_message = true;
+        return;
+    }
 
-            graphics_device_info->count++;
-        }
+    VDInternalBuf *internal_buf = (VDInternalBuf *)char_dev_buf->buf;
+    VDAgentGraphicsDeviceInfo *graphics_device_info = &internal_buf->u.graphics_device_info;
+    graphics_device_info->count = GUINT32_TO_LE(device_count);
+
+    int free_info;
+    size_t len_info;
+    uint8_t *info = spice_marshaller_linearize(m, 0, &len_info, &free_info);
+    memcpy(graphics_device_info->display_info, info, len_info);
+    if (free_info) {
+        free(info);
     }
 
     reds->pending_device_display_info_message = false;
commit d7f5c6e5183a5e45466723a1077d58d1c5e75c07
Author: Frediano Ziglio <fziglio at redhat.com>
Date:   Sat Feb 9 06:34:51 2019 +0000

    SAVE remove inputs_channel dependency
    
    only needed to save mouse state, not hard to store all state

diff --git a/server/vdi.c b/server/vdi.c
index dbbac41d..59e0f28a 100644
--- a/server/vdi.c
+++ b/server/vdi.c
@@ -34,8 +34,8 @@
 // XXX declaration to make code happy
 struct RedsState {
     RedCharDeviceVDIPort *agent_dev;
+    // should be moved to RedCharDeviceVDIPortPrivate
     bool pending_device_display_info_message;
-    InputsChannel *inputs_channel;
 };
 
 SpiceCharDeviceInstance *reds_get_vdagent(RedsState *reds);
@@ -99,7 +99,7 @@ struct RedCharDeviceVDIPortPrivate {
     /* Intermediate state for on going monitors config message from a single
      * client, being passed to the guest */
     SpiceBuffer client_monitors_config;
-    bool pending_mouse_event;
+    VDAgentMouseState *pending_mouse_state;
 };
 
 G_DEFINE_TYPE_WITH_PRIVATE(RedCharDeviceVDIPort, red_char_device_vdi_port, RED_TYPE_CHAR_DEVICE)
@@ -333,6 +333,7 @@ red_char_device_vdi_port_finalize(GObject *object)
 {
     RedCharDeviceVDIPort *dev = RED_CHAR_DEVICE_VDIPORT(object);
 
+    g_clear_pointer(&dev->priv->pending_mouse_state, g_free);
     spice_buffer_free(&dev->priv->client_monitors_config);
 
     /* make sure we have no other references to RedVDIReadBuf buffers */
@@ -382,9 +383,12 @@ static void vdi_port_on_free_self_token(RedCharDevice *self)
     RedsState *reds = red_char_device_get_server(self);
     RedCharDeviceVDIPort *dev = RED_CHAR_DEVICE_VDIPORT(self);
 
-    if (reds->inputs_channel && dev->priv->pending_mouse_event) {
+    if (dev->priv->pending_mouse_state != NULL) {
         spice_debug("pending mouse event");
-        reds_handle_agent_mouse_event(reds, inputs_channel_get_mouse_state(reds->inputs_channel));
+        // detach from the object to avoid possible double free
+        VDAgentMouseState pending_mouse_state = *dev->priv->pending_mouse_state;
+        g_clear_pointer(&dev->priv->pending_mouse_state, g_free);
+        reds_handle_agent_mouse_event(reds, &pending_mouse_state);
     }
 
     if (reds->pending_device_display_info_message) {
@@ -687,10 +691,11 @@ static RedCharDeviceWriteBuffer *vdagent_new_write_buffer(RedCharDeviceVDIPort *
     return char_dev_buf;
 }
 
+// XXX rename? still reds_
 void reds_handle_agent_mouse_event(RedsState *reds, const VDAgentMouseState *mouse_state)
 {
     RedCharDeviceVDIPort *dev = reds->agent_dev;
-    if (!reds->inputs_channel || !dev->priv->agent_attached) {
+    if (!dev->priv->agent_attached) {
         return;
     }
 
@@ -700,11 +705,11 @@ void reds_handle_agent_mouse_event(RedsState *reds, const VDAgentMouseState *mou
                                                                       true);
 
     if (!char_dev_buf) {
-        dev->priv->pending_mouse_event = true;
+        dev->priv->pending_mouse_state = g_memdup(mouse_state, sizeof(*mouse_state));
         return;
     }
 
-    dev->priv->pending_mouse_event = false;
+    g_clear_pointer(&dev->priv->pending_mouse_state, g_free);
 
     VDInternalBuf *internal_buf = (VDInternalBuf *)char_dev_buf->buf;
     internal_buf->u.mouse_state = *mouse_state;
commit e2d3e4f17e164a7c265512a7dae4e99d413fa0f4
Author: Frediano Ziglio <fziglio at redhat.com>
Date:   Sat Feb 9 01:56:55 2019 +0000

    UGLY... avoid a function to set agent_attached
    
    how set to FALSE ??

diff --git a/server/reds.c b/server/reds.c
index 3ffb2e8e..8a18a2f7 100644
--- a/server/reds.c
+++ b/server/reds.c
@@ -2425,9 +2425,6 @@ static RedCharDevice *attach_to_red_agent(RedsState *reds, SpiceCharDeviceInstan
     RedCharDeviceVDIPort *dev = reds->agent_dev;
     SpiceCharDeviceInterface *sif;
 
-#if 0
-    dev->priv->agent_attached = TRUE;
-#endif
     red_char_device_reset_dev_instance(RED_CHAR_DEVICE(dev), sin);
 
     reds->vdagent = sin;
diff --git a/server/vdi.c b/server/vdi.c
index af808a07..dbbac41d 100644
--- a/server/vdi.c
+++ b/server/vdi.c
@@ -287,6 +287,17 @@ static RedPipeItem *vdi_port_read_one_msg_from_device(RedCharDevice *self,
 }
 
 static void
+vdi_on_sin_changed(RedCharDeviceVDIPort *dev, GParamSpec *pspec, gpointer user_data)
+{
+    RedCharDevice *char_dev = RED_CHAR_DEVICE(dev);
+
+    SpiceCharDeviceInstance *sin = NULL;
+    g_object_get(char_dev, "sin", &sin, NULL);
+
+    dev->priv->agent_attached = (sin != NULL);
+}
+
+static void
 red_char_device_vdi_port_init(RedCharDeviceVDIPort *self)
 {
     self->priv = red_char_device_vdi_port_get_instance_private(self);
@@ -295,6 +306,7 @@ red_char_device_vdi_port_init(RedCharDeviceVDIPort *self)
     self->priv->read_state = VDI_PORT_READ_STATE_READ_HEADER;
     self->priv->receive_pos = (uint8_t *)&self->priv->vdi_chunk_header;
     self->priv->receive_len = sizeof(self->priv->vdi_chunk_header);
+    g_signal_connect(self, "notify::sin", G_CALLBACK(vdi_on_sin_changed), NULL);
 }
 
 static void vdi_filter_init(AgentMsgFilter *filter, RedCharDeviceVDIPort *dev)
commit cee630079b8ca24bd290bf9f64575752f190b658
Author: Frediano Ziglio <fziglio at redhat.com>
Date:   Sat Feb 9 01:34:13 2019 +0000

    SAVE one factor out, implement setting filters

diff --git a/server/reds.c b/server/reds.c
index 97144af2..3ffb2e8e 100644
--- a/server/reds.c
+++ b/server/reds.c
@@ -536,17 +536,11 @@ static void reds_update_mouse_mode(RedsState *reds)
 
 static void reds_update_agent_properties(RedsState *reds)
 {
-#if 0
     if (reds->agent_dev == NULL || reds->config == NULL) {
         return;
     }
-    /* copy & paste */
-    reds->agent_dev->priv->write_filter.copy_paste_enabled = reds->config->agent_copypaste;
-    reds->agent_dev->priv->read_filter.copy_paste_enabled = reds->config->agent_copypaste;
-    /* file transfer */
-    reds->agent_dev->priv->write_filter.file_xfer_enabled = reds->config->agent_file_xfer;
-    reds->agent_dev->priv->read_filter.file_xfer_enabled = reds->config->agent_file_xfer;
-#endif
+    vdi_update_filters(reds->agent_dev, reds->config->agent_copypaste,
+                       reds->config->agent_file_xfer);
 }
 
 void reds_agent_remove(RedsState *reds)
diff --git a/server/vdi.c b/server/vdi.c
index 08f99d1c..af808a07 100644
--- a/server/vdi.c
+++ b/server/vdi.c
@@ -32,7 +32,6 @@
 #include "inputs-channel.h"
 
 // XXX declaration to make code happy
-//#include "reds-private.h"
 struct RedsState {
     RedCharDeviceVDIPort *agent_dev;
     bool pending_device_display_info_message;
@@ -40,8 +39,6 @@ struct RedsState {
 };
 
 SpiceCharDeviceInstance *reds_get_vdagent(RedsState *reds);
-static inline gboolean reds_get_agent_copypaste(RedsState *reds) { return FALSE; }
-static inline gboolean reds_get_agent_file_xfer(RedsState *reds) { return FALSE; }
 void reds_agent_remove(RedsState *reds);
 gboolean reds_use_client_monitors_config(RedsState *reds);
 void reds_client_monitors_config(RedsState *reds, VDAgentMonitorsConfig *monitors_config);
@@ -107,6 +104,17 @@ struct RedCharDeviceVDIPortPrivate {
 
 G_DEFINE_TYPE_WITH_PRIVATE(RedCharDeviceVDIPort, red_char_device_vdi_port, RED_TYPE_CHAR_DEVICE)
 
+// utilities to get some value easily, these 2 values are always copied from RedsState
+static inline gboolean get_agent_copypaste(const RedCharDeviceVDIPort *dev)
+{
+    return dev->priv->read_filter.copy_paste_enabled;
+}
+
+static inline gboolean get_agent_file_xfer(const RedCharDeviceVDIPort *dev)
+{
+    return dev->priv->read_filter.file_xfer_enabled;
+}
+
 static void vdi_port_read_buf_free(RedPipeItem *base)
 {
     RedVDIReadBuf *buf = SPICE_UPCAST(RedVDIReadBuf, base);
@@ -174,9 +182,10 @@ static AgentMsgFilterResult vdi_port_read_buf_process(RedCharDeviceVDIPort *dev,
     }
 }
 
-static void agent_adjust_capabilities(VDAgentMessage *message,
-                                      bool clipboard_enabled, bool xfer_enabled)
+static void agent_adjust_capabilities(VDAgentMessage *message, RedCharDeviceVDIPort *dev)
 {
+    bool clipboard_enabled = get_agent_copypaste(dev);
+    bool xfer_enabled = get_agent_file_xfer(dev);
     VDAgentAnnounceCapabilities *capabilities;
 
     if (message->type != VD_AGENT_ANNOUNCE_CAPABILITIES) {
@@ -261,9 +270,7 @@ static RedPipeItem *vdi_port_read_one_msg_from_device(RedCharDevice *self,
             }
             switch (vdi_port_read_buf_process(dev, dispatch_buf)) {
             case AGENT_MSG_FILTER_OK:
-                agent_adjust_capabilities((VDAgentMessage *) dispatch_buf->data,
-                                          reds_get_agent_copypaste(reds),
-                                          reds_get_agent_file_xfer(reds));
+                agent_adjust_capabilities((VDAgentMessage *) dispatch_buf->data, dev);
                 return &dispatch_buf->base;
             case AGENT_MSG_FILTER_PROTO_ERROR:
                 reds_agent_remove(reds);
@@ -290,23 +297,23 @@ red_char_device_vdi_port_init(RedCharDeviceVDIPort *self)
     self->priv->receive_len = sizeof(self->priv->vdi_chunk_header);
 }
 
+static void vdi_filter_init(AgentMsgFilter *filter, RedCharDeviceVDIPort *dev)
+{
+    RedsState *reds = red_char_device_get_server(RED_CHAR_DEVICE(dev));
+    agent_msg_filter_init(filter, get_agent_copypaste(dev),
+                          get_agent_file_xfer(dev),
+                          reds_use_client_monitors_config(reds),
+                          TRUE);
+}
+
 static void red_char_device_vdi_port_constructed(GObject *object)
 {
     RedCharDeviceVDIPort *dev = RED_CHAR_DEVICE_VDIPORT(object);
-    RedsState *reds;
 
     G_OBJECT_CLASS(red_char_device_vdi_port_parent_class)->constructed(object);
 
-    reds = red_char_device_get_server(RED_CHAR_DEVICE(object));
-
-    agent_msg_filter_init(&dev->priv->write_filter, reds_get_agent_copypaste(reds),
-                          reds_get_agent_file_xfer(reds),
-                          reds_use_client_monitors_config(reds),
-                          TRUE);
-    agent_msg_filter_init(&dev->priv->read_filter, reds_get_agent_copypaste(reds),
-                          reds_get_agent_file_xfer(reds),
-                          reds_use_client_monitors_config(reds),
-                          TRUE);
+    vdi_filter_init(&dev->priv->write_filter, dev);
+    vdi_filter_init(&dev->priv->read_filter, dev);
 }
 
 static void
@@ -532,9 +539,7 @@ void reds_on_main_channel_migrate(RedsState *reds, MainChannelClient *mcc)
         read_buf->len = read_data_len;
         switch (vdi_port_read_buf_process(agent_dev, read_buf)) {
         case AGENT_MSG_FILTER_OK:
-            agent_adjust_capabilities((VDAgentMessage *)read_buf->data,
-                                      reds_get_agent_copypaste(reds),
-                                      reds_get_agent_file_xfer(reds));
+            agent_adjust_capabilities((VDAgentMessage *)read_buf->data, agent_dev);
             main_channel_client_push_agent_data(mcc,
                                                 read_buf->data,
                                                 read_buf->len,
@@ -710,9 +715,7 @@ void vdi_reset(RedCharDeviceVDIPort *dev)
         dev->priv->current_read_buf = NULL;
     }
     /* Reset read filter to start with clean state when the agent reconnects */
-    agent_msg_filter_init(&dev->priv->read_filter, reds_get_agent_copypaste(reds),
-                          reds_get_agent_file_xfer(reds),
-                          reds_use_client_monitors_config(reds), TRUE);
+    vdi_filter_init(&dev->priv->read_filter, dev);
     /* Throw away pending chunks from the current (if any) and future
      * messages written by the client.
      * TODO: client should clear its agent messages queue when the agent
@@ -745,8 +748,6 @@ void vdi_reset(RedCharDeviceVDIPort *dev)
 
 void vdi_all_client_disconnected(RedCharDeviceVDIPort *agent_dev)
 {
-    RedsState *reds = red_char_device_get_server(RED_CHAR_DEVICE(agent_dev));
-
     if (agent_dev->priv->agent_attached) {
         RedCharDeviceWriteBuffer *char_dev_buf =
             vdagent_new_write_buffer(agent_dev,
@@ -758,9 +759,7 @@ void vdi_all_client_disconnected(RedCharDeviceVDIPort *agent_dev)
     }
 
     /* Reset write filter to start with clean state on client reconnect */
-    agent_msg_filter_init(&agent_dev->priv->write_filter, reds_get_agent_copypaste(reds),
-                          reds_get_agent_file_xfer(reds),
-                          reds_use_client_monitors_config(reds), TRUE);
+    vdi_filter_init(&agent_dev->priv->write_filter, agent_dev);
 
     /* Throw away pending chunks from the current (if any) and future
      *  messages read from the agent */
@@ -873,8 +872,8 @@ void vdi_on_main_agent_start(RedCharDeviceVDIPort *agent_dev, MainChannelClient
     RedsState *reds = red_char_device_get_server(dev_state);
     reds_send_device_display_info(reds);
 
-    agent_msg_filter_config(&agent_dev->priv->write_filter, reds_get_agent_copypaste(reds),
-                            reds_get_agent_file_xfer(reds),
+    agent_msg_filter_config(&agent_dev->priv->write_filter, get_agent_copypaste(agent_dev),
+                            get_agent_file_xfer(agent_dev),
                             reds_use_client_monitors_config(reds));
     agent_dev->priv->write_filter.discard_all = FALSE;
 }
@@ -889,4 +888,14 @@ RedCharDeviceVDIPort *red_char_device_vdi_port_new(RedsState *reds)
                         NULL);
 }
 
+void vdi_update_filters(RedCharDeviceVDIPort *dev, bool clipboard_enabled, bool xfer_enabled)
+{
+    /* copy & paste */
+    dev->priv->write_filter.copy_paste_enabled = clipboard_enabled;
+    dev->priv->read_filter.copy_paste_enabled = clipboard_enabled;
+    /* file transfer */
+    dev->priv->write_filter.file_xfer_enabled = xfer_enabled;
+    dev->priv->read_filter.file_xfer_enabled = xfer_enabled;
+}
+
 // TODO look as XXX comments
diff --git a/server/vdi.h b/server/vdi.h
index eb63180e..7296def0 100644
--- a/server/vdi.h
+++ b/server/vdi.h
@@ -62,6 +62,7 @@ void vdi_all_client_disconnected(RedCharDeviceVDIPort *agent_dev);
 void vdi_marshall_migrate_data(RedCharDeviceVDIPort *agent_dev, SpiceMarshaller *m);
 void vdi_on_main_agent_start(RedCharDeviceVDIPort *agent_dev, MainChannelClient *mcc,
                              uint32_t num_tokens);
+void vdi_update_filters(RedCharDeviceVDIPort *dev, bool clipboard_enabled, bool xfer_enabled);
 
 G_END_DECLS
 


More information about the Spice-commits mailing list