[Spice-devel] [PATCH spice-gtk 02/14] channel: add spice_channel_set_handlers()
Marc-André Lureau
marcandre.lureau at gmail.com
Thu Sep 12 05:09:10 PDT 2013
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
More information about the Spice-devel
mailing list