summaryrefslogtreecommitdiff
path: root/contrib/SDL-3.2.8/src/core/openbsd
diff options
context:
space:
mode:
author3gg <3gg@shellblade.net>2025-12-27 12:03:39 -0800
committer3gg <3gg@shellblade.net>2025-12-27 12:03:39 -0800
commit5a079a2d114f96d4847d1ee305d5b7c16eeec50e (patch)
tree8926ab44f168acf787d8e19608857b3af0f82758 /contrib/SDL-3.2.8/src/core/openbsd
Initial commit
Diffstat (limited to 'contrib/SDL-3.2.8/src/core/openbsd')
-rw-r--r--contrib/SDL-3.2.8/src/core/openbsd/SDL_wscons.h25
-rw-r--r--contrib/SDL-3.2.8/src/core/openbsd/SDL_wscons_kbd.c948
-rw-r--r--contrib/SDL-3.2.8/src/core/openbsd/SDL_wscons_mouse.c127
3 files changed, 1100 insertions, 0 deletions
diff --git a/contrib/SDL-3.2.8/src/core/openbsd/SDL_wscons.h b/contrib/SDL-3.2.8/src/core/openbsd/SDL_wscons.h
new file mode 100644
index 0000000..f9b7bf8
--- /dev/null
+++ b/contrib/SDL-3.2.8/src/core/openbsd/SDL_wscons.h
@@ -0,0 +1,25 @@
1/*
2 Simple DirectMedia Layer
3 Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
4
5 This software is provided 'as-is', without any express or implied
6 warranty. In no event will the authors be held liable for any damages
7 arising from the use of this software.
8
9 Permission is granted to anyone to use this software for any purpose,
10 including commercial applications, and to alter it and redistribute it
11 freely, subject to the following restrictions:
12
13 1. The origin of this software must not be misrepresented; you must not
14 claim that you wrote the original software. If you use this software
15 in a product, an acknowledgment in the product documentation would be
16 appreciated but is not required.
17 2. Altered source versions must be plainly marked as such, and must not be
18 misrepresented as being the original software.
19 3. This notice may not be removed or altered from any source distribution.
20*/
21
22void SDL_WSCONS_Init(void);
23void SDL_WSCONS_Quit(void);
24
25void SDL_WSCONS_PumpEvents(void);
diff --git a/contrib/SDL-3.2.8/src/core/openbsd/SDL_wscons_kbd.c b/contrib/SDL-3.2.8/src/core/openbsd/SDL_wscons_kbd.c
new file mode 100644
index 0000000..5a71044
--- /dev/null
+++ b/contrib/SDL-3.2.8/src/core/openbsd/SDL_wscons_kbd.c
@@ -0,0 +1,948 @@
1/*
2 Simple DirectMedia Layer
3 Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
4
5 This software is provided 'as-is', without any express or implied
6 warranty. In no event will the authors be held liable for any damages
7 arising from the use of this software.
8
9 Permission is granted to anyone to use this software for any purpose,
10 including commercial applications, and to alter it and redistribute it
11 freely, subject to the following restrictions:
12
13 1. The origin of this software must not be misrepresented; you must not
14 claim that you wrote the original software. If you use this software
15 in a product, an acknowledgment in the product documentation would be
16 appreciated but is not required.
17 2. Altered source versions must be plainly marked as such, and must not be
18 misrepresented as being the original software.
19 3. This notice may not be removed or altered from any source distribution.
20*/
21
22#include "SDL_internal.h"
23#include <dev/wscons/wsksymvar.h>
24#include <dev/wscons/wsksymdef.h>
25#include "SDL_wscons.h"
26#include <sys/time.h>
27#include <dev/wscons/wsconsio.h>
28#include <dev/wscons/wsdisplay_usl_io.h>
29#include <termios.h>
30#include <fcntl.h>
31#include <sys/ioctl.h>
32#include <sys/param.h>
33#include <unistd.h>
34
35#include "../../events/SDL_events_c.h"
36#include "../../events/SDL_keyboard_c.h"
37
38#ifdef SDL_PLATFORM_NETBSD
39#define KS_GROUP_Ascii KS_GROUP_Plain
40#define KS_Cmd_ScrollBack KS_Cmd_ScrollFastUp
41#define KS_Cmd_ScrollFwd KS_Cmd_ScrollFastDown
42#endif
43
44#define RETIFIOCTLERR(x) \
45 if ((x) == -1) { \
46 SDL_free(input); \
47 input = NULL; \
48 return NULL; \
49 }
50
51typedef struct SDL_WSCONS_mouse_input_data SDL_WSCONS_mouse_input_data;
52extern SDL_WSCONS_mouse_input_data *SDL_WSCONS_Init_Mouse(void);
53extern void updateMouse(SDL_WSCONS_mouse_input_data *input);
54extern void SDL_WSCONS_Quit_Mouse(SDL_WSCONS_mouse_input_data *input);
55
56// Conversion table courtesy of /usr/src/sys/dev/wscons/wskbdutil.c
57static const unsigned char latin1_to_upper[256] = {
58 // 0 8 1 9 2 a 3 b 4 c 5 d 6 e 7 f
59 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0
60 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0
61 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 1
62 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 1
63 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 2
64 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 2
65 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 3
66 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 3
67 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 4
68 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 4
69 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 5
70 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 5
71 0x00, 'A', 'B', 'C', 'D', 'E', 'F', 'G', // 6
72 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', // 6
73 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', // 7
74 'X', 'Y', 'Z', 0x00, 0x00, 0x00, 0x00, 0x00, // 7
75 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 8
76 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 8
77 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 9
78 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 9
79 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // a
80 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // a
81 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // b
82 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // b
83 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // c
84 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // c
85 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // d
86 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // d
87 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, // e
88 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, // e
89 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0x00, // f
90 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0x00, // f
91};
92
93// Compose table courtesy of /usr/src/sys/dev/wscons/wskbdutil.c
94static struct SDL_wscons_compose_tab_s
95{
96 keysym_t elem[2];
97 keysym_t result;
98} compose_tab[] = {
99 { { KS_plus, KS_plus }, KS_numbersign },
100 { { KS_a, KS_a }, KS_at },
101 { { KS_parenleft, KS_parenleft }, KS_bracketleft },
102 { { KS_slash, KS_slash }, KS_backslash },
103 { { KS_parenright, KS_parenright }, KS_bracketright },
104 { { KS_parenleft, KS_minus }, KS_braceleft },
105 { { KS_slash, KS_minus }, KS_bar },
106 { { KS_parenright, KS_minus }, KS_braceright },
107 { { KS_exclam, KS_exclam }, KS_exclamdown },
108 { { KS_c, KS_slash }, KS_cent },
109 { { KS_l, KS_minus }, KS_sterling },
110 { { KS_y, KS_minus }, KS_yen },
111 { { KS_s, KS_o }, KS_section },
112 { { KS_x, KS_o }, KS_currency },
113 { { KS_c, KS_o }, KS_copyright },
114 { { KS_less, KS_less }, KS_guillemotleft },
115 { { KS_greater, KS_greater }, KS_guillemotright },
116 { { KS_question, KS_question }, KS_questiondown },
117 { { KS_dead_acute, KS_space }, KS_apostrophe },
118 { { KS_dead_grave, KS_space }, KS_grave },
119 { { KS_dead_tilde, KS_space }, KS_asciitilde },
120 { { KS_dead_circumflex, KS_space }, KS_asciicircum },
121 { { KS_dead_diaeresis, KS_space }, KS_quotedbl },
122 { { KS_dead_cedilla, KS_space }, KS_comma },
123 { { KS_dead_circumflex, KS_A }, KS_Acircumflex },
124 { { KS_dead_diaeresis, KS_A }, KS_Adiaeresis },
125 { { KS_dead_grave, KS_A }, KS_Agrave },
126 { { KS_dead_abovering, KS_A }, KS_Aring },
127 { { KS_dead_tilde, KS_A }, KS_Atilde },
128 { { KS_dead_cedilla, KS_C }, KS_Ccedilla },
129 { { KS_dead_acute, KS_E }, KS_Eacute },
130 { { KS_dead_circumflex, KS_E }, KS_Ecircumflex },
131 { { KS_dead_diaeresis, KS_E }, KS_Ediaeresis },
132 { { KS_dead_grave, KS_E }, KS_Egrave },
133 { { KS_dead_acute, KS_I }, KS_Iacute },
134 { { KS_dead_circumflex, KS_I }, KS_Icircumflex },
135 { { KS_dead_diaeresis, KS_I }, KS_Idiaeresis },
136 { { KS_dead_grave, KS_I }, KS_Igrave },
137 { { KS_dead_tilde, KS_N }, KS_Ntilde },
138 { { KS_dead_acute, KS_O }, KS_Oacute },
139 { { KS_dead_circumflex, KS_O }, KS_Ocircumflex },
140 { { KS_dead_diaeresis, KS_O }, KS_Odiaeresis },
141 { { KS_dead_grave, KS_O }, KS_Ograve },
142 { { KS_dead_tilde, KS_O }, KS_Otilde },
143 { { KS_dead_acute, KS_U }, KS_Uacute },
144 { { KS_dead_circumflex, KS_U }, KS_Ucircumflex },
145 { { KS_dead_diaeresis, KS_U }, KS_Udiaeresis },
146 { { KS_dead_grave, KS_U }, KS_Ugrave },
147 { { KS_dead_acute, KS_Y }, KS_Yacute },
148 { { KS_dead_acute, KS_a }, KS_aacute },
149 { { KS_dead_circumflex, KS_a }, KS_acircumflex },
150 { { KS_dead_diaeresis, KS_a }, KS_adiaeresis },
151 { { KS_dead_grave, KS_a }, KS_agrave },
152 { { KS_dead_abovering, KS_a }, KS_aring },
153 { { KS_dead_tilde, KS_a }, KS_atilde },
154 { { KS_dead_cedilla, KS_c }, KS_ccedilla },
155 { { KS_dead_acute, KS_e }, KS_eacute },
156 { { KS_dead_circumflex, KS_e }, KS_ecircumflex },
157 { { KS_dead_diaeresis, KS_e }, KS_ediaeresis },
158 { { KS_dead_grave, KS_e }, KS_egrave },
159 { { KS_dead_acute, KS_i }, KS_iacute },
160 { { KS_dead_circumflex, KS_i }, KS_icircumflex },
161 { { KS_dead_diaeresis, KS_i }, KS_idiaeresis },
162 { { KS_dead_grave, KS_i }, KS_igrave },
163 { { KS_dead_tilde, KS_n }, KS_ntilde },
164 { { KS_dead_acute, KS_o }, KS_oacute },
165 { { KS_dead_circumflex, KS_o }, KS_ocircumflex },
166 { { KS_dead_diaeresis, KS_o }, KS_odiaeresis },
167 { { KS_dead_grave, KS_o }, KS_ograve },
168 { { KS_dead_tilde, KS_o }, KS_otilde },
169 { { KS_dead_acute, KS_u }, KS_uacute },
170 { { KS_dead_circumflex, KS_u }, KS_ucircumflex },
171 { { KS_dead_diaeresis, KS_u }, KS_udiaeresis },
172 { { KS_dead_grave, KS_u }, KS_ugrave },
173 { { KS_dead_acute, KS_y }, KS_yacute },
174 { { KS_dead_diaeresis, KS_y }, KS_ydiaeresis },
175 { { KS_quotedbl, KS_A }, KS_Adiaeresis },
176 { { KS_quotedbl, KS_E }, KS_Ediaeresis },
177 { { KS_quotedbl, KS_I }, KS_Idiaeresis },
178 { { KS_quotedbl, KS_O }, KS_Odiaeresis },
179 { { KS_quotedbl, KS_U }, KS_Udiaeresis },
180 { { KS_quotedbl, KS_a }, KS_adiaeresis },
181 { { KS_quotedbl, KS_e }, KS_ediaeresis },
182 { { KS_quotedbl, KS_i }, KS_idiaeresis },
183 { { KS_quotedbl, KS_o }, KS_odiaeresis },
184 { { KS_quotedbl, KS_u }, KS_udiaeresis },
185 { { KS_quotedbl, KS_y }, KS_ydiaeresis },
186 { { KS_acute, KS_A }, KS_Aacute },
187 { { KS_asciicircum, KS_A }, KS_Acircumflex },
188 { { KS_grave, KS_A }, KS_Agrave },
189 { { KS_asterisk, KS_A }, KS_Aring },
190 { { KS_asciitilde, KS_A }, KS_Atilde },
191 { { KS_cedilla, KS_C }, KS_Ccedilla },
192 { { KS_acute, KS_E }, KS_Eacute },
193 { { KS_asciicircum, KS_E }, KS_Ecircumflex },
194 { { KS_grave, KS_E }, KS_Egrave },
195 { { KS_acute, KS_I }, KS_Iacute },
196 { { KS_asciicircum, KS_I }, KS_Icircumflex },
197 { { KS_grave, KS_I }, KS_Igrave },
198 { { KS_asciitilde, KS_N }, KS_Ntilde },
199 { { KS_acute, KS_O }, KS_Oacute },
200 { { KS_asciicircum, KS_O }, KS_Ocircumflex },
201 { { KS_grave, KS_O }, KS_Ograve },
202 { { KS_asciitilde, KS_O }, KS_Otilde },
203 { { KS_acute, KS_U }, KS_Uacute },
204 { { KS_asciicircum, KS_U }, KS_Ucircumflex },
205 { { KS_grave, KS_U }, KS_Ugrave },
206 { { KS_acute, KS_Y }, KS_Yacute },
207 { { KS_acute, KS_a }, KS_aacute },
208 { { KS_asciicircum, KS_a }, KS_acircumflex },
209 { { KS_grave, KS_a }, KS_agrave },
210 { { KS_asterisk, KS_a }, KS_aring },
211 { { KS_asciitilde, KS_a }, KS_atilde },
212 { { KS_cedilla, KS_c }, KS_ccedilla },
213 { { KS_acute, KS_e }, KS_eacute },
214 { { KS_asciicircum, KS_e }, KS_ecircumflex },
215 { { KS_grave, KS_e }, KS_egrave },
216 { { KS_acute, KS_i }, KS_iacute },
217 { { KS_asciicircum, KS_i }, KS_icircumflex },
218 { { KS_grave, KS_i }, KS_igrave },
219 { { KS_asciitilde, KS_n }, KS_ntilde },
220 { { KS_acute, KS_o }, KS_oacute },
221 { { KS_asciicircum, KS_o }, KS_ocircumflex },
222 { { KS_grave, KS_o }, KS_ograve },
223 { { KS_asciitilde, KS_o }, KS_otilde },
224 { { KS_acute, KS_u }, KS_uacute },
225 { { KS_asciicircum, KS_u }, KS_ucircumflex },
226 { { KS_grave, KS_u }, KS_ugrave },
227 { { KS_acute, KS_y }, KS_yacute },
228#ifndef SDL_PLATFORM_NETBSD
229 { { KS_dead_caron, KS_space }, KS_L2_caron },
230 { { KS_dead_caron, KS_S }, KS_L2_Scaron },
231 { { KS_dead_caron, KS_Z }, KS_L2_Zcaron },
232 { { KS_dead_caron, KS_s }, KS_L2_scaron },
233 { { KS_dead_caron, KS_z }, KS_L2_zcaron }
234#endif
235};
236
237static keysym_t ksym_upcase(keysym_t ksym)
238{
239 if (ksym >= KS_f1 && ksym <= KS_f20) {
240 return KS_F1 - KS_f1 + ksym;
241 }
242
243 if (KS_GROUP(ksym) == KS_GROUP_Ascii && ksym <= 0xff && latin1_to_upper[ksym] != 0x00) {
244 return latin1_to_upper[ksym];
245 }
246
247 return ksym;
248}
249static struct wscons_keycode_to_SDL
250{
251 keysym_t sourcekey;
252 SDL_Scancode targetKey;
253} conversion_table[] = {
254 { KS_Menu, SDL_SCANCODE_APPLICATION },
255 { KS_Up, SDL_SCANCODE_UP },
256 { KS_Down, SDL_SCANCODE_DOWN },
257 { KS_Left, SDL_SCANCODE_LEFT },
258 { KS_Right, SDL_SCANCODE_RIGHT },
259 { KS_Hold_Screen, SDL_SCANCODE_SCROLLLOCK },
260 { KS_Num_Lock, SDL_SCANCODE_NUMLOCKCLEAR },
261 { KS_Caps_Lock, SDL_SCANCODE_CAPSLOCK },
262 { KS_BackSpace, SDL_SCANCODE_BACKSPACE },
263 { KS_space, SDL_SCANCODE_SPACE },
264 { KS_Delete, SDL_SCANCODE_BACKSPACE },
265 { KS_Home, SDL_SCANCODE_HOME },
266 { KS_End, SDL_SCANCODE_END },
267 { KS_Pause, SDL_SCANCODE_PAUSE },
268 { KS_Print_Screen, SDL_SCANCODE_PRINTSCREEN },
269 { KS_Insert, SDL_SCANCODE_INSERT },
270 { KS_Escape, SDL_SCANCODE_ESCAPE },
271 { KS_Return, SDL_SCANCODE_RETURN },
272 { KS_Linefeed, SDL_SCANCODE_RETURN },
273 { KS_KP_Delete, SDL_SCANCODE_DELETE },
274 { KS_KP_Insert, SDL_SCANCODE_INSERT },
275 { KS_Control_L, SDL_SCANCODE_LCTRL },
276 { KS_Control_R, SDL_SCANCODE_RCTRL },
277 { KS_Shift_L, SDL_SCANCODE_LSHIFT },
278 { KS_Shift_R, SDL_SCANCODE_RSHIFT },
279 { KS_Alt_L, SDL_SCANCODE_LALT },
280 { KS_Alt_R, SDL_SCANCODE_RALT },
281 { KS_grave, SDL_SCANCODE_GRAVE },
282
283 { KS_KP_0, SDL_SCANCODE_KP_0 },
284 { KS_KP_1, SDL_SCANCODE_KP_1 },
285 { KS_KP_2, SDL_SCANCODE_KP_2 },
286 { KS_KP_3, SDL_SCANCODE_KP_3 },
287 { KS_KP_4, SDL_SCANCODE_KP_4 },
288 { KS_KP_5, SDL_SCANCODE_KP_5 },
289 { KS_KP_6, SDL_SCANCODE_KP_6 },
290 { KS_KP_7, SDL_SCANCODE_KP_7 },
291 { KS_KP_8, SDL_SCANCODE_KP_8 },
292 { KS_KP_9, SDL_SCANCODE_KP_9 },
293 { KS_KP_Enter, SDL_SCANCODE_KP_ENTER },
294 { KS_KP_Multiply, SDL_SCANCODE_KP_MULTIPLY },
295 { KS_KP_Add, SDL_SCANCODE_KP_PLUS },
296 { KS_KP_Subtract, SDL_SCANCODE_KP_MINUS },
297 { KS_KP_Divide, SDL_SCANCODE_KP_DIVIDE },
298 { KS_KP_Up, SDL_SCANCODE_UP },
299 { KS_KP_Down, SDL_SCANCODE_DOWN },
300 { KS_KP_Left, SDL_SCANCODE_LEFT },
301 { KS_KP_Right, SDL_SCANCODE_RIGHT },
302 { KS_KP_Equal, SDL_SCANCODE_KP_EQUALS },
303 { KS_f1, SDL_SCANCODE_F1 },
304 { KS_f2, SDL_SCANCODE_F2 },
305 { KS_f3, SDL_SCANCODE_F3 },
306 { KS_f4, SDL_SCANCODE_F4 },
307 { KS_f5, SDL_SCANCODE_F5 },
308 { KS_f6, SDL_SCANCODE_F6 },
309 { KS_f7, SDL_SCANCODE_F7 },
310 { KS_f8, SDL_SCANCODE_F8 },
311 { KS_f9, SDL_SCANCODE_F9 },
312 { KS_f10, SDL_SCANCODE_F10 },
313 { KS_f11, SDL_SCANCODE_F11 },
314 { KS_f12, SDL_SCANCODE_F12 },
315 { KS_f13, SDL_SCANCODE_F13 },
316 { KS_f14, SDL_SCANCODE_F14 },
317 { KS_f15, SDL_SCANCODE_F15 },
318 { KS_f16, SDL_SCANCODE_F16 },
319 { KS_f17, SDL_SCANCODE_F17 },
320 { KS_f18, SDL_SCANCODE_F18 },
321 { KS_f19, SDL_SCANCODE_F19 },
322 { KS_f20, SDL_SCANCODE_F20 },
323#ifndef SDL_PLATFORM_NETBSD
324 { KS_f21, SDL_SCANCODE_F21 },
325 { KS_f22, SDL_SCANCODE_F22 },
326 { KS_f23, SDL_SCANCODE_F23 },
327 { KS_f24, SDL_SCANCODE_F24 },
328#endif
329 { KS_Meta_L, SDL_SCANCODE_LGUI },
330 { KS_Meta_R, SDL_SCANCODE_RGUI },
331 { KS_Zenkaku_Hankaku, SDL_SCANCODE_LANG5 },
332 { KS_Hiragana_Katakana, SDL_SCANCODE_INTERNATIONAL2 },
333 { KS_yen, SDL_SCANCODE_INTERNATIONAL3 },
334 { KS_Henkan, SDL_SCANCODE_INTERNATIONAL4 },
335 { KS_Muhenkan, SDL_SCANCODE_INTERNATIONAL5 },
336 { KS_KP_Prior, SDL_SCANCODE_PRIOR },
337
338 { KS_a, SDL_SCANCODE_A },
339 { KS_b, SDL_SCANCODE_B },
340 { KS_c, SDL_SCANCODE_C },
341 { KS_d, SDL_SCANCODE_D },
342 { KS_e, SDL_SCANCODE_E },
343 { KS_f, SDL_SCANCODE_F },
344 { KS_g, SDL_SCANCODE_G },
345 { KS_h, SDL_SCANCODE_H },
346 { KS_i, SDL_SCANCODE_I },
347 { KS_j, SDL_SCANCODE_J },
348 { KS_k, SDL_SCANCODE_K },
349 { KS_l, SDL_SCANCODE_L },
350 { KS_m, SDL_SCANCODE_M },
351 { KS_n, SDL_SCANCODE_N },
352 { KS_o, SDL_SCANCODE_O },
353 { KS_p, SDL_SCANCODE_P },
354 { KS_q, SDL_SCANCODE_Q },
355 { KS_r, SDL_SCANCODE_R },
356 { KS_s, SDL_SCANCODE_S },
357 { KS_t, SDL_SCANCODE_T },
358 { KS_u, SDL_SCANCODE_U },
359 { KS_v, SDL_SCANCODE_V },
360 { KS_w, SDL_SCANCODE_W },
361 { KS_x, SDL_SCANCODE_X },
362 { KS_y, SDL_SCANCODE_Y },
363 { KS_z, SDL_SCANCODE_Z },
364
365 { KS_0, SDL_SCANCODE_0 },
366 { KS_1, SDL_SCANCODE_1 },
367 { KS_2, SDL_SCANCODE_2 },
368 { KS_3, SDL_SCANCODE_3 },
369 { KS_4, SDL_SCANCODE_4 },
370 { KS_5, SDL_SCANCODE_5 },
371 { KS_6, SDL_SCANCODE_6 },
372 { KS_7, SDL_SCANCODE_7 },
373 { KS_8, SDL_SCANCODE_8 },
374 { KS_9, SDL_SCANCODE_9 },
375 { KS_minus, SDL_SCANCODE_MINUS },
376 { KS_equal, SDL_SCANCODE_EQUALS },
377 { KS_Tab, SDL_SCANCODE_TAB },
378 { KS_KP_Tab, SDL_SCANCODE_KP_TAB },
379 { KS_apostrophe, SDL_SCANCODE_APOSTROPHE },
380 { KS_bracketleft, SDL_SCANCODE_LEFTBRACKET },
381 { KS_bracketright, SDL_SCANCODE_RIGHTBRACKET },
382 { KS_semicolon, SDL_SCANCODE_SEMICOLON },
383 { KS_comma, SDL_SCANCODE_COMMA },
384 { KS_period, SDL_SCANCODE_PERIOD },
385 { KS_slash, SDL_SCANCODE_SLASH },
386 { KS_backslash, SDL_SCANCODE_BACKSLASH }
387};
388
389typedef struct
390{
391 int fd;
392 SDL_KeyboardID keyboardID;
393 struct wskbd_map_data keymap;
394 int ledstate;
395 int origledstate;
396 int shiftstate[4];
397 int shiftheldstate[8];
398 int lockheldstate[5];
399 kbd_t encoding;
400 char text[128];
401 unsigned int text_len;
402 keysym_t composebuffer[2];
403 unsigned char composelen;
404 int type;
405} SDL_WSCONS_input_data;
406
407static SDL_WSCONS_input_data *inputs[4] = { NULL, NULL, NULL, NULL };
408static SDL_WSCONS_mouse_input_data *mouseInputData = NULL;
409#define IS_CONTROL_HELD (input->shiftstate[2] > 0)
410#define IS_ALT_HELD (input->shiftstate[1] > 0)
411#define IS_SHIFT_HELD ((input->shiftstate[0] > 0) || (input->ledstate & (1 << 5)))
412
413#define IS_ALTGR_MODE ((input->ledstate & (1 << 4)) || (input->shiftstate[3] > 0))
414#define IS_NUMLOCK_ON (input->ledstate & LED_NUM)
415#define IS_SCROLLLOCK_ON (input->ledstate & LED_SCR)
416#define IS_CAPSLOCK_ON (input->ledstate & LED_CAP)
417static SDL_WSCONS_input_data *SDL_WSCONS_Init_Keyboard(const char *dev)
418{
419#ifdef WSKBDIO_SETVERSION
420 int version = WSKBDIO_EVENT_VERSION;
421#endif
422 SDL_WSCONS_input_data *input = (SDL_WSCONS_input_data *)SDL_calloc(1, sizeof(SDL_WSCONS_input_data));
423
424 if (!input) {
425 return NULL;
426 }
427
428 input->fd = open(dev, O_RDWR | O_NONBLOCK | O_CLOEXEC);
429 if (input->fd == -1) {
430 SDL_free(input);
431 input = NULL;
432 return NULL;
433 }
434
435 input->keyboardID = SDL_GetNextObjectID();
436 SDL_AddKeyboard(input->keyboardID, NULL, false);
437
438 input->keymap.map = SDL_calloc(KS_NUMKEYCODES, sizeof(struct wscons_keymap));
439 if (!input->keymap.map) {
440 SDL_free(input);
441 return NULL;
442 }
443 input->keymap.maplen = KS_NUMKEYCODES;
444 RETIFIOCTLERR(ioctl(input->fd, WSKBDIO_GETMAP, &input->keymap));
445 RETIFIOCTLERR(ioctl(input->fd, WSKBDIO_GETLEDS, &input->ledstate));
446 input->origledstate = input->ledstate;
447 RETIFIOCTLERR(ioctl(input->fd, WSKBDIO_GETENCODING, &input->encoding));
448 RETIFIOCTLERR(ioctl(input->fd, WSKBDIO_GTYPE, &input->type));
449#ifdef WSKBDIO_SETVERSION
450 RETIFIOCTLERR(ioctl(input->fd, WSKBDIO_SETVERSION, &version));
451#endif
452 return input;
453}
454
455void SDL_WSCONS_Init(void)
456{
457 inputs[0] = SDL_WSCONS_Init_Keyboard("/dev/wskbd0");
458 inputs[1] = SDL_WSCONS_Init_Keyboard("/dev/wskbd1");
459 inputs[2] = SDL_WSCONS_Init_Keyboard("/dev/wskbd2");
460 inputs[3] = SDL_WSCONS_Init_Keyboard("/dev/wskbd3");
461
462 mouseInputData = SDL_WSCONS_Init_Mouse();
463 return;
464}
465
466void SDL_WSCONS_Quit(void)
467{
468 int i = 0;
469 SDL_WSCONS_input_data *input = NULL;
470
471 SDL_WSCONS_Quit_Mouse(mouseInputData);
472 mouseInputData = NULL;
473 for (i = 0; i < 4; i++) {
474 input = inputs[i];
475 if (input) {
476 if (input->fd != -1 && input->fd != 0) {
477 ioctl(input->fd, WSKBDIO_SETLEDS, &input->origledstate);
478 close(input->fd);
479 input->fd = -1;
480 }
481 SDL_free(input);
482 input = NULL;
483 }
484 inputs[i] = NULL;
485 }
486}
487
488static void put_queue(SDL_WSCONS_input_data *kbd, uint c)
489{
490 // c is already part of a UTF-8 sequence and safe to add as a character
491 if (kbd->text_len < (sizeof(kbd->text) - 1)) {
492 kbd->text[kbd->text_len++] = (char)(c);
493 }
494}
495
496static void put_utf8(SDL_WSCONS_input_data *input, uint c)
497{
498 if (c < 0x80)
499 /* 0******* */
500 put_queue(input, c);
501 else if (c < 0x800) {
502 /* 110***** 10****** */
503 put_queue(input, 0xc0 | (c >> 6));
504 put_queue(input, 0x80 | (c & 0x3f));
505 } else if (c < 0x10000) {
506 if (c >= 0xD800 && c <= 0xF500) {
507 return;
508 }
509 if (c == 0xFFFF) {
510 return;
511 }
512 /* 1110**** 10****** 10****** */
513 put_queue(input, 0xe0 | (c >> 12));
514 put_queue(input, 0x80 | ((c >> 6) & 0x3f));
515 put_queue(input, 0x80 | (c & 0x3f));
516 } else if (c < 0x110000) {
517 /* 11110*** 10****** 10****** 10****** */
518 put_queue(input, 0xf0 | (c >> 18));
519 put_queue(input, 0x80 | ((c >> 12) & 0x3f));
520 put_queue(input, 0x80 | ((c >> 6) & 0x3f));
521 put_queue(input, 0x80 | (c & 0x3f));
522 }
523}
524
525static void Translate_to_text(SDL_WSCONS_input_data *input, keysym_t ksym)
526{
527 if (KS_GROUP(ksym) == KS_GROUP_Keypad) {
528 if (SDL_isprint(ksym & 0xFF)) {
529 ksym &= 0xFF;
530 }
531 }
532 switch (ksym) {
533 case KS_Escape:
534 case KS_Delete:
535 case KS_BackSpace:
536 case KS_Return:
537 case KS_Linefeed:
538 // All of these are unprintable characters. Ignore them
539 break;
540 default:
541 put_utf8(input, ksym);
542 break;
543 }
544 if (input->text_len > 0) {
545 input->text[input->text_len] = '\0';
546 SDL_SendKeyboardText(input->text);
547 // SDL_memset(input->text, 0, sizeof(input->text));
548 input->text_len = 0;
549 input->text[0] = 0;
550 }
551}
552
553static void Translate_to_keycode(SDL_WSCONS_input_data *input, int type, keysym_t ksym, Uint64 timestamp)
554{
555 struct wscons_keymap keyDesc = input->keymap.map[ksym];
556 keysym_t *group = &keyDesc.group1[KS_GROUP(keyDesc.group1[0]) == KS_GROUP_Keypad && IS_NUMLOCK_ON ? !IS_SHIFT_HELD : 0];
557 int i = 0;
558
559 // Check command first, then group[0]
560 switch (keyDesc.command) {
561 case KS_Cmd_ScrollBack:
562 {
563 SDL_SendKeyboardKey(timestamp, input->keyboardID, 0, SDL_SCANCODE_PAGEUP, (type == WSCONS_EVENT_KEY_DOWN));
564 return;
565 }
566 case KS_Cmd_ScrollFwd:
567 {
568 SDL_SendKeyboardKey(timestamp, input->keyboardID, 0, SDL_SCANCODE_PAGEDOWN, (type == WSCONS_EVENT_KEY_DOWN));
569 return;
570 }
571 default:
572 break;
573 }
574 for (i = 0; i < SDL_arraysize(conversion_table); i++) {
575 if (conversion_table[i].sourcekey == group[0]) {
576 SDL_SendKeyboardKey(timestamp, input->keyboardID, group[0], conversion_table[i].targetKey, (type == WSCONS_EVENT_KEY_DOWN));
577 return;
578 }
579 }
580 SDL_SendKeyboardKey(timestamp, input->keyboardID, group[0], SDL_SCANCODE_UNKNOWN, (type == WSCONS_EVENT_KEY_DOWN));
581}
582
583static Uint64 GetEventTimestamp(struct timespec *time)
584{
585 // FIXME: Get the event time in the SDL tick time base
586 return SDL_GetTicksNS();
587}
588
589static void updateKeyboard(SDL_WSCONS_input_data *input)
590{
591 struct wscons_event events[64];
592 int type;
593 int n, i, gindex, acc_i;
594 keysym_t *group;
595 keysym_t ksym, result;
596
597 if (!input) {
598 return;
599 }
600 if ((n = read(input->fd, events, sizeof(events))) > 0) {
601 n /= sizeof(struct wscons_event);
602 for (i = 0; i < n; i++) {
603 Uint64 timestamp = GetEventTimestamp(&events[i].time);
604 type = events[i].type;
605 switch (type) {
606 case WSCONS_EVENT_KEY_DOWN:
607 {
608 switch (input->keymap.map[events[i].value].group1[0]) {
609 case KS_Hold_Screen:
610 {
611 if (input->lockheldstate[0] >= 1) {
612 break;
613 }
614 input->ledstate ^= LED_SCR;
615 ioctl(input->fd, WSKBDIO_SETLEDS, &input->ledstate);
616 input->lockheldstate[0] = 1;
617 break;
618 }
619 case KS_Num_Lock:
620 {
621 if (input->lockheldstate[1] >= 1) {
622 break;
623 }
624 input->ledstate ^= LED_NUM;
625 ioctl(input->fd, WSKBDIO_SETLEDS, &input->ledstate);
626 input->lockheldstate[1] = 1;
627 break;
628 }
629 case KS_Caps_Lock:
630 {
631 if (input->lockheldstate[2] >= 1) {
632 break;
633 }
634 input->ledstate ^= LED_CAP;
635 ioctl(input->fd, WSKBDIO_SETLEDS, &input->ledstate);
636 input->lockheldstate[2] = 1;
637 break;
638 }
639#ifndef SDL_PLATFORM_NETBSD
640 case KS_Mode_Lock:
641 {
642 if (input->lockheldstate[3] >= 1) {
643 break;
644 }
645 input->ledstate ^= 1 << 4;
646 ioctl(input->fd, WSKBDIO_SETLEDS, &input->ledstate);
647 input->lockheldstate[3] = 1;
648 break;
649 }
650#endif
651 case KS_Shift_Lock:
652 {
653 if (input->lockheldstate[4] >= 1) {
654 break;
655 }
656 input->ledstate ^= 1 << 5;
657 ioctl(input->fd, WSKBDIO_SETLEDS, &input->ledstate);
658 input->lockheldstate[4] = 1;
659 break;
660 }
661 case KS_Shift_L:
662 {
663 if (input->shiftheldstate[0]) {
664 break;
665 }
666 input->shiftstate[0]++;
667 input->shiftheldstate[0] = 1;
668 break;
669 }
670 case KS_Shift_R:
671 {
672 if (input->shiftheldstate[1]) {
673 break;
674 }
675 input->shiftstate[0]++;
676 input->shiftheldstate[1] = 1;
677 break;
678 }
679 case KS_Alt_L:
680 {
681 if (input->shiftheldstate[2]) {
682 break;
683 }
684 input->shiftstate[1]++;
685 input->shiftheldstate[2] = 1;
686 break;
687 }
688 case KS_Alt_R:
689 {
690 if (input->shiftheldstate[3]) {
691 break;
692 }
693 input->shiftstate[1]++;
694 input->shiftheldstate[3] = 1;
695 break;
696 }
697 case KS_Control_L:
698 {
699 if (input->shiftheldstate[4]) {
700 break;
701 }
702 input->shiftstate[2]++;
703 input->shiftheldstate[4] = 1;
704 break;
705 }
706 case KS_Control_R:
707 {
708 if (input->shiftheldstate[5]) {
709 break;
710 }
711 input->shiftstate[2]++;
712 input->shiftheldstate[5] = 1;
713 break;
714 }
715 case KS_Mode_switch:
716 {
717 if (input->shiftheldstate[6]) {
718 break;
719 }
720 input->shiftstate[3]++;
721 input->shiftheldstate[6] = 1;
722 break;
723 }
724 }
725 } break;
726 case WSCONS_EVENT_KEY_UP:
727 {
728 switch (input->keymap.map[events[i].value].group1[0]) {
729 case KS_Hold_Screen:
730 {
731 if (input->lockheldstate[0]) {
732 input->lockheldstate[0] = 0;
733 }
734 } break;
735 case KS_Num_Lock:
736 {
737 if (input->lockheldstate[1]) {
738 input->lockheldstate[1] = 0;
739 }
740 } break;
741 case KS_Caps_Lock:
742 {
743 if (input->lockheldstate[2]) {
744 input->lockheldstate[2] = 0;
745 }
746 } break;
747#ifndef SDL_PLATFORM_NETBSD
748 case KS_Mode_Lock:
749 {
750 if (input->lockheldstate[3]) {
751 input->lockheldstate[3] = 0;
752 }
753 } break;
754#endif
755 case KS_Shift_Lock:
756 {
757 if (input->lockheldstate[4]) {
758 input->lockheldstate[4] = 0;
759 }
760 } break;
761 case KS_Shift_L:
762 {
763 input->shiftheldstate[0] = 0;
764 if (input->shiftstate[0]) {
765 input->shiftstate[0]--;
766 }
767 break;
768 }
769 case KS_Shift_R:
770 {
771 input->shiftheldstate[1] = 0;
772 if (input->shiftstate[0]) {
773 input->shiftstate[0]--;
774 }
775 break;
776 }
777 case KS_Alt_L:
778 {
779 input->shiftheldstate[2] = 0;
780 if (input->shiftstate[1]) {
781 input->shiftstate[1]--;
782 }
783 break;
784 }
785 case KS_Alt_R:
786 {
787 input->shiftheldstate[3] = 0;
788 if (input->shiftstate[1]) {
789 input->shiftstate[1]--;
790 }
791 break;
792 }
793 case KS_Control_L:
794 {
795 input->shiftheldstate[4] = 0;
796 if (input->shiftstate[2]) {
797 input->shiftstate[2]--;
798 }
799 break;
800 }
801 case KS_Control_R:
802 {
803 input->shiftheldstate[5] = 0;
804 if (input->shiftstate[2]) {
805 input->shiftstate[2]--;
806 }
807 break;
808 }
809 case KS_Mode_switch:
810 {
811 input->shiftheldstate[6] = 0;
812 if (input->shiftstate[3]) {
813 input->shiftstate[3]--;
814 }
815 break;
816 }
817 }
818 } break;
819 case WSCONS_EVENT_ALL_KEYS_UP:
820 for (i = 0; i < SDL_SCANCODE_COUNT; i++) {
821 SDL_SendKeyboardKey(timestamp, input->keyboardID, 0, (SDL_Scancode)i, false);
822 }
823 break;
824 default:
825 break;
826 }
827
828 if (input->type == WSKBD_TYPE_USB && events[i].value <= 0xE7) {
829 SDL_SendKeyboardKey(timestamp, input->keyboardID, 0, (SDL_Scancode)events[i].value, (type == WSCONS_EVENT_KEY_DOWN));
830 } else {
831 Translate_to_keycode(input, type, events[i].value, timestamp);
832 }
833
834 if (type == WSCONS_EVENT_KEY_UP) {
835 continue;
836 }
837
838 if (IS_ALTGR_MODE && !IS_CONTROL_HELD)
839 group = &input->keymap.map[events[i].value].group2[0];
840 else
841 group = &input->keymap.map[events[i].value].group1[0];
842
843 if (IS_NUMLOCK_ON && KS_GROUP(group[1]) == KS_GROUP_Keypad) {
844 gindex = !IS_SHIFT_HELD;
845 ksym = group[gindex];
846 } else {
847 if (IS_CAPSLOCK_ON && !IS_SHIFT_HELD) {
848 gindex = 0;
849 ksym = ksym_upcase(group[0]);
850 } else {
851 gindex = IS_SHIFT_HELD;
852 ksym = group[gindex];
853 }
854 }
855 result = KS_voidSymbol;
856
857 switch (KS_GROUP(ksym)) {
858 case KS_GROUP_Ascii:
859 case KS_GROUP_Keypad:
860 case KS_GROUP_Function:
861 result = ksym;
862 break;
863 case KS_GROUP_Mod:
864 if (ksym == KS_Multi_key) {
865 input->ledstate |= WSKBD_LED_COMPOSE;
866 ioctl(input->fd, WSKBDIO_SETLEDS, &input->ledstate);
867 input->composelen = 2;
868 input->composebuffer[0] = input->composebuffer[1] = 0;
869 }
870 break;
871 case KS_GROUP_Dead:
872 if (input->composelen == 0) {
873 input->ledstate |= WSKBD_LED_COMPOSE;
874 ioctl(input->fd, WSKBDIO_SETLEDS, &input->ledstate);
875 input->composelen = 1;
876 input->composebuffer[0] = ksym;
877 input->composebuffer[1] = 0;
878 } else
879 result = ksym;
880 break;
881 }
882 if (result == KS_voidSymbol) {
883 continue;
884 }
885
886 if (input->composelen > 0) {
887 if (input->composelen == 2 && group == &input->keymap.map[events[i].value].group2[0]) {
888 if (input->keymap.map[events[i].value].group2[gindex] == input->keymap.map[events[i].value].group1[gindex]) {
889 input->composelen = 0;
890 input->composebuffer[0] = input->composebuffer[1] = 0;
891 }
892 }
893
894 if (input->composelen != 0) {
895 input->composebuffer[2 - input->composelen] = result;
896 if (--input->composelen == 0) {
897 result = KS_voidSymbol;
898 input->ledstate &= ~WSKBD_LED_COMPOSE;
899 ioctl(input->fd, WSKBDIO_SETLEDS, &input->ledstate);
900 for (acc_i = 0; acc_i < SDL_arraysize(compose_tab); acc_i++) {
901 if ((compose_tab[acc_i].elem[0] == input->composebuffer[0] && compose_tab[acc_i].elem[1] == input->composebuffer[1]) || (compose_tab[acc_i].elem[0] == input->composebuffer[1] && compose_tab[acc_i].elem[1] == input->composebuffer[0])) {
902 result = compose_tab[acc_i].result;
903 break;
904 }
905 }
906 } else
907 continue;
908 }
909 }
910
911 if (KS_GROUP(result) == KS_GROUP_Ascii) {
912 if (IS_CONTROL_HELD) {
913 if ((result >= KS_at && result <= KS_z) || result == KS_space) {
914 result = result & 0x1f;
915 } else if (result == KS_2) {
916 result = 0x00;
917 } else if (result >= KS_3 && result <= KS_7) {
918 result = KS_Escape + (result - KS_3);
919 } else if (result == KS_8) {
920 result = KS_Delete;
921 }
922 }
923 if (IS_ALT_HELD) {
924 if (input->encoding & KB_METAESC) {
925 Translate_to_keycode(input, WSCONS_EVENT_KEY_DOWN, KS_Escape, 0);
926 Translate_to_text(input, result);
927 continue;
928 } else {
929 result |= 0x80;
930 }
931 }
932 }
933 Translate_to_text(input, result);
934 continue;
935 }
936 }
937}
938
939void SDL_WSCONS_PumpEvents(void)
940{
941 int i = 0;
942 for (i = 0; i < 4; i++) {
943 updateKeyboard(inputs[i]);
944 }
945 if (mouseInputData) {
946 updateMouse(mouseInputData);
947 }
948}
diff --git a/contrib/SDL-3.2.8/src/core/openbsd/SDL_wscons_mouse.c b/contrib/SDL-3.2.8/src/core/openbsd/SDL_wscons_mouse.c
new file mode 100644
index 0000000..51195f3
--- /dev/null
+++ b/contrib/SDL-3.2.8/src/core/openbsd/SDL_wscons_mouse.c
@@ -0,0 +1,127 @@
1/*
2 Simple DirectMedia Layer
3 Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
4
5 This software is provided 'as-is', without any express or implied
6 warranty. In no event will the authors be held liable for any damages
7 arising from the use of this software.
8
9 Permission is granted to anyone to use this software for any purpose,
10 including commercial applications, and to alter it and redistribute it
11 freely, subject to the following restrictions:
12
13 1. The origin of this software must not be misrepresented; you must not
14 claim that you wrote the original software. If you use this software
15 in a product, an acknowledgment in the product documentation would be
16 appreciated but is not required.
17 2. Altered source versions must be plainly marked as such, and must not be
18 misrepresented as being the original software.
19 3. This notice may not be removed or altered from any source distribution.
20*/
21
22#include "SDL_internal.h"
23#include <sys/time.h>
24#include <dev/wscons/wsconsio.h>
25#include <unistd.h>
26#include <sys/ioctl.h>
27#include <stdlib.h>
28#include <fcntl.h>
29
30#include "../../events/SDL_mouse_c.h"
31
32typedef struct SDL_WSCONS_mouse_input_data
33{
34 int fd;
35 SDL_MouseID mouseID;
36} SDL_WSCONS_mouse_input_data;
37
38SDL_WSCONS_mouse_input_data *SDL_WSCONS_Init_Mouse(void)
39{
40#ifdef WSMOUSEIO_SETVERSION
41 int version = WSMOUSE_EVENT_VERSION;
42#endif
43 SDL_WSCONS_mouse_input_data *input = SDL_calloc(1, sizeof(SDL_WSCONS_mouse_input_data));
44
45 if (!input) {
46 return NULL;
47 }
48 input->fd = open("/dev/wsmouse", O_RDWR | O_NONBLOCK | O_CLOEXEC);
49 if (input->fd == -1) {
50 SDL_free(input);
51 return NULL;
52 }
53
54 input->mouseID = SDL_GetNextObjectID();
55 SDL_AddMouse(input->mouseID, NULL, false);
56
57#ifdef WSMOUSEIO_SETMODE
58 ioctl(input->fd, WSMOUSEIO_SETMODE, WSMOUSE_COMPAT);
59#endif
60#ifdef WSMOUSEIO_SETVERSION
61 ioctl(input->fd, WSMOUSEIO_SETVERSION, &version);
62#endif
63 return input;
64}
65
66static Uint64 GetEventTimestamp(struct timespec *time)
67{
68 // FIXME: Get the event time in the SDL tick time base
69 return SDL_GetTicksNS();
70}
71
72void updateMouse(SDL_WSCONS_mouse_input_data *input)
73{
74 struct wscons_event events[64];
75 int n;
76 SDL_Mouse *mouse = SDL_GetMouse();
77
78 if ((n = read(input->fd, events, sizeof(events))) > 0) {
79 int i;
80 n /= sizeof(struct wscons_event);
81 for (i = 0; i < n; i++) {
82 Uint64 timestamp = GetEventTimestamp(&events[i].time);
83 int type = events[i].type;
84 switch (type) {
85 case WSCONS_EVENT_MOUSE_DOWN:
86 case WSCONS_EVENT_MOUSE_UP:
87 {
88 Uint8 button = SDL_BUTTON_LEFT + events[i].value;
89 bool down = (type == WSCONS_EVENT_MOUSE_DOWN);
90 SDL_SendMouseButton(timestamp, mouse->focus, input->mouseID, button, down);
91 break;
92 }
93 case WSCONS_EVENT_MOUSE_DELTA_X:
94 {
95 SDL_SendMouseMotion(timestamp, mouse->focus, input->mouseID, true, (float)events[i].value, 0.0f);
96 break;
97 }
98 case WSCONS_EVENT_MOUSE_DELTA_Y:
99 {
100 SDL_SendMouseMotion(timestamp, mouse->focus, input->mouseID, true, 0.0f, -(float)events[i].value);
101 break;
102 }
103 case WSCONS_EVENT_MOUSE_DELTA_W:
104 {
105 SDL_SendMouseWheel(timestamp, mouse->focus, input->mouseID, events[i].value, 0, SDL_MOUSEWHEEL_NORMAL);
106 break;
107 }
108 case WSCONS_EVENT_MOUSE_DELTA_Z:
109 {
110 SDL_SendMouseWheel(timestamp, mouse->focus, input->mouseID, 0, -events[i].value, SDL_MOUSEWHEEL_NORMAL);
111 break;
112 }
113 default:
114 break;
115 }
116 }
117 }
118}
119
120void SDL_WSCONS_Quit_Mouse(SDL_WSCONS_mouse_input_data *input)
121{
122 if (!input) {
123 return;
124 }
125 close(input->fd);
126 SDL_free(input);
127}