This allows the server to add channels after the client is connected. Signed-off-by: Frediano Ziglio <fziglio@xxxxxxxxxx> --- Changes since v4: - get type and id from channel as soon as possible to prevent possible thread issues; - allocate channels_info on the stack; - do not sent additional channels if channel list was never requested. --- server/main-channel-client.c | 48 ++++++++++++++++++++++++++++++++++++++++++++ server/main-channel-client.h | 3 +++ server/main-channel.c | 6 ++++++ server/main-channel.h | 3 +++ server/reds.c | 2 ++ 5 files changed, 62 insertions(+) diff --git a/server/main-channel-client.c b/server/main-channel-client.c index db8e4823..7268e861 100644 --- a/server/main-channel-client.c +++ b/server/main-channel-client.c @@ -62,6 +62,7 @@ struct MainChannelClientPrivate { int mig_wait_prev_try_seamless; int init_sent; int seamless_mig_dst; + bool channels_list_sent; uint8_t recv_buf[MAIN_CHANNEL_RECEIVE_BUF_SIZE]; }; @@ -119,6 +120,12 @@ typedef struct RedMultiMediaTimePipeItem { uint32_t time; } RedMultiMediaTimePipeItem; +typedef struct RedRegisterChannelPipeItem { + RedPipeItem base; + uint32_t channel_type; + uint32_t channel_id; +} RedRegisterChannelPipeItem; + #define ZERO_BUF_SIZE 4096 static const uint8_t zero_page[ZERO_BUF_SIZE] = {0}; @@ -437,6 +444,21 @@ RedPipeItem *main_multi_media_time_item_new(RedChannelClient *rcc, return &item->base; } +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(&item->base, RED_PIPE_ITEM_TYPE_MAIN_REGISTERED_CHANNEL); + + uint32_t type, id; + g_object_get(channel, "channel-type", &type, "id", &id, NULL); + item->channel_type = type; + item->channel_id = id; + return &item->base; +} + void main_channel_client_handle_migrate_connected(MainChannelClient *mcc, int success, int seamless) @@ -918,6 +940,25 @@ 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) +{ + struct { + SpiceMsgChannels info; + SpiceChannelId ids[1]; + } channels_info_buffer; + SpiceMsgChannels* channels_info = &channels_info_buffer.info; + + red_channel_client_init_send_data(rcc, SPICE_MSG_MAIN_CHANNELS_LIST); + + channels_info->channels[0].type = item->channel_type; + channels_info->channels[0].id = item->channel_id; + channels_info->num_of_channels = 1; + + spice_marshall_msg_main_channels_list(m, channels_info); +} + void main_channel_client_send_item(RedChannelClient *rcc, RedPipeItem *base) { MainChannelClient *mcc = MAIN_CHANNEL_CLIENT(rcc); @@ -938,6 +979,7 @@ void main_channel_client_send_item(RedChannelClient *rcc, RedPipeItem *base) switch (base->type) { case RED_PIPE_ITEM_TYPE_MAIN_CHANNELS_LIST: main_channel_marshall_channels(rcc, m, base); + mcc->priv->channels_list_sent = true; break; case RED_PIPE_ITEM_TYPE_MAIN_PING: main_channel_marshall_ping(rcc, m, @@ -994,6 +1036,12 @@ 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: + if (mcc->priv->channels_list_sent) { + 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 0f8e4f49..e936686b 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 982b6203..ecaab811 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 eb3bcec3..0cb5be72 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, uint32_t 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 b6ecc6c6..877d3ba2 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