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 _______________________________________________ Spice-devel mailing list Spice-devel@xxxxxxxxxxxxxxxxxxxxx http://lists.freedesktop.org/mailman/listinfo/spice-devel