FreeBSD bhyve keyboard layout patch
リビジョン | 540e494f2d9651e10a5849f1760a4fabc938ac79 (tree) |
---|---|
日時 | 2022-01-02 13:21:32 |
作者 | Koine Yuusuke(koinec) <koinec@user...> |
コミッター | Koine Yuusuke(koinec) |
Add for the patches for FreeBSD 13-statble (20211223).
@@ -0,0 +1,260 @@ | ||
1 | +diff -uprN bhyve_orig/Makefile bhyve/Makefile | |
2 | +--- bhyve_orig/Makefile 2021-12-23 09:07:49.000000000 +0900 | |
3 | ++++ bhyve/Makefile 2022-01-02 10:48:16.788031000 +0900 | |
4 | +@@ -132,4 +132,6 @@ CFLAGS+=-DGDB_LOG | |
5 | + | |
6 | + WARNS?= 2 | |
7 | + | |
8 | ++SUBDIR= kbdlayout | |
9 | ++ | |
10 | + .include <bsd.prog.mk> | |
11 | +diff -uprN bhyve_orig/bhyve.8 bhyve/bhyve.8 | |
12 | +--- bhyve_orig/bhyve.8 2021-12-23 09:07:49.000000000 +0900 | |
13 | ++++ bhyve/bhyve.8 2022-01-02 11:18:37.389081000 +0900 | |
14 | +@@ -47,6 +47,7 @@ | |
15 | + .Sm on | |
16 | + .Op Fl G Ar port | |
17 | + .Op Fl k Ar config_file | |
18 | ++.Op Fl K Ar layout | |
19 | + .Oo Fl l | |
20 | + .Sm off | |
21 | + .Ar lpcdev Op Cm \&, Ar conf | |
22 | +@@ -169,6 +170,14 @@ are ignored. | |
23 | + See | |
24 | + .Xr bhyve_config 5 | |
25 | + for more details. | |
26 | ++.It Fl K Ar layout | |
27 | ++Specify the keyboard layout. | |
28 | ++The value that can be specified sets the file name in | |
29 | ++.Ar /usr/share/bhyve/kbdlayout . | |
30 | ++This specification only works when loaded with UEFI mode for VNC. | |
31 | ++(Not working via serial console or SSH) | |
32 | ++When using a VNC client that supports QEMU Extended Key Event Message (e.g. TigerVNC), this option isn't needed. | |
33 | ++When using a VNC client that doesn't support QEMU Extended Key Event Message (e.g. tightVNC), the default layout defaults to the US keyboard unless specified otherwise. | |
34 | + .It Fl l Cm help | |
35 | + Print a list of supported LPC devices. | |
36 | + .It Fl l Ar lpcdev Ns Op Cm \&, Ns Ar conf | |
37 | +diff -uprN bhyve_orig/bhyve_config.5 bhyve/bhyve_config.5 | |
38 | +--- bhyve_orig/bhyve_config.5 2021-12-23 09:07:49.000000000 +0900 | |
39 | ++++ bhyve/bhyve_config.5 2022-01-02 11:23:42.989892000 +0900 | |
40 | +@@ -131,6 +131,12 @@ will listen for connections on this port. | |
41 | + .It Va gdb.wait Ta bool Ta false Ta | |
42 | + If the debug server is enabled, wait for a debugger to connect | |
43 | + before starting the guest. | |
44 | ++.It Va keyboard.layout Ta string Ta Ta | |
45 | ++Specify the keyboard layout name with the file name in | |
46 | ++.Ar /usr/share/bhyve/kbdlayout . | |
47 | ++This value only works when loaded with UEFI mode for VNC, and | |
48 | ++used a VNC client that don't support QEMU Extended Key Event | |
49 | ++Message (e.g. TightVNC). | |
50 | + .It Va rtc.use_localtime Ta bool Ta true Ta | |
51 | + The real time clock uses the local time of the host. | |
52 | + If this is set to false, the real time clock uses UTC. | |
53 | +diff -uprN bhyve_orig/bhyverun.c bhyve/bhyverun.c | |
54 | +--- bhyve_orig/bhyverun.c 2021-12-23 09:07:49.000000000 +0900 | |
55 | ++++ bhyve/bhyverun.c 2022-01-02 11:31:05.019976000 +0900 | |
56 | +@@ -224,8 +224,9 @@ usage(int code) | |
57 | + fprintf(stderr, | |
58 | + "Usage: %s [-AaCDeHhPSuWwxY]\n" | |
59 | + " %*s [-c [[cpus=]numcpus][,sockets=n][,cores=n][,threads=n]]\n" | |
60 | +- " %*s [-G port] [-k config_file] [-l lpc] [-m mem] [-o var=value]\n" | |
61 | +- " %*s [-p vcpu:hostcpu] [-r file] [-s pci] [-U uuid] vmname\n" | |
62 | ++ " %*s [-G port] [-k config_file] [-K layout] [-l lpc] [-m mem]\n" | |
63 | ++ " %*s [-o var=value] [-p vcpu:hostcpu] [-r file] [-s pci]\n" | |
64 | ++ " %*s [-U uuid] vmname\n" | |
65 | + " -A: create ACPI tables\n" | |
66 | + " -a: local apic is in xAPIC mode (deprecated)\n" | |
67 | + " -C: include guest memory in core file\n" | |
68 | +@@ -236,6 +237,7 @@ usage(int code) | |
69 | + " -H: vmexit from the guest on HLT\n" | |
70 | + " -h: help\n" | |
71 | + " -k: key=value flat config file\n" | |
72 | ++ " -K: PS2 keyboard layout\n" | |
73 | + " -l: LPC device configuration\n" | |
74 | + " -m: memory size in MB\n" | |
75 | + " -o: set config 'var' to 'value'\n" | |
76 | +@@ -253,7 +255,7 @@ usage(int code) | |
77 | + " -x: local APIC is in x2APIC mode\n" | |
78 | + " -Y: disable MPtable generation\n", | |
79 | + progname, (int)strlen(progname), "", (int)strlen(progname), "", | |
80 | +- (int)strlen(progname), ""); | |
81 | ++ (int)strlen(progname), "", (int)strlen(progname), ""); | |
82 | + | |
83 | + exit(code); | |
84 | + } | |
85 | +@@ -1225,9 +1227,9 @@ main(int argc, char *argv[]) | |
86 | + progname = basename(argv[0]); | |
87 | + | |
88 | + #ifdef BHYVE_SNAPSHOT | |
89 | +- optstr = "aehuwxACDHIPSWYk:o:p:G:c:s:m:l:U:r:"; | |
90 | ++ optstr = "aehuwxACDHIPSWYk:o:p:G:c:s:m:l:K:U:r:"; | |
91 | + #else | |
92 | +- optstr = "aehuwxACDHIPSWYk:o:p:G:c:s:m:l:U:"; | |
93 | ++ optstr = "aehuwxACDHIPSWYk:o:p:G:c:s:m:l:K:U:"; | |
94 | + #endif | |
95 | + while ((c = getopt(argc, argv, optstr)) != -1) { | |
96 | + switch (c) { | |
97 | +@@ -1264,6 +1266,9 @@ main(int argc, char *argv[]) | |
98 | + break; | |
99 | + case 'k': | |
100 | + parse_simple_config_file(optarg); | |
101 | ++ break; | |
102 | ++ case 'K': | |
103 | ++ set_config_value("keyboard.layout", optarg); | |
104 | + break; | |
105 | + case 'l': | |
106 | + if (strncmp(optarg, "help", strlen(optarg)) == 0) { | |
107 | +diff -uprN bhyve_orig/ps2kbd.c bhyve/ps2kbd.c | |
108 | +--- bhyve_orig/ps2kbd.c 2021-12-23 09:07:49.000000000 +0900 | |
109 | ++++ bhyve/ps2kbd.c 2022-01-02 11:33:03.248964000 +0900 | |
110 | +@@ -31,6 +31,7 @@ | |
111 | + __FBSDID("$FreeBSD$"); | |
112 | + | |
113 | + #include <sys/types.h> | |
114 | ++#include <sys/stat.h> | |
115 | + | |
116 | + #include <machine/vmm_snapshot.h> | |
117 | + | |
118 | +@@ -42,9 +43,13 @@ __FBSDID("$FreeBSD$"); | |
119 | + #include <strings.h> | |
120 | + #include <pthread.h> | |
121 | + #include <pthread_np.h> | |
122 | ++#include <unistd.h> | |
123 | ++#include <fcntl.h> | |
124 | + | |
125 | ++#include "bhyverun.h" | |
126 | + #include "atkbdc.h" | |
127 | + #include "debug.h" | |
128 | ++#include "config.h" | |
129 | + #include "console.h" | |
130 | + | |
131 | + /* keyboard device commands */ | |
132 | +@@ -62,6 +67,10 @@ __FBSDID("$FreeBSD$"); | |
133 | + | |
134 | + #define PS2KBD_FIFOSZ 16 | |
135 | + | |
136 | ++#define PS2KBD_LAYOUT_BASEDIR "/usr/share/bhyve/kbdlayout/" | |
137 | ++ | |
138 | ++#define MAX_PATHNAME 256 | |
139 | ++ | |
140 | + struct fifo { | |
141 | + uint8_t buf[PS2KBD_FIFOSZ]; | |
142 | + int rindex; /* index to read from */ | |
143 | +@@ -90,7 +99,7 @@ struct extended_translation { | |
144 | + /* | |
145 | + * FIXME: Pause/break and Print Screen/SysRq require special handling. | |
146 | + */ | |
147 | +-static const struct extended_translation extended_translations[] = { | |
148 | ++static struct extended_translation extended_translations[128] = { | |
149 | + {0xff08, 0x66}, /* Back space */ | |
150 | + {0xff09, 0x0d}, /* Tab */ | |
151 | + {0xff0d, 0x5a}, /* Return */ | |
152 | +@@ -162,7 +171,7 @@ static const struct extended_translation extended_tran | |
153 | + }; | |
154 | + | |
155 | + /* ASCII to type 2 scancode lookup table */ | |
156 | +-static const uint8_t ascii_translations[128] = { | |
157 | ++static uint8_t ascii_translations[128] = { | |
158 | + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
159 | + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
160 | + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
161 | +@@ -320,7 +329,7 @@ ps2kbd_keysym_queue(struct ps2kbd_softc *sc, | |
162 | + assert(pthread_mutex_isowned_np(&sc->mtx)); | |
163 | + int e0_prefix, found; | |
164 | + uint8_t code; | |
165 | +- const struct extended_translation *trans; | |
166 | ++ struct extended_translation *trans; | |
167 | + | |
168 | + found = 0; | |
169 | + if (keysym < 0x80) { | |
170 | +@@ -370,10 +379,90 @@ ps2kbd_event(int down, uint32_t keysym, void *arg) | |
171 | + atkbdc_event(sc->atkbdc_sc, 1); | |
172 | + } | |
173 | + | |
174 | ++static void | |
175 | ++ps2kbd_update_extended_translation(uint32_t keycode, uint32_t scancode, uint32_t prefix) | |
176 | ++{ | |
177 | ++ int i = 0; | |
178 | ++ | |
179 | ++ do { | |
180 | ++ if (extended_translations[i].keysym == keycode) | |
181 | ++ break; | |
182 | ++ } while(extended_translations[++i].keysym); | |
183 | ++ | |
184 | ++ if (i == (sizeof(extended_translations) / sizeof(struct extended_translation) - 1)) | |
185 | ++ return; | |
186 | ++ | |
187 | ++ if (!extended_translations[i].keysym) { | |
188 | ++ extended_translations[i].keysym = keycode; | |
189 | ++ | |
190 | ++ extended_translations[i+1].keysym = 0; | |
191 | ++ extended_translations[i+1].scancode = 0; | |
192 | ++ extended_translations[i+1].flags = 0; | |
193 | ++ } | |
194 | ++ | |
195 | ++ extended_translations[i].scancode = (uint8_t)(scancode & 0xff); | |
196 | ++ extended_translations[i].flags = (prefix ? SCANCODE_E0_PREFIX : 0); | |
197 | ++} | |
198 | ++ | |
199 | ++static void | |
200 | ++ps2kbd_setkbdlayout(void) | |
201 | ++{ | |
202 | ++ int err; | |
203 | ++ int fd; | |
204 | ++ char path[MAX_PATHNAME]; | |
205 | ++ char *buf, *next, *line; | |
206 | ++ struct stat sb; | |
207 | ++ size_t sz; | |
208 | ++ uint8_t ascii; | |
209 | ++ uint32_t keycode, scancode, prefix; | |
210 | ++ | |
211 | ++ snprintf(path, MAX_PATHNAME, PS2KBD_LAYOUT_BASEDIR"%s", get_config_value("keyboard.layout") ); | |
212 | ++ | |
213 | ++ err = stat(path, &sb); | |
214 | ++ if (err) | |
215 | ++ return; | |
216 | ++ | |
217 | ++ buf = (char *)malloc(sizeof(char) * sb.st_size); | |
218 | ++ if (buf == NULL) | |
219 | ++ return; | |
220 | ++ | |
221 | ++ fd = open(path, O_RDONLY); | |
222 | ++ if (fd == -1) | |
223 | ++ goto out; | |
224 | ++ | |
225 | ++ sz = read(fd, buf, sb.st_size ); | |
226 | ++ | |
227 | ++ close(fd); | |
228 | ++ | |
229 | ++ if (sz != sb.st_size ) | |
230 | ++ goto out; | |
231 | ++ | |
232 | ++ next = buf; | |
233 | ++ while ((line = strsep(&next, "\n")) != NULL) { | |
234 | ++ if (sscanf(line, "'%c',%x;", &ascii, &scancode) == 2) { | |
235 | ++ if (ascii < 0x80) | |
236 | ++ ascii_translations[ascii] = (uint8_t)(scancode & 0xff); | |
237 | ++ } else if (sscanf(line, "%x,%x,%x;", &keycode, &scancode, &prefix) == 3 ) { | |
238 | ++ ps2kbd_update_extended_translation(keycode, scancode, prefix); | |
239 | ++ } else if (sscanf(line, "%x,%x;", &keycode, &scancode) == 2) { | |
240 | ++ if (keycode < 0x80) | |
241 | ++ ascii_translations[(uint8_t)(keycode & 0xff)] = (uint8_t)(scancode & 0xff); | |
242 | ++ else | |
243 | ++ ps2kbd_update_extended_translation(keycode, scancode, 0); | |
244 | ++ } | |
245 | ++ } | |
246 | ++ | |
247 | ++out: | |
248 | ++ free(buf); | |
249 | ++} | |
250 | ++ | |
251 | + struct ps2kbd_softc * | |
252 | + ps2kbd_init(struct atkbdc_softc *atkbdc_sc) | |
253 | + { | |
254 | + struct ps2kbd_softc *sc; | |
255 | ++ | |
256 | ++ if (get_config_value("keyboard.layout") != NULL) | |
257 | ++ ps2kbd_setkbdlayout(); | |
258 | + | |
259 | + sc = calloc(1, sizeof (struct ps2kbd_softc)); | |
260 | + pthread_mutex_init(&sc->mtx, NULL); |
@@ -0,0 +1,41 @@ | ||
1 | +diff -uprN examples/bhyve_orig/vmrun.sh examples/bhyve/vmrun.sh | |
2 | +--- examples/bhyve_orig/vmrun.sh 2021-04-09 09:24:07.000000000 +0900 | |
3 | ++++ examples/bhyve/vmrun.sh 2021-05-03 13:46:11.358862000 +0900 | |
4 | +@@ -59,8 +59,8 @@ usage() { | |
5 | + echo " [-e <name=value>] [-f <path of firmware>]" \ | |
6 | + "[-F <size>]" | |
7 | + echo " [-H <directory>]" | |
8 | +- echo " [-I <location of installation iso>] [-l <loader>]" | |
9 | +- echo " [-L <VNC IP for UEFI framebuffer>]" | |
10 | ++ echo " [-I <location of installation iso>] [-K <layout>]" | |
11 | ++ echo " [-l <loader>] [-L <VNC IP for UEFI framebuffer>]" | |
12 | + echo " [-m <memsize>]" \ | |
13 | + "[-n <network adapter emulation type>]" | |
14 | + echo " [-P <port>] [-t <tapdev>] <vmname>" | |
15 | +@@ -80,6 +80,7 @@ usage() { | |
16 | + echo " -i: force boot of the Installation CDROM image" | |
17 | + echo " -I: Installation CDROM image location" \ | |
18 | + "(default: ${DEFAULT_ISOFILE})" | |
19 | ++ echo " -K: Specify the keyboard layout" | |
20 | + echo " -l: the OS loader to use (default: /boot/userboot.so)" | |
21 | + echo " -L: IP address for UEFI GOP VNC server" \ | |
22 | + "(default: ${DEFAULT_VNCHOST}" | |
23 | +@@ -132,7 +133,7 @@ vncport=${DEFAULT_VNCPORT} | |
24 | + vncsize=${DEFAULT_VNCSIZE} | |
25 | + tablet="" | |
26 | + | |
27 | +-while getopts aAc:C:d:e:Ef:F:g:hH:iI:l:L:m:n:p:P:t:Tuvw c ; do | |
28 | ++while getopts aAc:C:d:e:Ef:F:g:hH:iI:K:l:L:m:n:p:P:t:Tuvw c ; do | |
29 | + case $c in | |
30 | + a) | |
31 | + bhyverun_opt="${bhyverun_opt} -a" | |
32 | +@@ -173,6 +174,9 @@ while getopts aAc:C:d:e:Ef:F:g:hH:iI:l:L:m:n:p:P:t:Tuv | |
33 | + ;; | |
34 | + I) | |
35 | + isofile=${OPTARG} | |
36 | ++ ;; | |
37 | ++ K) | |
38 | ++ bhyverun_opt="${bhyverun_opt} -K ${OPTARG}" | |
39 | + ;; | |
40 | + l) | |
41 | + loader_opt="${loader_opt} -l ${OPTARG}" |
@@ -0,0 +1,281 @@ | ||
1 | +diff -uprN bhyve_orig/console.c bhyve/console.c | |
2 | +--- bhyve_orig/console.c 2021-04-09 09:24:13.000000000 +0900 | |
3 | ++++ bhyve/console.c 2021-05-03 13:11:57.869902000 +0900 | |
4 | +@@ -106,10 +106,10 @@ console_ptr_register(ptr_event_func_t event_cb, void * | |
5 | + } | |
6 | + | |
7 | + void | |
8 | +-console_key_event(int down, uint32_t keysym) | |
9 | ++console_key_event(int down, uint32_t keysym, uint32_t keycode) | |
10 | + { | |
11 | + if (console.kbd_event_cb) | |
12 | +- (*console.kbd_event_cb)(down, keysym, console.kbd_arg); | |
13 | ++ (*console.kbd_event_cb)(down, keysym, keycode, console.kbd_arg); | |
14 | + } | |
15 | + | |
16 | + void | |
17 | +diff -uprN bhyve_orig/console.h bhyve/console.h | |
18 | +--- bhyve_orig/console.h 2021-04-09 09:24:13.000000000 +0900 | |
19 | ++++ bhyve/console.h 2021-05-03 13:11:57.870288000 +0900 | |
20 | +@@ -34,7 +34,7 @@ | |
21 | + struct bhyvegc; | |
22 | + | |
23 | + typedef void (*fb_render_func_t)(struct bhyvegc *gc, void *arg); | |
24 | +-typedef void (*kbd_event_func_t)(int down, uint32_t keysym, void *arg); | |
25 | ++typedef void (*kbd_event_func_t)(int down, uint32_t keysym, uint32_t keycode, void *arg); | |
26 | + typedef void (*ptr_event_func_t)(uint8_t mask, int x, int y, void *arg); | |
27 | + | |
28 | + void console_init(int w, int h, void *fbaddr); | |
29 | +@@ -47,7 +47,7 @@ void console_fb_register(fb_render_func_t render_cb, v | |
30 | + void console_refresh(void); | |
31 | + | |
32 | + void console_kbd_register(kbd_event_func_t event_cb, void *arg, int pri); | |
33 | +-void console_key_event(int down, uint32_t keysym); | |
34 | ++void console_key_event(int down, uint32_t keysym, uint32_t keycode); | |
35 | + | |
36 | + void console_ptr_register(ptr_event_func_t event_cb, void *arg, int pri); | |
37 | + void console_ptr_event(uint8_t button, int x, int y); | |
38 | +diff -uprN bhyve_orig/ps2kbd.c bhyve/ps2kbd.c | |
39 | +--- bhyve_orig/ps2kbd.c 2021-04-09 09:24:13.000000000 +0900 | |
40 | ++++ bhyve/ps2kbd.c 2021-05-03 13:11:57.870908000 +0900 | |
41 | +@@ -181,6 +181,26 @@ static const uint8_t ascii_translations[128] = { | |
42 | + 0x22, 0x35, 0x1a, 0x54, 0x5d, 0x5b, 0x0e, 0x00, | |
43 | + }; | |
44 | + | |
45 | ++/* ScanCode set1 to set2 lookup table */ | |
46 | ++const uint8_t keyset1to2_translations[128] = { | |
47 | ++ 0, 0x76, 0x16, 0x1E, 0x26, 0x25, 0x2e, 0x36, | |
48 | ++ 0x3d, 0x3e, 0x46, 0x45, 0x4e, 0x55, 0x66, 0x0d, | |
49 | ++ 0x15, 0x1d, 0x24, 0x2d, 0x2c, 0x35, 0x3c, 0x43, | |
50 | ++ 0x44, 0x4d, 0x54, 0x5b, 0x5a, 0x14, 0x1c, 0x1b, | |
51 | ++ 0x23, 0x2b, 0x34, 0x33, 0x3b, 0x42, 0x4b, 0x4c, | |
52 | ++ 0x52, 0x0e, 0x12, 0x5d, 0x1a, 0x22, 0x21, 0x2a, | |
53 | ++ 0x32, 0x31, 0x3a, 0x41, 0x49, 0x4a, 0x59, 0x7c, | |
54 | ++ 0x11, 0x29, 0x58, 0x05, 0x06, 0x04, 0x0c, 0x03, | |
55 | ++ 0x0b, 0x83, 0x0a, 0x01, 0x09, 0x77, 0x7e, 0x6c, | |
56 | ++ 0x75, 0x7d, 0x7b, 0x6b, 0x73, 0x74, 0x79, 0x69, | |
57 | ++ 0x72, 0x7a, 0x70, 0x71, 0x84, 0x60, 0x61, 0x78, | |
58 | ++ 0x07, 0x0f, 0x17, 0x1f, 0x27, 0x2f, 0x37, 0x3f, | |
59 | ++ 0x47, 0x4f, 0x56, 0x5e, 0x08, 0x10, 0x18, 0x20, | |
60 | ++ 0x28, 0x30, 0x38, 0x40, 0x48, 0x50, 0x57, 0x6f, | |
61 | ++ 0x13, 0x19, 0x39, 0x51, 0x53, 0x5c, 0x5f, 0x62, | |
62 | ++ 0x63, 0x64, 0x65, 0x67, 0x68, 0x6a, 0x6d, 0x6e, | |
63 | ++}; | |
64 | ++ | |
65 | + static void | |
66 | + fifo_init(struct ps2kbd_softc *sc) | |
67 | + { | |
68 | +@@ -315,26 +335,32 @@ ps2kbd_write(struct ps2kbd_softc *sc, uint8_t val) | |
69 | + */ | |
70 | + static void | |
71 | + ps2kbd_keysym_queue(struct ps2kbd_softc *sc, | |
72 | +- int down, uint32_t keysym) | |
73 | ++ int down, uint32_t keysym, uint32_t keycode) | |
74 | + { | |
75 | + assert(pthread_mutex_isowned_np(&sc->mtx)); | |
76 | + int e0_prefix, found; | |
77 | + uint8_t code; | |
78 | + const struct extended_translation *trans; | |
79 | + | |
80 | +- found = 0; | |
81 | +- if (keysym < 0x80) { | |
82 | +- code = ascii_translations[keysym]; | |
83 | +- e0_prefix = 0; | |
84 | ++ if (keycode) { | |
85 | ++ code = keyset1to2_translations[(uint8_t)(keycode & 0x7f)]; | |
86 | ++ e0_prefix = ((keycode & 0x80) ? SCANCODE_E0_PREFIX : 0); | |
87 | + found = 1; | |
88 | + } else { | |
89 | +- for (trans = &(extended_translations[0]); trans->keysym != 0; | |
90 | +- trans++) { | |
91 | +- if (keysym == trans->keysym) { | |
92 | +- code = trans->scancode; | |
93 | +- e0_prefix = trans->flags & SCANCODE_E0_PREFIX; | |
94 | +- found = 1; | |
95 | +- break; | |
96 | ++ found = 0; | |
97 | ++ if (keysym < 0x80) { | |
98 | ++ code = ascii_translations[keysym]; | |
99 | ++ e0_prefix = 0; | |
100 | ++ found = 1; | |
101 | ++ } else { | |
102 | ++ for (trans = &(extended_translations[0]); trans->keysym != 0; | |
103 | ++ trans++) { | |
104 | ++ if (keysym == trans->keysym) { | |
105 | ++ code = trans->scancode; | |
106 | ++ e0_prefix = trans->flags & SCANCODE_E0_PREFIX; | |
107 | ++ found = 1; | |
108 | ++ break; | |
109 | ++ } | |
110 | + } | |
111 | + } | |
112 | + } | |
113 | +@@ -352,7 +378,7 @@ ps2kbd_keysym_queue(struct ps2kbd_softc *sc, | |
114 | + } | |
115 | + | |
116 | + static void | |
117 | +-ps2kbd_event(int down, uint32_t keysym, void *arg) | |
118 | ++ps2kbd_event(int down, uint32_t keysym, uint32_t keycode, void *arg) | |
119 | + { | |
120 | + struct ps2kbd_softc *sc = arg; | |
121 | + int fifo_full; | |
122 | +@@ -363,7 +389,7 @@ ps2kbd_event(int down, uint32_t keysym, void *arg) | |
123 | + return; | |
124 | + } | |
125 | + fifo_full = sc->fifo.num == PS2KBD_FIFOSZ; | |
126 | +- ps2kbd_keysym_queue(sc, down, keysym); | |
127 | ++ ps2kbd_keysym_queue(sc, down, keysym, keycode); | |
128 | + pthread_mutex_unlock(&sc->mtx); | |
129 | + | |
130 | + if (!fifo_full) | |
131 | +diff -uprN bhyve_orig/rfb.c bhyve/rfb.c | |
132 | +--- bhyve_orig/rfb.c 2021-04-09 09:24:13.000000000 +0900 | |
133 | ++++ bhyve/rfb.c 2021-05-03 13:13:08.713857000 +0900 | |
134 | +@@ -98,6 +98,7 @@ static int rfb_debug = 0; | |
135 | + #define CS_KEY_EVENT 4 | |
136 | + #define CS_POINTER_EVENT 5 | |
137 | + #define CS_CUT_TEXT 6 | |
138 | ++#define CS_MSG_CLIENT_QEMU 255 | |
139 | + | |
140 | + #define SECURITY_TYPE_NONE 1 | |
141 | + #define SECURITY_TYPE_VNC_AUTH 2 | |
142 | +@@ -118,7 +119,10 @@ struct rfb_softc { | |
143 | + bool enc_raw_ok; | |
144 | + bool enc_zlib_ok; | |
145 | + bool enc_resize_ok; | |
146 | ++ bool enc_extkeyevent_ok; | |
147 | + | |
148 | ++ bool enc_extkeyevent_send; | |
149 | ++ | |
150 | + z_stream zstream; | |
151 | + uint8_t *zbuf; | |
152 | + int zbuflen; | |
153 | +@@ -170,7 +174,10 @@ struct rfb_pixfmt_msg { | |
154 | + #define RFB_ENCODING_RAW 0 | |
155 | + #define RFB_ENCODING_ZLIB 6 | |
156 | + #define RFB_ENCODING_RESIZE -223 | |
157 | ++#define RFB_ENCODING_EXT_KEYEVENT -258 | |
158 | + | |
159 | ++#define RFB_CLIENTMSG_EXT_KEYEVENT 0 | |
160 | ++ | |
161 | + #define RFB_MAX_WIDTH 2000 | |
162 | + #define RFB_MAX_HEIGHT 1200 | |
163 | + #define RFB_ZLIB_BUFSZ RFB_MAX_WIDTH*RFB_MAX_HEIGHT*4 | |
164 | +@@ -197,6 +204,19 @@ struct rfb_key_msg { | |
165 | + uint8_t type; | |
166 | + uint8_t down; | |
167 | + uint16_t pad; | |
168 | ++ uint32_t sym; | |
169 | ++}; | |
170 | ++ | |
171 | ++struct rfb_client_msg { | |
172 | ++ uint8_t type; | |
173 | ++ uint8_t subtype; | |
174 | ++}; | |
175 | ++ | |
176 | ++struct rfb_extended_key_msg { | |
177 | ++ uint8_t type; | |
178 | ++ uint8_t subtype; | |
179 | ++ uint16_t down; | |
180 | ++ uint32_t sym; | |
181 | + uint32_t code; | |
182 | + }; | |
183 | + | |
184 | +@@ -277,6 +297,27 @@ rfb_send_resize_update_msg(struct rfb_softc *rc, int c | |
185 | + } | |
186 | + | |
187 | + static void | |
188 | ++rfb_send_extended_keyevent_update_msg(struct rfb_softc *rc, int cfd) | |
189 | ++{ | |
190 | ++ struct rfb_srvr_updt_msg supdt_msg; | |
191 | ++ struct rfb_srvr_rect_hdr srect_hdr; | |
192 | ++ | |
193 | ++ /* Number of rectangles: 1 */ | |
194 | ++ supdt_msg.type = 0; | |
195 | ++ supdt_msg.pad = 0; | |
196 | ++ supdt_msg.numrects = htons(1); | |
197 | ++ stream_write(cfd, &supdt_msg, sizeof(struct rfb_srvr_updt_msg)); | |
198 | ++ | |
199 | ++ /* Rectangle header */ | |
200 | ++ srect_hdr.x = htons(0); | |
201 | ++ srect_hdr.y = htons(0); | |
202 | ++ srect_hdr.width = htons(rc->width); | |
203 | ++ srect_hdr.height = htons(rc->height); | |
204 | ++ srect_hdr.encoding = htonl(RFB_ENCODING_EXT_KEYEVENT); | |
205 | ++ stream_write(cfd, &srect_hdr, sizeof(struct rfb_srvr_rect_hdr)); | |
206 | ++} | |
207 | ++ | |
208 | ++static void | |
209 | + rfb_recv_set_pixfmt_msg(struct rfb_softc *rc, int cfd) | |
210 | + { | |
211 | + struct rfb_pixfmt_msg pixfmt_msg; | |
212 | +@@ -309,6 +350,9 @@ rfb_recv_set_encodings_msg(struct rfb_softc *rc, int c | |
213 | + case RFB_ENCODING_RESIZE: | |
214 | + rc->enc_resize_ok = true; | |
215 | + break; | |
216 | ++ case RFB_ENCODING_EXT_KEYEVENT: | |
217 | ++ rc->enc_extkeyevent_ok = true; | |
218 | ++ break; | |
219 | + } | |
220 | + } | |
221 | + } | |
222 | +@@ -686,6 +730,11 @@ rfb_recv_update_msg(struct rfb_softc *rc, int cfd) | |
223 | + | |
224 | + (void)stream_read(cfd, ((void *)&updt_msg) + 1 , sizeof(updt_msg) - 1); | |
225 | + | |
226 | ++ if (rc->enc_extkeyevent_ok && (!rc->enc_extkeyevent_send)) { | |
227 | ++ rfb_send_extended_keyevent_update_msg(rc, cfd); | |
228 | ++ rc->enc_extkeyevent_send = true; | |
229 | ++ } | |
230 | ++ | |
231 | + rc->pending = true; | |
232 | + if (!updt_msg.incremental) | |
233 | + rc->update_all = true; | |
234 | +@@ -698,11 +747,26 @@ rfb_recv_key_msg(struct rfb_softc *rc, int cfd) | |
235 | + | |
236 | + (void)stream_read(cfd, ((void *)&key_msg) + 1, sizeof(key_msg) - 1); | |
237 | + | |
238 | +- console_key_event(key_msg.down, htonl(key_msg.code)); | |
239 | ++ console_key_event(key_msg.down, htonl(key_msg.sym), htonl(0)); | |
240 | + rc->input_detected = true; | |
241 | + } | |
242 | + | |
243 | + static void | |
244 | ++rfb_recv_client_msg(struct rfb_softc *rc, int cfd) | |
245 | ++{ | |
246 | ++ struct rfb_client_msg client_msg; | |
247 | ++ struct rfb_extended_key_msg extkey_msg; | |
248 | ++ | |
249 | ++ (void)stream_read(cfd, ((void *)&client_msg) + 1, sizeof(client_msg) - 1); | |
250 | ++ | |
251 | ++ if (client_msg.subtype == RFB_CLIENTMSG_EXT_KEYEVENT ) { | |
252 | ++ (void)stream_read(cfd, ((void *)&extkey_msg) + 2, sizeof(extkey_msg) - 2); | |
253 | ++ console_key_event((int)extkey_msg.down, htonl(extkey_msg.sym), htonl(extkey_msg.code)); | |
254 | ++ rc->input_detected = true; | |
255 | ++ } | |
256 | ++} | |
257 | ++ | |
258 | ++static void | |
259 | + rfb_recv_ptr_msg(struct rfb_softc *rc, int cfd) | |
260 | + { | |
261 | + struct rfb_ptr_msg ptr_msg; | |
262 | +@@ -997,6 +1061,9 @@ report_and_done: | |
263 | + case CS_CUT_TEXT: | |
264 | + rfb_recv_cuttext_msg(rc, cfd); | |
265 | + break; | |
266 | ++ case CS_MSG_CLIENT_QEMU: | |
267 | ++ rfb_recv_client_msg(rc, cfd); | |
268 | ++ break; | |
269 | + default: | |
270 | + WPRINTF(("rfb unknown cli-code %d!", buf[0] & 0xff)); | |
271 | + goto done; | |
272 | +@@ -1031,6 +1098,9 @@ rfb_thr(void *arg) | |
273 | + rc->enc_raw_ok = false; | |
274 | + rc->enc_zlib_ok = false; | |
275 | + rc->enc_resize_ok = false; | |
276 | ++ rc->enc_extkeyevent_ok = false; | |
277 | ++ | |
278 | ++ rc->enc_extkeyevent_send = false; | |
279 | + | |
280 | + cfd = accept(rc->sfd, NULL, NULL); | |
281 | + if (rc->conn_wait) { |