FreeBSD bhyve keyboard layout patch
リビジョン | b2a09ce2ef5c8996cd2f5154d13eaa97cf434d97 (tree) |
---|---|
日時 | 2021-01-02 12:40:49 |
作者 | ![]() |
コミッター | Koine Yuusuke(koinec) |
kbdlayout: regist old version(2020/05/29-v3: support for QEMU extended keyevent message)
@@ -1,6 +1,6 @@ | ||
1 | 1 | diff -upN bhyve_orig/Makefile bhyve/Makefile |
2 | 2 | --- bhyve_orig/Makefile 2020-05-01 11:25:57.446272000 +0900 |
3 | -+++ bhyve/Makefile 2020-04-28 21:10:08.503651000 +0900 | |
3 | ++++ bhyve/Makefile 2020-05-28 09:25:47.142698000 +0900 | |
4 | 4 | @@ -95,4 +95,6 @@ CFLAGS+=-DGDB_LOG |
5 | 5 | |
6 | 6 | WARNS?= 2 |
@@ -8,9 +8,41 @@ diff -upN bhyve_orig/Makefile bhyve/Makefile | ||
8 | 8 | +SUBDIR= kbdlayout |
9 | 9 | + |
10 | 10 | .include <bsd.prog.mk> |
11 | +diff -upN bhyve_orig/atkbdc.c bhyve/atkbdc.c | |
12 | +--- bhyve_orig/atkbdc.c 2020-05-01 11:25:57.441270000 +0900 | |
13 | ++++ bhyve/atkbdc.c 2020-05-28 16:28:56.411057000 +0900 | |
14 | +@@ -211,24 +211,25 @@ atkbdc_kbd_read(struct atkbdc_softc *sc) | |
15 | + 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff | |
16 | + }; | |
17 | + uint8_t val; | |
18 | ++ uint8_t trans; | |
19 | + uint8_t release = 0; | |
20 | + | |
21 | + assert(pthread_mutex_isowned_np(&sc->mtx)); | |
22 | + | |
23 | + if (sc->ram[0] & KBD_TRANSLATION) { | |
24 | +- while (ps2kbd_read(sc->ps2kbd_sc, &val) != -1) { | |
25 | ++ while (ps2kbd_read(sc->ps2kbd_sc, &val, &trans) != -1) { | |
26 | + if (val == 0xf0) { | |
27 | + release = 0x80; | |
28 | + continue; | |
29 | + } else { | |
30 | +- val = translation[val] | release; | |
31 | ++ val = ((trans) ? translation[val] : val) | release; | |
32 | + } | |
33 | + atkbdc_kbd_queue_data(sc, val); | |
34 | + break; | |
35 | + } | |
36 | + } else { | |
37 | + while (sc->kbd.bcnt < FIFOSZ) { | |
38 | +- if (ps2kbd_read(sc->ps2kbd_sc, &val) != -1) | |
39 | ++ if (ps2kbd_read(sc->ps2kbd_sc, &val, &trans) != -1) | |
40 | + atkbdc_kbd_queue_data(sc, val); | |
41 | + else | |
42 | + break; | |
11 | 43 | diff -upN bhyve_orig/bhyve.8 bhyve/bhyve.8 |
12 | 44 | --- bhyve_orig/bhyve.8 2020-05-01 11:25:57.441891000 +0900 |
13 | -+++ bhyve/bhyve.8 2020-05-01 12:24:39.448446000 +0900 | |
45 | ++++ bhyve/bhyve.8 2020-05-28 14:26:02.139585000 +0900 | |
14 | 46 | @@ -44,6 +44,7 @@ |
15 | 47 | .Op Ar ,threads=n |
16 | 48 | .Oc |
@@ -19,7 +51,7 @@ diff -upN bhyve_orig/bhyve.8 bhyve/bhyve.8 | ||
19 | 51 | .Op Fl l Ar help|lpcdev Ns Op , Ns Ar conf |
20 | 52 | .Op Fl m Ar memsize Ns Op Ar K|k|M|m|G|g|T|t |
21 | 53 | .Op Fl p Ar vcpu:hostcpu |
22 | -@@ -144,6 +145,12 @@ Print help message and exit. | |
54 | +@@ -144,6 +145,13 @@ Print help message and exit. | |
23 | 55 | .It Fl H |
24 | 56 | Yield the virtual CPU thread when a HLT instruction is detected. |
25 | 57 | If this option is not specified, virtual CPUs will use 100% of a host CPU. |
@@ -28,13 +60,14 @@ diff -upN bhyve_orig/bhyve.8 bhyve/bhyve.8 | ||
28 | 60 | +The value that can be specified sets the file name in |
29 | 61 | +.Ar /usr/share/bhyve/kbdlayout . |
30 | 62 | +This specification only works when loaded with UEFI mode.(Not working via console or SSH) |
31 | -+If not specified, the US keyboard layout(default) is specified. | |
63 | ++If you are using a VNC client that supports QEMU Extended Key Event Message (e.g. TigerVNC), don't need to specify this option. | |
64 | ++If you are using a VNC client that doesn't support it(e.g. tightVNC), and you don't specify this option, the US keyboard layout(default) is specified. | |
32 | 65 | .It Fl l Op Ar help|lpcdev Ns Op , Ns Ar conf |
33 | 66 | Allow devices behind the LPC PCI-ISA bridge to be configured. |
34 | 67 | The only supported devices are the TTY-class devices |
35 | 68 | diff -upN bhyve_orig/bhyverun.c bhyve/bhyverun.c |
36 | 69 | --- bhyve_orig/bhyverun.c 2020-05-01 11:25:57.439138000 +0900 |
37 | -+++ bhyve/bhyverun.c 2020-05-01 11:56:57.568136000 +0900 | |
70 | ++++ bhyve/bhyverun.c 2020-05-28 09:25:47.144660000 +0900 | |
38 | 71 | @@ -165,6 +165,8 @@ char *vmname; |
39 | 72 | int guest_ncpus; |
40 | 73 | uint16_t cores, maxcpus, sockets, threads; |
@@ -84,7 +117,7 @@ diff -upN bhyve_orig/bhyverun.c bhyve/bhyverun.c | ||
84 | 117 | if (strncmp(optarg, "help", strlen(optarg)) == 0) { |
85 | 118 | diff -upN bhyve_orig/bhyverun.h bhyve/bhyverun.h |
86 | 119 | --- bhyve_orig/bhyverun.h 2020-05-01 11:25:57.444136000 +0900 |
87 | -+++ bhyve/bhyverun.h 2020-04-28 20:51:08.322277000 +0900 | |
120 | ++++ bhyve/bhyverun.h 2020-05-28 09:25:47.145111000 +0900 | |
88 | 121 | @@ -39,6 +39,7 @@ extern int guest_ncpus; |
89 | 122 | extern uint16_t cores, sockets, threads; |
90 | 123 | extern char *guest_uuid_str; |
@@ -93,10 +126,47 @@ diff -upN bhyve_orig/bhyverun.h bhyve/bhyverun.h | ||
93 | 126 | |
94 | 127 | void *paddr_guest2host(struct vmctx *ctx, uintptr_t addr, size_t len); |
95 | 128 | |
129 | +diff -upN bhyve_orig/console.c bhyve/console.c | |
130 | +--- bhyve_orig/console.c 2020-05-01 11:25:57.441001000 +0900 | |
131 | ++++ bhyve/console.c 2020-05-28 10:47:10.699395000 +0900 | |
132 | +@@ -106,10 +106,10 @@ console_ptr_register(ptr_event_func_t event_cb, void * | |
133 | + } | |
134 | + | |
135 | + void | |
136 | +-console_key_event(int down, uint32_t keysym) | |
137 | ++console_key_event(int down, uint32_t keysym, uint32_t keycode) | |
138 | + { | |
139 | + if (console.kbd_event_cb) | |
140 | +- (*console.kbd_event_cb)(down, keysym, console.kbd_arg); | |
141 | ++ (*console.kbd_event_cb)(down, keysym, keycode, console.kbd_arg); | |
142 | + } | |
143 | + | |
144 | + void | |
145 | +diff -upN bhyve_orig/console.h bhyve/console.h | |
146 | +--- bhyve_orig/console.h 2020-05-01 11:25:57.446732000 +0900 | |
147 | ++++ bhyve/console.h 2020-05-28 10:47:47.290438000 +0900 | |
148 | +@@ -34,7 +34,7 @@ | |
149 | + struct bhyvegc; | |
150 | + | |
151 | + typedef void (*fb_render_func_t)(struct bhyvegc *gc, void *arg); | |
152 | +-typedef void (*kbd_event_func_t)(int down, uint32_t keysym, void *arg); | |
153 | ++typedef void (*kbd_event_func_t)(int down, uint32_t keysym, uint32_t keycode, void *arg); | |
154 | + typedef void (*ptr_event_func_t)(uint8_t mask, int x, int y, void *arg); | |
155 | + | |
156 | + void console_init(int w, int h, void *fbaddr); | |
157 | +@@ -47,7 +47,7 @@ void console_fb_register(fb_render_func_t render_cb, v | |
158 | + void console_refresh(void); | |
159 | + | |
160 | + void console_kbd_register(kbd_event_func_t event_cb, void *arg, int pri); | |
161 | +-void console_key_event(int down, uint32_t keysym); | |
162 | ++void console_key_event(int down, uint32_t keysym, uint32_t keycode); | |
163 | + | |
164 | + void console_ptr_register(ptr_event_func_t event_cb, void *arg, int pri); | |
165 | + void console_ptr_event(uint8_t button, int x, int y); | |
96 | 166 | Common subdirectories: bhyve_orig/kbdlayout and bhyve/kbdlayout |
97 | 167 | diff -upN bhyve_orig/ps2kbd.c bhyve/ps2kbd.c |
98 | 168 | --- bhyve_orig/ps2kbd.c 2020-05-01 11:25:57.446548000 +0900 |
99 | -+++ bhyve/ps2kbd.c 2020-04-30 21:16:15.390220000 +0900 | |
169 | ++++ bhyve/ps2kbd.c 2020-05-28 16:28:16.325233000 +0900 | |
100 | 170 | @@ -31,15 +31,20 @@ |
101 | 171 | __FBSDID("$FreeBSD: releng/12.1/usr.sbin/bhyve/ps2kbd.c 341757 2018-12-09 06:41:57Z araujo $"); |
102 | 172 |
@@ -118,7 +188,7 @@ diff -upN bhyve_orig/ps2kbd.c bhyve/ps2kbd.c | ||
118 | 188 | #include "atkbdc.h" |
119 | 189 | #include "console.h" |
120 | 190 | |
121 | -@@ -58,6 +63,8 @@ __FBSDID("$FreeBSD: releng/12.1/usr.sbin/bhyve/ps2kbd. | |
191 | +@@ -58,8 +63,11 @@ __FBSDID("$FreeBSD: releng/12.1/usr.sbin/bhyve/ps2kbd. | |
122 | 192 | |
123 | 193 | #define PS2KBD_FIFOSZ 16 |
124 | 194 |
@@ -126,8 +196,11 @@ diff -upN bhyve_orig/ps2kbd.c bhyve/ps2kbd.c | ||
126 | 196 | + |
127 | 197 | struct fifo { |
128 | 198 | uint8_t buf[PS2KBD_FIFOSZ]; |
199 | ++ uint8_t trans[PS2KBD_FIFOSZ]; | |
129 | 200 | int rindex; /* index to read from */ |
130 | -@@ -86,7 +93,7 @@ struct extended_translation { | |
201 | + int windex; /* index to write to */ | |
202 | + int num; /* number of bytes in the fifo */ | |
203 | +@@ -86,7 +94,7 @@ struct extended_translation { | |
131 | 204 | /* |
132 | 205 | * FIXME: Pause/break and Print Screen/SysRq require special handling. |
133 | 206 | */ |
@@ -136,7 +209,7 @@ diff -upN bhyve_orig/ps2kbd.c bhyve/ps2kbd.c | ||
136 | 209 | {0xff08, 0x66}, /* Back space */ |
137 | 210 | {0xff09, 0x0d}, /* Tab */ |
138 | 211 | {0xff0d, 0x5a}, /* Return */ |
139 | -@@ -158,7 +165,7 @@ static const struct extended_translation extended_tran | |
212 | +@@ -158,7 +166,7 @@ static const struct extended_translation extended_tran | |
140 | 213 | }; |
141 | 214 | |
142 | 215 | /* ASCII to type 2 scancode lookup table */ |
@@ -145,16 +218,197 @@ diff -upN bhyve_orig/ps2kbd.c bhyve/ps2kbd.c | ||
145 | 218 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
146 | 219 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
147 | 220 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
148 | -@@ -316,7 +323,7 @@ ps2kbd_keysym_queue(struct ps2kbd_softc *sc, | |
221 | +@@ -197,26 +205,28 @@ fifo_reset(struct ps2kbd_softc *sc) | |
222 | + } | |
223 | + | |
224 | + static void | |
225 | +-fifo_put(struct ps2kbd_softc *sc, uint8_t val) | |
226 | ++fifo_put(struct ps2kbd_softc *sc, uint8_t val, uint8_t trans) | |
227 | + { | |
228 | + struct fifo *fifo; | |
229 | + | |
230 | + fifo = &sc->fifo; | |
231 | + if (fifo->num < fifo->size) { | |
232 | + fifo->buf[fifo->windex] = val; | |
233 | ++ fifo->trans[fifo->windex] = trans; | |
234 | + fifo->windex = (fifo->windex + 1) % fifo->size; | |
235 | + fifo->num++; | |
236 | + } | |
237 | + } | |
238 | + | |
239 | + static int | |
240 | +-fifo_get(struct ps2kbd_softc *sc, uint8_t *val) | |
241 | ++fifo_get(struct ps2kbd_softc *sc, uint8_t *val, uint8_t *trans) | |
242 | + { | |
243 | + struct fifo *fifo; | |
244 | + | |
245 | + fifo = &sc->fifo; | |
246 | + if (fifo->num > 0) { | |
247 | + *val = fifo->buf[fifo->rindex]; | |
248 | ++ *trans = fifo->trans[fifo->rindex]; | |
249 | + fifo->rindex = (fifo->rindex + 1) % fifo->size; | |
250 | + fifo->num--; | |
251 | + return (0); | |
252 | +@@ -226,12 +236,12 @@ fifo_get(struct ps2kbd_softc *sc, uint8_t *val) | |
253 | + } | |
254 | + | |
255 | + int | |
256 | +-ps2kbd_read(struct ps2kbd_softc *sc, uint8_t *val) | |
257 | ++ps2kbd_read(struct ps2kbd_softc *sc, uint8_t *val, uint8_t *trans) | |
258 | + { | |
259 | + int retval; | |
260 | + | |
261 | + pthread_mutex_lock(&sc->mtx); | |
262 | +- retval = fifo_get(sc, val); | |
263 | ++ retval = fifo_get(sc, val, trans); | |
264 | + pthread_mutex_unlock(&sc->mtx); | |
265 | + | |
266 | + return (retval); | |
267 | +@@ -244,13 +254,13 @@ ps2kbd_write(struct ps2kbd_softc *sc, uint8_t val) | |
268 | + if (sc->curcmd) { | |
269 | + switch (sc->curcmd) { | |
270 | + case PS2KC_SET_TYPEMATIC: | |
271 | +- fifo_put(sc, PS2KC_ACK); | |
272 | ++ fifo_put(sc, PS2KC_ACK, 0); | |
273 | + break; | |
274 | + case PS2KC_SET_SCANCODE_SET: | |
275 | +- fifo_put(sc, PS2KC_ACK); | |
276 | ++ fifo_put(sc, PS2KC_ACK, 0); | |
277 | + break; | |
278 | + case PS2KC_SET_LEDS: | |
279 | +- fifo_put(sc, PS2KC_ACK); | |
280 | ++ fifo_put(sc, PS2KC_ACK, 0); | |
281 | + break; | |
282 | + default: | |
283 | + fprintf(stderr, "Unhandled ps2 keyboard current " | |
284 | +@@ -261,41 +271,41 @@ ps2kbd_write(struct ps2kbd_softc *sc, uint8_t val) | |
285 | + } else { | |
286 | + switch (val) { | |
287 | + case 0x00: | |
288 | +- fifo_put(sc, PS2KC_ACK); | |
289 | ++ fifo_put(sc, PS2KC_ACK, 0); | |
290 | + break; | |
291 | + case PS2KC_RESET_DEV: | |
292 | + fifo_reset(sc); | |
293 | +- fifo_put(sc, PS2KC_ACK); | |
294 | +- fifo_put(sc, PS2KC_BAT_SUCCESS); | |
295 | ++ fifo_put(sc, PS2KC_ACK, 0); | |
296 | ++ fifo_put(sc, PS2KC_BAT_SUCCESS, 0); | |
297 | + break; | |
298 | + case PS2KC_DISABLE: | |
299 | + sc->enabled = false; | |
300 | +- fifo_put(sc, PS2KC_ACK); | |
301 | ++ fifo_put(sc, PS2KC_ACK, 0); | |
302 | + break; | |
303 | + case PS2KC_ENABLE: | |
304 | + sc->enabled = true; | |
305 | + fifo_reset(sc); | |
306 | +- fifo_put(sc, PS2KC_ACK); | |
307 | ++ fifo_put(sc, PS2KC_ACK, 0); | |
308 | + break; | |
309 | + case PS2KC_SET_TYPEMATIC: | |
310 | + sc->curcmd = val; | |
311 | +- fifo_put(sc, PS2KC_ACK); | |
312 | ++ fifo_put(sc, PS2KC_ACK, 0); | |
313 | + break; | |
314 | + case PS2KC_SEND_DEV_ID: | |
315 | +- fifo_put(sc, PS2KC_ACK); | |
316 | +- fifo_put(sc, 0xab); | |
317 | +- fifo_put(sc, 0x83); | |
318 | ++ fifo_put(sc, PS2KC_ACK, 0); | |
319 | ++ fifo_put(sc, 0xab, 0); | |
320 | ++ fifo_put(sc, 0x83, 0); | |
321 | + break; | |
322 | + case PS2KC_SET_SCANCODE_SET: | |
323 | + sc->curcmd = val; | |
324 | +- fifo_put(sc, PS2KC_ACK); | |
325 | ++ fifo_put(sc, PS2KC_ACK, 0); | |
326 | + break; | |
327 | + case PS2KC_ECHO: | |
328 | +- fifo_put(sc, PS2KC_ECHO); | |
329 | ++ fifo_put(sc, PS2KC_ECHO, 0); | |
330 | + break; | |
331 | + case PS2KC_SET_LEDS: | |
332 | + sc->curcmd = val; | |
333 | +- fifo_put(sc, PS2KC_ACK); | |
334 | ++ fifo_put(sc, PS2KC_ACK, 0); | |
335 | + break; | |
336 | + default: | |
337 | + fprintf(stderr, "Unhandled ps2 keyboard command " | |
338 | +@@ -311,26 +321,32 @@ ps2kbd_write(struct ps2kbd_softc *sc, uint8_t val) | |
339 | + */ | |
340 | + static void | |
341 | + ps2kbd_keysym_queue(struct ps2kbd_softc *sc, | |
342 | +- int down, uint32_t keysym) | |
343 | ++ int down, uint32_t keysym, uint32_t keycode) | |
344 | + { | |
149 | 345 | assert(pthread_mutex_isowned_np(&sc->mtx)); |
150 | 346 | int e0_prefix, found; |
151 | 347 | uint8_t code; |
152 | 348 | - const struct extended_translation *trans; |
153 | 349 | + struct extended_translation *trans; |
154 | 350 | |
155 | - found = 0; | |
156 | - if (keysym < 0x80) { | |
157 | -@@ -366,10 +373,91 @@ ps2kbd_event(int down, uint32_t keysym, void *arg) | |
351 | +- found = 0; | |
352 | +- if (keysym < 0x80) { | |
353 | +- code = ascii_translations[keysym]; | |
354 | +- e0_prefix = 0; | |
355 | ++ if (keycode) { | |
356 | ++ code = (uint8_t)(keycode & 0x7f); | |
357 | ++ e0_prefix = ((keycode & 0x80) ? SCANCODE_E0_PREFIX : 0); | |
358 | + found = 1; | |
359 | + } else { | |
360 | +- for (trans = &(extended_translations[0]); trans->keysym != 0; | |
361 | +- trans++) { | |
362 | +- if (keysym == trans->keysym) { | |
363 | +- code = trans->scancode; | |
364 | +- e0_prefix = trans->flags & SCANCODE_E0_PREFIX; | |
365 | +- found = 1; | |
366 | +- break; | |
367 | ++ found = 0; | |
368 | ++ if (keysym < 0x80) { | |
369 | ++ code = ascii_translations[keysym]; | |
370 | ++ e0_prefix = 0; | |
371 | ++ found = 1; | |
372 | ++ } else { | |
373 | ++ for (trans = &(extended_translations[0]); trans->keysym != 0; | |
374 | ++ trans++) { | |
375 | ++ if (keysym == trans->keysym) { | |
376 | ++ code = trans->scancode; | |
377 | ++ e0_prefix = trans->flags & SCANCODE_E0_PREFIX; | |
378 | ++ found = 1; | |
379 | ++ break; | |
380 | ++ } | |
381 | + } | |
382 | + } | |
383 | + } | |
384 | +@@ -341,14 +357,14 @@ ps2kbd_keysym_queue(struct ps2kbd_softc *sc, | |
385 | + } | |
386 | + | |
387 | + if (e0_prefix) | |
388 | +- fifo_put(sc, 0xe0); | |
389 | ++ fifo_put(sc, 0xe0, 0); | |
390 | + if (!down) | |
391 | +- fifo_put(sc, 0xf0); | |
392 | +- fifo_put(sc, code); | |
393 | ++ fifo_put(sc, 0xf0, 0); | |
394 | ++ fifo_put(sc, code, (keycode ? 0 : 1)); | |
395 | + } | |
396 | + | |
397 | + static void | |
398 | +-ps2kbd_event(int down, uint32_t keysym, void *arg) | |
399 | ++ps2kbd_event(int down, uint32_t keysym, uint32_t keycode, void *arg) | |
400 | + { | |
401 | + struct ps2kbd_softc *sc = arg; | |
402 | + int fifo_full; | |
403 | +@@ -359,17 +375,98 @@ ps2kbd_event(int down, uint32_t keysym, void *arg) | |
404 | + return; | |
405 | + } | |
406 | + fifo_full = sc->fifo.num == PS2KBD_FIFOSZ; | |
407 | +- ps2kbd_keysym_queue(sc, down, keysym); | |
408 | ++ ps2kbd_keysym_queue(sc, down, keysym, keycode); | |
409 | + pthread_mutex_unlock(&sc->mtx); | |
410 | + | |
411 | + if (!fifo_full) | |
158 | 412 | atkbdc_event(sc->atkbdc_sc, 1); |
159 | 413 | } |
160 | 414 |
@@ -246,3 +500,156 @@ diff -upN bhyve_orig/ps2kbd.c bhyve/ps2kbd.c | ||
246 | 500 | |
247 | 501 | sc = calloc(1, sizeof (struct ps2kbd_softc)); |
248 | 502 | pthread_mutex_init(&sc->mtx, NULL); |
503 | +diff -upN bhyve_orig/ps2kbd.h bhyve/ps2kbd.h | |
504 | +--- bhyve_orig/ps2kbd.h 2020-05-01 11:25:57.441775000 +0900 | |
505 | ++++ bhyve/ps2kbd.h 2020-05-28 13:42:50.937234000 +0900 | |
506 | +@@ -35,7 +35,7 @@ struct atkbdc_softc; | |
507 | + | |
508 | + struct ps2kbd_softc *ps2kbd_init(struct atkbdc_softc *sc); | |
509 | + | |
510 | +-int ps2kbd_read(struct ps2kbd_softc *sc, uint8_t *val); | |
511 | ++int ps2kbd_read(struct ps2kbd_softc *sc, uint8_t *val, uint8_t *trans); | |
512 | + void ps2kbd_write(struct ps2kbd_softc *sc, uint8_t val); | |
513 | + | |
514 | + #endif /* _PS2KBD_H_ */ | |
515 | +diff -upN bhyve_orig/rfb.c bhyve/rfb.c | |
516 | +--- bhyve_orig/rfb.c 2020-05-01 11:25:57.446856000 +0900 | |
517 | ++++ bhyve/rfb.c 2020-05-28 13:16:38.135646000 +0900 | |
518 | +@@ -97,7 +97,10 @@ struct rfb_softc { | |
519 | + bool enc_raw_ok; | |
520 | + bool enc_zlib_ok; | |
521 | + bool enc_resize_ok; | |
522 | ++ bool enc_extkeyevent_ok; | |
523 | + | |
524 | ++ bool enc_extkeyevent_send; | |
525 | ++ | |
526 | + z_stream zstream; | |
527 | + uint8_t *zbuf; | |
528 | + int zbuflen; | |
529 | +@@ -143,7 +146,10 @@ struct rfb_pixfmt_msg { | |
530 | + #define RFB_ENCODING_RAW 0 | |
531 | + #define RFB_ENCODING_ZLIB 6 | |
532 | + #define RFB_ENCODING_RESIZE -223 | |
533 | ++#define RFB_ENCODING_EXT_KEYEVENT -258 | |
534 | + | |
535 | ++#define RFB_CLIENTMSG_EXT_KEYEVENT 0 | |
536 | ++ | |
537 | + #define RFB_MAX_WIDTH 2000 | |
538 | + #define RFB_MAX_HEIGHT 1200 | |
539 | + #define RFB_ZLIB_BUFSZ RFB_MAX_WIDTH*RFB_MAX_HEIGHT*4 | |
540 | +@@ -170,6 +176,19 @@ struct rfb_key_msg { | |
541 | + uint8_t type; | |
542 | + uint8_t down; | |
543 | + uint16_t pad; | |
544 | ++ uint32_t sym; | |
545 | ++}; | |
546 | ++ | |
547 | ++struct rfb_client_msg { | |
548 | ++ uint8_t type; | |
549 | ++ uint8_t subtype; | |
550 | ++}; | |
551 | ++ | |
552 | ++struct rfb_extended_key_msg { | |
553 | ++ uint8_t type; | |
554 | ++ uint8_t subtype; | |
555 | ++ uint16_t down; | |
556 | ++ uint32_t sym; | |
557 | + uint32_t code; | |
558 | + }; | |
559 | + | |
560 | +@@ -248,6 +267,27 @@ rfb_send_resize_update_msg(struct rfb_softc *rc, int c | |
561 | + } | |
562 | + | |
563 | + static void | |
564 | ++rfb_send_extended_keyevent_update_msg(struct rfb_softc *rc, int cfd) | |
565 | ++{ | |
566 | ++ struct rfb_srvr_updt_msg supdt_msg; | |
567 | ++ struct rfb_srvr_rect_hdr srect_hdr; | |
568 | ++ | |
569 | ++ /* Number of rectangles: 1 */ | |
570 | ++ supdt_msg.type = 0; | |
571 | ++ supdt_msg.pad = 0; | |
572 | ++ supdt_msg.numrects = htons(1); | |
573 | ++ stream_write(cfd, &supdt_msg, sizeof(struct rfb_srvr_updt_msg)); | |
574 | ++ | |
575 | ++ /* Rectangle header */ | |
576 | ++ srect_hdr.x = htons(0); | |
577 | ++ srect_hdr.y = htons(0); | |
578 | ++ srect_hdr.width = htons(rc->width); | |
579 | ++ srect_hdr.height = htons(rc->height); | |
580 | ++ srect_hdr.encoding = htonl(RFB_ENCODING_EXT_KEYEVENT); | |
581 | ++ stream_write(cfd, &srect_hdr, sizeof(struct rfb_srvr_rect_hdr)); | |
582 | ++} | |
583 | ++ | |
584 | ++static void | |
585 | + rfb_recv_set_pixfmt_msg(struct rfb_softc *rc, int cfd) | |
586 | + { | |
587 | + struct rfb_pixfmt_msg pixfmt_msg; | |
588 | +@@ -281,6 +321,9 @@ rfb_recv_set_encodings_msg(struct rfb_softc *rc, int c | |
589 | + case RFB_ENCODING_RESIZE: | |
590 | + rc->enc_resize_ok = true; | |
591 | + break; | |
592 | ++ case RFB_ENCODING_EXT_KEYEVENT: | |
593 | ++ rc->enc_extkeyevent_ok = true; | |
594 | ++ break; | |
595 | + } | |
596 | + } | |
597 | + } | |
598 | +@@ -646,6 +689,11 @@ rfb_recv_update_msg(struct rfb_softc *rc, int cfd, int | |
599 | + rfb_send_resize_update_msg(rc, cfd); | |
600 | + } | |
601 | + | |
602 | ++ if (rc->enc_extkeyevent_ok && (!rc->enc_extkeyevent_send)) { | |
603 | ++ rfb_send_extended_keyevent_update_msg(rc, cfd); | |
604 | ++ rc->enc_extkeyevent_send = true; | |
605 | ++ } | |
606 | ++ | |
607 | + if (discardonly) | |
608 | + return; | |
609 | + | |
610 | +@@ -659,10 +707,24 @@ rfb_recv_key_msg(struct rfb_softc *rc, int cfd) | |
611 | + | |
612 | + (void)stream_read(cfd, ((void *)&key_msg) + 1, sizeof(key_msg) - 1); | |
613 | + | |
614 | +- console_key_event(key_msg.down, htonl(key_msg.code)); | |
615 | ++ console_key_event(key_msg.down, htonl(key_msg.sym), htonl(0)); | |
616 | + } | |
617 | + | |
618 | + static void | |
619 | ++rfb_recv_client_msg(struct rfb_softc *rc, int cfd) | |
620 | ++{ | |
621 | ++ struct rfb_client_msg client_msg; | |
622 | ++ struct rfb_extended_key_msg extkey_msg; | |
623 | ++ | |
624 | ++ (void)stream_read(cfd, ((void *)&client_msg) + 1, sizeof(client_msg) - 1); | |
625 | ++ | |
626 | ++ if (client_msg.subtype == RFB_CLIENTMSG_EXT_KEYEVENT ) { | |
627 | ++ (void)stream_read(cfd, ((void *)&extkey_msg) + 2, sizeof(extkey_msg) - 2); | |
628 | ++ console_key_event((int)extkey_msg.down, htonl(extkey_msg.sym), htonl(extkey_msg.code)); | |
629 | ++ } | |
630 | ++} | |
631 | ++ | |
632 | ++static void | |
633 | + rfb_recv_ptr_msg(struct rfb_softc *rc, int cfd) | |
634 | + { | |
635 | + struct rfb_ptr_msg ptr_msg; | |
636 | +@@ -901,6 +963,9 @@ rfb_handle(struct rfb_softc *rc, int cfd) | |
637 | + case 6: | |
638 | + rfb_recv_cuttext_msg(rc, cfd); | |
639 | + break; | |
640 | ++ case 255: | |
641 | ++ rfb_recv_client_msg(rc, cfd); | |
642 | ++ break; | |
643 | + default: | |
644 | + WPRINTF(("rfb unknown cli-code %d!\n", buf[0] & 0xff)); | |
645 | + goto done; | |
646 | +@@ -935,6 +1000,9 @@ rfb_thr(void *arg) | |
647 | + rc->enc_raw_ok = false; | |
648 | + rc->enc_zlib_ok = false; | |
649 | + rc->enc_resize_ok = false; | |
650 | ++ rc->enc_extkeyevent_ok = false; | |
651 | ++ | |
652 | ++ rc->enc_extkeyevent_send = false; | |
653 | + | |
654 | + cfd = accept(rc->sfd, NULL, NULL); | |
655 | + if (rc->conn_wait) { |
@@ -1,6 +1,6 @@ | ||
1 | 1 | diff -upN bhyve_orig/Makefile bhyve/Makefile |
2 | 2 | --- bhyve_orig/Makefile 2020-04-23 09:06:39.000000000 +0900 |
3 | -+++ bhyve/Makefile 2020-05-02 13:09:01.382770000 +0900 | |
3 | ++++ bhyve/Makefile 2020-05-29 18:03:10.627095000 +0900 | |
4 | 4 | @@ -99,4 +99,6 @@ CFLAGS+=-DGDB_LOG |
5 | 5 | |
6 | 6 | WARNS?= 2 |
@@ -8,9 +8,41 @@ diff -upN bhyve_orig/Makefile bhyve/Makefile | ||
8 | 8 | +SUBDIR= kbdlayout |
9 | 9 | + |
10 | 10 | .include <bsd.prog.mk> |
11 | +diff -upN bhyve_orig/atkbdc.c bhyve/atkbdc.c | |
12 | +--- bhyve_orig/atkbdc.c 2020-04-23 09:06:39.000000000 +0900 | |
13 | ++++ bhyve/atkbdc.c 2020-05-29 18:03:10.653893000 +0900 | |
14 | +@@ -211,24 +211,25 @@ atkbdc_kbd_read(struct atkbdc_softc *sc) | |
15 | + 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff | |
16 | + }; | |
17 | + uint8_t val; | |
18 | ++ uint8_t trans; | |
19 | + uint8_t release = 0; | |
20 | + | |
21 | + assert(pthread_mutex_isowned_np(&sc->mtx)); | |
22 | + | |
23 | + if (sc->ram[0] & KBD_TRANSLATION) { | |
24 | +- while (ps2kbd_read(sc->ps2kbd_sc, &val) != -1) { | |
25 | ++ while (ps2kbd_read(sc->ps2kbd_sc, &val, &trans) != -1) { | |
26 | + if (val == 0xf0) { | |
27 | + release = 0x80; | |
28 | + continue; | |
29 | + } else { | |
30 | +- val = translation[val] | release; | |
31 | ++ val = ((trans) ? translation[val] : val) | release; | |
32 | + } | |
33 | + atkbdc_kbd_queue_data(sc, val); | |
34 | + break; | |
35 | + } | |
36 | + } else { | |
37 | + while (sc->kbd.bcnt < FIFOSZ) { | |
38 | +- if (ps2kbd_read(sc->ps2kbd_sc, &val) != -1) | |
39 | ++ if (ps2kbd_read(sc->ps2kbd_sc, &val, &trans) != -1) | |
40 | + atkbdc_kbd_queue_data(sc, val); | |
41 | + else | |
42 | + break; | |
11 | 43 | diff -upN bhyve_orig/bhyve.8 bhyve/bhyve.8 |
12 | 44 | --- bhyve_orig/bhyve.8 2020-04-23 09:06:39.000000000 +0900 |
13 | -+++ bhyve/bhyve.8 2020-05-02 13:11:28.198679000 +0900 | |
45 | ++++ bhyve/bhyve.8 2020-05-29 18:11:54.290185000 +0900 | |
14 | 46 | @@ -47,6 +47,7 @@ |
15 | 47 | .Sm on |
16 | 48 | .Op Fl G Ar port |
@@ -19,7 +51,7 @@ diff -upN bhyve_orig/bhyve.8 bhyve/bhyve.8 | ||
19 | 51 | .Oo Fl l |
20 | 52 | .Sm off |
21 | 53 | .Cm help | Ar lpcdev Op Cm \&, Ar conf |
22 | -@@ -161,6 +162,12 @@ Print help message and exit. | |
54 | +@@ -161,6 +162,13 @@ Print help message and exit. | |
23 | 55 | .It Fl H |
24 | 56 | Yield the virtual CPU thread when a HLT instruction is detected. |
25 | 57 | If this option is not specified, virtual CPUs will use 100% of a host CPU. |
@@ -28,13 +60,14 @@ diff -upN bhyve_orig/bhyve.8 bhyve/bhyve.8 | ||
28 | 60 | +The value that can be specified sets the file name in |
29 | 61 | +.Ar /usr/share/bhyve/kbdlayout . |
30 | 62 | +This specification only works when loaded with UEFI mode.(Not working via console or SSH) |
31 | -+If not specified, the US keyboard layout(default) is specified. | |
63 | ++If you are using a VNC client that supports QEMU Extended Key Event Message (e.g. TigerVNC), don't need to specify this option. | |
64 | ++If you are using a VNC client that doesn't support it(e.g. tightVNC), and you don't specify this option, the US keyboard layout(default) is specified. | |
32 | 65 | .It Fl l Op Ar help|lpcdev Ns Op , Ns Ar conf |
33 | 66 | Allow devices behind the LPC PCI-ISA bridge to be configured. |
34 | 67 | The only supported devices are the TTY-class devices |
35 | 68 | diff -upN bhyve_orig/bhyverun.c bhyve/bhyverun.c |
36 | 69 | --- bhyve_orig/bhyverun.c 2020-04-23 09:06:39.000000000 +0900 |
37 | -+++ bhyve/bhyverun.c 2020-05-02 13:09:01.437624000 +0900 | |
70 | ++++ bhyve/bhyverun.c 2020-05-29 18:03:10.699642000 +0900 | |
38 | 71 | @@ -168,6 +168,8 @@ char *vmname; |
39 | 72 | int guest_ncpus; |
40 | 73 | uint16_t cores, maxcpus, sockets, threads; |
@@ -84,7 +117,7 @@ diff -upN bhyve_orig/bhyverun.c bhyve/bhyverun.c | ||
84 | 117 | if (strncmp(optarg, "help", strlen(optarg)) == 0) { |
85 | 118 | diff -upN bhyve_orig/bhyverun.h bhyve/bhyverun.h |
86 | 119 | --- bhyve_orig/bhyverun.h 2020-04-23 09:06:39.000000000 +0900 |
87 | -+++ bhyve/bhyverun.h 2020-05-02 13:09:01.444814000 +0900 | |
120 | ++++ bhyve/bhyverun.h 2020-05-29 18:03:10.703030000 +0900 | |
88 | 121 | @@ -39,6 +39,7 @@ extern int guest_ncpus; |
89 | 122 | extern uint16_t cores, sockets, threads; |
90 | 123 | extern char *guest_uuid_str; |
@@ -93,10 +126,47 @@ diff -upN bhyve_orig/bhyverun.h bhyve/bhyverun.h | ||
93 | 126 | |
94 | 127 | void *paddr_guest2host(struct vmctx *ctx, uintptr_t addr, size_t len); |
95 | 128 | |
129 | +diff -upN bhyve_orig/console.c bhyve/console.c | |
130 | +--- bhyve_orig/console.c 2020-04-23 09:06:39.000000000 +0900 | |
131 | ++++ bhyve/console.c 2020-05-29 18:03:10.705936000 +0900 | |
132 | +@@ -106,10 +106,10 @@ console_ptr_register(ptr_event_func_t event_cb, void * | |
133 | + } | |
134 | + | |
135 | + void | |
136 | +-console_key_event(int down, uint32_t keysym) | |
137 | ++console_key_event(int down, uint32_t keysym, uint32_t keycode) | |
138 | + { | |
139 | + if (console.kbd_event_cb) | |
140 | +- (*console.kbd_event_cb)(down, keysym, console.kbd_arg); | |
141 | ++ (*console.kbd_event_cb)(down, keysym, keycode, console.kbd_arg); | |
142 | + } | |
143 | + | |
144 | + void | |
145 | +diff -upN bhyve_orig/console.h bhyve/console.h | |
146 | +--- bhyve_orig/console.h 2020-04-23 09:06:39.000000000 +0900 | |
147 | ++++ bhyve/console.h 2020-05-29 18:03:10.708779000 +0900 | |
148 | +@@ -34,7 +34,7 @@ | |
149 | + struct bhyvegc; | |
150 | + | |
151 | + typedef void (*fb_render_func_t)(struct bhyvegc *gc, void *arg); | |
152 | +-typedef void (*kbd_event_func_t)(int down, uint32_t keysym, void *arg); | |
153 | ++typedef void (*kbd_event_func_t)(int down, uint32_t keysym, uint32_t keycode, void *arg); | |
154 | + typedef void (*ptr_event_func_t)(uint8_t mask, int x, int y, void *arg); | |
155 | + | |
156 | + void console_init(int w, int h, void *fbaddr); | |
157 | +@@ -47,7 +47,7 @@ void console_fb_register(fb_render_func_t render_cb, v | |
158 | + void console_refresh(void); | |
159 | + | |
160 | + void console_kbd_register(kbd_event_func_t event_cb, void *arg, int pri); | |
161 | +-void console_key_event(int down, uint32_t keysym); | |
162 | ++void console_key_event(int down, uint32_t keysym, uint32_t keycode); | |
163 | + | |
164 | + void console_ptr_register(ptr_event_func_t event_cb, void *arg, int pri); | |
165 | + void console_ptr_event(uint8_t button, int x, int y); | |
96 | 166 | Common subdirectories: bhyve_orig/kbdlayout and bhyve/kbdlayout |
97 | 167 | diff -upN bhyve_orig/ps2kbd.c bhyve/ps2kbd.c |
98 | 168 | --- bhyve_orig/ps2kbd.c 2020-04-23 09:06:39.000000000 +0900 |
99 | -+++ bhyve/ps2kbd.c 2020-05-02 13:09:01.462761000 +0900 | |
169 | ++++ bhyve/ps2kbd.c 2020-05-29 18:03:10.788431000 +0900 | |
100 | 170 | @@ -31,15 +31,20 @@ |
101 | 171 | __FBSDID("$FreeBSD: head/usr.sbin/bhyve/ps2kbd.c 356523 2020-01-08 22:55:22Z vmaffione $"); |
102 | 172 |
@@ -118,7 +188,7 @@ diff -upN bhyve_orig/ps2kbd.c bhyve/ps2kbd.c | ||
118 | 188 | #include "atkbdc.h" |
119 | 189 | #include "debug.h" |
120 | 190 | #include "console.h" |
121 | -@@ -59,6 +64,8 @@ __FBSDID("$FreeBSD: head/usr.sbin/bhyve/ps2kbd.c 35652 | |
191 | +@@ -59,8 +64,11 @@ __FBSDID("$FreeBSD: head/usr.sbin/bhyve/ps2kbd.c 35652 | |
122 | 192 | |
123 | 193 | #define PS2KBD_FIFOSZ 16 |
124 | 194 |
@@ -126,8 +196,11 @@ diff -upN bhyve_orig/ps2kbd.c bhyve/ps2kbd.c | ||
126 | 196 | + |
127 | 197 | struct fifo { |
128 | 198 | uint8_t buf[PS2KBD_FIFOSZ]; |
199 | ++ uint8_t trans[PS2KBD_FIFOSZ]; | |
129 | 200 | int rindex; /* index to read from */ |
130 | -@@ -87,7 +94,7 @@ struct extended_translation { | |
201 | + int windex; /* index to write to */ | |
202 | + int num; /* number of bytes in the fifo */ | |
203 | +@@ -87,7 +95,7 @@ struct extended_translation { | |
131 | 204 | /* |
132 | 205 | * FIXME: Pause/break and Print Screen/SysRq require special handling. |
133 | 206 | */ |
@@ -136,7 +209,7 @@ diff -upN bhyve_orig/ps2kbd.c bhyve/ps2kbd.c | ||
136 | 209 | {0xff08, 0x66}, /* Back space */ |
137 | 210 | {0xff09, 0x0d}, /* Tab */ |
138 | 211 | {0xff0d, 0x5a}, /* Return */ |
139 | -@@ -159,7 +166,7 @@ static const struct extended_translation extended_tran | |
212 | +@@ -159,7 +167,7 @@ static const struct extended_translation extended_tran | |
140 | 213 | }; |
141 | 214 | |
142 | 215 | /* ASCII to type 2 scancode lookup table */ |
@@ -145,16 +218,197 @@ diff -upN bhyve_orig/ps2kbd.c bhyve/ps2kbd.c | ||
145 | 218 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
146 | 219 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
147 | 220 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
148 | -@@ -317,7 +324,7 @@ ps2kbd_keysym_queue(struct ps2kbd_softc *sc, | |
221 | +@@ -198,26 +206,28 @@ fifo_reset(struct ps2kbd_softc *sc) | |
222 | + } | |
223 | + | |
224 | + static void | |
225 | +-fifo_put(struct ps2kbd_softc *sc, uint8_t val) | |
226 | ++fifo_put(struct ps2kbd_softc *sc, uint8_t val, uint8_t trans) | |
227 | + { | |
228 | + struct fifo *fifo; | |
229 | + | |
230 | + fifo = &sc->fifo; | |
231 | + if (fifo->num < fifo->size) { | |
232 | + fifo->buf[fifo->windex] = val; | |
233 | ++ fifo->trans[fifo->windex] = trans; | |
234 | + fifo->windex = (fifo->windex + 1) % fifo->size; | |
235 | + fifo->num++; | |
236 | + } | |
237 | + } | |
238 | + | |
239 | + static int | |
240 | +-fifo_get(struct ps2kbd_softc *sc, uint8_t *val) | |
241 | ++fifo_get(struct ps2kbd_softc *sc, uint8_t *val, uint8_t *trans) | |
242 | + { | |
243 | + struct fifo *fifo; | |
244 | + | |
245 | + fifo = &sc->fifo; | |
246 | + if (fifo->num > 0) { | |
247 | + *val = fifo->buf[fifo->rindex]; | |
248 | ++ *trans = fifo->trans[fifo->rindex]; | |
249 | + fifo->rindex = (fifo->rindex + 1) % fifo->size; | |
250 | + fifo->num--; | |
251 | + return (0); | |
252 | +@@ -227,12 +237,12 @@ fifo_get(struct ps2kbd_softc *sc, uint8_t *val) | |
253 | + } | |
254 | + | |
255 | + int | |
256 | +-ps2kbd_read(struct ps2kbd_softc *sc, uint8_t *val) | |
257 | ++ps2kbd_read(struct ps2kbd_softc *sc, uint8_t *val, uint8_t *trans) | |
258 | + { | |
259 | + int retval; | |
260 | + | |
261 | + pthread_mutex_lock(&sc->mtx); | |
262 | +- retval = fifo_get(sc, val); | |
263 | ++ retval = fifo_get(sc, val, trans); | |
264 | + pthread_mutex_unlock(&sc->mtx); | |
265 | + | |
266 | + return (retval); | |
267 | +@@ -245,13 +255,13 @@ ps2kbd_write(struct ps2kbd_softc *sc, uint8_t val) | |
268 | + if (sc->curcmd) { | |
269 | + switch (sc->curcmd) { | |
270 | + case PS2KC_SET_TYPEMATIC: | |
271 | +- fifo_put(sc, PS2KC_ACK); | |
272 | ++ fifo_put(sc, PS2KC_ACK, 0); | |
273 | + break; | |
274 | + case PS2KC_SET_SCANCODE_SET: | |
275 | +- fifo_put(sc, PS2KC_ACK); | |
276 | ++ fifo_put(sc, PS2KC_ACK, 0); | |
277 | + break; | |
278 | + case PS2KC_SET_LEDS: | |
279 | +- fifo_put(sc, PS2KC_ACK); | |
280 | ++ fifo_put(sc, PS2KC_ACK, 0); | |
281 | + break; | |
282 | + default: | |
283 | + EPRINTLN("Unhandled ps2 keyboard current " | |
284 | +@@ -262,41 +272,41 @@ ps2kbd_write(struct ps2kbd_softc *sc, uint8_t val) | |
285 | + } else { | |
286 | + switch (val) { | |
287 | + case 0x00: | |
288 | +- fifo_put(sc, PS2KC_ACK); | |
289 | ++ fifo_put(sc, PS2KC_ACK, 0); | |
290 | + break; | |
291 | + case PS2KC_RESET_DEV: | |
292 | + fifo_reset(sc); | |
293 | +- fifo_put(sc, PS2KC_ACK); | |
294 | +- fifo_put(sc, PS2KC_BAT_SUCCESS); | |
295 | ++ fifo_put(sc, PS2KC_ACK, 0); | |
296 | ++ fifo_put(sc, PS2KC_BAT_SUCCESS, 0); | |
297 | + break; | |
298 | + case PS2KC_DISABLE: | |
299 | + sc->enabled = false; | |
300 | +- fifo_put(sc, PS2KC_ACK); | |
301 | ++ fifo_put(sc, PS2KC_ACK, 0); | |
302 | + break; | |
303 | + case PS2KC_ENABLE: | |
304 | + sc->enabled = true; | |
305 | + fifo_reset(sc); | |
306 | +- fifo_put(sc, PS2KC_ACK); | |
307 | ++ fifo_put(sc, PS2KC_ACK, 0); | |
308 | + break; | |
309 | + case PS2KC_SET_TYPEMATIC: | |
310 | + sc->curcmd = val; | |
311 | +- fifo_put(sc, PS2KC_ACK); | |
312 | ++ fifo_put(sc, PS2KC_ACK, 0); | |
313 | + break; | |
314 | + case PS2KC_SEND_DEV_ID: | |
315 | +- fifo_put(sc, PS2KC_ACK); | |
316 | +- fifo_put(sc, 0xab); | |
317 | +- fifo_put(sc, 0x83); | |
318 | ++ fifo_put(sc, PS2KC_ACK, 0); | |
319 | ++ fifo_put(sc, 0xab, 0); | |
320 | ++ fifo_put(sc, 0x83, 0); | |
321 | + break; | |
322 | + case PS2KC_SET_SCANCODE_SET: | |
323 | + sc->curcmd = val; | |
324 | +- fifo_put(sc, PS2KC_ACK); | |
325 | ++ fifo_put(sc, PS2KC_ACK, 0); | |
326 | + break; | |
327 | + case PS2KC_ECHO: | |
328 | +- fifo_put(sc, PS2KC_ECHO); | |
329 | ++ fifo_put(sc, PS2KC_ECHO, 0); | |
330 | + break; | |
331 | + case PS2KC_SET_LEDS: | |
332 | + sc->curcmd = val; | |
333 | +- fifo_put(sc, PS2KC_ACK); | |
334 | ++ fifo_put(sc, PS2KC_ACK, 0); | |
335 | + break; | |
336 | + default: | |
337 | + EPRINTLN("Unhandled ps2 keyboard command " | |
338 | +@@ -312,26 +322,32 @@ ps2kbd_write(struct ps2kbd_softc *sc, uint8_t val) | |
339 | + */ | |
340 | + static void | |
341 | + ps2kbd_keysym_queue(struct ps2kbd_softc *sc, | |
342 | +- int down, uint32_t keysym) | |
343 | ++ int down, uint32_t keysym, uint32_t keycode) | |
344 | + { | |
149 | 345 | assert(pthread_mutex_isowned_np(&sc->mtx)); |
150 | 346 | int e0_prefix, found; |
151 | 347 | uint8_t code; |
152 | 348 | - const struct extended_translation *trans; |
153 | 349 | + struct extended_translation *trans; |
154 | 350 | |
155 | - found = 0; | |
156 | - if (keysym < 0x80) { | |
157 | -@@ -367,10 +374,91 @@ ps2kbd_event(int down, uint32_t keysym, void *arg) | |
351 | +- found = 0; | |
352 | +- if (keysym < 0x80) { | |
353 | +- code = ascii_translations[keysym]; | |
354 | +- e0_prefix = 0; | |
355 | ++ if (keycode) { | |
356 | ++ code = (uint8_t)(keycode & 0x7f); | |
357 | ++ e0_prefix = ((keycode & 0x80) ? SCANCODE_E0_PREFIX : 0); | |
358 | + found = 1; | |
359 | + } else { | |
360 | +- for (trans = &(extended_translations[0]); trans->keysym != 0; | |
361 | +- trans++) { | |
362 | +- if (keysym == trans->keysym) { | |
363 | +- code = trans->scancode; | |
364 | +- e0_prefix = trans->flags & SCANCODE_E0_PREFIX; | |
365 | +- found = 1; | |
366 | +- break; | |
367 | ++ found = 0; | |
368 | ++ if (keysym < 0x80) { | |
369 | ++ code = ascii_translations[keysym]; | |
370 | ++ e0_prefix = 0; | |
371 | ++ found = 1; | |
372 | ++ } else { | |
373 | ++ for (trans = &(extended_translations[0]); trans->keysym != 0; | |
374 | ++ trans++) { | |
375 | ++ if (keysym == trans->keysym) { | |
376 | ++ code = trans->scancode; | |
377 | ++ e0_prefix = trans->flags & SCANCODE_E0_PREFIX; | |
378 | ++ found = 1; | |
379 | ++ break; | |
380 | ++ } | |
381 | + } | |
382 | + } | |
383 | + } | |
384 | +@@ -342,14 +358,14 @@ ps2kbd_keysym_queue(struct ps2kbd_softc *sc, | |
385 | + } | |
386 | + | |
387 | + if (e0_prefix) | |
388 | +- fifo_put(sc, 0xe0); | |
389 | ++ fifo_put(sc, 0xe0, 0); | |
390 | + if (!down) | |
391 | +- fifo_put(sc, 0xf0); | |
392 | +- fifo_put(sc, code); | |
393 | ++ fifo_put(sc, 0xf0, 0); | |
394 | ++ fifo_put(sc, code, (keycode ? 0 : 1)); | |
395 | + } | |
396 | + | |
397 | + static void | |
398 | +-ps2kbd_event(int down, uint32_t keysym, void *arg) | |
399 | ++ps2kbd_event(int down, uint32_t keysym, uint32_t keycode, void *arg) | |
400 | + { | |
401 | + struct ps2kbd_softc *sc = arg; | |
402 | + int fifo_full; | |
403 | +@@ -360,17 +376,98 @@ ps2kbd_event(int down, uint32_t keysym, void *arg) | |
404 | + return; | |
405 | + } | |
406 | + fifo_full = sc->fifo.num == PS2KBD_FIFOSZ; | |
407 | +- ps2kbd_keysym_queue(sc, down, keysym); | |
408 | ++ ps2kbd_keysym_queue(sc, down, keysym, keycode); | |
409 | + pthread_mutex_unlock(&sc->mtx); | |
410 | + | |
411 | + if (!fifo_full) | |
158 | 412 | atkbdc_event(sc->atkbdc_sc, 1); |
159 | 413 | } |
160 | 414 |
@@ -246,3 +500,156 @@ diff -upN bhyve_orig/ps2kbd.c bhyve/ps2kbd.c | ||
246 | 500 | |
247 | 501 | sc = calloc(1, sizeof (struct ps2kbd_softc)); |
248 | 502 | pthread_mutex_init(&sc->mtx, NULL); |
503 | +diff -upN bhyve_orig/ps2kbd.h bhyve/ps2kbd.h | |
504 | +--- bhyve_orig/ps2kbd.h 2020-04-23 09:06:39.000000000 +0900 | |
505 | ++++ bhyve/ps2kbd.h 2020-05-29 18:03:10.795460000 +0900 | |
506 | +@@ -35,7 +35,7 @@ struct atkbdc_softc; | |
507 | + | |
508 | + struct ps2kbd_softc *ps2kbd_init(struct atkbdc_softc *sc); | |
509 | + | |
510 | +-int ps2kbd_read(struct ps2kbd_softc *sc, uint8_t *val); | |
511 | ++int ps2kbd_read(struct ps2kbd_softc *sc, uint8_t *val, uint8_t *trans); | |
512 | + void ps2kbd_write(struct ps2kbd_softc *sc, uint8_t val); | |
513 | + | |
514 | + #endif /* _PS2KBD_H_ */ | |
515 | +diff -upN bhyve_orig/rfb.c bhyve/rfb.c | |
516 | +--- bhyve_orig/rfb.c 2020-04-23 09:06:39.000000000 +0900 | |
517 | ++++ bhyve/rfb.c 2020-05-29 18:03:10.843000000 +0900 | |
518 | +@@ -99,7 +99,10 @@ struct rfb_softc { | |
519 | + bool enc_raw_ok; | |
520 | + bool enc_zlib_ok; | |
521 | + bool enc_resize_ok; | |
522 | ++ bool enc_extkeyevent_ok; | |
523 | + | |
524 | ++ bool enc_extkeyevent_send; | |
525 | ++ | |
526 | + z_stream zstream; | |
527 | + uint8_t *zbuf; | |
528 | + int zbuflen; | |
529 | +@@ -145,7 +148,10 @@ struct rfb_pixfmt_msg { | |
530 | + #define RFB_ENCODING_RAW 0 | |
531 | + #define RFB_ENCODING_ZLIB 6 | |
532 | + #define RFB_ENCODING_RESIZE -223 | |
533 | ++#define RFB_ENCODING_EXT_KEYEVENT -258 | |
534 | + | |
535 | ++#define RFB_CLIENTMSG_EXT_KEYEVENT 0 | |
536 | ++ | |
537 | + #define RFB_MAX_WIDTH 2000 | |
538 | + #define RFB_MAX_HEIGHT 1200 | |
539 | + #define RFB_ZLIB_BUFSZ RFB_MAX_WIDTH*RFB_MAX_HEIGHT*4 | |
540 | +@@ -172,6 +178,19 @@ struct rfb_key_msg { | |
541 | + uint8_t type; | |
542 | + uint8_t down; | |
543 | + uint16_t pad; | |
544 | ++ uint32_t sym; | |
545 | ++}; | |
546 | ++ | |
547 | ++struct rfb_client_msg { | |
548 | ++ uint8_t type; | |
549 | ++ uint8_t subtype; | |
550 | ++}; | |
551 | ++ | |
552 | ++struct rfb_extended_key_msg { | |
553 | ++ uint8_t type; | |
554 | ++ uint8_t subtype; | |
555 | ++ uint16_t down; | |
556 | ++ uint32_t sym; | |
557 | + uint32_t code; | |
558 | + }; | |
559 | + | |
560 | +@@ -250,6 +269,27 @@ rfb_send_resize_update_msg(struct rfb_softc *rc, int c | |
561 | + } | |
562 | + | |
563 | + static void | |
564 | ++rfb_send_extended_keyevent_update_msg(struct rfb_softc *rc, int cfd) | |
565 | ++{ | |
566 | ++ struct rfb_srvr_updt_msg supdt_msg; | |
567 | ++ struct rfb_srvr_rect_hdr srect_hdr; | |
568 | ++ | |
569 | ++ /* Number of rectangles: 1 */ | |
570 | ++ supdt_msg.type = 0; | |
571 | ++ supdt_msg.pad = 0; | |
572 | ++ supdt_msg.numrects = htons(1); | |
573 | ++ stream_write(cfd, &supdt_msg, sizeof(struct rfb_srvr_updt_msg)); | |
574 | ++ | |
575 | ++ /* Rectangle header */ | |
576 | ++ srect_hdr.x = htons(0); | |
577 | ++ srect_hdr.y = htons(0); | |
578 | ++ srect_hdr.width = htons(rc->width); | |
579 | ++ srect_hdr.height = htons(rc->height); | |
580 | ++ srect_hdr.encoding = htonl(RFB_ENCODING_EXT_KEYEVENT); | |
581 | ++ stream_write(cfd, &srect_hdr, sizeof(struct rfb_srvr_rect_hdr)); | |
582 | ++} | |
583 | ++ | |
584 | ++static void | |
585 | + rfb_recv_set_pixfmt_msg(struct rfb_softc *rc, int cfd) | |
586 | + { | |
587 | + struct rfb_pixfmt_msg pixfmt_msg; | |
588 | +@@ -283,6 +323,9 @@ rfb_recv_set_encodings_msg(struct rfb_softc *rc, int c | |
589 | + case RFB_ENCODING_RESIZE: | |
590 | + rc->enc_resize_ok = true; | |
591 | + break; | |
592 | ++ case RFB_ENCODING_EXT_KEYEVENT: | |
593 | ++ rc->enc_extkeyevent_ok = true; | |
594 | ++ break; | |
595 | + } | |
596 | + } | |
597 | + } | |
598 | +@@ -648,6 +691,11 @@ rfb_recv_update_msg(struct rfb_softc *rc, int cfd, int | |
599 | + rfb_send_resize_update_msg(rc, cfd); | |
600 | + } | |
601 | + | |
602 | ++ if (rc->enc_extkeyevent_ok && (!rc->enc_extkeyevent_send)) { | |
603 | ++ rfb_send_extended_keyevent_update_msg(rc, cfd); | |
604 | ++ rc->enc_extkeyevent_send = true; | |
605 | ++ } | |
606 | ++ | |
607 | + if (discardonly) | |
608 | + return; | |
609 | + | |
610 | +@@ -661,10 +709,24 @@ rfb_recv_key_msg(struct rfb_softc *rc, int cfd) | |
611 | + | |
612 | + (void)stream_read(cfd, ((void *)&key_msg) + 1, sizeof(key_msg) - 1); | |
613 | + | |
614 | +- console_key_event(key_msg.down, htonl(key_msg.code)); | |
615 | ++ console_key_event(key_msg.down, htonl(key_msg.sym), htonl(0)); | |
616 | + } | |
617 | + | |
618 | + static void | |
619 | ++rfb_recv_client_msg(struct rfb_softc *rc, int cfd) | |
620 | ++{ | |
621 | ++ struct rfb_client_msg client_msg; | |
622 | ++ struct rfb_extended_key_msg extkey_msg; | |
623 | ++ | |
624 | ++ (void)stream_read(cfd, ((void *)&client_msg) + 1, sizeof(client_msg) - 1); | |
625 | ++ | |
626 | ++ if (client_msg.subtype == RFB_CLIENTMSG_EXT_KEYEVENT ) { | |
627 | ++ (void)stream_read(cfd, ((void *)&extkey_msg) + 2, sizeof(extkey_msg) - 2); | |
628 | ++ console_key_event((int)extkey_msg.down, htonl(extkey_msg.sym), htonl(extkey_msg.code)); | |
629 | ++ } | |
630 | ++} | |
631 | ++ | |
632 | ++static void | |
633 | + rfb_recv_ptr_msg(struct rfb_softc *rc, int cfd) | |
634 | + { | |
635 | + struct rfb_ptr_msg ptr_msg; | |
636 | +@@ -903,6 +965,9 @@ rfb_handle(struct rfb_softc *rc, int cfd) | |
637 | + case 6: | |
638 | + rfb_recv_cuttext_msg(rc, cfd); | |
639 | + break; | |
640 | ++ case 255: | |
641 | ++ rfb_recv_client_msg(rc, cfd); | |
642 | ++ break; | |
643 | + default: | |
644 | + WPRINTF(("rfb unknown cli-code %d!", buf[0] & 0xff)); | |
645 | + goto done; | |
646 | +@@ -937,6 +1002,9 @@ rfb_thr(void *arg) | |
647 | + rc->enc_raw_ok = false; | |
648 | + rc->enc_zlib_ok = false; | |
649 | + rc->enc_resize_ok = false; | |
650 | ++ rc->enc_extkeyevent_ok = false; | |
651 | ++ | |
652 | ++ rc->enc_extkeyevent_send = false; | |
653 | + | |
654 | + cfd = accept(rc->sfd, NULL, NULL); | |
655 | + if (rc->conn_wait) { |