mirror of https://gitee.com/openkylin/qemu.git
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
This commit is contained in:
parent
492b239197
commit
9ca313aa08
59
vnc.c
59
vnc.c
|
@ -939,12 +939,8 @@ static void press_key(VncState *vs, int keysym)
|
||||||
kbd_put_keycode(keysym2scancode(vs->kbd_layout, keysym) | 0x80);
|
kbd_put_keycode(keysym2scancode(vs->kbd_layout, keysym) | 0x80);
|
||||||
}
|
}
|
||||||
|
|
||||||
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 keycode;
|
|
||||||
|
|
||||||
keycode = keysym2scancode(vs->kbd_layout, sym & 0xFFFF);
|
|
||||||
|
|
||||||
/* QEMU console switch */
|
/* QEMU console switch */
|
||||||
switch(keycode) {
|
switch(keycode) {
|
||||||
case 0x2a: /* Left Shift */
|
case 0x2a: /* Left Shift */
|
||||||
|
@ -1046,9 +1042,23 @@ static void do_key_event(VncState *vs, int down, uint32_t sym)
|
||||||
|
|
||||||
static void key_event(VncState *vs, int down, uint32_t sym)
|
static void key_event(VncState *vs, int down, uint32_t sym)
|
||||||
{
|
{
|
||||||
|
int keycode;
|
||||||
|
|
||||||
if (sym >= 'A' && sym <= 'Z' && is_graphic_console())
|
if (sym >= 'A' && sym <= 'Z' && is_graphic_console())
|
||||||
sym = sym - 'A' + 'a';
|
sym = sym - 'A' + 'a';
|
||||||
do_key_event(vs, down, sym);
|
|
||||||
|
keycode = keysym2scancode(vs->kbd_layout, sym & 0xFFFF);
|
||||||
|
do_key_event(vs, down, keycode, sym);
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void framebuffer_update_request(VncState *vs, int incremental,
|
static void framebuffer_update_request(VncState *vs, int incremental,
|
||||||
|
@ -1078,6 +1088,15 @@ static void framebuffer_update_request(VncState *vs, int incremental,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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, vs->ds->width, vs->ds->height, -258);
|
||||||
|
vnc_flush(vs);
|
||||||
|
}
|
||||||
|
|
||||||
static void set_encodings(VncState *vs, int32_t *encodings, size_t n_encodings)
|
static void set_encodings(VncState *vs, int32_t *encodings, size_t n_encodings)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
@ -1105,6 +1124,9 @@ static void set_encodings(VncState *vs, int32_t *encodings, size_t n_encodings)
|
||||||
case -257:
|
case -257:
|
||||||
vs->has_pointer_type_change = 1;
|
vs->has_pointer_type_change = 1;
|
||||||
break;
|
break;
|
||||||
|
case -258:
|
||||||
|
send_ext_key_event_ack(vs);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -1256,6 +1278,24 @@ static int protocol_client_msg(VncState *vs, uint8_t *data, size_t len)
|
||||||
|
|
||||||
client_cut_text(vs, read_u32(data, 4), data + 8);
|
client_cut_text(vs, read_u32(data, 4), data + 8);
|
||||||
break;
|
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:
|
default:
|
||||||
printf("Msg: %d\n", data[0]);
|
printf("Msg: %d\n", data[0]);
|
||||||
vnc_client_error(vs);
|
vnc_client_error(vs);
|
||||||
|
@ -1974,10 +2014,11 @@ void vnc_display_init(DisplayState *ds)
|
||||||
|
|
||||||
vs->ds = ds;
|
vs->ds = ds;
|
||||||
|
|
||||||
if (!keyboard_layout)
|
if (keyboard_layout)
|
||||||
keyboard_layout = "en-us";
|
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)
|
if (!vs->kbd_layout)
|
||||||
exit(1);
|
exit(1);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue