[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