[Spice-devel] [PATCH spice-server 4/4] Convert ClientCbs to channel virtual functions
Christophe Fergeau
cfergeau at redhat.com
Wed Aug 30 07:06:50 UTC 2017
On Tue, Aug 29, 2017 at 05:28:09PM -0500, Jonathon Jongsma wrote:
> These client callbacks really make more sense as virtual functions of
> the channel class. We never set different callbacks for different
> objects of the same class, so there's no need to be able to register
> e.g. different callbacks for different DisplayChannels.
>
> In the process, the signature for 'disconnect' and 'migrate' were
> changed slightly to provide a 'self' pointer to the channel as the first
> argument.
Acked-by: Christophe Fergeau <cfergeau at redhat.com>
I'd use this as an opportunity to remove the
channel_client_connect_proc, channel_client_disconnect_proc
and channel_client_migrate_proc typedef which are only used once. The
types can be used directly in RedChannelClass definition, no need for
the typedef indirection in my opinion.
Christophe
>
> Signed-off-by: Jonathon Jongsma <jjongsma at redhat.com>
> ---
> server/cursor-channel.c | 26 ++++++---------------
> server/display-channel.c | 18 ++++++---------
> server/inputs-channel.c | 11 ++++-----
> server/main-channel-client.c | 8 -------
> server/main-channel-client.h | 1 -
> server/main-channel.c | 13 +++++++----
> server/red-channel.c | 54 +++++++++++++++++---------------------------
> server/red-channel.h | 25 +++++++++-----------
> server/smartcard.c | 6 ++---
> server/sound.c | 21 ++++++++---------
> server/spicevmc.c | 7 +++---
> 11 files changed, 74 insertions(+), 116 deletions(-)
>
> diff --git a/server/cursor-channel.c b/server/cursor-channel.c
> index 02a9fe3a1..d3c1dcc71 100644
> --- a/server/cursor-channel.c
> +++ b/server/cursor-channel.c
> @@ -454,12 +454,11 @@ static void red_qxl_set_cursor_peer(RedChannel *channel, RedClient *client, Reds
> &payload);
> }
>
> -static void red_qxl_disconnect_cursor_peer(RedChannelClient *rcc)
> +static void red_qxl_disconnect_cursor_peer(RedChannel *channel, RedChannelClient *rcc)
> {
> RedWorkerMessageCursorDisconnect payload;
> QXLInstance *qxl;
> Dispatcher *dispatcher;
> - RedChannel *channel = red_channel_client_get_channel(rcc);
>
> if (!channel) {
> return;
> @@ -475,12 +474,11 @@ static void red_qxl_disconnect_cursor_peer(RedChannelClient *rcc)
> &payload);
> }
>
> -static void red_qxl_cursor_migrate(RedChannelClient *rcc)
> +static void red_qxl_cursor_migrate(RedChannel *channel, RedChannelClient *rcc)
> {
> RedWorkerMessageCursorMigrate payload;
> QXLInstance *qxl;
> Dispatcher *dispatcher;
> - RedChannel *channel = red_channel_client_get_channel(rcc);
> uint32_t type, id;
>
> if (!channel) {
> @@ -497,26 +495,11 @@ static void red_qxl_cursor_migrate(RedChannelClient *rcc)
> }
>
> static void
> -cursor_channel_constructed(GObject *object)
> -{
> - RedChannel *channel = RED_CHANNEL(object);
> - ClientCbs client_cbs = { NULL, };
> -
> - G_OBJECT_CLASS(cursor_channel_parent_class)->constructed(object);
> -
> - client_cbs.connect = red_qxl_set_cursor_peer;
> - client_cbs.disconnect = red_qxl_disconnect_cursor_peer;
> - client_cbs.migrate = red_qxl_cursor_migrate;
> - red_channel_register_client_cbs(channel, &client_cbs, NULL);
> -}
> -
> -static void
> cursor_channel_class_init(CursorChannelClass *klass)
> {
> GObjectClass *object_class = G_OBJECT_CLASS(klass);
> RedChannelClass *channel_class = RED_CHANNEL_CLASS(klass);
>
> - object_class->constructed = cursor_channel_constructed;
> object_class->finalize = cursor_channel_finalize;
>
> channel_class->parser = spice_get_client_channel_parser(SPICE_CHANNEL_CURSOR, NULL);
> @@ -524,6 +507,11 @@ cursor_channel_class_init(CursorChannelClass *klass)
>
> channel_class->on_disconnect = cursor_channel_client_on_disconnect;
> channel_class->send_item = cursor_channel_send_item;
> +
> + /* client cbs */
> + channel_class->connect = red_qxl_set_cursor_peer;
> + channel_class->disconnect = red_qxl_disconnect_cursor_peer;
> + channel_class->migrate = red_qxl_cursor_migrate;
> }
>
> static void
> diff --git a/server/display-channel.c b/server/display-channel.c
> index cccf1dea9..a55b857d6 100644
> --- a/server/display-channel.c
> +++ b/server/display-channel.c
> @@ -2310,12 +2310,11 @@ static void red_qxl_set_display_peer(RedChannel *channel, RedClient *client,
> &payload);
> }
>
> -static void red_qxl_disconnect_display_peer(RedChannelClient *rcc)
> +static void red_qxl_disconnect_display_peer(RedChannel *channel, RedChannelClient *rcc)
> {
> RedWorkerMessageDisplayDisconnect payload;
> QXLInstance *qxl;
> Dispatcher *dispatcher;
> - RedChannel *channel = red_channel_client_get_channel(rcc);
>
> if (!channel) {
> return;
> @@ -2334,12 +2333,11 @@ static void red_qxl_disconnect_display_peer(RedChannelClient *rcc)
> &payload);
> }
>
> -static void red_qxl_display_migrate(RedChannelClient *rcc)
> +static void red_qxl_display_migrate(RedChannel *channel, RedChannelClient *rcc)
> {
> RedWorkerMessageDisplayMigrate payload;
> QXLInstance *qxl;
> Dispatcher *dispatcher;
> - RedChannel *channel = red_channel_client_get_channel(rcc);
> uint32_t type, id;
>
> if (!channel) {
> @@ -2362,7 +2360,6 @@ display_channel_constructed(GObject *object)
> {
> DisplayChannel *self = DISPLAY_CHANNEL(object);
> RedChannel *channel = RED_CHANNEL(self);
> - ClientCbs client_cbs = { NULL, };
>
> G_OBJECT_CLASS(display_channel_parent_class)->constructed(object);
>
> @@ -2389,12 +2386,6 @@ display_channel_constructed(GObject *object)
> red_channel_set_cap(channel, SPICE_DISPLAY_CAP_PREF_COMPRESSION);
> red_channel_set_cap(channel, SPICE_DISPLAY_CAP_PREF_VIDEO_CODEC_TYPE);
> red_channel_set_cap(channel, SPICE_DISPLAY_CAP_STREAM_REPORT);
> -
> - client_cbs.connect = red_qxl_set_display_peer;
> - client_cbs.disconnect = red_qxl_disconnect_display_peer;
> - client_cbs.migrate = red_qxl_display_migrate;
> -
> - red_channel_register_client_cbs(channel, &client_cbs, NULL);
> }
>
> void display_channel_process_surface_cmd(DisplayChannel *display,
> @@ -2589,6 +2580,11 @@ display_channel_class_init(DisplayChannelClass *klass)
> channel_class->handle_migrate_data = handle_migrate_data;
> channel_class->handle_migrate_data_get_serial = handle_migrate_data_get_serial;
>
> + /* client cbs */
> + channel_class->connect = red_qxl_set_display_peer;
> + channel_class->disconnect = red_qxl_disconnect_display_peer;
> + channel_class->migrate = red_qxl_display_migrate;
> +
> g_object_class_install_property(object_class,
> PROP_N_SURFACES,
> g_param_spec_uint("n-surfaces",
> diff --git a/server/inputs-channel.c b/server/inputs-channel.c
> index 943c69d6c..51dec304f 100644
> --- a/server/inputs-channel.c
> +++ b/server/inputs-channel.c
> @@ -471,9 +471,9 @@ static void inputs_connect(RedChannel *channel, RedClient *client,
> inputs_pipe_add_init(rcc);
> }
>
> -static void inputs_migrate(RedChannelClient *rcc)
> +static void inputs_migrate(RedChannel *self, RedChannelClient *rcc)
> {
> - InputsChannel *inputs = INPUTS_CHANNEL(red_channel_client_get_channel(rcc));
> + InputsChannel *inputs = INPUTS_CHANNEL(self);
> inputs->src_during_migrate = TRUE;
> red_channel_client_default_migrate(rcc);
> }
> @@ -545,16 +545,11 @@ InputsChannel* inputs_channel_new(RedsState *reds)
> static void
> inputs_channel_constructed(GObject *object)
> {
> - ClientCbs client_cbs = { NULL, };
> InputsChannel *self = INPUTS_CHANNEL(object);
> RedsState *reds = red_channel_get_server(RED_CHANNEL(self));
>
> G_OBJECT_CLASS(inputs_channel_parent_class)->constructed(object);
>
> - client_cbs.connect = inputs_connect;
> - client_cbs.migrate = inputs_migrate;
> - red_channel_register_client_cbs(RED_CHANNEL(self), &client_cbs, NULL);
> -
> red_channel_set_cap(RED_CHANNEL(self), SPICE_INPUTS_CAP_KEY_SCANCODE);
> reds_register_channel(reds, RED_CHANNEL(self));
>
> @@ -598,6 +593,8 @@ inputs_channel_class_init(InputsChannelClass *klass)
> 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;
> + channel_class->connect = inputs_connect;
> + channel_class->migrate = inputs_migrate;
> }
>
> static SpiceKbdInstance* inputs_channel_get_keyboard(InputsChannel *inputs)
> diff --git a/server/main-channel-client.c b/server/main-channel-client.c
> index 82b578c8b..4f25462c1 100644
> --- a/server/main-channel-client.c
> +++ b/server/main-channel-client.c
> @@ -646,14 +646,6 @@ uint64_t main_channel_client_get_roundtrip_ms(MainChannelClient *mcc)
> return mcc->priv->latency / 1000;
> }
>
> -void main_channel_client_migrate(RedChannelClient *rcc)
> -{
> - RedChannel *channel = red_channel_client_get_channel(rcc);
> - reds_on_main_channel_migrate(red_channel_get_server(channel),
> - MAIN_CHANNEL_CLIENT(rcc));
> - red_channel_client_default_migrate(rcc);
> -}
> -
> gboolean main_channel_client_connect_semi_seamless(MainChannelClient *mcc)
> {
> RedChannelClient *rcc = RED_CHANNEL_CLIENT(mcc);
> diff --git a/server/main-channel-client.h b/server/main-channel-client.h
> index a2e38c2fb..dbdf0243d 100644
> --- a/server/main-channel-client.h
> +++ b/server/main-channel-client.h
> @@ -74,7 +74,6 @@ void main_channel_client_push_init(MainChannelClient *mcc,
> int multi_media_time,
> int ram_hint);
> void main_channel_client_push_notify(MainChannelClient *mcc, const char *msg);
> -void main_channel_client_migrate(RedChannelClient *rcc);
> gboolean main_channel_client_connect_semi_seamless(MainChannelClient *mcc);
> void main_channel_client_connect_seamless(MainChannelClient *mcc);
> void main_channel_client_handle_migrate_connected(MainChannelClient *mcc,
> diff --git a/server/main-channel.c b/server/main-channel.c
> index 4834f79b6..ec0c538ac 100644
> --- a/server/main-channel.c
> +++ b/server/main-channel.c
> @@ -283,19 +283,22 @@ MainChannel* main_channel_new(RedsState *reds)
> NULL);
> }
>
> +static void main_channel_client_migrate(RedChannel *self, RedChannelClient *rcc)
> +{
> + reds_on_main_channel_migrate(red_channel_get_server(self),
> + MAIN_CHANNEL_CLIENT(rcc));
> + red_channel_client_default_migrate(rcc);
> +}
> +
> static void
> main_channel_constructed(GObject *object)
> {
> MainChannel *self = MAIN_CHANNEL(object);
> - ClientCbs client_cbs = { NULL, };
>
> G_OBJECT_CLASS(main_channel_parent_class)->constructed(object);
>
> red_channel_set_cap(RED_CHANNEL(self), SPICE_MAIN_CAP_SEMI_SEAMLESS_MIGRATE);
> red_channel_set_cap(RED_CHANNEL(self), SPICE_MAIN_CAP_SEAMLESS_MIGRATE);
> -
> - client_cbs.migrate = main_channel_client_migrate;
> - red_channel_register_client_cbs(RED_CHANNEL(self), &client_cbs, NULL);
> }
>
> static void
> @@ -319,6 +322,8 @@ main_channel_class_init(MainChannelClass *klass)
> 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;
> + /* client cbs */
> + channel_class->migrate = main_channel_client_migrate;
> }
>
> static int main_channel_connect_semi_seamless(MainChannel *main_channel)
> diff --git a/server/red-channel.c b/server/red-channel.c
> index 9ff3474a7..b8e2e886d 100644
> --- a/server/red-channel.c
> +++ b/server/red-channel.c
> @@ -91,9 +91,6 @@ struct RedChannelPrivate
> RedChannelCapabilities local_caps;
> uint32_t migration_flags;
>
> - void *data;
> -
> - ClientCbs client_cbs;
> // TODO: when different channel_clients are in different threads
> // from Channel -> need to protect!
> pthread_t thread_id;
> @@ -201,19 +198,19 @@ red_channel_constructed(GObject *object)
> spice_assert(klass->on_disconnect);
> spice_assert(klass->handle_migrate_data ||
> !(self->priv->migration_flags & SPICE_MIGRATE_NEED_DATA_TRANSFER));
> + spice_assert(klass->connect || self->priv->type == SPICE_CHANNEL_MAIN);
> }
>
> -static void red_channel_client_default_connect(RedChannel *channel, RedClient *client,
> - RedsStream *stream,
> - int migration,
> - RedChannelCapabilities *caps)
> +static void red_channel_default_client_disconnect(RedChannel *self G_GNUC_UNUSED,
> + RedChannelClient *rcc)
> {
> - spice_error("not implemented");
> + red_channel_client_disconnect(rcc);
> }
>
> -static void red_channel_client_default_disconnect(RedChannelClient *base)
> +static void red_channel_default_client_migrate(RedChannel *self G_GNUC_UNUSED,
> + RedChannelClient *rcc)
> {
> - red_channel_client_disconnect(base);
> + red_channel_client_default_migrate(rcc);
> }
>
> static void
> @@ -229,6 +226,11 @@ red_channel_class_init(RedChannelClass *klass)
> object_class->finalize = red_channel_finalize;
> object_class->constructed = red_channel_constructed;
>
> + /* client cbs */
> + klass->disconnect = red_channel_default_client_disconnect;
> + klass->migrate = red_channel_default_client_migrate;
> + /* 'connect' must be implemented by sub-classes */
> +
> spec = g_param_spec_pointer("spice-server",
> "spice-server",
> "The spice server associated with this channel",
> @@ -296,10 +298,6 @@ red_channel_init(RedChannel *self)
>
> red_channel_set_common_cap(self, SPICE_COMMON_CAP_MINI_HEADER);
> self->priv->thread_id = pthread_self();
> -
> - self->priv->client_cbs.connect = red_channel_client_default_connect;
> - self->priv->client_cbs.disconnect = red_channel_client_default_disconnect;
> - self->priv->client_cbs.migrate = red_channel_client_default_migrate;
> }
>
>
> @@ -356,22 +354,6 @@ const RedStatNode *red_channel_get_stat_node(RedChannel *channel)
> return &channel->priv->stat;
> }
>
> -void red_channel_register_client_cbs(RedChannel *channel, const ClientCbs *client_cbs,
> - gpointer cbs_data)
> -{
> - spice_assert(client_cbs->connect || channel->priv->type == SPICE_CHANNEL_MAIN);
> - channel->priv->client_cbs.connect = client_cbs->connect;
> -
> - if (client_cbs->disconnect) {
> - channel->priv->client_cbs.disconnect = client_cbs->disconnect;
> - }
> -
> - if (client_cbs->migrate) {
> - channel->priv->client_cbs.migrate = client_cbs->migrate;
> - }
> - channel->priv->data = cbs_data;
> -}
> -
> static void add_capability(uint32_t **caps, int *num_caps, uint32_t cap)
> {
> int nbefore, n;
> @@ -489,7 +471,9 @@ void red_channel_connect(RedChannel *channel, RedClient *client,
> RedsStream *stream, int migration,
> RedChannelCapabilities *caps)
> {
> - channel->priv->client_cbs.connect(channel, client, stream, migration, caps);
> + RedChannelClass *klass = RED_CHANNEL_GET_CLASS(channel);
> + g_return_if_fail(klass->connect);
> + klass->connect(channel, client, stream, migration, caps);
> }
>
> void red_channel_apply_clients(RedChannel *channel, channel_client_callback cb)
> @@ -719,10 +703,14 @@ const RedChannelCapabilities* red_channel_get_local_capabilities(RedChannel *sel
>
> void red_channel_migrate_client(RedChannel *channel, RedChannelClient *rcc)
> {
> - channel->priv->client_cbs.migrate(rcc);
> + RedChannelClass *klass = RED_CHANNEL_GET_CLASS(channel);
> + g_return_if_fail(klass->migrate);
> + klass->migrate(channel, rcc);
> }
>
> void red_channel_disconnect_client(RedChannel *channel, RedChannelClient *rcc)
> {
> - channel->priv->client_cbs.disconnect(rcc);
> + RedChannelClass *klass = RED_CHANNEL_GET_CLASS(channel);
> + g_return_if_fail(klass->disconnect);
> + klass->disconnect(channel, rcc);
> }
> diff --git a/server/red-channel.h b/server/red-channel.h
> index e65eea1eb..c7817fa5e 100644
> --- a/server/red-channel.h
> +++ b/server/red-channel.h
> @@ -56,22 +56,12 @@ typedef uint64_t (*channel_handle_migrate_data_get_serial_proc)(RedChannelClient
> uint32_t size, void *message);
>
>
> -typedef void (*channel_client_connect_proc)(RedChannel *channel, RedClient *client, RedsStream *stream,
> +typedef void (*channel_client_connect_proc)(RedChannel *self, RedClient *client, RedsStream *stream,
> int migration, RedChannelCapabilities *caps);
> -typedef void (*channel_client_disconnect_proc)(RedChannelClient *base);
> -typedef void (*channel_client_migrate_proc)(RedChannelClient *base);
> +typedef void (*channel_client_disconnect_proc)(RedChannel *self, RedChannelClient *base);
> +typedef void (*channel_client_migrate_proc)(RedChannel *self, RedChannelClient *base);
>
>
> -/*
> - * callbacks that are triggered from client events.
> - * They should be called from the thread that handles the RedClient
> - */
> -typedef struct {
> - channel_client_connect_proc connect;
> - channel_client_disconnect_proc disconnect;
> - channel_client_migrate_proc migrate;
> -} ClientCbs;
> -
> static inline gboolean test_capability(const uint32_t *caps, int num_caps, uint32_t cap)
> {
> return VD_AGENT_HAS_CAPABILITY(caps, num_caps, cap);
> @@ -120,6 +110,14 @@ struct RedChannelClass
> channel_handle_migrate_flush_mark_proc handle_migrate_flush_mark;
> channel_handle_migrate_data_proc handle_migrate_data;
> channel_handle_migrate_data_get_serial_proc handle_migrate_data_get_serial;
> +
> + /*
> + * callbacks that are triggered from client events.
> + * They should be called from the thread that handles the RedClient
> + */
> + channel_client_connect_proc connect;
> + channel_client_disconnect_proc disconnect;
> + channel_client_migrate_proc migrate;
> };
>
> #define FOREACH_CLIENT(_channel, _data) \
> @@ -135,7 +133,6 @@ void red_channel_remove_client(RedChannel *channel, RedChannelClient *rcc);
>
> void red_channel_init_stat_node(RedChannel *channel, const RedStatNode *parent, const char *name);
>
> -void red_channel_register_client_cbs(RedChannel *channel, const ClientCbs *client_cbs, gpointer cbs_data);
> // caps are freed when the channel is destroyed
> void red_channel_set_common_cap(RedChannel *channel, uint32_t cap);
> void red_channel_set_cap(RedChannel *channel, uint32_t cap);
> diff --git a/server/smartcard.c b/server/smartcard.c
> index ac2fc1e19..e420c8d1f 100644
> --- a/server/smartcard.c
> +++ b/server/smartcard.c
> @@ -554,13 +554,9 @@ red_smartcard_channel_constructed(GObject *object)
> {
> RedSmartcardChannel *self = RED_SMARTCARD_CHANNEL(object);
> RedsState *reds = red_channel_get_server(RED_CHANNEL(self));
> - ClientCbs client_cbs = { NULL, };
>
> G_OBJECT_CLASS(red_smartcard_channel_parent_class)->constructed(object);
>
> - client_cbs.connect = smartcard_connect_client;
> - red_channel_register_client_cbs(RED_CHANNEL(self), &client_cbs, NULL);
> -
> reds_register_channel(reds, RED_CHANNEL(self));
> }
>
> @@ -579,6 +575,8 @@ red_smartcard_channel_class_init(RedSmartcardChannelClass *klass)
> channel_class->handle_migrate_flush_mark = smartcard_channel_client_handle_migrate_flush_mark;
> channel_class->handle_migrate_data = smartcard_channel_client_handle_migrate_data;
>
> + /* client cbs */
> + channel_class->connect = smartcard_connect_client;
> }
>
> static void smartcard_init(RedsState *reds)
> diff --git a/server/sound.c b/server/sound.c
> index 54b897139..4810ac2f5 100644
> --- a/server/sound.c
> +++ b/server/sound.c
> @@ -1117,7 +1117,8 @@ static void snd_set_playback_peer(RedChannel *red_channel, RedClient *client, Re
> TYPE_PLAYBACK_CHANNEL_CLIENT);
> }
>
> -static void snd_migrate_channel_client(RedChannelClient *rcc)
> +static void snd_migrate_channel_client(RedChannel *channel G_GNUC_UNUSED,
> + RedChannelClient *rcc)
> {
> snd_set_command(SND_CHANNEL_CLIENT(rcc), SND_MIGRATE_MASK);
> snd_send(SND_CHANNEL_CLIENT(rcc));
> @@ -1331,16 +1332,11 @@ playback_channel_init(PlaybackChannel *self)
> static void
> playback_channel_constructed(GObject *object)
> {
> - ClientCbs client_cbs = { NULL, };
> SndChannel *self = SND_CHANNEL(object);
> RedsState *reds = red_channel_get_server(RED_CHANNEL(self));
>
> G_OBJECT_CLASS(playback_channel_parent_class)->constructed(object);
>
> - client_cbs.connect = snd_set_playback_peer;
> - client_cbs.migrate = snd_migrate_channel_client;
> - red_channel_register_client_cbs(RED_CHANNEL(self), &client_cbs, self);
> -
> if (snd_codec_is_capable(SPICE_AUDIO_DATA_MODE_CELT_0_5_1, SND_CODEC_ANY_FREQUENCY)) {
> red_channel_set_cap(RED_CHANNEL(self), SPICE_PLAYBACK_CAP_CELT_0_5_1);
> }
> @@ -1361,6 +1357,10 @@ playback_channel_class_init(PlaybackChannelClass *klass)
> channel_class->parser = spice_get_client_channel_parser(SPICE_CHANNEL_PLAYBACK, NULL);
> channel_class->handle_message = red_channel_client_handle_message;
> channel_class->send_item = playback_channel_send_item;
> +
> + /* client cbs */
> + channel_class->connect = snd_set_playback_peer;
> + channel_class->migrate = snd_migrate_channel_client;
> }
>
> void snd_attach_playback(RedsState *reds, SpicePlaybackInstance *sin)
> @@ -1381,16 +1381,11 @@ record_channel_init(RecordChannel *self)
> static void
> record_channel_constructed(GObject *object)
> {
> - ClientCbs client_cbs = { NULL, };
> SndChannel *self = SND_CHANNEL(object);
> RedsState *reds = red_channel_get_server(RED_CHANNEL(self));
>
> G_OBJECT_CLASS(record_channel_parent_class)->constructed(object);
>
> - client_cbs.connect = snd_set_record_peer;
> - client_cbs.migrate = snd_migrate_channel_client;
> - red_channel_register_client_cbs(RED_CHANNEL(self), &client_cbs, self);
> -
> if (snd_codec_is_capable(SPICE_AUDIO_DATA_MODE_CELT_0_5_1, SND_CODEC_ANY_FREQUENCY)) {
> red_channel_set_cap(RED_CHANNEL(self), SPICE_RECORD_CAP_CELT_0_5_1);
> }
> @@ -1411,6 +1406,10 @@ record_channel_class_init(RecordChannelClass *klass)
> channel_class->parser = spice_get_client_channel_parser(SPICE_CHANNEL_RECORD, NULL);
> channel_class->handle_message = record_channel_handle_message;
> channel_class->send_item = record_channel_send_item;
> +
> + /* client cbs */
> + channel_class->connect = snd_set_record_peer;
> + channel_class->migrate = snd_migrate_channel_client;
> }
>
> void snd_attach_record(RedsState *reds, SpiceRecordInstance *sin)
> diff --git a/server/spicevmc.c b/server/spicevmc.c
> index 9305c9b4b..2f1a5b533 100644
> --- a/server/spicevmc.c
> +++ b/server/spicevmc.c
> @@ -225,14 +225,10 @@ static void
> red_vmc_channel_constructed(GObject *object)
> {
> RedVmcChannel *self = RED_VMC_CHANNEL(object);
> - ClientCbs client_cbs = { NULL, };
> RedsState *reds = red_channel_get_server(RED_CHANNEL(self));
>
> G_OBJECT_CLASS(red_vmc_channel_parent_class)->constructed(object);
>
> - client_cbs.connect = spicevmc_connect;
> - red_channel_register_client_cbs(RED_CHANNEL(self), &client_cbs, NULL);
> -
> red_channel_init_stat_node(RED_CHANNEL(self), NULL, "spicevmc");
> const RedStatNode *stat = red_channel_get_stat_node(RED_CHANNEL(self));
> stat_init_counter(&self->in_data, reds, stat, "in_data", TRUE);
> @@ -767,6 +763,9 @@ red_vmc_channel_class_init(RedVmcChannelClass *klass)
> 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;
> +
> + /* client cbs */
> + channel_class->connect = spicevmc_connect;
> }
>
> static void
> --
> 2.13.3
>
> _______________________________________________
> Spice-devel mailing list
> Spice-devel at lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/spice-devel
More information about the Spice-devel
mailing list