If the server is capable of SPICE_INPUTS_CAP_SCANCODE, then we send can send a single message with key press and release, to avoid unwanted guest side key repeatition due to network jitter. If the server is not capable, spice-gtk will use some compatibility mode and send the existing DOWN and UP key events seperately. --- doc/reference/spice-gtk-sections.txt | 1 + gtk/channel-inputs.c | 37 ++++++++++++++++++++++++++++++++++ gtk/channel-inputs.h | 1 + gtk/map-file | 1 + 4 files changed, 40 insertions(+) diff --git a/doc/reference/spice-gtk-sections.txt b/doc/reference/spice-gtk-sections.txt index daf575c..60e287a 100644 --- a/doc/reference/spice-gtk-sections.txt +++ b/doc/reference/spice-gtk-sections.txt @@ -203,6 +203,7 @@ spice_inputs_position spice_inputs_button_press spice_inputs_button_release spice_inputs_key_press +spice_inputs_key_press_and_release spice_inputs_key_release spice_inputs_set_key_locks <SUBSECTION Standard> diff --git a/gtk/channel-inputs.c b/gtk/channel-inputs.c index 3259da8..0526738 100644 --- a/gtk/channel-inputs.c +++ b/gtk/channel-inputs.c @@ -514,6 +514,43 @@ void spice_inputs_key_release(SpiceInputsChannel *channel, guint scancode) spice_msg_out_send(msg); } +/** + * spice_inputs_key_press_and_release: + * @channel: + * @scancode: a PC AT key scancode + * + * Press and release a key event atomically (in the same message). + * + * Since: 0.13 + **/ +void spice_inputs_key_press_and_release(SpiceInputsChannel *input_channel, guint scancode) +{ + SpiceChannel *channel = SPICE_CHANNEL(input_channel); + + g_return_if_fail(channel != NULL); + g_return_if_fail(channel->priv->state != SPICE_CHANNEL_STATE_UNCONNECTED); + + if (channel->priv->state != SPICE_CHANNEL_STATE_READY) + return; + if (spice_channel_get_read_only(channel)) + return; + + if (spice_channel_test_capability(channel, SPICE_INPUTS_CAP_KEY_SCANCODE)) { + SpiceMsgOut *msg; + guint16 *code; + + msg = spice_msg_out_new(channel, SPICE_MSGC_INPUTS_KEY_SCANCODE); + code = (guint16*)spice_marshaller_reserve_space(msg->marshaller, 2 * sizeof(guint16)); + *code++ = spice_make_scancode(scancode, FALSE); + *code = spice_make_scancode(scancode, TRUE); + spice_msg_out_send(msg); + } else { + SPICE_DEBUG("The server doesn't support atomic press and release"); + spice_inputs_key_press(input_channel, scancode); + spice_inputs_key_release(input_channel, scancode); + } +} + /* main or coroutine context */ static SpiceMsgOut* set_key_locks(SpiceInputsChannel *channel, guint locks) { diff --git a/gtk/channel-inputs.h b/gtk/channel-inputs.h index 9968b3b..3179a76 100644 --- a/gtk/channel-inputs.h +++ b/gtk/channel-inputs.h @@ -82,6 +82,7 @@ void spice_inputs_button_release(SpiceInputsChannel *channel, gint button, void spice_inputs_key_press(SpiceInputsChannel *channel, guint scancode); void spice_inputs_key_release(SpiceInputsChannel *channel, guint scancode); void spice_inputs_set_key_locks(SpiceInputsChannel *channel, guint locks); +void spice_inputs_key_press_and_release(SpiceInputsChannel *channel, guint scancode); G_END_DECLS diff --git a/gtk/map-file b/gtk/map-file index 0d48bb3..ed2c07f 100644 --- a/gtk/map-file +++ b/gtk/map-file @@ -46,6 +46,7 @@ spice_inputs_button_press; spice_inputs_button_release; spice_inputs_channel_get_type; spice_inputs_key_press; +spice_inputs_key_press_and_release; spice_inputs_key_release; spice_inputs_lock_get_type; spice_inputs_motion; -- 1.7.10.4 _______________________________________________ Spice-devel mailing list Spice-devel@xxxxxxxxxxxxxxxxxxxxx http://lists.freedesktop.org/mailman/listinfo/spice-devel