This function will allow to set base handlers and specific channel handlers in a common way, instead of each channel having to override the base channel virtual handle_msg(). --- gtk/channel-base.c | 39 +++++++++++++++++++++++++++++++++++++++ gtk/spice-channel-priv.h | 2 ++ gtk/spice-channel.h | 3 ++- 3 files changed, 43 insertions(+), 1 deletion(-) diff --git a/gtk/channel-base.c b/gtk/channel-base.c index dff3024..76d681a 100644 --- a/gtk/channel-base.c +++ b/gtk/channel-base.c @@ -189,3 +189,42 @@ void spice_channel_handle_migrate(SpiceChannel *channel, SpiceMsgIn *in) spice_msg_out_send_internal(out); } } + + +static void set_handlers(SpiceChannelClass *klass, + const spice_msg_handler* handlers, const int n) +{ + int i; + + g_array_set_size(klass->handlers, MAX(klass->handlers->len, n)); + for (i = 0; i < n; i++) { + if (handlers[i]) + g_array_index(klass->handlers, spice_msg_handler, i) = handlers[i]; + } +} + +static void spice_channel_add_base_handlers(SpiceChannelClass *klass) +{ + static const spice_msg_handler handlers[] = { + [ SPICE_MSG_SET_ACK ] = spice_channel_handle_set_ack, + [ SPICE_MSG_PING ] = spice_channel_handle_ping, + [ SPICE_MSG_NOTIFY ] = spice_channel_handle_notify, + [ SPICE_MSG_DISCONNECTING ] = spice_channel_handle_disconnect, + [ SPICE_MSG_WAIT_FOR_CHANNELS ] = spice_channel_handle_wait_for_channels, + [ SPICE_MSG_MIGRATE ] = spice_channel_handle_migrate, + }; + + set_handlers(klass, handlers, G_N_ELEMENTS(handlers)); +} + +G_GNUC_INTERNAL +void spice_channel_set_handlers(SpiceChannelClass *klass, + const spice_msg_handler* handlers, const int n) +{ + /* FIXME: use class private (requires glib 2.24) */ + g_return_if_fail(klass->handlers == NULL); + klass->handlers = g_array_sized_new(FALSE, TRUE, sizeof(spice_msg_handler), n); + + spice_channel_add_base_handlers(klass); + set_handlers(klass, handlers, n); +} diff --git a/gtk/spice-channel-priv.h b/gtk/spice-channel-priv.h index be061c5..0070d71 100644 --- a/gtk/spice-channel-priv.h +++ b/gtk/spice-channel-priv.h @@ -172,6 +172,8 @@ void spice_channel_handle_set_ack(SpiceChannel *channel, SpiceMsgIn *in); void spice_channel_handle_ping(SpiceChannel *channel, SpiceMsgIn *in); void spice_channel_handle_notify(SpiceChannel *channel, SpiceMsgIn *in); void spice_channel_handle_disconnect(SpiceChannel *channel, SpiceMsgIn *in); +void spice_channel_set_handlers(SpiceChannelClass *klass, + const spice_msg_handler* handlers, const int n); void spice_channel_handle_wait_for_channels(SpiceChannel *channel, SpiceMsgIn *in); void spice_channel_handle_migrate(SpiceChannel *channel, SpiceMsgIn *in); diff --git a/gtk/spice-channel.h b/gtk/spice-channel.h index 0507b68..705dddf 100644 --- a/gtk/spice-channel.h +++ b/gtk/spice-channel.h @@ -94,11 +94,12 @@ struct _SpiceChannelClass /* virtual methods, coroutine context */ void (*channel_send_migration_handshake)(SpiceChannel *channel); + GArray *handlers; /* * If adding fields to this struct, remove corresponding * amount of padding to avoid changing overall struct size */ - gchar _spice_reserved[SPICE_RESERVED_PADDING - sizeof(void *)]; + gchar _spice_reserved[SPICE_RESERVED_PADDING - 2 * sizeof(void *)]; }; GType spice_channel_get_type(void); -- 1.8.3.1 _______________________________________________ Spice-devel mailing list Spice-devel@xxxxxxxxxxxxxxxxxxxxx http://lists.freedesktop.org/mailman/listinfo/spice-devel