FreeBSD bhyve keyboard layout patch
Revision | 2ceab8f54c688ca347380b5b77f60b3903f9a8e3 (tree) |
---|---|
Time | 2023-04-12 21:56:41 |
Author | Koine Yuusuke(koinec) <koinec@user...> |
Commiter | Koine Yuusuke(koinec) |
Add support for FreeBSD 12.4-RELEASE.
@@ -0,0 +1,249 @@ | ||
1 | +diff -uprN bhyve_orig/Makefile bhyve/Makefile | |
2 | +--- bhyve_orig/Makefile 2022-12-10 21:20:17.716130000 +0900 | |
3 | ++++ bhyve/Makefile 2022-12-10 22:39:00.042679000 +0900 | |
4 | +@@ -96,4 +96,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 2022-12-10 21:20:17.747712000 +0900 | |
13 | ++++ bhyve/bhyve.8 2022-12-10 22:39:00.043583000 +0900 | |
14 | +@@ -47,6 +47,7 @@ | |
15 | + .Sm on | |
16 | + .Op Fl G Ar port | |
17 | + .Op Fl g Ar gdbport | |
18 | ++.Op Fl K Ar layout | |
19 | + .Oo Fl l | |
20 | + .Sm off | |
21 | + .Ar lpcdev Op Cm \&, Ar conf | |
22 | +@@ -180,6 +181,14 @@ value. | |
23 | + Blank lines and lines starting with | |
24 | + .Sq # | |
25 | + are ignored. | |
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/bhyverun.c bhyve/bhyverun.c | |
38 | +--- bhyve_orig/bhyverun.c 2022-12-10 21:20:17.759626000 +0900 | |
39 | ++++ bhyve/bhyverun.c 2022-12-10 22:39:00.044670000 +0900 | |
40 | +@@ -165,6 +165,8 @@ char *vmname; | |
41 | + int guest_ncpus; | |
42 | + uint16_t cores, maxcpus, sockets, threads; | |
43 | + | |
44 | ++char *kbdlayout_name; | |
45 | ++ | |
46 | + char *guest_uuid_str; | |
47 | + | |
48 | + int raw_stdio = 0; | |
49 | +@@ -215,7 +217,7 @@ usage(int code) | |
50 | + fprintf(stderr, | |
51 | + "Usage: %s [-AaCDeHhPSuWwxY]\n" | |
52 | + " %*s [-c [[cpus=]numcpus][,sockets=n][,cores=n][,threads=n]]\n" | |
53 | +- " %*s [-G port] [-k file] [-l lpc] [-m mem] [-o var=value]\n" | |
54 | ++ " %*s [-G port] [-k file] [-K layout] [-l lpc] [-m mem] [-o var=value]\n" | |
55 | + " %*s [-p vcpu:hostcpu] [-s pci] [-U uuid] vmname\n" | |
56 | + " -A: create ACPI tables\n" | |
57 | + " -a: local apic is in xAPIC mode (deprecated)\n" | |
58 | +@@ -227,6 +229,7 @@ usage(int code) | |
59 | + " -H: vmexit from the guest on HLT\n" | |
60 | + " -h: help\n" | |
61 | + " -k: key=value flat config file\n" | |
62 | ++ " -K: PS2 keyboard layout\n" | |
63 | + " -l: LPC device configuration\n" | |
64 | + " -m: memory size in MB\n" | |
65 | + " -o: set config 'var' to 'value'\n" | |
66 | +@@ -1025,8 +1028,9 @@ main(int argc, char *argv[]) | |
67 | + mptgen = 1; | |
68 | + rtc_localtime = 1; | |
69 | + memflags = 0; | |
70 | ++ kbdlayout_name = NULL; | |
71 | + | |
72 | +- optstr = "abehuwxACDHIPSWYp:g:G:c:s:m:l:U:"; | |
73 | ++ optstr = "abehuwxACDHIPSWYp:g:G:c:s:m:l:K:U:"; | |
74 | + while ((c = getopt(argc, argv, optstr)) != -1) { | |
75 | + switch (c) { | |
76 | + case 'a': | |
77 | +@@ -1067,6 +1071,9 @@ main(int argc, char *argv[]) | |
78 | + optarg++; | |
79 | + } | |
80 | + gdb_port = atoi(optarg); | |
81 | ++ break; | |
82 | ++ case 'K': | |
83 | ++ kbdlayout_name = optarg; | |
84 | + break; | |
85 | + case 'l': | |
86 | + if (strncmp(optarg, "help", strlen(optarg)) == 0) { | |
87 | +diff -uprN bhyve_orig/bhyverun.h bhyve/bhyverun.h | |
88 | +--- bhyve_orig/bhyverun.h 2022-12-10 21:20:17.763484000 +0900 | |
89 | ++++ bhyve/bhyverun.h 2022-12-10 22:39:00.045056000 +0900 | |
90 | +@@ -39,6 +39,7 @@ extern int guest_ncpus; | |
91 | + extern uint16_t cores, sockets, threads; | |
92 | + extern char *guest_uuid_str; | |
93 | + extern char *vmname; | |
94 | ++extern char *kbdlayout_name; | |
95 | + | |
96 | + void *paddr_guest2host(struct vmctx *ctx, uintptr_t addr, size_t len); | |
97 | + | |
98 | +diff -uprN bhyve_orig/ps2kbd.c bhyve/ps2kbd.c | |
99 | +--- bhyve_orig/ps2kbd.c 2022-12-10 21:20:17.986325000 +0900 | |
100 | ++++ bhyve/ps2kbd.c 2022-12-10 22:39:00.045908000 +0900 | |
101 | +@@ -31,15 +31,20 @@ | |
102 | + __FBSDID("$FreeBSD: releng/12.4/usr.sbin/bhyve/ps2kbd.c 358184 2020-02-20 21:48:36Z vmaffione $"); | |
103 | + | |
104 | + #include <sys/types.h> | |
105 | ++#include <sys/stat.h> | |
106 | + | |
107 | + #include <assert.h> | |
108 | + #include <stdbool.h> | |
109 | + #include <stdio.h> | |
110 | + #include <stdlib.h> | |
111 | ++#include <string.h> | |
112 | + #include <strings.h> | |
113 | + #include <pthread.h> | |
114 | + #include <pthread_np.h> | |
115 | ++#include <unistd.h> | |
116 | ++#include <fcntl.h> | |
117 | + | |
118 | ++#include "bhyverun.h" | |
119 | + #include "atkbdc.h" | |
120 | + #include "debug.h" | |
121 | + #include "console.h" | |
122 | +@@ -59,6 +64,8 @@ __FBSDID("$FreeBSD: releng/12.4/usr.sbin/bhyve/ps2kbd. | |
123 | + | |
124 | + #define PS2KBD_FIFOSZ 16 | |
125 | + | |
126 | ++#define PS2KBD_LAYOUT_BASEDIR "/usr/share/bhyve/kbdlayout/" | |
127 | ++ | |
128 | + struct fifo { | |
129 | + uint8_t buf[PS2KBD_FIFOSZ]; | |
130 | + int rindex; /* index to read from */ | |
131 | +@@ -87,7 +94,7 @@ struct extended_translation { | |
132 | + /* | |
133 | + * FIXME: Pause/break and Print Screen/SysRq require special handling. | |
134 | + */ | |
135 | +-static const struct extended_translation extended_translations[] = { | |
136 | ++static struct extended_translation extended_translations[128] = { | |
137 | + {0xff08, 0x66}, /* Back space */ | |
138 | + {0xff09, 0x0d}, /* Tab */ | |
139 | + {0xff0d, 0x5a}, /* Return */ | |
140 | +@@ -159,7 +166,7 @@ static const struct extended_translation extended_tran | |
141 | + }; | |
142 | + | |
143 | + /* ASCII to type 2 scancode lookup table */ | |
144 | +-static const uint8_t ascii_translations[128] = { | |
145 | ++static uint8_t ascii_translations[128] = { | |
146 | + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
147 | + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
148 | + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
149 | +@@ -317,7 +324,7 @@ ps2kbd_keysym_queue(struct ps2kbd_softc *sc, | |
150 | + assert(pthread_mutex_isowned_np(&sc->mtx)); | |
151 | + int e0_prefix, found; | |
152 | + uint8_t code; | |
153 | +- const struct extended_translation *trans; | |
154 | ++ struct extended_translation *trans; | |
155 | + | |
156 | + found = 0; | |
157 | + if (keysym < 0x80) { | |
158 | +@@ -367,10 +374,91 @@ ps2kbd_event(int down, uint32_t keysym, void *arg) | |
159 | + atkbdc_event(sc->atkbdc_sc, 1); | |
160 | + } | |
161 | + | |
162 | ++static void | |
163 | ++ps2kbd_update_extended_translation(uint32_t keycode, uint32_t scancode, uint32_t prefix) | |
164 | ++{ | |
165 | ++ int i = 0; | |
166 | ++ | |
167 | ++ do { | |
168 | ++ if (extended_translations[i].keysym == keycode) | |
169 | ++ break; | |
170 | ++ } while(extended_translations[++i].keysym); | |
171 | ++ | |
172 | ++ if (i == (sizeof(extended_translations) / sizeof(struct extended_translation) - 1)) | |
173 | ++ return; | |
174 | ++ | |
175 | ++ if (!extended_translations[i].keysym) { | |
176 | ++ extended_translations[i].keysym = keycode; | |
177 | ++ | |
178 | ++ extended_translations[i+1].keysym = 0; | |
179 | ++ extended_translations[i+1].scancode = 0; | |
180 | ++ extended_translations[i+1].flags = 0; | |
181 | ++ } | |
182 | ++ | |
183 | ++ extended_translations[i].scancode = (uint8_t)(scancode & 0xff); | |
184 | ++ extended_translations[i].flags = (prefix ? SCANCODE_E0_PREFIX : 0); | |
185 | ++} | |
186 | ++ | |
187 | ++static void | |
188 | ++ps2kbd_setkbdlayout(void) | |
189 | ++{ | |
190 | ++ int err; | |
191 | ++ int fd; | |
192 | ++ char path[256]; | |
193 | ++ char *buf, *next, *line; | |
194 | ++ struct stat sb; | |
195 | ++ size_t sz; | |
196 | ++ uint8_t ascii; | |
197 | ++ uint32_t keycode, scancode, prefix; | |
198 | ++ | |
199 | ++ strcpy(path, PS2KBD_LAYOUT_BASEDIR); | |
200 | ++ strncat(path, kbdlayout_name, (sizeof(path) - strlen(PS2KBD_LAYOUT_BASEDIR) - 1)); | |
201 | ++ | |
202 | ++ err = stat(path, &sb); | |
203 | ++ if (err) | |
204 | ++ return; | |
205 | ++ | |
206 | ++ buf = (char *)malloc(sizeof(char) * sb.st_size); | |
207 | ++ if (buf == NULL) | |
208 | ++ return; | |
209 | ++ | |
210 | ++ fd = open(path, O_RDONLY); | |
211 | ++ if (fd == -1) | |
212 | ++ goto out; | |
213 | ++ | |
214 | ++ sz = read(fd, buf, sb.st_size ); | |
215 | ++ | |
216 | ++ close(fd); | |
217 | ++ | |
218 | ++ if (sz != sb.st_size ) | |
219 | ++ goto out; | |
220 | ++ | |
221 | ++ next = buf; | |
222 | ++ while ((line = strsep(&next, "\n")) != NULL) { | |
223 | ++ if (sscanf(line, "'%c',%x;", &ascii, &scancode) == 2) { | |
224 | ++ if (ascii < 0x80) | |
225 | ++ ascii_translations[ascii] = (uint8_t)(scancode & 0xff); | |
226 | ++ } else if (sscanf(line, "%x,%x,%x;", &keycode, &scancode, &prefix) == 3 ) { | |
227 | ++ ps2kbd_update_extended_translation(keycode, scancode, prefix); | |
228 | ++ } else if (sscanf(line, "%x,%x;", &keycode, &scancode) == 2) { | |
229 | ++ if (keycode < 0x80) | |
230 | ++ ascii_translations[(uint8_t)(keycode & 0xff)] = (uint8_t)(scancode & 0xff); | |
231 | ++ else | |
232 | ++ ps2kbd_update_extended_translation(keycode, scancode, 0); | |
233 | ++ } | |
234 | ++ } | |
235 | ++ | |
236 | ++out: | |
237 | ++ free(buf); | |
238 | ++} | |
239 | ++ | |
240 | + struct ps2kbd_softc * | |
241 | + ps2kbd_init(struct atkbdc_softc *atkbdc_sc) | |
242 | + { | |
243 | + struct ps2kbd_softc *sc; | |
244 | ++ | |
245 | ++ if (kbdlayout_name != NULL) | |
246 | ++ ps2kbd_setkbdlayout(); | |
247 | + | |
248 | + sc = calloc(1, sizeof (struct ps2kbd_softc)); | |
249 | + 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 2022-12-10 21:18:44.321626000 +0900 | |
3 | ++++ examples/bhyve/vmrun.sh 2022-12-10 22:54:29.032949000 +0900 | |
4 | +@@ -59,8 +59,8 @@ usage() { | |
5 | + echo " [-e <name=value>] [-f <path of firmware>]" \ | |
6 | + "[-F <size>]" | |
7 | + echo " [-g <gdbport> ] [-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 | +@@ -81,6 +81,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 | +@@ -134,7 +135,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 | +@@ -178,6 +179,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,271 @@ | ||
1 | +diff -uprN bhyve_orig/console.c bhyve/console.c | |
2 | +--- bhyve_orig/console.c 2022-12-10 21:20:17.782899000 +0900 | |
3 | ++++ bhyve/console.c 2022-12-10 22:28:51.486209000 +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 2022-12-10 21:20:17.786790000 +0900 | |
19 | ++++ bhyve/console.h 2022-12-10 22:28:51.486696000 +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 2022-12-10 21:20:17.986325000 +0900 | |
40 | ++++ bhyve/ps2kbd.c 2022-12-10 22:28:51.487502000 +0900 | |
41 | +@@ -178,6 +178,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 | +@@ -312,26 +332,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 | +@@ -349,7 +375,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 | +@@ -360,7 +386,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 2022-12-10 21:20:18.001975000 +0900 | |
133 | ++++ bhyve/rfb.c 2022-12-10 22:28:51.488744000 +0900 | |
134 | +@@ -99,7 +99,10 @@ struct rfb_softc { | |
135 | + bool enc_raw_ok; | |
136 | + bool enc_zlib_ok; | |
137 | + bool enc_resize_ok; | |
138 | ++ bool enc_extkeyevent_ok; | |
139 | + | |
140 | ++ bool enc_extkeyevent_send; | |
141 | ++ | |
142 | + z_stream zstream; | |
143 | + uint8_t *zbuf; | |
144 | + int zbuflen; | |
145 | +@@ -145,7 +148,10 @@ struct rfb_pixfmt_msg { | |
146 | + #define RFB_ENCODING_RAW 0 | |
147 | + #define RFB_ENCODING_ZLIB 6 | |
148 | + #define RFB_ENCODING_RESIZE -223 | |
149 | ++#define RFB_ENCODING_EXT_KEYEVENT -258 | |
150 | + | |
151 | ++#define RFB_CLIENTMSG_EXT_KEYEVENT 0 | |
152 | ++ | |
153 | + #define RFB_MAX_WIDTH 2000 | |
154 | + #define RFB_MAX_HEIGHT 1200 | |
155 | + #define RFB_ZLIB_BUFSZ RFB_MAX_WIDTH*RFB_MAX_HEIGHT*4 | |
156 | +@@ -172,6 +178,19 @@ struct rfb_key_msg { | |
157 | + uint8_t type; | |
158 | + uint8_t down; | |
159 | + uint16_t pad; | |
160 | ++ uint32_t sym; | |
161 | ++}; | |
162 | ++ | |
163 | ++struct rfb_client_msg { | |
164 | ++ uint8_t type; | |
165 | ++ uint8_t subtype; | |
166 | ++}; | |
167 | ++ | |
168 | ++struct rfb_extended_key_msg { | |
169 | ++ uint8_t type; | |
170 | ++ uint8_t subtype; | |
171 | ++ uint16_t down; | |
172 | ++ uint32_t sym; | |
173 | + uint32_t code; | |
174 | + }; | |
175 | + | |
176 | +@@ -250,6 +269,27 @@ rfb_send_resize_update_msg(struct rfb_softc *rc, int c | |
177 | + } | |
178 | + | |
179 | + static void | |
180 | ++rfb_send_extended_keyevent_update_msg(struct rfb_softc *rc, int cfd) | |
181 | ++{ | |
182 | ++ struct rfb_srvr_updt_msg supdt_msg; | |
183 | ++ struct rfb_srvr_rect_hdr srect_hdr; | |
184 | ++ | |
185 | ++ /* Number of rectangles: 1 */ | |
186 | ++ supdt_msg.type = 0; | |
187 | ++ supdt_msg.pad = 0; | |
188 | ++ supdt_msg.numrects = htons(1); | |
189 | ++ stream_write(cfd, &supdt_msg, sizeof(struct rfb_srvr_updt_msg)); | |
190 | ++ | |
191 | ++ /* Rectangle header */ | |
192 | ++ srect_hdr.x = htons(0); | |
193 | ++ srect_hdr.y = htons(0); | |
194 | ++ srect_hdr.width = htons(rc->width); | |
195 | ++ srect_hdr.height = htons(rc->height); | |
196 | ++ srect_hdr.encoding = htonl(RFB_ENCODING_EXT_KEYEVENT); | |
197 | ++ stream_write(cfd, &srect_hdr, sizeof(struct rfb_srvr_rect_hdr)); | |
198 | ++} | |
199 | ++ | |
200 | ++static void | |
201 | + rfb_recv_set_pixfmt_msg(struct rfb_softc *rc, int cfd) | |
202 | + { | |
203 | + struct rfb_pixfmt_msg pixfmt_msg; | |
204 | +@@ -283,6 +323,9 @@ rfb_recv_set_encodings_msg(struct rfb_softc *rc, int c | |
205 | + case RFB_ENCODING_RESIZE: | |
206 | + rc->enc_resize_ok = true; | |
207 | + break; | |
208 | ++ case RFB_ENCODING_EXT_KEYEVENT: | |
209 | ++ rc->enc_extkeyevent_ok = true; | |
210 | ++ break; | |
211 | + } | |
212 | + } | |
213 | + } | |
214 | +@@ -648,6 +691,11 @@ rfb_recv_update_msg(struct rfb_softc *rc, int cfd, int | |
215 | + rfb_send_resize_update_msg(rc, cfd); | |
216 | + } | |
217 | + | |
218 | ++ if (rc->enc_extkeyevent_ok && (!rc->enc_extkeyevent_send)) { | |
219 | ++ rfb_send_extended_keyevent_update_msg(rc, cfd); | |
220 | ++ rc->enc_extkeyevent_send = true; | |
221 | ++ } | |
222 | ++ | |
223 | + if (discardonly) | |
224 | + return; | |
225 | + | |
226 | +@@ -661,10 +709,24 @@ rfb_recv_key_msg(struct rfb_softc *rc, int cfd) | |
227 | + | |
228 | + (void)stream_read(cfd, ((void *)&key_msg) + 1, sizeof(key_msg) - 1); | |
229 | + | |
230 | +- console_key_event(key_msg.down, htonl(key_msg.code)); | |
231 | ++ console_key_event(key_msg.down, htonl(key_msg.sym), htonl(0)); | |
232 | + } | |
233 | + | |
234 | + static void | |
235 | ++rfb_recv_client_msg(struct rfb_softc *rc, int cfd) | |
236 | ++{ | |
237 | ++ struct rfb_client_msg client_msg; | |
238 | ++ struct rfb_extended_key_msg extkey_msg; | |
239 | ++ | |
240 | ++ (void)stream_read(cfd, ((void *)&client_msg) + 1, sizeof(client_msg) - 1); | |
241 | ++ | |
242 | ++ if (client_msg.subtype == RFB_CLIENTMSG_EXT_KEYEVENT ) { | |
243 | ++ (void)stream_read(cfd, ((void *)&extkey_msg) + 2, sizeof(extkey_msg) - 2); | |
244 | ++ console_key_event((int)extkey_msg.down, htonl(extkey_msg.sym), htonl(extkey_msg.code)); | |
245 | ++ } | |
246 | ++} | |
247 | ++ | |
248 | ++static void | |
249 | + rfb_recv_ptr_msg(struct rfb_softc *rc, int cfd) | |
250 | + { | |
251 | + struct rfb_ptr_msg ptr_msg; | |
252 | +@@ -903,6 +965,9 @@ rfb_handle(struct rfb_softc *rc, int cfd) | |
253 | + case 6: | |
254 | + rfb_recv_cuttext_msg(rc, cfd); | |
255 | + break; | |
256 | ++ case 255: | |
257 | ++ rfb_recv_client_msg(rc, cfd); | |
258 | ++ break; | |
259 | + default: | |
260 | + WPRINTF(("rfb unknown cli-code %d!", buf[0] & 0xff)); | |
261 | + goto done; | |
262 | +@@ -937,6 +1002,9 @@ rfb_thr(void *arg) | |
263 | + rc->enc_raw_ok = false; | |
264 | + rc->enc_zlib_ok = false; | |
265 | + rc->enc_resize_ok = false; | |
266 | ++ rc->enc_extkeyevent_ok = false; | |
267 | ++ | |
268 | ++ rc->enc_extkeyevent_send = false; | |
269 | + | |
270 | + cfd = accept(rc->sfd, NULL, NULL); | |
271 | + if (rc->conn_wait) { |
@@ -59,8 +59,8 @@ | ||
59 | 59 | 3. make |
60 | 60 | 4. make install |
61 | 61 | |
62 | - * If you use the FreeBSD 12.1/2/3-RELEASE, please replace the "fbsd131r" of the above No.2 to the | |
63 | - "fbsd123r" or "fbsd122r" or "fbsd121r". | |
62 | + * If you use the FreeBSD 12.1/2/3/4-RELEASE, please replace the "fbsd131r" of the above No.2 to | |
63 | + the "fbsd124r" or "fbsd123r" or "fbsd122r" or "fbsd121r". | |
64 | 64 | |
65 | 65 | |
66 | 66 | <<Usage [Patch 2] Append Keyboard Layout specified option.>>======================================== |
@@ -75,8 +75,8 @@ | ||
75 | 75 | 6. make |
76 | 76 | 7. make install |
77 | 77 | |
78 | - * If you use the FreeBSD 12.1/2/3-RELEASE, please replace the "fbsd131r" of the above No.2 to the | |
79 | - "fbsd123r" or "fbsd122r" or "fbsd121r". | |
78 | + * If you use the FreeBSD 12.1/2/3/4-RELEASE, please replace the "fbsd131r" of the above No.2 to | |
79 | + the "fbsd124r" or "fbsd123r" or "fbsd122r" or "fbsd121r". | |
80 | 80 | |
81 | 81 | Second, please apply the patch to vmrun.sh. |
82 | 82 |
@@ -98,6 +98,9 @@ | ||
98 | 98 | |
99 | 99 | |
100 | 100 | <<ChangeLog>>======================================================================================= |
101 | + * 2023/04/12 | |
102 | + - Add the patches for FreeBSD 12.4-RELEASE. | |
103 | + | |
101 | 104 | * 2022/05/19 |
102 | 105 | - Add the patches for FreeBSD 13.1-RELEASE. |
103 | 106 | - Remove the patches for FreeBSD 13-STABLE(20211223). |