Signed-off-by: Dietmar Maurer <dietmar@xxxxxxxxxxx> --- gtk/channel-inputs.c | 33 ++++++++++++++++++++++++++++----- gtk/channel-inputs.h | 6 +++--- gtk/spice-widget-priv.h | 1 + gtk/spice-widget.c | 24 ++++++++++++++---------- 4 files changed, 46 insertions(+), 18 deletions(-) diff --git a/gtk/channel-inputs.c b/gtk/channel-inputs.c index ee86dc2..ce9173a 100644 --- a/gtk/channel-inputs.c +++ b/gtk/channel-inputs.c @@ -464,6 +464,23 @@ void spice_inputs_button_release(SpiceInputsChannel *channel, gint button, spice_msg_out_send(msg); } +static void spice_inputs_key_keyval(SpiceInputsChannel *channel, guint keyval, int flags) +{ + g_return_if_fail(channel != NULL); + + if (spice_channel_test_capability(SPICE_CHANNEL(channel), SPICE_INPUTS_CAP_KEY_KEYVAL)) { + SpiceMsgcKeyKeyval keyval_msg; + SpiceMsgOut *msg; + + keyval_msg.keyval = keyval; + keyval_msg.flags = flags; + + msg = spice_msg_out_new(SPICE_CHANNEL(channel), SPICE_MSGC_INPUTS_KEY_KEYVAL); + msg->marshallers->msgc_inputs_key_keyval(msg->marshaller, &keyval_msg); + spice_msg_out_send(msg); + } +} + /** * spice_inputs_key_press: * @channel: @@ -471,7 +488,7 @@ void spice_inputs_button_release(SpiceInputsChannel *channel, gint button, * * Press a key. **/ -void spice_inputs_key_press(SpiceInputsChannel *channel, guint scancode) +void spice_inputs_key_press(SpiceInputsChannel *channel, guint scancode, guint keyval) { SpiceMsgcKeyDown down; SpiceMsgOut *msg; @@ -487,6 +504,8 @@ void spice_inputs_key_press(SpiceInputsChannel *channel, guint scancode) msg = spice_msg_out_new(SPICE_CHANNEL(channel), SPICE_MSGC_INPUTS_KEY_DOWN); msg->marshallers->msgc_inputs_key_down(msg->marshaller, &down); spice_msg_out_send(msg); + + spice_inputs_key_keyval(channel, keyval, 1); } /** @@ -496,7 +515,7 @@ void spice_inputs_key_press(SpiceInputsChannel *channel, guint scancode) * * Release a key. **/ -void spice_inputs_key_release(SpiceInputsChannel *channel, guint scancode) +void spice_inputs_key_release(SpiceInputsChannel *channel, guint scancode, guint keyval) { SpiceMsgcKeyUp up; SpiceMsgOut *msg; @@ -512,6 +531,8 @@ void spice_inputs_key_release(SpiceInputsChannel *channel, guint scancode) msg = spice_msg_out_new(SPICE_CHANNEL(channel), SPICE_MSGC_INPUTS_KEY_UP); msg->marshallers->msgc_inputs_key_up(msg->marshaller, &up); spice_msg_out_send(msg); + + spice_inputs_key_keyval(channel, keyval, 2); } /** @@ -523,7 +544,7 @@ void spice_inputs_key_release(SpiceInputsChannel *channel, guint scancode) * * Since: 0.13 **/ -void spice_inputs_key_press_and_release(SpiceInputsChannel *input_channel, guint scancode) +void spice_inputs_key_press_and_release(SpiceInputsChannel *input_channel, guint scancode, guint keyval) { SpiceChannel *channel = SPICE_CHANNEL(input_channel); @@ -555,11 +576,13 @@ void spice_inputs_key_press_and_release(SpiceInputsChannel *input_channel, guint buf[3] = code >> 8; } spice_msg_out_send(msg); + spice_inputs_key_keyval(input_channel, keyval, 3); } else { CHANNEL_DEBUG(channel, "The server doesn't support atomic press and release"); - spice_inputs_key_press(input_channel, scancode); - spice_inputs_key_release(input_channel, scancode); + spice_inputs_key_press(input_channel, scancode, keyval); + spice_inputs_key_release(input_channel, scancode, keyval); } + } /* main or coroutine context */ diff --git a/gtk/channel-inputs.h b/gtk/channel-inputs.h index 3179a76..1a6bbc1 100644 --- a/gtk/channel-inputs.h +++ b/gtk/channel-inputs.h @@ -79,10 +79,10 @@ void spice_inputs_button_press(SpiceInputsChannel *channel, gint button, gint button_state); void spice_inputs_button_release(SpiceInputsChannel *channel, gint button, gint button_state); -void spice_inputs_key_press(SpiceInputsChannel *channel, guint scancode); -void spice_inputs_key_release(SpiceInputsChannel *channel, guint scancode); +void spice_inputs_key_press(SpiceInputsChannel *channel, guint scancode, guint keyval); +void spice_inputs_key_release(SpiceInputsChannel *channel, guint scancode, guint keyval); void spice_inputs_set_key_locks(SpiceInputsChannel *channel, guint locks); -void spice_inputs_key_press_and_release(SpiceInputsChannel *channel, guint scancode); +void spice_inputs_key_press_and_release(SpiceInputsChannel *channel, guint scancode, guint keyval); G_END_DECLS diff --git a/gtk/spice-widget-priv.h b/gtk/spice-widget-priv.h index 597ce10..6eb1c11 100644 --- a/gtk/spice-widget-priv.h +++ b/gtk/spice-widget-priv.h @@ -108,6 +108,7 @@ struct _SpiceDisplayPrivate { size_t keycode_maplen; uint32_t key_state[512 / 32]; int key_delayed_scancode; + uint32_t key_delayed_keyval; guint key_delayed_id; SpiceGrabSequence *grabseq; /* the configured key sequence */ gboolean *activeseq; /* the currently pressed keys */ diff --git a/gtk/spice-widget.c b/gtk/spice-widget.c index d25edca..a739ba4 100644 --- a/gtk/spice-widget.c +++ b/gtk/spice-widget.c @@ -1153,8 +1153,9 @@ static void key_press_and_release(SpiceDisplay *display) if (d->key_delayed_scancode == 0) return; - spice_inputs_key_press_and_release(d->inputs, d->key_delayed_scancode); + spice_inputs_key_press_and_release(d->inputs, d->key_delayed_scancode, d->key_delayed_keyval); d->key_delayed_scancode = 0; + d->key_delayed_keyval = 0; if (d->key_delayed_id) { g_source_remove(d->key_delayed_id); @@ -1169,8 +1170,9 @@ static gboolean key_press_delayed(gpointer data) if (d->key_delayed_scancode == 0) return FALSE; - spice_inputs_key_press(d->inputs, d->key_delayed_scancode); + spice_inputs_key_press(d->inputs, d->key_delayed_scancode, d->key_delayed_keyval); d->key_delayed_scancode = 0; + d->key_delayed_keyval = 0; if (d->key_delayed_id) { g_source_remove(d->key_delayed_id); @@ -1180,7 +1182,7 @@ static gboolean key_press_delayed(gpointer data) return FALSE; } -static void send_key(SpiceDisplay *display, int scancode, SendKeyType type, gboolean press_delayed) +static void send_key(SpiceDisplay *display, int scancode, guint keyval, SendKeyType type, gboolean press_delayed) { SpiceDisplayPrivate *d = SPICE_DISPLAY_GET_PRIVATE(display); uint32_t i, b, m; @@ -1209,8 +1211,9 @@ static void send_key(SpiceDisplay *display, int scancode, SendKeyType type, gboo g_warn_if_fail(d->key_delayed_id == 0); d->key_delayed_id = g_timeout_add(d->keypress_delay, key_press_delayed, display); d->key_delayed_scancode = scancode; + d->key_delayed_keyval = keyval; } else - spice_inputs_key_press(d->inputs, scancode); + spice_inputs_key_press(d->inputs, scancode, keyval); d->key_state[i] |= m; break; @@ -1224,7 +1227,7 @@ static void send_key(SpiceDisplay *display, int scancode, SendKeyType type, gboo else { /* ensure delayed key is pressed before other key are released */ key_press_delayed(display); - spice_inputs_key_release(d->inputs, scancode); + spice_inputs_key_release(d->inputs, scancode, keyval); } d->key_state[i] &= ~m; @@ -1246,7 +1249,7 @@ static void release_keys(SpiceDisplay *display) continue; } for (b = 0; b < 32; b++) { - send_key(display, i * 32 + b, SEND_KEY_RELEASE, FALSE); + send_key(display, i * 32 + b, 0, SEND_KEY_RELEASE, FALSE); } } } @@ -1337,10 +1340,10 @@ static gboolean key_event(GtkWidget *widget, GdkEventKey *key) switch (key->type) { case GDK_KEY_PRESS: - send_key(display, scancode, SEND_KEY_PRESS, !key->is_modifier); + send_key(display, scancode, key->keyval, SEND_KEY_PRESS, !key->is_modifier); break; case GDK_KEY_RELEASE: - send_key(display, scancode, SEND_KEY_RELEASE, !key->is_modifier); + send_key(display, scancode, key->keyval, SEND_KEY_RELEASE, !key->is_modifier); break; default: g_warn_if_reached(); @@ -1393,12 +1396,13 @@ void spice_display_send_keys(SpiceDisplay *display, const guint *keyvals, if (kind & SPICE_DISPLAY_KEY_EVENT_PRESS) { for (i = 0 ; i < nkeyvals ; i++) - send_key(display, get_scancode_from_keyval(display, keyvals[i]), SEND_KEY_PRESS, FALSE); + send_key(display, get_scancode_from_keyval(display, keyvals[i]), + keyvals[i], SEND_KEY_PRESS, FALSE); } if (kind & SPICE_DISPLAY_KEY_EVENT_RELEASE) { for (i = (nkeyvals-1) ; i >= 0 ; i--) - send_key(display, get_scancode_from_keyval(display, keyvals[i]), SEND_KEY_RELEASE, FALSE); + send_key(display, get_scancode_from_keyval(display, keyvals[i]), keyvals[i], SEND_KEY_RELEASE, FALSE); } } -- 1.7.10.4 _______________________________________________ Spice-devel mailing list Spice-devel@xxxxxxxxxxxxxxxxxxxxx http://lists.freedesktop.org/mailman/listinfo/spice-devel