2014-01-02 20:09:07 +01:00
|
|
|
From 9ca313aa0824f2d350a7a6c9b1ef6c47e0408f1d Mon Sep 17 00:00:00 2001
|
|
|
|
From: aliguori <aliguori@c046a42c-6fe2-441c-8c8c-71466251a162>
|
|
|
|
Date: Sat, 23 Aug 2008 23:27:37 +0000
|
|
|
|
Subject: [PATCH] VNC: Support for ExtendedKeyEvent client message
|
|
|
|
|
|
|
|
This patch adds support for the ExtendedKeyEvent client message. This message
|
|
|
|
allows a client to send raw scan codes directly to the server. If the client
|
|
|
|
and server are using the same keymap, then it's unnecessary to use the '-k'
|
|
|
|
option with QEMU when this extension is supported.
|
|
|
|
|
|
|
|
This is extension is currently only implemented by gtk-vnc based clients
|
|
|
|
(gvncviewer, virt-manager, vinagre, etc.).
|
|
|
|
|
|
|
|
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@5076 c046a42c-6fe2-441c-8c8c-71466251a162
|
|
|
|
---
|
|
|
|
vnc.c | 59 ++++++++++++++++++++++++++++++++++++++++++++++++++---------
|
|
|
|
1 files changed, 50 insertions(+), 9 deletions(-)
|
|
|
|
|
2015-11-11 18:04:52 +01:00
|
|
|
Index: xen-4.6.0-testing/tools/qemu-xen-traditional-dir-remote/vnc.c
|
2014-01-02 20:09:07 +01:00
|
|
|
===================================================================
|
2015-11-11 18:04:52 +01:00
|
|
|
--- xen-4.6.0-testing.orig/tools/qemu-xen-traditional-dir-remote/vnc.c
|
|
|
|
+++ xen-4.6.0-testing/tools/qemu-xen-traditional-dir-remote/vnc.c
|
2014-01-02 20:09:07 +01:00
|
|
|
@@ -1285,35 +1285,22 @@ static void press_key_altgr_down(VncStat
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
-static void do_key_event(VncState *vs, int down, uint32_t sym)
|
|
|
|
+static void do_key_event(VncState *vs, int down, int keycode, int sym, int shift)
|
|
|
|
{
|
|
|
|
- int keycode;
|
|
|
|
int shift_keys = 0;
|
|
|
|
- int shift = 0;
|
|
|
|
int keypad = 0;
|
|
|
|
int altgr = 0;
|
|
|
|
int altgr_keys = 0;
|
|
|
|
|
|
|
|
if (is_graphic_console()) {
|
|
|
|
- if (sym >= 'A' && sym <= 'Z') {
|
|
|
|
- sym = sym - 'A' + 'a';
|
|
|
|
- shift = 1;
|
|
|
|
- }
|
|
|
|
- else {
|
|
|
|
+ if (!shift)
|
|
|
|
shift = keysym_is_shift(vs->kbd_layout, sym & 0xFFFF);
|
|
|
|
- }
|
|
|
|
|
|
|
|
altgr = keysym_is_altgr(vs->kbd_layout, sym & 0xFFFF);
|
|
|
|
}
|
|
|
|
shift_keys = vs->modifiers_state[0x2a] | vs->modifiers_state[0x36];
|
|
|
|
altgr_keys = vs->modifiers_state[0xb8];
|
|
|
|
|
|
|
|
- keycode = keysym2scancode(vs->kbd_layout, sym & 0xFFFF);
|
|
|
|
- if (keycode == 0) {
|
|
|
|
- fprintf(stderr, "Key lost : keysym=0x%x(%d)\n", sym, sym);
|
|
|
|
- return;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
/* QEMU console switch */
|
|
|
|
switch(keycode) {
|
|
|
|
case 0x2a: /* Left Shift */
|
|
|
|
@@ -1445,7 +1432,25 @@ static void do_key_event(VncState *vs, i
|
|
|
|
|
|
|
|
static void key_event(VncState *vs, int down, uint32_t sym)
|
|
|
|
{
|
|
|
|
- do_key_event(vs, down, sym);
|
|
|
|
+ int keycode;
|
|
|
|
+ int shift = 0;
|
|
|
|
+
|
|
|
|
+ if (sym >= 'A' && sym <= 'Z' && is_graphic_console()) {
|
|
|
|
+ sym = sym - 'A' + 'a';
|
|
|
|
+ shift = 1;
|
|
|
|
+ }
|
|
|
|
+ keycode = keysym2scancode(vs->kbd_layout, sym & 0xFFFF);
|
|
|
|
+ do_key_event(vs, down, keycode, sym, shift);
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+static void ext_key_event(VncState *vs, int down,
|
|
|
|
+ uint32_t sym, uint16_t keycode)
|
|
|
|
+{
|
|
|
|
+ /* if the user specifies a keyboard layout, always use it */
|
|
|
|
+ if (keyboard_layout)
|
|
|
|
+ key_event(vs, down, sym);
|
|
|
|
+ else
|
|
|
|
+ do_key_event(vs, down, keycode, sym, 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void framebuffer_set_updated(VncState *vs, int x, int y, int w, int h)
|
|
|
|
@@ -1534,6 +1539,15 @@ static void framebuffer_update_request(V
|
|
|
|
qemu_mod_timer(vs->timer, qemu_get_clock(rt_clock));
|
|
|
|
}
|
|
|
|
|
|
|
|
+static void send_ext_key_event_ack(VncState *vs)
|
|
|
|
+{
|
|
|
|
+ vnc_write_u8(vs, 0);
|
|
|
|
+ vnc_write_u8(vs, 0);
|
|
|
|
+ vnc_write_u16(vs, 1);
|
|
|
|
+ vnc_framebuffer_update(vs, 0, 0, ds_get_width(vs->ds), ds_get_height(vs->ds), -258);
|
|
|
|
+ vnc_flush(vs);
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
static void set_encodings(VncState *vs, int32_t *encodings, size_t n_encodings)
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
@@ -1562,6 +1576,9 @@ static void set_encodings(VncState *vs,
|
|
|
|
case -257:
|
|
|
|
vs->has_pointer_type_change = 1;
|
|
|
|
break;
|
|
|
|
+ case -258:
|
|
|
|
+ send_ext_key_event_ack(vs);
|
|
|
|
+ break;
|
|
|
|
case 0x574D5669:
|
|
|
|
vs->has_WMVi = 1;
|
|
|
|
default:
|
2015-11-04 21:30:31 +01:00
|
|
|
@@ -1780,6 +1797,24 @@ static int protocol_client_msg(VncState
|
2014-01-02 20:09:07 +01:00
|
|
|
|
|
|
|
client_cut_text(vs, read_u32(data, 4), (char *)(data + 8));
|
|
|
|
break;
|
|
|
|
+ case 255:
|
|
|
|
+ if (len == 1)
|
|
|
|
+ return 2;
|
|
|
|
+
|
|
|
|
+ switch (read_u8(data, 1)) {
|
|
|
|
+ case 0:
|
|
|
|
+ if (len == 2)
|
|
|
|
+ return 12;
|
|
|
|
+
|
|
|
|
+ ext_key_event(vs, read_u16(data, 2),
|
|
|
|
+ read_u32(data, 4), read_u32(data, 8));
|
|
|
|
+ break;
|
|
|
|
+ default:
|
|
|
|
+ printf("Msg: %d\n", read_u16(data, 0));
|
|
|
|
+ vnc_client_error(vs);
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+ break;
|
|
|
|
default:
|
|
|
|
printf("Msg: %d\n", data[0]);
|
|
|
|
vnc_client_error(vs);
|
2015-11-04 21:30:31 +01:00
|
|
|
@@ -2451,10 +2486,11 @@ void vnc_display_init(DisplayState *ds)
|
2014-01-02 20:09:07 +01:00
|
|
|
|
|
|
|
vs->ds = ds;
|
|
|
|
|
|
|
|
- if (!keyboard_layout)
|
|
|
|
- keyboard_layout = "en-us";
|
|
|
|
+ if (keyboard_layout)
|
|
|
|
+ vs->kbd_layout = init_keyboard_layout(keyboard_layout);
|
|
|
|
+ else
|
|
|
|
+ vs->kbd_layout = init_keyboard_layout("en-us");
|
|
|
|
|
|
|
|
- vs->kbd_layout = init_keyboard_layout(keyboard_layout);
|
|
|
|
if (!vs->kbd_layout)
|
|
|
|
exit(1);
|
|
|
|
vs->modifiers_state[0x45] = 1; /* NumLock on - on boot */
|