[Spice-devel] [RFC PATCH spice-server v4 02/22] Notify client of the creation of new channels dynamically
Frediano Ziglio
fziglio at redhat.com
Fri Aug 25 09:53:49 UTC 2017
This allows to add channels after the client is connected.
Signed-off-by: Frediano Ziglio <fziglio at redhat.com>
---
server/main-channel-client.c | 50 ++++++++++++++++++++++++++++++++++++++++++++
server/main-channel-client.h | 3 +++
server/main-channel.c | 6 ++++++
server/main-channel.h | 3 +++
server/reds.c | 2 ++
5 files changed, 64 insertions(+)
diff --git a/server/main-channel-client.c b/server/main-channel-client.c
index 82b578c8..25c7c13e 100644
--- a/server/main-channel-client.c
+++ b/server/main-channel-client.c
@@ -119,6 +119,11 @@ typedef struct RedMultiMediaTimePipeItem {
int time;
} RedMultiMediaTimePipeItem;
+typedef struct RedRegisterChannelPipeItem {
+ RedPipeItem base;
+ RedChannel *channel;
+} RedRegisterChannelPipeItem;
+
#define ZERO_BUF_SIZE 4096
static const uint8_t zero_page[ZERO_BUF_SIZE] = {0};
@@ -437,6 +442,26 @@ RedPipeItem *main_multi_media_time_item_new(RedChannelClient *rcc,
return &item->base;
}
+static void register_channel_pipe_item_free(RedPipeItem *base)
+{
+ RedRegisterChannelPipeItem *pipe_item = SPICE_UPCAST(RedRegisterChannelPipeItem, base);
+
+ g_object_unref(pipe_item->channel);
+ free(pipe_item);
+}
+
+RedPipeItem *register_channel_item_new(RedChannelClient *rcc, void *data, int num)
+{
+ RedChannel *channel = data;
+ RedRegisterChannelPipeItem *item;
+
+ item = spice_new0(RedRegisterChannelPipeItem, 1);
+ red_pipe_item_init_full(&item->base, RED_PIPE_ITEM_TYPE_MAIN_REGISTERED_CHANNEL,
+ register_channel_pipe_item_free);
+ item->channel = g_object_ref(channel);
+ return &item->base;
+}
+
void main_channel_client_handle_migrate_connected(MainChannelClient *mcc,
int success,
int seamless)
@@ -918,6 +943,27 @@ static void main_channel_marshall_agent_connected(SpiceMarshaller *m,
spice_marshall_msg_main_agent_connected_tokens(m, &connected);
}
+static void main_channel_marshall_registered_channel(RedChannelClient *rcc,
+ SpiceMarshaller *m,
+ RedRegisterChannelPipeItem *item)
+{
+ SpiceMsgChannels* channels_info;
+ RedChannel *channel = item->channel;
+
+ red_channel_client_init_send_data(rcc, SPICE_MSG_MAIN_CHANNELS_LIST);
+ channels_info = (SpiceMsgChannels *)spice_malloc(sizeof(SpiceMsgChannels)
+ + 1 * sizeof(SpiceChannelId));
+
+ uint32_t type, id;
+ g_object_get(channel, "channel-type", &type, "id", &id, NULL);
+ channels_info->channels[0].type = type;
+ channels_info->channels[0].id = id;
+ channels_info->num_of_channels = 1;
+
+ spice_marshall_msg_main_channels_list(m, channels_info);
+ free(channels_info);
+}
+
void main_channel_client_send_item(RedChannelClient *rcc, RedPipeItem *base)
{
MainChannelClient *mcc = MAIN_CHANNEL_CLIENT(rcc);
@@ -994,6 +1040,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_REGISTERED_CHANNEL:
+ main_channel_marshall_registered_channel(rcc, m,
+ SPICE_UPCAST(RedRegisterChannelPipeItem, base));
+ break;
default:
break;
};
diff --git a/server/main-channel-client.h b/server/main-channel-client.h
index a2e38c2f..6911cb07 100644
--- a/server/main-channel-client.h
+++ b/server/main-channel-client.h
@@ -122,6 +122,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_REGISTERED_CHANNEL,
};
typedef struct MainMouseModeItemInfo {
@@ -138,6 +139,8 @@ typedef struct MainMultiMediaTimeItemInfo {
RedPipeItem *main_multi_media_time_item_new(RedChannelClient *rcc,
void *data, int num);
+RedPipeItem *register_channel_item_new(RedChannelClient *rcc, void *data, int num);
+
G_END_DECLS
#endif /* MAIN_CHANNEL_CLIENT_H_ */
diff --git a/server/main-channel.c b/server/main-channel.c
index 4834f79b..f9be9e6c 100644
--- a/server/main-channel.c
+++ b/server/main-channel.c
@@ -170,6 +170,12 @@ static void main_channel_fill_mig_target(MainChannel *main_channel, RedsMigSpice
main_channel->mig_target.sport = mig_target->sport;
}
+void
+main_channel_registered_new_channel(MainChannel *main_chan, RedChannel *channel)
+{
+ red_channel_pipes_new_add(RED_CHANNEL(main_chan), register_channel_item_new, channel);
+}
+
void main_channel_migrate_switch(MainChannel *main_chan, RedsMigSpice *mig_target)
{
main_channel_fill_mig_target(main_chan, mig_target);
diff --git a/server/main-channel.h b/server/main-channel.h
index 833957dd..d2bdcc35 100644
--- a/server/main-channel.h
+++ b/server/main-channel.h
@@ -66,6 +66,9 @@ void main_channel_push_mouse_mode(MainChannel *main_chan, SpiceMouseMode current
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);
+/* tell MainChannel we have a new channel ready */
+void main_channel_registered_new_channel(MainChannel *main_chan,
+ RedChannel *channel);
int main_channel_is_connected(MainChannel *main_chan);
diff --git a/server/reds.c b/server/reds.c
index 005ead47..b712c182 100644
--- a/server/reds.c
+++ b/server/reds.c
@@ -387,6 +387,8 @@ void reds_register_channel(RedsState *reds, RedChannel *channel)
{
spice_assert(reds);
reds->channels = g_list_prepend(reds->channels, channel);
+ // create new channel in the client if possible
+ main_channel_registered_new_channel(reds->main_channel, channel);
}
void reds_unregister_channel(RedsState *reds, RedChannel *channel)
--
2.13.5
More information about the Spice-devel
mailing list