diff --git a/server/cursor-channel-client.c b/server/cursor-channel-client.c index bbb0588f..42ab5d76 100644 --- a/server/cursor-channel-client.c +++ b/server/cursor-channel-client.c @@ -48,10 +48,16 @@ struct CursorChannelClientPrivate uint32_t cursor_cache_items; }; +static void cursor_channel_client_on_disconnect(RedChannelClient *rcc); + static void cursor_channel_client_class_init(CursorChannelClientClass *klass) { + RedChannelClientClass *client_class = RED_CHANNEL_CLIENT_CLASS(klass); + g_type_class_add_private(klass, sizeof(CursorChannelClientPrivate)); + + client_class->on_disconnect = cursor_channel_client_on_disconnect; } static void @@ -75,7 +81,7 @@ void cursor_channel_client_reset_cursor_cache(RedChannelClient *rcc) red_cursor_cache_reset(CURSOR_CHANNEL_CLIENT(rcc), CLIENT_CURSOR_CACHE_SIZE); } -void cursor_channel_client_on_disconnect(RedChannelClient *rcc) +static void cursor_channel_client_on_disconnect(RedChannelClient *rcc) { if (!rcc) { return; diff --git a/server/cursor-channel-client.h b/server/cursor-channel-client.h index 82612659..dc69369f 100644 --- a/server/cursor-channel-client.h +++ b/server/cursor-channel-client.h @@ -66,7 +66,6 @@ CursorChannelClient* cursor_channel_client_new(CursorChannel *cursor, RedChannelCapabilities *caps); void cursor_channel_client_reset_cursor_cache(RedChannelClient *rcc); -void cursor_channel_client_on_disconnect(RedChannelClient *rcc); RedCacheItem* cursor_channel_client_cache_find(CursorChannelClient *ccc, uint64_t id); int cursor_channel_client_cache_add(CursorChannelClient *ccc, uint64_t id, size_t size); diff --git a/server/cursor-channel.c b/server/cursor-channel.c index 5ece576c..f35c9b20 100644 --- a/server/cursor-channel.c +++ b/server/cursor-channel.c @@ -448,7 +448,6 @@ cursor_channel_class_init(CursorChannelClass *klass) channel_class->parser = spice_get_client_channel_parser(SPICE_CHANNEL_CURSOR, NULL); channel_class->handle_message = red_channel_client_handle_message; - channel_class->on_disconnect = cursor_channel_client_on_disconnect; channel_class->send_item = cursor_channel_send_item; } diff --git a/server/dcc.c b/server/dcc.c index 2778bb88..ec8b6074 100644 --- a/server/dcc.c +++ b/server/dcc.c @@ -42,6 +42,7 @@ enum static void on_display_video_codecs_update(GObject *gobject, GParamSpec *pspec, gpointer user_data); static bool dcc_config_socket(RedChannelClient *rcc); +static void dcc_on_disconnect(RedChannelClient *rcc); static void display_channel_client_get_property(GObject *object, @@ -133,6 +134,7 @@ display_channel_client_class_init(DisplayChannelClientClass *klass) object_class->finalize = display_channel_client_finalize; client_class->config_socket = dcc_config_socket; + client_class->on_disconnect = dcc_on_disconnect; g_object_class_install_property(object_class, PROP_IMAGE_COMPRESSION, @@ -1429,6 +1431,26 @@ static bool dcc_config_socket(RedChannelClient *rcc) return common_channel_client_config_socket(rcc); } +static void dcc_on_disconnect(RedChannelClient *rcc) +{ + DisplayChannel *display; + DisplayChannelClient *dcc; + + spice_debug("trace"); + spice_return_if_fail(rcc != NULL); + + dcc = DISPLAY_CHANNEL_CLIENT(rcc); + display = DCC_TO_DC(dcc); + + dcc_stop(dcc); // TODO: start/stop -> connect/disconnect? + display_channel_compress_stats_print(display); + + // this was the last channel client + spice_debug("#draw=%d, #glz_draw=%d", + display->priv->drawable_count, + display->priv->encoder_shared_data.glz_drawable_count); +} + gboolean dcc_is_low_bandwidth(DisplayChannelClient *dcc) { return dcc->is_low_bandwidth; diff --git a/server/display-channel.c b/server/display-channel.c index 792fbd25..c745790f 100644 --- a/server/display-channel.c +++ b/server/display-channel.c @@ -2189,26 +2189,6 @@ void display_channel_create_surface(DisplayChannel *display, uint32_t surface_id send_create_surface(display, surface_id, data_is_valid); } -static void on_disconnect(RedChannelClient *rcc) -{ - DisplayChannel *display; - DisplayChannelClient *dcc; - - spice_debug("trace"); - spice_return_if_fail(rcc != NULL); - - dcc = DISPLAY_CHANNEL_CLIENT(rcc); - display = DCC_TO_DC(dcc); - - dcc_stop(dcc); // TODO: start/stop -> connect/disconnect? - display_channel_compress_stats_print(display); - - // this was the last channel client - spice_debug("#draw=%d, #glz_draw=%d", - display->priv->drawable_count, - display->priv->encoder_shared_data.glz_drawable_count); -} - static bool handle_migrate_flush_mark(RedChannelClient *rcc) { RedChannel *channel = red_channel_client_get_channel(rcc); @@ -2510,7 +2490,6 @@ display_channel_class_init(DisplayChannelClass *klass) channel_class->parser = spice_get_client_channel_parser(SPICE_CHANNEL_DISPLAY, NULL); channel_class->handle_message = dcc_handle_message; - channel_class->on_disconnect = on_disconnect; channel_class->send_item = dcc_send_item; channel_class->handle_migrate_flush_mark = handle_migrate_flush_mark; channel_class->handle_migrate_data = handle_migrate_data; diff --git a/server/inputs-channel-client.c b/server/inputs-channel-client.c index c28e24eb..c9c88da2 100644 --- a/server/inputs-channel-client.c +++ b/server/inputs-channel-client.c @@ -63,6 +63,14 @@ inputs_channel_client_release_msg_rcv_buf(RedChannelClient *rcc, { } +static void inputs_channel_client_on_disconnect(RedChannelClient *rcc) +{ + if (!rcc) { + return; + } + inputs_release_keys(INPUTS_CHANNEL(red_channel_client_get_channel(rcc))); +} + static void inputs_channel_client_class_init(InputsChannelClientClass *klass) { @@ -72,6 +80,7 @@ inputs_channel_client_class_init(InputsChannelClientClass *klass) client_class->alloc_recv_buf = inputs_channel_client_alloc_msg_rcv_buf; client_class->release_recv_buf = inputs_channel_client_release_msg_rcv_buf; + client_class->on_disconnect = inputs_channel_client_on_disconnect; } static void diff --git a/server/inputs-channel.c b/server/inputs-channel.c index 943c69d6..5ddf2b39 100644 --- a/server/inputs-channel.c +++ b/server/inputs-channel.c @@ -405,7 +405,7 @@ static bool inputs_channel_handle_message(RedChannelClient *rcc, uint16_t type, return TRUE; } -static void inputs_release_keys(InputsChannel *inputs) +void inputs_release_keys(InputsChannel *inputs) { int i; SpiceKbdState *st; @@ -434,14 +434,6 @@ static void inputs_release_keys(InputsChannel *inputs) } } -static void inputs_channel_on_disconnect(RedChannelClient *rcc) -{ - if (!rcc) { - return; - } - inputs_release_keys(INPUTS_CHANNEL(red_channel_client_get_channel(rcc))); -} - static void inputs_pipe_add_init(RedChannelClient *rcc) { RedInputsInitPipeItem *item = spice_malloc(sizeof(RedInputsInitPipeItem)); @@ -594,7 +586,6 @@ inputs_channel_class_init(InputsChannelClass *klass) channel_class->handle_message = inputs_channel_handle_message; /* channel callbacks */ - channel_class->on_disconnect = inputs_channel_on_disconnect; channel_class->send_item = inputs_channel_send_item; channel_class->handle_migrate_data = inputs_channel_handle_migrate_data; channel_class->handle_migrate_flush_mark = inputs_channel_handle_migrate_flush_mark; diff --git a/server/inputs-channel.h b/server/inputs-channel.h index e3cc2519..27d81a87 100644 --- a/server/inputs-channel.h +++ b/server/inputs-channel.h @@ -58,6 +58,7 @@ void inputs_channel_detach_tablet(InputsChannel *inputs, SpiceTabletInstance *ta RedsState* spice_tablet_state_get_server(SpiceTabletState *dev); RedsState* spice_kbd_state_get_server(SpiceKbdState *dev); gboolean inputs_channel_is_src_during_migrate(InputsChannel *inputs); +void inputs_release_keys(InputsChannel *inputs); G_END_DECLS diff --git a/server/main-channel-client.c b/server/main-channel-client.c index db8e4823..4d841c81 100644 --- a/server/main-channel-client.c +++ b/server/main-channel-client.c @@ -189,6 +189,17 @@ main_channel_client_release_msg_rcv_buf(RedChannelClient *rcc, } } +/* + * When the main channel is disconnected, disconnect the entire client. + */ +static void main_channel_client_on_disconnect(RedChannelClient *rcc) +{ + RedsState *reds = red_channel_get_server(red_channel_client_get_channel(rcc)); + spice_printerr("rcc=%p", rcc); + main_dispatcher_client_disconnect(reds_get_main_dispatcher(reds), + red_channel_client_get_client(rcc)); +} + static void main_channel_client_class_init(MainChannelClientClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS(klass); @@ -201,6 +212,7 @@ static void main_channel_client_class_init(MainChannelClientClass *klass) client_class->alloc_recv_buf = main_channel_client_alloc_msg_rcv_buf; client_class->release_recv_buf = main_channel_client_release_msg_rcv_buf; + client_class->on_disconnect = main_channel_client_on_disconnect; g_object_class_install_property(object_class, PROP_CONNECTION_ID, diff --git a/server/main-channel.c b/server/main-channel.c index 982b6203..c30374c3 100644 --- a/server/main-channel.c +++ b/server/main-channel.c @@ -49,17 +49,6 @@ int main_channel_is_connected(MainChannel *main_chan) return red_channel_is_connected(RED_CHANNEL(main_chan)); } -/* - * When the main channel is disconnected, disconnect the entire client. - */ -static void main_channel_client_on_disconnect(RedChannelClient *rcc) -{ - RedsState *reds = red_channel_get_server(red_channel_client_get_channel(rcc)); - spice_printerr("rcc=%p", rcc); - main_dispatcher_client_disconnect(reds_get_main_dispatcher(reds), - red_channel_client_get_client(rcc)); -} - RedClient *main_channel_get_client_by_link_id(MainChannel *main_chan, uint32_t connection_id) { RedChannelClient *rcc; @@ -315,7 +304,6 @@ main_channel_class_init(MainChannelClass *klass) channel_class->handle_message = main_channel_handle_message; /* channel callbacks */ - channel_class->on_disconnect = main_channel_client_on_disconnect; channel_class->send_item = main_channel_client_send_item; channel_class->handle_migrate_flush_mark = main_channel_handle_migrate_flush_mark; channel_class->handle_migrate_data = main_channel_handle_migrate_data; diff --git a/server/red-channel-client.c b/server/red-channel-client.c index 145ba43f..43b8eb8b 100644 --- a/server/red-channel-client.c +++ b/server/red-channel-client.c @@ -1665,6 +1665,13 @@ void red_channel_client_push_set_ack(RedChannelClient *rcc) red_channel_client_pipe_add_type(rcc, RED_PIPE_ITEM_TYPE_SET_ACK); } +static void red_channel_client_on_disconnect(RedChannelClient *rcc) +{ + RedChannelClientClass *klass = RED_CHANNEL_CLIENT_GET_CLASS(rcc); + + klass->on_disconnect(rcc); +} + void red_channel_client_disconnect(RedChannelClient *rcc) { RedChannel *channel = rcc->priv->channel; @@ -1691,7 +1698,7 @@ void red_channel_client_disconnect(RedChannelClient *rcc) rcc->priv->connectivity_monitor.timer = NULL; } red_channel_remove_client(channel, rcc); - red_channel_on_disconnect(channel, rcc); + red_channel_client_on_disconnect(rcc); } gboolean red_channel_client_is_blocked(RedChannelClient *rcc) diff --git a/server/red-channel-client.h b/server/red-channel-client.h index 057732f4..3665dacc 100644 --- a/server/red-channel-client.h +++ b/server/red-channel-client.h @@ -168,6 +168,8 @@ struct RedChannelClientClass bool (*config_socket)(RedChannelClient *rcc); uint8_t *(*alloc_recv_buf)(RedChannelClient *channel, uint16_t type, uint32_t size); void (*release_recv_buf)(RedChannelClient *channel, uint16_t type, uint32_t size, uint8_t *msg); + + void (*on_disconnect)(RedChannelClient *rcc); }; #define SPICE_SERVER_ERROR spice_server_error_quark() diff --git a/server/red-channel.c b/server/red-channel.c index 9ff3474a..a8ab5230 100644 --- a/server/red-channel.c +++ b/server/red-channel.c @@ -198,7 +198,6 @@ red_channel_constructed(GObject *object) G_OBJECT_CLASS(red_channel_parent_class)->constructed(object); - spice_assert(klass->on_disconnect); spice_assert(klass->handle_migrate_data || !(self->priv->migration_flags & SPICE_MIGRATE_NEED_DATA_TRANSFER)); } @@ -692,13 +691,6 @@ SpiceCoreInterfaceInternal* red_channel_get_core_interface(RedChannel *channel) return channel->priv->core; } -void red_channel_on_disconnect(RedChannel *self, RedChannelClient *rcc) -{ - RedChannelClass *klass = RED_CHANNEL_GET_CLASS(self); - - klass->on_disconnect(rcc); -} - void red_channel_send_item(RedChannel *self, RedChannelClient *rcc, RedPipeItem *item) { RedChannelClass *klass = RED_CHANNEL_GET_CLASS(self); diff --git a/server/red-channel.h b/server/red-channel.h index e65eea1e..8ea5a711 100644 --- a/server/red-channel.h +++ b/server/red-channel.h @@ -45,7 +45,6 @@ typedef struct MainChannelClient MainChannelClient; typedef bool (*channel_handle_message_proc)(RedChannelClient *rcc, uint16_t type, uint32_t size, void *msg); -typedef void (*channel_disconnect_proc)(RedChannelClient *rcc); typedef bool (*channel_configure_socket_proc)(RedChannelClient *rcc); typedef void (*channel_send_pipe_item_proc)(RedChannelClient *rcc, RedPipeItem *item); @@ -115,7 +114,6 @@ struct RedChannelClass * callbacks that are triggered from channel client stream events. * They are called from the thread that listen to the stream events. */ - channel_disconnect_proc on_disconnect; channel_send_pipe_item_proc send_item; channel_handle_migrate_flush_mark_proc handle_migrate_flush_mark; channel_handle_migrate_data_proc handle_migrate_data; @@ -217,7 +215,6 @@ struct RedsState* red_channel_get_server(RedChannel *channel); SpiceCoreInterfaceInternal* red_channel_get_core_interface(RedChannel *channel); /* channel callback function */ -void red_channel_on_disconnect(RedChannel *self, RedChannelClient *rcc); void red_channel_send_item(RedChannel *self, RedChannelClient *rcc, RedPipeItem *item); void red_channel_reset_thread_id(RedChannel *self); const RedStatNode *red_channel_get_stat_node(RedChannel *channel); diff --git a/server/smartcard-channel-client.c b/server/smartcard-channel-client.c index e934b2e9..7a2ef0dd 100644 --- a/server/smartcard-channel-client.c +++ b/server/smartcard-channel-client.c @@ -48,6 +48,7 @@ smartcard_channel_client_alloc_msg_rcv_buf(RedChannelClient *rcc, uint16_t type, static void smartcard_channel_client_release_msg_rcv_buf(RedChannelClient *rcc, uint16_t type, uint32_t size, uint8_t *msg); +static void smartcard_channel_client_on_disconnect(RedChannelClient *rcc); static void smart_card_channel_client_get_property(GObject *object, guint property_id, @@ -92,6 +93,7 @@ static void smart_card_channel_client_class_init(SmartCardChannelClientClass *kl RedChannelClientClass *client_class = RED_CHANNEL_CLIENT_CLASS(klass); client_class->alloc_recv_buf = smartcard_channel_client_alloc_msg_rcv_buf; client_class->release_recv_buf = smartcard_channel_client_release_msg_rcv_buf; + client_class->on_disconnect = smartcard_channel_client_on_disconnect; object_class->get_property = smart_card_channel_client_get_property; object_class->set_property = smart_card_channel_client_set_property; @@ -176,7 +178,7 @@ smartcard_channel_client_release_msg_rcv_buf(RedChannelClient *rcc, } } -void smartcard_channel_client_on_disconnect(RedChannelClient *rcc) +static void smartcard_channel_client_on_disconnect(RedChannelClient *rcc) { SmartCardChannelClient *scc = SMARTCARD_CHANNEL_CLIENT(rcc); RedCharDeviceSmartcard *device = scc->priv->smartcard; diff --git a/server/smartcard-channel-client.h b/server/smartcard-channel-client.h index 8f2ab0f0..fffad231 100644 --- a/server/smartcard-channel-client.h +++ b/server/smartcard-channel-client.h @@ -61,8 +61,6 @@ SmartCardChannelClient* smartcard_channel_client_create(RedChannel *channel, bool smartcard_channel_client_handle_migrate_flush_mark(RedChannelClient *rcc); -void smartcard_channel_client_on_disconnect(RedChannelClient *rcc); - void smartcard_channel_client_send_data(RedChannelClient *rcc, SpiceMarshaller *m, RedPipeItem *item, diff --git a/server/smartcard.c b/server/smartcard.c index ac2fc1e1..73f24851 100644 --- a/server/smartcard.c +++ b/server/smartcard.c @@ -574,7 +574,6 @@ red_smartcard_channel_class_init(RedSmartcardChannelClass *klass) channel_class->handle_message = smartcard_channel_client_handle_message, - channel_class->on_disconnect = smartcard_channel_client_on_disconnect; channel_class->send_item = smartcard_channel_send_item; channel_class->handle_migrate_flush_mark = smartcard_channel_client_handle_migrate_flush_mark; channel_class->handle_migrate_data = smartcard_channel_client_handle_migrate_data; diff --git a/server/sound.c b/server/sound.c index 54b89713..28e18126 100644 --- a/server/sound.c +++ b/server/sound.c @@ -789,7 +789,7 @@ static bool snd_channel_client_config_socket(RedChannelClient *rcc) return true; } -static void snd_channel_on_disconnect(RedChannelClient *rcc) +static void snd_channel_client_on_disconnect(RedChannelClient *rcc) { } @@ -1316,11 +1316,8 @@ static void snd_channel_class_init(SndChannelClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS(klass); - RedChannelClass *channel_class = RED_CHANNEL_CLASS(klass); object_class->finalize = snd_channel_finalize; - - channel_class->on_disconnect = snd_channel_on_disconnect; } static void @@ -1478,6 +1475,7 @@ snd_channel_client_class_init(SndChannelClientClass *klass) client_class->config_socket = snd_channel_client_config_socket; client_class->alloc_recv_buf = snd_channel_client_alloc_recv_buf; client_class->release_recv_buf = snd_channel_client_release_recv_buf; + client_class->on_disconnect = snd_channel_client_on_disconnect; } static void diff --git a/server/spicevmc.c b/server/spicevmc.c index 9305c9b4..51b6913c 100644 --- a/server/spicevmc.c +++ b/server/spicevmc.c @@ -763,7 +763,6 @@ red_vmc_channel_class_init(RedVmcChannelClass *klass) channel_class->handle_message = spicevmc_red_channel_client_handle_message; - channel_class->on_disconnect = spicevmc_red_channel_client_on_disconnect; channel_class->send_item = spicevmc_red_channel_send_item; channel_class->handle_migrate_flush_mark = spicevmc_channel_client_handle_migrate_flush_mark; channel_class->handle_migrate_data = spicevmc_channel_client_handle_migrate_data; @@ -986,6 +985,7 @@ vmc_channel_client_class_init(VmcChannelClientClass *klass) client_class->alloc_recv_buf = spicevmc_red_channel_alloc_msg_rcv_buf; client_class->release_recv_buf = spicevmc_red_channel_release_msg_rcv_buf; + client_class->on_disconnect = spicevmc_red_channel_client_on_disconnect; } static RedChannelClient *