Signed-off-by: Dietmar Maurer <dietmar@xxxxxxxxxxx> Index: new/gtk/channel-inputs.c =================================================================== --- new.orig/gtk/channel-inputs.c 2013-10-03 11:11:56.000000000 +0200 +++ new/gtk/channel-inputs.c 2013-10-11 11:59:07.000000000 +0200 @@ -451,6 +451,48 @@ spice_msg_out_send(msg); } +static uint8_t assemble_scancodes(uint8_t *code, guint code_down, guint code_up) +{ + uint8_t code_len = 0; + + if (code_down) { + if (code_down < 0x100) { + code[code_len++] = spice_make_scancode(code_down, FALSE); + } else { + guint16 scancode = spice_make_scancode(code_down, FALSE); + code[code_len++] = scancode & 0xff; + code[code_len++] = scancode >> 8; + } + } + if (code_up) { + if (code_up < 0x100) { + code[code_len++] = spice_make_scancode(code_up, FALSE); + } else { + guint16 scancode = spice_make_scancode(code_up, FALSE); + code[code_len++] = scancode & 0xff; + code[code_len++] = scancode >> 8; + } + } + + return code_len; +} + +static void spice_inputs_key_x11_keysym(SpiceInputsChannel *channel, guint keysym, guint flags, + guint code_down, guint code_up) +{ + SpiceMsgOut *msg; + uint8_t code[32]; + uint8_t code_len = assemble_scancodes(code, code_down, code_up); + + msg = spice_msg_out_new(SPICE_CHANNEL(channel), SPICE_MSGC_INPUTS_KEY_X11_KEYSYM); + spice_marshaller_add_uint32(msg->marshaller, keysym); + spice_marshaller_add_uint32(msg->marshaller, flags); + spice_marshaller_add_uint8(msg->marshaller, code_len); + uint8_t *buf = (guint8*)spice_marshaller_reserve_space(msg->marshaller, code_len); + memcpy(buf, code, code_len); + spice_msg_out_send(msg); +} + /** * spice_inputs_key_press: * @channel: @@ -458,7 +500,7 @@ * * Press a key. **/ -void spice_inputs_key_press(SpiceInputsChannel *channel, guint scancode) +void spice_inputs_key_press(SpiceInputsChannel *channel, guint scancode, guint keysym) { SpiceMsgcKeyDown down; SpiceMsgOut *msg; @@ -470,10 +512,14 @@ if (spice_channel_get_read_only(SPICE_CHANNEL(channel))) return; - down.code = spice_make_scancode(scancode, FALSE); - 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 (spice_channel_test_capability(SPICE_CHANNEL(channel), SPICE_INPUTS_CAP_KEY_X11_KEYSYM)) { + spice_inputs_key_x11_keysym(channel, keysym, SPICE_KEYBOARD_FLAG_DOWN, scancode, 0); + } else { + down.code = spice_make_scancode(scancode, FALSE); + 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); + } } /** @@ -483,7 +529,7 @@ * * Release a key. **/ -void spice_inputs_key_release(SpiceInputsChannel *channel, guint scancode) +void spice_inputs_key_release(SpiceInputsChannel *channel, guint scancode, guint keysym) { SpiceMsgcKeyUp up; SpiceMsgOut *msg; @@ -495,10 +541,14 @@ if (spice_channel_get_read_only(SPICE_CHANNEL(channel))) return; - up.code = spice_make_scancode(scancode, TRUE); - 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); + if (spice_channel_test_capability(SPICE_CHANNEL(channel), SPICE_INPUTS_CAP_KEY_X11_KEYSYM)) { + spice_inputs_key_x11_keysym(channel, keysym, SPICE_KEYBOARD_FLAG_UP, 0, scancode); + } else { + up.code = spice_make_scancode(scancode, TRUE); + 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); + } } /** @@ -510,7 +560,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, guint keysym) { SpiceChannel *channel = SPICE_CHANNEL(input_channel); @@ -522,30 +572,25 @@ if (spice_channel_get_read_only(channel)) return; - if (spice_channel_test_capability(channel, SPICE_INPUTS_CAP_KEY_SCANCODE)) { + if (spice_channel_test_capability(channel, SPICE_INPUTS_CAP_KEY_X11_KEYSYM)) { + spice_inputs_key_x11_keysym(input_channel, keysym, + SPICE_KEYBOARD_FLAG_DOWN|SPICE_KEYBOARD_FLAG_UP, + scancode, scancode); + } else if (spice_channel_test_capability(channel, SPICE_INPUTS_CAP_KEY_SCANCODE)) { SpiceMsgOut *msg; - guint16 code; - guint8 *buf; + + uint8_t code[32]; + uint8_t code_len = assemble_scancodes(code, scancode, scancode); msg = spice_msg_out_new(channel, SPICE_MSGC_INPUTS_KEY_SCANCODE); - if (scancode < 0x100) { - buf = (guint8*)spice_marshaller_reserve_space(msg->marshaller, 2); - buf[0] = spice_make_scancode(scancode, FALSE); - buf[1] = spice_make_scancode(scancode, TRUE); - } else { - buf = (guint8*)spice_marshaller_reserve_space(msg->marshaller, 4); - code = spice_make_scancode(scancode, FALSE); - buf[0] = code & 0xff; - buf[1] = code >> 8; - code = spice_make_scancode(scancode, TRUE); - buf[2] = code & 0xff; - buf[3] = code >> 8; - } + uint8_t *buf = (guint8*)spice_marshaller_reserve_space(msg->marshaller, code_len); + memcpy(buf, code, code_len); + 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_release(input_channel, scancode); + spice_inputs_key_press(input_channel, scancode, keysym); + spice_inputs_key_release(input_channel, scancode, keysym); } } Index: new/gtk/channel-inputs.h =================================================================== --- new.orig/gtk/channel-inputs.h 2013-10-03 11:11:56.000000000 +0200 +++ new/gtk/channel-inputs.h 2013-10-11 11:16:45.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_release(SpiceInputsChannel *channel, guint scancode); +void spice_inputs_key_press(SpiceInputsChannel *channel, guint scancode, guint keysym); +void spice_inputs_key_release(SpiceInputsChannel *channel, guint scancode, guint keysym); 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 keysym); G_END_DECLS Index: new/gtk/spice-widget-priv.h =================================================================== --- new.orig/gtk/spice-widget-priv.h 2013-10-03 11:11:56.000000000 +0200 +++ new/gtk/spice-widget-priv.h 2013-10-11 11:16:45.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-11 11:16:30.000000000 +0200 +++ new/gtk/spice-widget.c 2013-10-11 11:55:29.000000000 +0200 @@ -1153,8 +1153,9 @@ 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_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 +1170,9 @@ 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_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 +1182,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 +1211,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, keysym); d->key_state[i] |= m; break; @@ -1224,7 +1227,7 @@ 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, keysym); } d->key_state[i] &= ~m; @@ -1246,7 +1249,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 +1341,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 +1397,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