[Spice-devel] [PATCH spice-gtk 02/14] channel: use base handlers array
Marc-André Lureau
marcandre.lureau at gmail.com
Tue Sep 10 07:44:01 PDT 2013
This allows to simplify a little bit derived class, to avoid overriding
handle_msg, and allows the base class more flexibility (for example for
filtering messages, as in the following patch)
---
gtk/channel-base.c | 39 +++++++++++++++++++
gtk/channel-cursor.c | 43 ++++++++-------------
gtk/channel-display.c | 97 +++++++++++++++++++++---------------------------
gtk/channel-inputs.c | 31 +++++-----------
gtk/channel-main.c | 60 +++++++++++++++---------------
gtk/channel-playback.c | 42 +++++++--------------
gtk/channel-port.c | 32 +++++-----------
gtk/channel-record.c | 36 ++++++------------
gtk/channel-smartcard.c | 21 -----------
gtk/channel-usbredir.c | 32 +++++-----------
gtk/spice-channel-priv.h | 8 +---
gtk/spice-channel.c | 18 +++------
gtk/spice-channel.h | 3 +-
13 files changed, 189 insertions(+), 273 deletions(-)
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/channel-cursor.c b/gtk/channel-cursor.c
index e4a996b..5d2db84 100644
--- a/gtk/channel-cursor.c
+++ b/gtk/channel-cursor.c
@@ -66,10 +66,10 @@ enum {
static guint signals[SPICE_CURSOR_LAST_SIGNAL];
-static void spice_cursor_handle_msg(SpiceChannel *channel, SpiceMsgIn *msg);
static void delete_cursor_all(SpiceChannel *channel);
static display_cursor * display_cursor_ref(display_cursor *cursor);
static void display_cursor_unref(display_cursor *cursor);
+static void channel_set_handlers(SpiceChannelClass *klass);
G_DEFINE_TYPE(SpiceCursorChannel, spice_cursor_channel, SPICE_TYPE_CHANNEL)
@@ -109,7 +109,6 @@ static void spice_cursor_channel_class_init(SpiceCursorChannelClass *klass)
SpiceChannelClass *channel_class = SPICE_CHANNEL_CLASS(klass);
gobject_class->finalize = spice_cursor_channel_finalize;
- channel_class->handle_msg = spice_cursor_handle_msg;
channel_class->channel_reset = spice_cursor_channel_reset;
/**
@@ -194,6 +193,7 @@ static void spice_cursor_channel_class_init(SpiceCursorChannelClass *klass)
0);
g_type_class_add_private(klass, sizeof(SpiceCursorChannelPrivate));
+ channel_set_handlers(SPICE_CHANNEL_CLASS(klass));
}
/* signal trampoline---------------------------------------------------------- */
@@ -598,31 +598,18 @@ static void cursor_handle_inval_all(SpiceChannel *channel, SpiceMsgIn *in)
delete_cursor_all(channel);
}
-static const spice_msg_handler cursor_handlers[] = {
- [ SPICE_MSG_CURSOR_INIT ] = cursor_handle_init,
- [ SPICE_MSG_CURSOR_RESET ] = cursor_handle_reset,
- [ SPICE_MSG_CURSOR_SET ] = cursor_handle_set,
- [ SPICE_MSG_CURSOR_MOVE ] = cursor_handle_move,
- [ SPICE_MSG_CURSOR_HIDE ] = cursor_handle_hide,
- [ SPICE_MSG_CURSOR_TRAIL ] = cursor_handle_trail,
- [ SPICE_MSG_CURSOR_INVAL_ONE ] = cursor_handle_inval_one,
- [ SPICE_MSG_CURSOR_INVAL_ALL ] = cursor_handle_inval_all,
-};
-
-/* coroutine context */
-static void spice_cursor_handle_msg(SpiceChannel *channel, SpiceMsgIn *msg)
+static void channel_set_handlers(SpiceChannelClass *klass)
{
- int type = spice_msg_in_type(msg);
- SpiceChannelClass *parent_class;
-
- g_return_if_fail(type < SPICE_N_ELEMENTS(cursor_handlers));
-
- parent_class = SPICE_CHANNEL_CLASS(spice_cursor_channel_parent_class);
-
- if (cursor_handlers[type] != NULL)
- cursor_handlers[type](channel, msg);
- else if (parent_class->handle_msg)
- parent_class->handle_msg(channel, msg);
- else
- g_return_if_reached();
+ static const spice_msg_handler handlers[] = {
+ [ SPICE_MSG_CURSOR_INIT ] = cursor_handle_init,
+ [ SPICE_MSG_CURSOR_RESET ] = cursor_handle_reset,
+ [ SPICE_MSG_CURSOR_SET ] = cursor_handle_set,
+ [ SPICE_MSG_CURSOR_MOVE ] = cursor_handle_move,
+ [ SPICE_MSG_CURSOR_HIDE ] = cursor_handle_hide,
+ [ SPICE_MSG_CURSOR_TRAIL ] = cursor_handle_trail,
+ [ SPICE_MSG_CURSOR_INVAL_ONE ] = cursor_handle_inval_one,
+ [ SPICE_MSG_CURSOR_INVAL_ALL ] = cursor_handle_inval_all,
+ };
+
+ spice_channel_set_handlers(klass, handlers, G_N_ELEMENTS(handlers));
}
diff --git a/gtk/channel-display.c b/gtk/channel-display.c
index 704d5a7..08d5dcb 100644
--- a/gtk/channel-display.c
+++ b/gtk/channel-display.c
@@ -107,8 +107,8 @@ enum {
static guint signals[SPICE_DISPLAY_LAST_SIGNAL];
-static void spice_display_handle_msg(SpiceChannel *channel, SpiceMsgIn *msg);
static void spice_display_channel_up(SpiceChannel *channel);
+static void channel_set_handlers(SpiceChannelClass *klass);
static void clear_surfaces(SpiceChannel *channel, gboolean keep_primary);
static void clear_streams(SpiceChannel *channel);
@@ -235,7 +235,6 @@ static void spice_display_channel_class_init(SpiceDisplayChannelClass *klass)
gobject_class->set_property = spice_display_set_property;
gobject_class->constructed = spice_display_channel_constructed;
- channel_class->handle_msg = spice_display_handle_msg;
channel_class->channel_up = spice_display_channel_up;
channel_class->channel_reset = spice_display_channel_reset;
channel_class->channel_reset_capabilities = spice_display_channel_reset_capabilities;
@@ -387,6 +386,7 @@ static void spice_display_channel_class_init(SpiceDisplayChannelClass *klass)
sw_canvas_init();
quic_init();
rop3_init();
+ channel_set_handlers(SPICE_CHANNEL_CLASS(klass));
}
/**
@@ -1841,58 +1841,45 @@ static void display_handle_monitors_config(SpiceChannel *channel, SpiceMsgIn *in
g_object_notify_main_context(G_OBJECT(channel), "monitors");
}
-static const spice_msg_handler display_handlers[] = {
- [ SPICE_MSG_DISPLAY_MODE ] = display_handle_mode,
- [ SPICE_MSG_DISPLAY_MARK ] = display_handle_mark,
- [ SPICE_MSG_DISPLAY_RESET ] = display_handle_reset,
- [ SPICE_MSG_DISPLAY_COPY_BITS ] = display_handle_copy_bits,
- [ SPICE_MSG_DISPLAY_INVAL_LIST ] = display_handle_inv_list,
- [ SPICE_MSG_DISPLAY_INVAL_ALL_PIXMAPS ] = display_handle_inv_pixmap_all,
- [ SPICE_MSG_DISPLAY_INVAL_PALETTE ] = display_handle_inv_palette,
- [ SPICE_MSG_DISPLAY_INVAL_ALL_PALETTES ] = display_handle_inv_palette_all,
-
- [ SPICE_MSG_DISPLAY_STREAM_CREATE ] = display_handle_stream_create,
- [ SPICE_MSG_DISPLAY_STREAM_DATA ] = display_handle_stream_data,
- [ SPICE_MSG_DISPLAY_STREAM_CLIP ] = display_handle_stream_clip,
- [ SPICE_MSG_DISPLAY_STREAM_DESTROY ] = display_handle_stream_destroy,
- [ SPICE_MSG_DISPLAY_STREAM_DESTROY_ALL ] = display_handle_stream_destroy_all,
- [ SPICE_MSG_DISPLAY_STREAM_DATA_SIZED ] = display_handle_stream_data,
- [ SPICE_MSG_DISPLAY_STREAM_ACTIVATE_REPORT ] = display_handle_stream_activate_report,
-
- [ SPICE_MSG_DISPLAY_DRAW_FILL ] = display_handle_draw_fill,
- [ SPICE_MSG_DISPLAY_DRAW_OPAQUE ] = display_handle_draw_opaque,
- [ SPICE_MSG_DISPLAY_DRAW_COPY ] = display_handle_draw_copy,
- [ SPICE_MSG_DISPLAY_DRAW_BLEND ] = display_handle_draw_blend,
- [ SPICE_MSG_DISPLAY_DRAW_BLACKNESS ] = display_handle_draw_blackness,
- [ SPICE_MSG_DISPLAY_DRAW_WHITENESS ] = display_handle_draw_whiteness,
- [ SPICE_MSG_DISPLAY_DRAW_INVERS ] = display_handle_draw_invers,
- [ SPICE_MSG_DISPLAY_DRAW_ROP3 ] = display_handle_draw_rop3,
- [ SPICE_MSG_DISPLAY_DRAW_STROKE ] = display_handle_draw_stroke,
- [ SPICE_MSG_DISPLAY_DRAW_TEXT ] = display_handle_draw_text,
- [ SPICE_MSG_DISPLAY_DRAW_TRANSPARENT ] = display_handle_draw_transparent,
- [ SPICE_MSG_DISPLAY_DRAW_ALPHA_BLEND ] = display_handle_draw_alpha_blend,
- [ SPICE_MSG_DISPLAY_DRAW_COMPOSITE ] = display_handle_draw_composite,
-
- [ SPICE_MSG_DISPLAY_SURFACE_CREATE ] = display_handle_surface_create,
- [ SPICE_MSG_DISPLAY_SURFACE_DESTROY ] = display_handle_surface_destroy,
-
- [ SPICE_MSG_DISPLAY_MONITORS_CONFIG ] = display_handle_monitors_config,
-};
-
-/* coroutine context */
-static void spice_display_handle_msg(SpiceChannel *channel, SpiceMsgIn *msg)
-{
- int type = spice_msg_in_type(msg);
- SpiceChannelClass *parent_class;
-
- g_return_if_fail(type < SPICE_N_ELEMENTS(display_handlers));
-
- parent_class = SPICE_CHANNEL_CLASS(spice_display_channel_parent_class);
+static void channel_set_handlers(SpiceChannelClass *klass)
+{
+ static const spice_msg_handler handlers[] = {
+ [ SPICE_MSG_DISPLAY_MODE ] = display_handle_mode,
+ [ SPICE_MSG_DISPLAY_MARK ] = display_handle_mark,
+ [ SPICE_MSG_DISPLAY_RESET ] = display_handle_reset,
+ [ SPICE_MSG_DISPLAY_COPY_BITS ] = display_handle_copy_bits,
+ [ SPICE_MSG_DISPLAY_INVAL_LIST ] = display_handle_inv_list,
+ [ SPICE_MSG_DISPLAY_INVAL_ALL_PIXMAPS ] = display_handle_inv_pixmap_all,
+ [ SPICE_MSG_DISPLAY_INVAL_PALETTE ] = display_handle_inv_palette,
+ [ SPICE_MSG_DISPLAY_INVAL_ALL_PALETTES ] = display_handle_inv_palette_all,
+
+ [ SPICE_MSG_DISPLAY_STREAM_CREATE ] = display_handle_stream_create,
+ [ SPICE_MSG_DISPLAY_STREAM_DATA ] = display_handle_stream_data,
+ [ SPICE_MSG_DISPLAY_STREAM_CLIP ] = display_handle_stream_clip,
+ [ SPICE_MSG_DISPLAY_STREAM_DESTROY ] = display_handle_stream_destroy,
+ [ SPICE_MSG_DISPLAY_STREAM_DESTROY_ALL ] = display_handle_stream_destroy_all,
+ [ SPICE_MSG_DISPLAY_STREAM_DATA_SIZED ] = display_handle_stream_data,
+ [ SPICE_MSG_DISPLAY_STREAM_ACTIVATE_REPORT ] = display_handle_stream_activate_report,
+
+ [ SPICE_MSG_DISPLAY_DRAW_FILL ] = display_handle_draw_fill,
+ [ SPICE_MSG_DISPLAY_DRAW_OPAQUE ] = display_handle_draw_opaque,
+ [ SPICE_MSG_DISPLAY_DRAW_COPY ] = display_handle_draw_copy,
+ [ SPICE_MSG_DISPLAY_DRAW_BLEND ] = display_handle_draw_blend,
+ [ SPICE_MSG_DISPLAY_DRAW_BLACKNESS ] = display_handle_draw_blackness,
+ [ SPICE_MSG_DISPLAY_DRAW_WHITENESS ] = display_handle_draw_whiteness,
+ [ SPICE_MSG_DISPLAY_DRAW_INVERS ] = display_handle_draw_invers,
+ [ SPICE_MSG_DISPLAY_DRAW_ROP3 ] = display_handle_draw_rop3,
+ [ SPICE_MSG_DISPLAY_DRAW_STROKE ] = display_handle_draw_stroke,
+ [ SPICE_MSG_DISPLAY_DRAW_TEXT ] = display_handle_draw_text,
+ [ SPICE_MSG_DISPLAY_DRAW_TRANSPARENT ] = display_handle_draw_transparent,
+ [ SPICE_MSG_DISPLAY_DRAW_ALPHA_BLEND ] = display_handle_draw_alpha_blend,
+ [ SPICE_MSG_DISPLAY_DRAW_COMPOSITE ] = display_handle_draw_composite,
+
+ [ SPICE_MSG_DISPLAY_SURFACE_CREATE ] = display_handle_surface_create,
+ [ SPICE_MSG_DISPLAY_SURFACE_DESTROY ] = display_handle_surface_destroy,
+
+ [ SPICE_MSG_DISPLAY_MONITORS_CONFIG ] = display_handle_monitors_config,
+ };
- if (display_handlers[type] != NULL)
- display_handlers[type](channel, msg);
- else if (parent_class->handle_msg)
- parent_class->handle_msg(channel, msg);
- else
- g_return_if_reached();
+ spice_channel_set_handlers(klass, handlers, G_N_ELEMENTS(handlers));
}
diff --git a/gtk/channel-inputs.c b/gtk/channel-inputs.c
index ee86dc2..a69dbe6 100644
--- a/gtk/channel-inputs.c
+++ b/gtk/channel-inputs.c
@@ -67,9 +67,9 @@ enum {
static guint signals[SPICE_INPUTS_LAST_SIGNAL];
-static void spice_inputs_handle_msg(SpiceChannel *channel, SpiceMsgIn *msg);
static void spice_inputs_channel_up(SpiceChannel *channel);
static void spice_inputs_channel_reset(SpiceChannel *channel, gboolean migrating);
+static void channel_set_handlers(SpiceChannelClass *klass);
/* ------------------------------------------------------------------ */
@@ -108,7 +108,6 @@ static void spice_inputs_channel_class_init(SpiceInputsChannelClass *klass)
gobject_class->finalize = spice_inputs_channel_finalize;
gobject_class->get_property = spice_inputs_get_property;
- channel_class->handle_msg = spice_inputs_handle_msg;
channel_class->channel_up = spice_inputs_channel_up;
channel_class->channel_reset = spice_inputs_channel_reset;
@@ -143,6 +142,7 @@ static void spice_inputs_channel_class_init(SpiceInputsChannelClass *klass)
0);
g_type_class_add_private(klass, sizeof(SpiceInputsChannelPrivate));
+ channel_set_handlers(SPICE_CHANNEL_CLASS(klass));
}
/* signal trampoline---------------------------------------------------------- */
@@ -281,28 +281,15 @@ static void inputs_handle_ack(SpiceChannel *channel, SpiceMsgIn *in)
}
}
-static const spice_msg_handler inputs_handlers[] = {
- [ SPICE_MSG_INPUTS_INIT ] = inputs_handle_init,
- [ SPICE_MSG_INPUTS_KEY_MODIFIERS ] = inputs_handle_modifiers,
- [ SPICE_MSG_INPUTS_MOUSE_MOTION_ACK ] = inputs_handle_ack,
-};
-
-/* coroutine context */
-static void spice_inputs_handle_msg(SpiceChannel *channel, SpiceMsgIn *msg)
+static void channel_set_handlers(SpiceChannelClass *klass)
{
- int type = spice_msg_in_type(msg);
- SpiceChannelClass *parent_class;
-
- g_return_if_fail(type < SPICE_N_ELEMENTS(inputs_handlers));
-
- parent_class = SPICE_CHANNEL_CLASS(spice_inputs_channel_parent_class);
+ static const spice_msg_handler handlers[] = {
+ [ SPICE_MSG_INPUTS_INIT ] = inputs_handle_init,
+ [ SPICE_MSG_INPUTS_KEY_MODIFIERS ] = inputs_handle_modifiers,
+ [ SPICE_MSG_INPUTS_MOUSE_MOTION_ACK ] = inputs_handle_ack,
+ };
- if (inputs_handlers[type] != NULL)
- inputs_handlers[type](channel, msg);
- else if (parent_class->handle_msg)
- parent_class->handle_msg(channel, msg);
- else
- g_return_if_reached();
+ spice_channel_set_handlers(klass, handlers, G_N_ELEMENTS(handlers));
}
/**
diff --git a/gtk/channel-main.c b/gtk/channel-main.c
index 93995f1..b342e97 100644
--- a/gtk/channel-main.c
+++ b/gtk/channel-main.c
@@ -158,6 +158,7 @@ enum {
static guint signals[SPICE_MAIN_LAST_SIGNAL];
static void spice_main_handle_msg(SpiceChannel *channel, SpiceMsgIn *msg);
+static void channel_set_handlers(SpiceChannelClass *klass);
static void agent_send_msg_queue(SpiceMainChannel *channel);
static void agent_free_msg_queue(SpiceMainChannel *channel);
static void migrate_channel_event_cb(SpiceChannel *channel, SpiceChannelEvent event,
@@ -728,6 +729,7 @@ static void spice_main_channel_class_init(SpiceMainChannelClass *klass)
G_TYPE_OBJECT);
g_type_class_add_private(klass, sizeof(SpiceMainChannelPrivate));
+ channel_set_handlers(SPICE_CHANNEL_CLASS(klass));
}
/* signal trampoline---------------------------------------------------------- */
@@ -2316,28 +2318,33 @@ static void main_handle_migrate_cancel(SpiceChannel *channel,
spice_session_abort_migration(session);
}
-static const spice_msg_handler main_handlers[] = {
- [ SPICE_MSG_MAIN_INIT ] = main_handle_init,
- [ SPICE_MSG_MAIN_NAME ] = main_handle_name,
- [ SPICE_MSG_MAIN_UUID ] = main_handle_uuid,
- [ SPICE_MSG_MAIN_CHANNELS_LIST ] = main_handle_channels_list,
- [ SPICE_MSG_MAIN_MOUSE_MODE ] = main_handle_mouse_mode,
- [ SPICE_MSG_MAIN_MULTI_MEDIA_TIME ] = main_handle_mm_time,
-
- [ SPICE_MSG_MAIN_AGENT_CONNECTED ] = main_handle_agent_connected,
- [ SPICE_MSG_MAIN_AGENT_DISCONNECTED ] = main_handle_agent_disconnected,
- [ SPICE_MSG_MAIN_AGENT_DATA ] = main_handle_agent_data,
- [ SPICE_MSG_MAIN_AGENT_TOKEN ] = main_handle_agent_token,
-
- [ SPICE_MSG_MAIN_MIGRATE_BEGIN ] = main_handle_migrate_begin,
- [ SPICE_MSG_MAIN_MIGRATE_END ] = main_handle_migrate_end,
- [ SPICE_MSG_MAIN_MIGRATE_CANCEL ] = main_handle_migrate_cancel,
- [ SPICE_MSG_MAIN_MIGRATE_SWITCH_HOST ] = main_handle_migrate_switch_host,
- [ SPICE_MSG_MAIN_AGENT_CONNECTED_TOKENS ] = main_handle_agent_connected_tokens,
- [ SPICE_MSG_MAIN_MIGRATE_BEGIN_SEAMLESS ] = main_handle_migrate_begin_seamless,
- [ SPICE_MSG_MAIN_MIGRATE_DST_SEAMLESS_ACK] = main_handle_migrate_dst_seamless_ack,
- [ SPICE_MSG_MAIN_MIGRATE_DST_SEAMLESS_NACK] = main_handle_migrate_dst_seamless_nack,
-};
+static void channel_set_handlers(SpiceChannelClass *klass)
+{
+ static const spice_msg_handler handlers[] = {
+ [ SPICE_MSG_MAIN_INIT ] = main_handle_init,
+ [ SPICE_MSG_MAIN_NAME ] = main_handle_name,
+ [ SPICE_MSG_MAIN_UUID ] = main_handle_uuid,
+ [ SPICE_MSG_MAIN_CHANNELS_LIST ] = main_handle_channels_list,
+ [ SPICE_MSG_MAIN_MOUSE_MODE ] = main_handle_mouse_mode,
+ [ SPICE_MSG_MAIN_MULTI_MEDIA_TIME ] = main_handle_mm_time,
+
+ [ SPICE_MSG_MAIN_AGENT_CONNECTED ] = main_handle_agent_connected,
+ [ SPICE_MSG_MAIN_AGENT_DISCONNECTED ] = main_handle_agent_disconnected,
+ [ SPICE_MSG_MAIN_AGENT_DATA ] = main_handle_agent_data,
+ [ SPICE_MSG_MAIN_AGENT_TOKEN ] = main_handle_agent_token,
+
+ [ SPICE_MSG_MAIN_MIGRATE_BEGIN ] = main_handle_migrate_begin,
+ [ SPICE_MSG_MAIN_MIGRATE_END ] = main_handle_migrate_end,
+ [ SPICE_MSG_MAIN_MIGRATE_CANCEL ] = main_handle_migrate_cancel,
+ [ SPICE_MSG_MAIN_MIGRATE_SWITCH_HOST ] = main_handle_migrate_switch_host,
+ [ SPICE_MSG_MAIN_AGENT_CONNECTED_TOKENS ] = main_handle_agent_connected_tokens,
+ [ SPICE_MSG_MAIN_MIGRATE_BEGIN_SEAMLESS ] = main_handle_migrate_begin_seamless,
+ [ SPICE_MSG_MAIN_MIGRATE_DST_SEAMLESS_ACK] = main_handle_migrate_dst_seamless_ack,
+ [ SPICE_MSG_MAIN_MIGRATE_DST_SEAMLESS_NACK] = main_handle_migrate_dst_seamless_nack,
+ };
+
+ spice_channel_set_handlers(klass, handlers, G_N_ELEMENTS(handlers));
+}
/* coroutine context */
static void spice_main_handle_msg(SpiceChannel *channel, SpiceMsgIn *msg)
@@ -2346,8 +2353,6 @@ static void spice_main_handle_msg(SpiceChannel *channel, SpiceMsgIn *msg)
SpiceChannelClass *parent_class;
SpiceChannelPrivate *c = SPICE_CHANNEL(channel)->priv;
- g_return_if_fail(type < SPICE_N_ELEMENTS(main_handlers));
-
parent_class = SPICE_CHANNEL_CLASS(spice_main_channel_parent_class);
if (c->state == SPICE_CHANNEL_STATE_MIGRATION_HANDSHAKE) {
@@ -2359,12 +2364,7 @@ static void spice_main_handle_msg(SpiceChannel *channel, SpiceMsgIn *msg)
}
}
- if (main_handlers[type] != NULL)
- main_handlers[type](channel, msg);
- else if (parent_class->handle_msg)
- parent_class->handle_msg(channel, msg);
- else
- g_return_if_reached();
+ parent_class->handle_msg(channel, msg);
}
/**
diff --git a/gtk/channel-playback.c b/gtk/channel-playback.c
index f246a80..60fc113 100644
--- a/gtk/channel-playback.c
+++ b/gtk/channel-playback.c
@@ -82,8 +82,7 @@ enum {
};
static guint signals[SPICE_PLAYBACK_LAST_SIGNAL];
-
-static void spice_playback_handle_msg(SpiceChannel *channel, SpiceMsgIn *msg);
+static void channel_set_handlers(SpiceChannelClass *klass);
/* ------------------------------------------------------------------ */
@@ -197,7 +196,6 @@ static void spice_playback_channel_class_init(SpicePlaybackChannelClass *klass)
gobject_class->get_property = spice_playback_channel_get_property;
gobject_class->set_property = spice_playback_channel_set_property;
- channel_class->handle_msg = spice_playback_handle_msg;
channel_class->channel_reset = spice_playback_channel_reset;
channel_class->channel_reset_capabilities = spice_playback_channel_reset_capabilities;
@@ -308,6 +306,7 @@ static void spice_playback_channel_class_init(SpicePlaybackChannelClass *klass)
0);
g_type_class_add_private(klass, sizeof(SpicePlaybackChannelPrivate));
+ channel_set_handlers(SPICE_CHANNEL_CLASS(klass));
}
/* signal trampoline---------------------------------------------------------- */
@@ -517,32 +516,19 @@ static void playback_handle_set_latency(SpiceChannel *channel, SpiceMsgIn *in)
g_object_notify_main_context(G_OBJECT(channel), "min-latency");
}
-static const spice_msg_handler playback_handlers[] = {
- [ SPICE_MSG_PLAYBACK_DATA ] = playback_handle_data,
- [ SPICE_MSG_PLAYBACK_MODE ] = playback_handle_mode,
- [ SPICE_MSG_PLAYBACK_START ] = playback_handle_start,
- [ SPICE_MSG_PLAYBACK_STOP ] = playback_handle_stop,
- [ SPICE_MSG_PLAYBACK_VOLUME ] = playback_handle_set_volume,
- [ SPICE_MSG_PLAYBACK_MUTE ] = playback_handle_set_mute,
- [ SPICE_MSG_PLAYBACK_LATENCY ] = playback_handle_set_latency,
-};
-
-/* coroutine context */
-static void spice_playback_handle_msg(SpiceChannel *channel, SpiceMsgIn *msg)
+static void channel_set_handlers(SpiceChannelClass *klass)
{
- int type = spice_msg_in_type(msg);
- SpiceChannelClass *parent_class;
-
- g_return_if_fail(type < SPICE_N_ELEMENTS(playback_handlers));
-
- parent_class = SPICE_CHANNEL_CLASS(spice_playback_channel_parent_class);
-
- if (playback_handlers[type] != NULL)
- playback_handlers[type](channel, msg);
- else if (parent_class->handle_msg)
- parent_class->handle_msg(channel, msg);
- else
- g_return_if_reached();
+ static const spice_msg_handler handlers[] = {
+ [ SPICE_MSG_PLAYBACK_DATA ] = playback_handle_data,
+ [ SPICE_MSG_PLAYBACK_MODE ] = playback_handle_mode,
+ [ SPICE_MSG_PLAYBACK_START ] = playback_handle_start,
+ [ SPICE_MSG_PLAYBACK_STOP ] = playback_handle_stop,
+ [ SPICE_MSG_PLAYBACK_VOLUME ] = playback_handle_set_volume,
+ [ SPICE_MSG_PLAYBACK_MUTE ] = playback_handle_set_mute,
+ [ SPICE_MSG_PLAYBACK_LATENCY ] = playback_handle_set_latency,
+ };
+
+ spice_channel_set_handlers(klass, handlers, G_N_ELEMENTS(handlers));
}
void spice_playback_channel_set_delay(SpicePlaybackChannel *channel, guint32 delay_ms)
diff --git a/gtk/channel-port.c b/gtk/channel-port.c
index 1d6eef2..11948bb 100644
--- a/gtk/channel-port.c
+++ b/gtk/channel-port.c
@@ -76,8 +76,7 @@ enum {
};
static guint signals[LAST_SIGNAL];
-
-static void spice_port_handle_msg(SpiceChannel *channel, SpiceMsgIn *msg);
+static void channel_set_handlers(SpiceChannelClass *klass);
static void spice_port_channel_init(SpicePortChannel *channel)
{
@@ -131,7 +130,6 @@ static void spice_port_channel_class_init(SpicePortChannelClass *klass)
gobject_class->finalize = spice_port_channel_finalize;
gobject_class->get_property = spice_port_get_property;
- channel_class->handle_msg = spice_port_handle_msg;
channel_class->channel_reset = spice_port_channel_reset;
g_object_class_install_property
@@ -194,6 +192,7 @@ static void spice_port_channel_class_init(SpicePortChannelClass *klass)
G_TYPE_INT);
g_type_class_add_private(klass, sizeof(SpicePortChannelPrivate));
+ channel_set_handlers(SPICE_CHANNEL_CLASS(klass));
}
/* signal trampoline---------------------------------------------------------- */
@@ -401,26 +400,13 @@ void spice_port_event(SpicePortChannel *self, guint8 event)
spice_msg_out_send(msg);
}
-static const spice_msg_handler port_handlers[] = {
- [ SPICE_MSG_PORT_INIT ] = port_handle_init,
- [ SPICE_MSG_PORT_EVENT ] = port_handle_event,
- [ SPICE_MSG_SPICEVMC_DATA ] = port_handle_msg,
-};
-
-/* coroutine context */
-static void spice_port_handle_msg(SpiceChannel *channel, SpiceMsgIn *msg)
+static void channel_set_handlers(SpiceChannelClass *klass)
{
- int type = spice_msg_in_type(msg);
- SpiceChannelClass *parent_class;
-
- g_return_if_fail(type < SPICE_N_ELEMENTS(port_handlers));
-
- parent_class = SPICE_CHANNEL_CLASS(spice_port_channel_parent_class);
+ static const spice_msg_handler handlers[] = {
+ [ SPICE_MSG_PORT_INIT ] = port_handle_init,
+ [ SPICE_MSG_PORT_EVENT ] = port_handle_event,
+ [ SPICE_MSG_SPICEVMC_DATA ] = port_handle_msg,
+ };
- if (port_handlers[type] != NULL)
- port_handlers[type](channel, msg);
- else if (parent_class->handle_msg)
- parent_class->handle_msg(channel, msg);
- else
- g_return_if_reached();
+ spice_channel_set_handlers(klass, handlers, G_N_ELEMENTS(handlers));
}
diff --git a/gtk/channel-record.c b/gtk/channel-record.c
index 6345569..e1f3ec7 100644
--- a/gtk/channel-record.c
+++ b/gtk/channel-record.c
@@ -81,7 +81,7 @@ enum {
static guint signals[SPICE_RECORD_LAST_SIGNAL];
-static void spice_record_handle_msg(SpiceChannel *channel, SpiceMsgIn *msg);
+static void channel_set_handlers(SpiceChannelClass *klass);
static void channel_up(SpiceChannel *channel);
#define FRAME_SIZE 256
@@ -197,7 +197,6 @@ static void spice_record_channel_class_init(SpiceRecordChannelClass *klass)
gobject_class->finalize = spice_record_channel_finalize;
gobject_class->get_property = spice_record_channel_get_property;
gobject_class->set_property = spice_record_channel_set_property;
- channel_class->handle_msg = spice_record_handle_msg;
channel_class->channel_up = channel_up;
channel_class->channel_reset = channel_reset;
channel_class->channel_reset_capabilities = spice_record_channel_reset_capabilities;
@@ -265,6 +264,7 @@ static void spice_record_channel_class_init(SpiceRecordChannelClass *klass)
0);
g_type_class_add_private(klass, sizeof(SpiceRecordChannelPrivate));
+ channel_set_handlers(SPICE_CHANNEL_CLASS(klass));
}
/* signal trampoline---------------------------------------------------------- */
@@ -521,28 +521,14 @@ static void record_handle_set_mute(SpiceChannel *channel, SpiceMsgIn *in)
g_object_notify_main_context(G_OBJECT(channel), "mute");
}
-static const spice_msg_handler record_handlers[] = {
- [ SPICE_MSG_RECORD_START ] = record_handle_start,
- [ SPICE_MSG_RECORD_STOP ] = record_handle_stop,
- [ SPICE_MSG_RECORD_VOLUME ] = record_handle_set_volume,
- [ SPICE_MSG_RECORD_MUTE ] = record_handle_set_mute,
-};
-
-/* coroutine context */
-static void spice_record_handle_msg(SpiceChannel *channel, SpiceMsgIn *msg)
+static void channel_set_handlers(SpiceChannelClass *klass)
{
- int type = spice_msg_in_type(msg);
-
- SpiceChannelClass *parent_class;
-
- g_return_if_fail(type < SPICE_N_ELEMENTS(record_handlers));
-
- parent_class = SPICE_CHANNEL_CLASS(spice_record_channel_parent_class);
-
- if (record_handlers[type] != NULL)
- record_handlers[type](channel, msg);
- else if (parent_class->handle_msg)
- parent_class->handle_msg(channel, msg);
- else
- g_return_if_reached();
+ static const spice_msg_handler handlers[] = {
+ [ SPICE_MSG_RECORD_START ] = record_handle_start,
+ [ SPICE_MSG_RECORD_STOP ] = record_handle_stop,
+ [ SPICE_MSG_RECORD_VOLUME ] = record_handle_set_volume,
+ [ SPICE_MSG_RECORD_MUTE ] = record_handle_set_mute,
+ };
+
+ spice_channel_set_handlers(klass, handlers, G_N_ELEMENTS(handlers));
}
diff --git a/gtk/channel-smartcard.c b/gtk/channel-smartcard.c
index 21b8343..0b5e050 100644
--- a/gtk/channel-smartcard.c
+++ b/gtk/channel-smartcard.c
@@ -95,7 +95,6 @@ enum {
SPICE_SMARTCARD_LAST_SIGNAL,
};
-static void spice_smartcard_handle_msg(SpiceChannel *channel, SpiceMsgIn *msg);
static void spice_smartcard_channel_up(SpiceChannel *channel);
static void handle_smartcard_msg(SpiceChannel *channel, SpiceMsgIn *in);
static void smartcard_message_free(SpiceSmartcardChannelMessage *message);
@@ -217,7 +216,6 @@ static void spice_smartcard_channel_class_init(SpiceSmartcardChannelClass *klass
gobject_class->finalize = spice_smartcard_channel_finalize;
gobject_class->constructed = spice_smartcard_channel_constructed;
- channel_class->handle_msg = spice_smartcard_handle_msg;
channel_class->channel_up = spice_smartcard_channel_up;
channel_class->channel_reset = spice_smartcard_channel_reset;
@@ -442,24 +440,6 @@ static void card_removed_cb(SpiceSmartcardManager *manager, VReader *reader,
}
#endif /* USE_SMARTCARD */
-/* coroutine context */
-static void spice_smartcard_handle_msg(SpiceChannel *channel, SpiceMsgIn *msg)
-{
- int type = spice_msg_in_type(msg);
- SpiceChannelClass *parent_class;
-
- g_return_if_fail(type < SPICE_N_ELEMENTS(smartcard_handlers));
-
- parent_class = SPICE_CHANNEL_CLASS(spice_smartcard_channel_parent_class);
-
- if (smartcard_handlers[type] != NULL)
- smartcard_handlers[type](channel, msg);
- else if (parent_class->handle_msg)
- parent_class->handle_msg(channel, msg);
- else
- g_return_if_reached();
-}
-
static void spice_smartcard_channel_up_cb(GObject *source_object,
GAsyncResult *res,
gpointer user_data)
@@ -570,4 +550,3 @@ static void handle_smartcard_msg(SpiceChannel *channel, SpiceMsgIn *in)
}
#endif
}
-
diff --git a/gtk/channel-usbredir.c b/gtk/channel-usbredir.c
index 11bf38c..239fe12 100644
--- a/gtk/channel-usbredir.c
+++ b/gtk/channel-usbredir.c
@@ -81,7 +81,7 @@ struct _SpiceUsbredirChannelPrivate {
#endif
};
-static void spice_usbredir_handle_msg(SpiceChannel *channel, SpiceMsgIn *msg);
+static void channel_set_handlers(SpiceChannelClass *klass);
static void spice_usbredir_channel_up(SpiceChannel *channel);
static void spice_usbredir_channel_dispose(GObject *obj);
static void spice_usbredir_channel_finalize(GObject *obj);
@@ -136,11 +136,11 @@ static void spice_usbredir_channel_class_init(SpiceUsbredirChannelClass *klass)
gobject_class->dispose = spice_usbredir_channel_dispose;
gobject_class->finalize = spice_usbredir_channel_finalize;
- channel_class->handle_msg = spice_usbredir_handle_msg;
channel_class->channel_up = spice_usbredir_channel_up;
channel_class->channel_reset = spice_usbredir_channel_reset;
g_type_class_add_private(klass, sizeof(SpiceUsbredirChannelPrivate));
+ channel_set_handlers(SPICE_CHANNEL_CLASS(klass));
#endif
}
@@ -188,9 +188,14 @@ static void spice_usbredir_channel_finalize(GObject *obj)
G_OBJECT_CLASS(spice_usbredir_channel_parent_class)->finalize(obj);
}
-static const spice_msg_handler usbredir_handlers[] = {
- [ SPICE_MSG_SPICEVMC_DATA ] = usbredir_handle_msg,
-};
+static void channel_set_handlers(SpiceChannelClass *klass)
+{
+ static const spice_msg_handler handlers[] = {
+ [ SPICE_MSG_SPICEVMC_DATA ] = usbredir_handle_msg,
+ };
+
+ spice_channel_set_handlers(klass, handlers, G_N_ELEMENTS(handlers));
+}
/* ------------------------------------------------------------------ */
/* private api */
@@ -608,23 +613,6 @@ static void do_emit_main_context(GObject *object, int event, gpointer params)
/* --------------------------------------------------------------------- */
/* coroutine context */
-static void spice_usbredir_handle_msg(SpiceChannel *c, SpiceMsgIn *msg)
-{
- int type = spice_msg_in_type(msg);
- SpiceChannelClass *parent_class;
-
- g_return_if_fail(type < SPICE_N_ELEMENTS(usbredir_handlers));
-
- parent_class = SPICE_CHANNEL_CLASS(spice_usbredir_channel_parent_class);
-
- if (usbredir_handlers[type] != NULL)
- usbredir_handlers[type](c, msg);
- else if (parent_class->handle_msg)
- parent_class->handle_msg(c, msg);
- else
- g_return_if_reached();
-}
-
static void spice_usbredir_channel_up(SpiceChannel *c)
{
SpiceUsbredirChannel *channel = SPICE_USBREDIR_CHANNEL(c);
diff --git a/gtk/spice-channel-priv.h b/gtk/spice-channel-priv.h
index be061c5..92c9315 100644
--- a/gtk/spice-channel-priv.h
+++ b/gtk/spice-channel-priv.h
@@ -167,13 +167,9 @@ typedef void (*handler_msg_in)(SpiceChannel *channel, SpiceMsgIn *msg, gpointer
void spice_channel_recv_msg(SpiceChannel *channel, handler_msg_in handler, gpointer data);
/* channel-base.c */
-/* coroutine context */
-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);
gint spice_channel_get_channel_id(SpiceChannel *channel);
gint spice_channel_get_channel_type(SpiceChannel *channel);
diff --git a/gtk/spice-channel.c b/gtk/spice-channel.c
index 093b292..a0d9c15 100644
--- a/gtk/spice-channel.c
+++ b/gtk/spice-channel.c
@@ -2763,24 +2763,18 @@ void spice_channel_swap(SpiceChannel *channel, SpiceChannel *swap, gboolean swap
#endif
}
-static const spice_msg_handler base_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,
-};
-
/* coroutine context */
static void spice_channel_handle_msg(SpiceChannel *channel, SpiceMsgIn *msg)
{
+ SpiceChannelClass *klass = SPICE_CHANNEL_GET_CLASS(channel);
int type = spice_msg_in_type(msg);
+ spice_msg_handler handler;
- g_return_if_fail(type < SPICE_N_ELEMENTS(base_handlers));
- g_return_if_fail(base_handlers[type] != NULL);
+ g_return_if_fail(type < klass->handlers->len);
- base_handlers[type](channel, msg);
+ handler = g_array_index(klass->handlers, spice_msg_handler, type);
+ g_return_if_fail(handler != NULL);
+ handler(channel, msg);
}
static void spice_channel_reset_capabilities(SpiceChannel *channel)
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