Commit 9ca313aa0824f2d350a7a6c9b1ef6c47e0408f1d

Authored by aliguori
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
... ... @@ -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  
... ...