Commit 9ca313aa0824f2d350a7a6c9b1ef6c47e0408f1d
1 parent
492b2391
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
Showing
1 changed file
with
50 additions
and
9 deletions
vnc.c
... | ... | @@ -939,12 +939,8 @@ static void press_key(VncState *vs, int keysym) |
939 | 939 | kbd_put_keycode(keysym2scancode(vs->kbd_layout, keysym) | 0x80); |
940 | 940 | } |
941 | 941 | |
942 | -static void do_key_event(VncState *vs, int down, uint32_t sym) | |
942 | +static void do_key_event(VncState *vs, int down, int keycode, int sym) | |
943 | 943 | { |
944 | - int keycode; | |
945 | - | |
946 | - keycode = keysym2scancode(vs->kbd_layout, sym & 0xFFFF); | |
947 | - | |
948 | 944 | /* QEMU console switch */ |
949 | 945 | switch(keycode) { |
950 | 946 | case 0x2a: /* Left Shift */ |
... | ... | @@ -1046,9 +1042,23 @@ static void do_key_event(VncState *vs, int down, uint32_t sym) |
1046 | 1042 | |
1047 | 1043 | static void key_event(VncState *vs, int down, uint32_t sym) |
1048 | 1044 | { |
1045 | + int keycode; | |
1046 | + | |
1049 | 1047 | if (sym >= 'A' && sym <= 'Z' && is_graphic_console()) |
1050 | 1048 | sym = sym - 'A' + 'a'; |
1051 | - do_key_event(vs, down, sym); | |
1049 | + | |
1050 | + keycode = keysym2scancode(vs->kbd_layout, sym & 0xFFFF); | |
1051 | + do_key_event(vs, down, keycode, sym); | |
1052 | +} | |
1053 | + | |
1054 | +static void ext_key_event(VncState *vs, int down, | |
1055 | + uint32_t sym, uint16_t keycode) | |
1056 | +{ | |
1057 | + /* if the user specifies a keyboard layout, always use it */ | |
1058 | + if (keyboard_layout) | |
1059 | + key_event(vs, down, sym); | |
1060 | + else | |
1061 | + do_key_event(vs, down, keycode, sym); | |
1052 | 1062 | } |
1053 | 1063 | |
1054 | 1064 | static void framebuffer_update_request(VncState *vs, int incremental, |
... | ... | @@ -1078,6 +1088,15 @@ static void framebuffer_update_request(VncState *vs, int incremental, |
1078 | 1088 | } |
1079 | 1089 | } |
1080 | 1090 | |
1091 | +static void send_ext_key_event_ack(VncState *vs) | |
1092 | +{ | |
1093 | + vnc_write_u8(vs, 0); | |
1094 | + vnc_write_u8(vs, 0); | |
1095 | + vnc_write_u16(vs, 1); | |
1096 | + vnc_framebuffer_update(vs, 0, 0, vs->ds->width, vs->ds->height, -258); | |
1097 | + vnc_flush(vs); | |
1098 | +} | |
1099 | + | |
1081 | 1100 | static void set_encodings(VncState *vs, int32_t *encodings, size_t n_encodings) |
1082 | 1101 | { |
1083 | 1102 | int i; |
... | ... | @@ -1105,6 +1124,9 @@ static void set_encodings(VncState *vs, int32_t *encodings, size_t n_encodings) |
1105 | 1124 | case -257: |
1106 | 1125 | vs->has_pointer_type_change = 1; |
1107 | 1126 | break; |
1127 | + case -258: | |
1128 | + send_ext_key_event_ack(vs); | |
1129 | + break; | |
1108 | 1130 | default: |
1109 | 1131 | break; |
1110 | 1132 | } |
... | ... | @@ -1256,6 +1278,24 @@ static int protocol_client_msg(VncState *vs, uint8_t *data, size_t len) |
1256 | 1278 | |
1257 | 1279 | client_cut_text(vs, read_u32(data, 4), data + 8); |
1258 | 1280 | break; |
1281 | + case 255: | |
1282 | + if (len == 1) | |
1283 | + return 2; | |
1284 | + | |
1285 | + switch (read_u8(data, 1)) { | |
1286 | + case 0: | |
1287 | + if (len == 2) | |
1288 | + return 12; | |
1289 | + | |
1290 | + ext_key_event(vs, read_u16(data, 2), | |
1291 | + read_u32(data, 4), read_u32(data, 8)); | |
1292 | + break; | |
1293 | + default: | |
1294 | + printf("Msg: %d\n", read_u16(data, 0)); | |
1295 | + vnc_client_error(vs); | |
1296 | + break; | |
1297 | + } | |
1298 | + break; | |
1259 | 1299 | default: |
1260 | 1300 | printf("Msg: %d\n", data[0]); |
1261 | 1301 | vnc_client_error(vs); |
... | ... | @@ -1974,10 +2014,11 @@ void vnc_display_init(DisplayState *ds) |
1974 | 2014 | |
1975 | 2015 | vs->ds = ds; |
1976 | 2016 | |
1977 | - if (!keyboard_layout) | |
1978 | - keyboard_layout = "en-us"; | |
2017 | + if (keyboard_layout) | |
2018 | + vs->kbd_layout = init_keyboard_layout(keyboard_layout); | |
2019 | + else | |
2020 | + vs->kbd_layout = init_keyboard_layout("en-us"); | |
1979 | 2021 | |
1980 | - vs->kbd_layout = init_keyboard_layout(keyboard_layout); | |
1981 | 2022 | if (!vs->kbd_layout) |
1982 | 2023 | exit(1); |
1983 | 2024 | ... | ... |