Signed-off-by: Dietmar Maurer <dietmar@xxxxxxxxxxx> Index: new/gtk/channel-inputs.c =================================================================== --- new.orig/gtk/channel-inputs.c 2013-10-16 09:53:10.000000000 +0200 +++ new/gtk/channel-inputs.c 2013-10-16 10:00:11.000000000 +0200 @@ -451,6 +451,21 @@ spice_msg_out_send(msg); } +static void spice_inputs_key_utf8(SpiceInputsChannel *channel, gunichar uc) +{ + SpiceMsgOut *msg; + + g_assert(uc != 0); + + uint8_t data[32]; + uint32_t size = g_unichar_to_utf8(uc, (gchar*)data); + + msg = spice_msg_out_new(SPICE_CHANNEL(channel), SPICE_MSGC_INPUTS_KEY_UTF8); + uint8_t *buf = (guint8*)spice_marshaller_reserve_space(msg->marshaller, size); + memcpy(buf, data, size); + spice_msg_out_send(msg); +} + /** * spice_inputs_key_press: * @channel: @@ -458,7 +473,7 @@ * * Press a key. **/ -void spice_inputs_key_press(SpiceInputsChannel *channel, guint scancode) +void spice_inputs_key_press(SpiceInputsChannel *channel, guint scancode, gunichar uc) { SpiceMsgcKeyDown down; SpiceMsgOut *msg; @@ -474,6 +489,10 @@ 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); + + if (uc && spice_channel_test_capability(SPICE_CHANNEL(channel), SPICE_INPUTS_CAP_KEY_UTF8)) { + spice_inputs_key_utf8(channel, uc); + } } /** @@ -510,7 +529,7 @@ * * 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, gunichar uc) { SpiceChannel *channel = SPICE_CHANNEL(input_channel); @@ -544,9 +563,13 @@ spice_msg_out_send(msg); } else { CHANNEL_DEBUG(channel, "The server doesn't support atomic press and release"); - spice_inputs_key_press(input_channel, scancode); + spice_inputs_key_press(input_channel, scancode, uc); spice_inputs_key_release(input_channel, scancode); } + + if (uc && spice_channel_test_capability(channel, SPICE_INPUTS_CAP_KEY_UTF8)) { + spice_inputs_key_utf8(input_channel, uc); + } } /* main or coroutine context */ Index: new/gtk/channel-inputs.h =================================================================== --- new.orig/gtk/channel-inputs.h 2013-10-16 09:53:10.000000000 +0200 +++ new/gtk/channel-inputs.h 2013-10-16 09:53:16.000000000 +0200 @@ -79,10 +79,10 @@ 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_press(SpiceInputsChannel *channel, guint scancode, gunichar unicode); 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); +void spice_inputs_key_press_and_release(SpiceInputsChannel *channel, guint scancode, gunichar unicode); G_END_DECLS Index: new/gtk/spice-widget-priv.h =================================================================== --- new.orig/gtk/spice-widget-priv.h 2013-10-16 09:53:10.000000000 +0200 +++ new/gtk/spice-widget-priv.h 2013-10-16 09:53:16.000000000 +0200 @@ -108,6 +108,7 @@ size_t keycode_maplen; uint32_t key_state[512 / 32]; int key_delayed_scancode; + guint key_delayed_keysym; guint key_delayed_id; SpiceGrabSequence *grabseq; /* the configured key sequence */ gboolean *activeseq; /* the currently pressed keys */ Index: new/gtk/spice-widget.c =================================================================== --- new.orig/gtk/spice-widget.c 2013-10-16 09:53:10.000000000 +0200 +++ new/gtk/spice-widget.c 2013-10-16 09:53:16.000000000 +0200 @@ -1153,8 +1153,10 @@ 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, + gdk_keyval_to_unicode(d->key_delayed_keysym)); d->key_delayed_scancode = 0; + d->key_delayed_keysym = 0; if (d->key_delayed_id) { g_source_remove(d->key_delayed_id); @@ -1169,8 +1171,10 @@ 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, + gdk_keyval_to_unicode(d->key_delayed_keysym)); d->key_delayed_scancode = 0; + d->key_delayed_keysym = 0; if (d->key_delayed_id) { g_source_remove(d->key_delayed_id); @@ -1180,7 +1184,7 @@ return FALSE; } -static void send_key(SpiceDisplay *display, int scancode, SendKeyType type, gboolean press_delayed) +static void send_key(SpiceDisplay *display, int scancode, guint keysym, SendKeyType type, gboolean press_delayed) { SpiceDisplayPrivate *d = SPICE_DISPLAY_GET_PRIVATE(display); uint32_t i, b, m; @@ -1209,8 +1213,9 @@ 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_keysym = keysym; } else - spice_inputs_key_press(d->inputs, scancode); + spice_inputs_key_press(d->inputs, scancode, gdk_keyval_to_unicode(keysym)); d->key_state[i] |= m; break; @@ -1246,7 +1251,8 @@ continue; } for (b = 0; b < 32; b++) { - send_key(display, i * 32 + b, SEND_KEY_RELEASE, FALSE); + // note: using keysym 0 here, because we do not have this information + send_key(display, i * 32 + b, 0, SEND_KEY_RELEASE, FALSE); } } } @@ -1337,10 +1343,10 @@ 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 +1399,12 @@ 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); } } _______________________________________________ Spice-devel mailing list Spice-devel@xxxxxxxxxxxxxxxxxxxxx http://lists.freedesktop.org/mailman/listinfo/spice-devel