This allows to add channels after the client is connected. Signed-off-by: Frediano Ziglio <fziglio@xxxxxxxxxx> --- 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 _______________________________________________ Spice-devel mailing list Spice-devel@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/spice-devel