limited minimize support
[sdl_omap.git] / src / video / omapdss / osdl_input.c
CommitLineData
b78828bf 1/*
b260fb56 2 * (C) Gražvydas "notaz" Ignotas, 2010-2012
b78828bf 3 *
4 * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
5 * See the COPYING file in the top-level directory.
6 */
7
3cb98c5e 8#include <strings.h>
83b5751b 9#include <sys/types.h>
10#include <sys/stat.h>
11#include <fcntl.h>
12#include <sys/ioctl.h>
13#include <unistd.h>
14#include <time.h>
15#include <errno.h>
3cb98c5e 16#include <linux/input.h>
b983f171 17#ifdef STANDALONE
83b5751b 18#include <SDL/SDL.h>
b983f171 19#else
20#include "SDL.h"
21#endif
17e19802 22#if SDL_INPUT_TSLIB
23#include <tslib.h>
24#endif
3cb98c5e 25
9ab462cd 26#include "osdl.h"
3cb98c5e 27
17e19802 28/* XXX: these should go to private data */
83b5751b 29static int osdl_evdev_devs[32];
30static int osdl_evdev_dev_count;
17e19802 31static int osdl_tslib_fd;
32static struct tsdev *osdl_tslib_dev;
83b5751b 33
34static short osdl_evdev_map[KEY_CNT] = {
6f13ad97 35 /* normal fn */
36 [KEY_0] = SDLK_0, [KEY_F10] = SDLK_F10,
37 [KEY_1] = SDLK_1, [KEY_F1] = SDLK_F1,
38 [KEY_2] = SDLK_2, [KEY_F2] = SDLK_F2,
39 [KEY_3] = SDLK_3, [KEY_F3] = SDLK_F3,
40 [KEY_4] = SDLK_4, [KEY_F4] = SDLK_F4,
41 [KEY_5] = SDLK_5, [KEY_F5] = SDLK_F5,
42 [KEY_6] = SDLK_6, [KEY_F6] = SDLK_F6,
43 [KEY_7] = SDLK_7, [KEY_F7] = SDLK_F7,
44 [KEY_8] = SDLK_8, [KEY_F8] = SDLK_F8,
45 [KEY_9] = SDLK_9, [KEY_F9] = SDLK_F9,
46 [KEY_A] = SDLK_a, [KEY_APOSTROPHE]= SDLK_QUOTE, /* ' */
47 [KEY_B] = SDLK_b, [KEY_F14] = 124, /* | */
48 [KEY_C] = SDLK_c, [KEY_BACKSLASH] = SDLK_BACKSLASH, /* \ */
49 [KEY_D] = SDLK_d, [KEY_KPMINUS] = SDLK_MINUS,
50 [KEY_E] = SDLK_e, [KEY_LEFTBRACE] = SDLK_LEFTPAREN,
51 [KEY_F] = SDLK_f, [KEY_KPPLUS] = SDLK_PLUS,
52 [KEY_G] = SDLK_g, [KEY_EQUAL] = SDLK_EQUALS,
53 [KEY_H] = SDLK_h, [KEY_GRAVE] = SDLK_BACKQUOTE, /* ` */
54 [KEY_I] = SDLK_i, /* [KEY_BRIGHTNESSUP] */
bade64ac 55 [KEY_J] = SDLK_j, [KEY_F13] = SDLK_WORLD_4, /* ’ (not on def SDL) */
56 [KEY_K] = SDLK_k, [KEY_F18] = SDLK_WORLD_3, /* £ (pound) */
57 [KEY_L] = SDLK_l, [KEY_YEN] = SDLK_WORLD_5,
6f13ad97 58 [KEY_M] = SDLK_m, [KEY_F23] = SDLK_EURO,
59 [KEY_N] = SDLK_n, [KEY_F22] = SDLK_DOLLAR, /* $ */
60 [KEY_O] = SDLK_o, [KEY_F11] = SDLK_F11,
61 [KEY_P] = SDLK_p, [KEY_F12] = SDLK_F12,
62 [KEY_Q] = SDLK_q, [KEY_ESC] = SDLK_ESCAPE,
63 [KEY_R] = SDLK_r, [KEY_RIGHTBRACE]= SDLK_RIGHTPAREN,
64 [KEY_S] = SDLK_s, [KEY_F19] = SDLK_QUOTEDBL, /* " */
65 [KEY_T] = SDLK_t, [KEY_F17] = SDLK_EXCLAIM, /* ! */
66 [KEY_U] = SDLK_u, /* [KEY_BRIGHTNESSDOWN] */
67 [KEY_V] = SDLK_v, [KEY_F16] = SDLK_HASH, /* # (pound/hash) */
68 [KEY_W] = SDLK_w, [KEY_F20] = SDLK_AT, /* @ */
69 [KEY_X] = SDLK_x, [KEY_QUESTION] = SDLK_QUESTION, /* ? */
70 [KEY_Y] = SDLK_y, [KEY_F15] = SDLK_UNDERSCORE,/* _ */
71 [KEY_Z] = SDLK_z, [KEY_SLASH] = SDLK_SLASH, /* / */
72 [KEY_SPACE] = SDLK_SPACE, [KEY_TAB] = SDLK_TAB,
73 [KEY_BACKSPACE] = SDLK_BACKSPACE, [KEY_INSERT] = SDLK_INSERT,
0f77a259 74 [KEY_FN] = SDLK_WORLD_95,
6f13ad97 75 [KEY_DOT] = SDLK_PERIOD, [KEY_F21] = SDLK_COLON, /* : */
76 [KEY_ENTER] = SDLK_RETURN,
77 [KEY_LEFTSHIFT] = SDLK_LSHIFT, [KEY_CAPSLOCK] = SDLK_CAPSLOCK,
78 [KEY_COMMA] = SDLK_COMMA, [KEY_SEMICOLON] = SDLK_SEMICOLON, /* ; */
3cb98c5e 79
80 [KEY_UP] = SDLK_UP,
81 [KEY_DOWN] = SDLK_DOWN,
82 [KEY_LEFT] = SDLK_LEFT,
83 [KEY_RIGHT] = SDLK_RIGHT,
84 [KEY_HOME] = SDLK_HOME,
85 [KEY_END] = SDLK_END,
86 [KEY_PAGEUP] = SDLK_PAGEUP,
87 [KEY_PAGEDOWN] = SDLK_PAGEDOWN,
88 [KEY_LEFTALT] = SDLK_LALT,
89 [KEY_LEFTCTRL] = SDLK_LCTRL,
6f13ad97 90 [KEY_MENU] = 147, /* match default SDL here */
3cb98c5e 91 [KEY_RIGHTSHIFT]= SDLK_RSHIFT,
92 [KEY_RIGHTCTRL] = SDLK_RCTRL,
93};
94
83b5751b 95static const char * const osdl_evdev_keys[KEY_CNT] = {
96 [KEY_RESERVED] = "Reserved", [KEY_ESC] = "Esc",
97 [KEY_1] = "1", [KEY_2] = "2",
98 [KEY_3] = "3", [KEY_4] = "4",
99 [KEY_5] = "5", [KEY_6] = "6",
100 [KEY_7] = "7", [KEY_8] = "8",
101 [KEY_9] = "9", [KEY_0] = "0",
102 [KEY_MINUS] = "Minus", [KEY_EQUAL] = "Equal",
103 [KEY_BACKSPACE] = "Backspace", [KEY_TAB] = "Tab",
104 [KEY_Q] = "Q", [KEY_W] = "W",
105 [KEY_E] = "E", [KEY_R] = "R",
106 [KEY_T] = "T", [KEY_Y] = "Y",
107 [KEY_U] = "U", [KEY_I] = "I",
108 [KEY_O] = "O", [KEY_P] = "P",
109 [KEY_LEFTBRACE] = "LeftBrace", [KEY_RIGHTBRACE] = "RightBrace",
110 [KEY_ENTER] = "Enter", [KEY_LEFTCTRL] = "LeftControl",
111 [KEY_A] = "A", [KEY_S] = "S",
112 [KEY_D] = "D", [KEY_F] = "F",
113 [KEY_G] = "G", [KEY_H] = "H",
114 [KEY_J] = "J", [KEY_K] = "K",
115 [KEY_L] = "L", [KEY_SEMICOLON] = "Semicolon",
116 [KEY_APOSTROPHE] = "Apostrophe", [KEY_GRAVE] = "Grave",
117 [KEY_LEFTSHIFT] = "LeftShift", [KEY_BACKSLASH] = "BackSlash",
118 [KEY_Z] = "Z", [KEY_X] = "X",
119 [KEY_C] = "C", [KEY_V] = "V",
120 [KEY_B] = "B", [KEY_N] = "N",
121 [KEY_M] = "M", [KEY_COMMA] = "Comma",
122 [KEY_DOT] = "Dot", [KEY_SLASH] = "Slash",
123 [KEY_RIGHTSHIFT] = "RightShift", [KEY_KPASTERISK] = "KPAsterisk",
124 [KEY_LEFTALT] = "LeftAlt", [KEY_SPACE] = "Space",
125 [KEY_CAPSLOCK] = "CapsLock", [KEY_F1] = "F1",
126 [KEY_F2] = "F2", [KEY_F3] = "F3",
127 [KEY_F4] = "F4", [KEY_F5] = "F5",
128 [KEY_F6] = "F6", [KEY_F7] = "F7",
129 [KEY_F8] = "F8", [KEY_F9] = "F9",
130 [KEY_F10] = "F10", [KEY_NUMLOCK] = "NumLock",
131 [KEY_SCROLLLOCK] = "ScrollLock", [KEY_KP7] = "KP7",
132 [KEY_KP8] = "KP8", [KEY_KP9] = "KP9",
133 [KEY_KPMINUS] = "KPMinus", [KEY_KP4] = "KP4",
134 [KEY_KP5] = "KP5", [KEY_KP6] = "KP6",
135 [KEY_KPPLUS] = "KPPlus", [KEY_KP1] = "KP1",
136 [KEY_KP2] = "KP2", [KEY_KP3] = "KP3",
137 [KEY_KP0] = "KP0", [KEY_KPDOT] = "KPDot",
138 [KEY_ZENKAKUHANKAKU] = "Zenkaku/Hankaku", [KEY_102ND] = "102nd",
139 [KEY_F11] = "F11", [KEY_F12] = "F12",
140 [KEY_KPJPCOMMA] = "KPJpComma", [KEY_KPENTER] = "KPEnter",
141 [KEY_RIGHTCTRL] = "RightCtrl", [KEY_KPSLASH] = "KPSlash",
142 [KEY_SYSRQ] = "SysRq", [KEY_RIGHTALT] = "RightAlt",
143 [KEY_LINEFEED] = "LineFeed", [KEY_HOME] = "Home",
144 [KEY_UP] = "Up", [KEY_PAGEUP] = "PageUp",
145 [KEY_LEFT] = "Left", [KEY_RIGHT] = "Right",
146 [KEY_END] = "End", [KEY_DOWN] = "Down",
147 [KEY_PAGEDOWN] = "PageDown", [KEY_INSERT] = "Insert",
148 [KEY_DELETE] = "Delete", [KEY_MACRO] = "Macro",
149 [KEY_HELP] = "Help", [KEY_MENU] = "Menu",
150 [KEY_COFFEE] = "Coffee", [KEY_DIRECTION] = "Direction",
151 [BTN_0] = "Btn0", [BTN_1] = "Btn1",
152 [BTN_2] = "Btn2", [BTN_3] = "Btn3",
153 [BTN_4] = "Btn4", [BTN_5] = "Btn5",
154 [BTN_6] = "Btn6", [BTN_7] = "Btn7",
155 [BTN_8] = "Btn8", [BTN_9] = "Btn9",
156 [BTN_LEFT] = "LeftBtn", [BTN_RIGHT] = "RightBtn",
157 [BTN_MIDDLE] = "MiddleBtn", [BTN_SIDE] = "SideBtn",
158 [BTN_EXTRA] = "ExtraBtn", [BTN_FORWARD] = "ForwardBtn",
159 [BTN_BACK] = "BackBtn", [BTN_TASK] = "TaskBtn",
160 [BTN_TRIGGER] = "Trigger", [BTN_THUMB] = "ThumbBtn",
161 [BTN_THUMB2] = "ThumbBtn2", [BTN_TOP] = "TopBtn",
162 [BTN_TOP2] = "TopBtn2", [BTN_PINKIE] = "PinkieBtn",
163 [BTN_BASE] = "BaseBtn", [BTN_BASE2] = "BaseBtn2",
164 [BTN_BASE3] = "BaseBtn3", [BTN_BASE4] = "BaseBtn4",
165 [BTN_BASE5] = "BaseBtn5", [BTN_BASE6] = "BaseBtn6",
166 [BTN_DEAD] = "BtnDead", [BTN_A] = "BtnA",
167 [BTN_B] = "BtnB", [BTN_C] = "BtnC",
168 [BTN_X] = "BtnX", [BTN_Y] = "BtnY",
169 [BTN_Z] = "BtnZ", [BTN_TL] = "BtnTL",
170 [BTN_TR] = "BtnTR", [BTN_TL2] = "BtnTL2",
171 [BTN_TR2] = "BtnTR2", [BTN_SELECT] = "BtnSelect",
172 [BTN_START] = "BtnStart", [BTN_MODE] = "BtnMode",
173 [BTN_THUMBL] = "BtnThumbL", [BTN_THUMBR] = "BtnThumbR",
174 [BTN_TOUCH] = "Touch", [BTN_STYLUS] = "Stylus",
175 [BTN_STYLUS2] = "Stylus2", [BTN_TOOL_DOUBLETAP] = "Tool Doubletap",
176 [BTN_TOOL_TRIPLETAP] = "Tool Tripletap", [BTN_GEAR_DOWN] = "WheelBtn",
177 [BTN_GEAR_UP] = "Gear up", [KEY_OK] = "Ok",
178};
179
3cb98c5e 180#define DNKEY(x) [SDLK_##x] = #x
83b5751b 181static const char * const sdl_keynames[SDLK_LAST] = {
3cb98c5e 182 DNKEY(BACKSPACE),
183 DNKEY(TAB),
184 DNKEY(RETURN),
185 DNKEY(ESCAPE),
186 DNKEY(SPACE),
187 DNKEY(EXCLAIM),
188 DNKEY(QUOTEDBL),
189 DNKEY(HASH),
190 DNKEY(DOLLAR),
191 DNKEY(AMPERSAND),
192 DNKEY(QUOTE),
193 DNKEY(LEFTPAREN),
194 DNKEY(RIGHTPAREN),
195 DNKEY(ASTERISK),
196 DNKEY(PLUS),
197 DNKEY(COMMA),
198 DNKEY(MINUS),
199 DNKEY(PERIOD),
200 DNKEY(SLASH),
201 DNKEY(0),
202 DNKEY(1),
203 DNKEY(2),
204 DNKEY(3),
205 DNKEY(4),
206 DNKEY(5),
207 DNKEY(6),
208 DNKEY(7),
209 DNKEY(8),
210 DNKEY(9),
211 DNKEY(COLON),
212 DNKEY(SEMICOLON),
213 DNKEY(LESS),
214 DNKEY(EQUALS),
215 DNKEY(GREATER),
216 DNKEY(QUESTION),
217 DNKEY(AT),
218 DNKEY(LEFTBRACKET),
219 DNKEY(BACKSLASH),
220 DNKEY(RIGHTBRACKET),
221 DNKEY(CARET),
222 DNKEY(UNDERSCORE),
223 DNKEY(BACKQUOTE),
224 DNKEY(a),
225 DNKEY(b),
226 DNKEY(c),
227 DNKEY(d),
228 DNKEY(e),
229 DNKEY(f),
230 DNKEY(g),
231 DNKEY(h),
232 DNKEY(i),
233 DNKEY(j),
234 DNKEY(k),
235 DNKEY(l),
236 DNKEY(m),
237 DNKEY(n),
238 DNKEY(o),
239 DNKEY(p),
240 DNKEY(q),
241 DNKEY(r),
242 DNKEY(s),
243 DNKEY(t),
244 DNKEY(u),
245 DNKEY(v),
246 DNKEY(w),
247 DNKEY(x),
248 DNKEY(y),
249 DNKEY(z),
250 DNKEY(DELETE),
251 DNKEY(WORLD_0),
252 DNKEY(WORLD_1),
253 DNKEY(WORLD_2),
254 DNKEY(WORLD_3),
255 DNKEY(WORLD_4),
256 DNKEY(WORLD_5),
257 DNKEY(WORLD_6),
258 DNKEY(WORLD_7),
259 DNKEY(WORLD_8),
260 DNKEY(WORLD_9),
261 DNKEY(WORLD_10),
262 DNKEY(WORLD_11),
263 DNKEY(WORLD_12),
264 DNKEY(WORLD_13),
265 DNKEY(WORLD_14),
266 DNKEY(WORLD_15),
267 DNKEY(WORLD_16),
268 DNKEY(WORLD_17),
269 DNKEY(WORLD_18),
270 DNKEY(WORLD_19),
271 DNKEY(WORLD_20),
272 DNKEY(WORLD_21),
273 DNKEY(WORLD_22),
274 DNKEY(WORLD_23),
275 DNKEY(WORLD_24),
276 DNKEY(WORLD_25),
277 DNKEY(WORLD_26),
278 DNKEY(WORLD_27),
279 DNKEY(WORLD_28),
280 DNKEY(WORLD_29),
281 DNKEY(WORLD_30),
282 DNKEY(WORLD_31),
283 DNKEY(WORLD_32),
284 DNKEY(WORLD_33),
285 DNKEY(WORLD_34),
286 DNKEY(WORLD_35),
287 DNKEY(WORLD_36),
288 DNKEY(WORLD_37),
289 DNKEY(WORLD_38),
290 DNKEY(WORLD_39),
291 DNKEY(WORLD_40),
292 DNKEY(WORLD_41),
293 DNKEY(WORLD_42),
294 DNKEY(WORLD_43),
295 DNKEY(WORLD_44),
296 DNKEY(WORLD_45),
297 DNKEY(WORLD_46),
298 DNKEY(WORLD_47),
299 DNKEY(WORLD_48),
300 DNKEY(WORLD_49),
301 DNKEY(WORLD_50),
302 DNKEY(WORLD_51),
303 DNKEY(WORLD_52),
304 DNKEY(WORLD_53),
305 DNKEY(WORLD_54),
306 DNKEY(WORLD_55),
307 DNKEY(WORLD_56),
308 DNKEY(WORLD_57),
309 DNKEY(WORLD_58),
310 DNKEY(WORLD_59),
311 DNKEY(WORLD_60),
312 DNKEY(WORLD_61),
313 DNKEY(WORLD_62),
314 DNKEY(WORLD_63),
315 DNKEY(WORLD_64),
316 DNKEY(WORLD_65),
317 DNKEY(WORLD_66),
318 DNKEY(WORLD_67),
319 DNKEY(WORLD_68),
320 DNKEY(WORLD_69),
321 DNKEY(WORLD_70),
322 DNKEY(WORLD_71),
323 DNKEY(WORLD_72),
324 DNKEY(WORLD_73),
325 DNKEY(WORLD_74),
326 DNKEY(WORLD_75),
327 DNKEY(WORLD_76),
328 DNKEY(WORLD_77),
329 DNKEY(WORLD_78),
330 DNKEY(WORLD_79),
331 DNKEY(WORLD_80),
332 DNKEY(WORLD_81),
333 DNKEY(WORLD_82),
334 DNKEY(WORLD_83),
335 DNKEY(WORLD_84),
336 DNKEY(WORLD_85),
337 DNKEY(WORLD_86),
338 DNKEY(WORLD_87),
339 DNKEY(WORLD_88),
340 DNKEY(WORLD_89),
341 DNKEY(WORLD_90),
342 DNKEY(WORLD_91),
343 DNKEY(WORLD_92),
344 DNKEY(WORLD_93),
345 DNKEY(WORLD_94),
346 DNKEY(WORLD_95),
347 DNKEY(KP0),
348 DNKEY(KP1),
349 DNKEY(KP2),
350 DNKEY(KP3),
351 DNKEY(KP4),
352 DNKEY(KP5),
353 DNKEY(KP6),
354 DNKEY(KP7),
355 DNKEY(KP8),
356 DNKEY(KP9),
357 DNKEY(KP_PERIOD),
358 DNKEY(KP_DIVIDE),
359 DNKEY(KP_MULTIPLY),
360 DNKEY(KP_MINUS),
361 DNKEY(KP_PLUS),
362 DNKEY(KP_ENTER),
363 DNKEY(KP_EQUALS),
364 DNKEY(UP),
365 DNKEY(DOWN),
366 DNKEY(RIGHT),
367 DNKEY(LEFT),
368 DNKEY(INSERT),
369 DNKEY(HOME),
370 DNKEY(END),
371 DNKEY(PAGEUP),
372 DNKEY(PAGEDOWN),
373 DNKEY(F1),
374 DNKEY(F2),
375 DNKEY(F3),
376 DNKEY(F4),
377 DNKEY(F5),
378 DNKEY(F6),
379 DNKEY(F7),
380 DNKEY(F8),
381 DNKEY(F9),
382 DNKEY(F10),
383 DNKEY(F11),
384 DNKEY(F12),
385 DNKEY(F13),
386 DNKEY(F14),
387 DNKEY(F15),
388 DNKEY(NUMLOCK),
389 DNKEY(CAPSLOCK),
390 DNKEY(SCROLLOCK),
391 DNKEY(RSHIFT),
392 DNKEY(LSHIFT),
393 DNKEY(RCTRL),
394 DNKEY(LCTRL),
395 DNKEY(RALT),
396 DNKEY(LALT),
397 DNKEY(RMETA),
398 DNKEY(LMETA),
399 DNKEY(LSUPER),
400 DNKEY(RSUPER),
401 DNKEY(MODE),
402 DNKEY(COMPOSE),
403};
404
b78828bf 405void omapsdl_input_bind(const char *kname, const char *sdlname)
3cb98c5e 406{
407 int i, kc;
408
83b5751b 409 if (kname == NULL || strncasecmp(kname, "ev_", 3) != 0)
410 goto bad_ev_key;
411
412 for (i = 0; i < ARRAY_SIZE(osdl_evdev_keys); i++) {
413 if (osdl_evdev_keys[i] == NULL)
414 continue;
415 if (strcasecmp(osdl_evdev_keys[i], kname + 3) == 0)
416 break;
3cb98c5e 417 }
418
83b5751b 419 if (i >= ARRAY_SIZE(osdl_evdev_keys))
420 goto bad_ev_key;
421 kc = i;
422
3cb98c5e 423 if (sdlname == NULL || strncasecmp(sdlname, "SDLK_", 5) != 0)
424 goto bad_sdlkey;
425
83b5751b 426 for (i = 0; i < ARRAY_SIZE(sdl_keynames); i++) {
3cb98c5e 427 if (sdl_keynames[i] == NULL)
428 continue;
429 if (strcasecmp(sdl_keynames[i], sdlname + 5) == 0)
430 break;
431 }
432
83b5751b 433 if (i >= ARRAY_SIZE(sdl_keynames))
3cb98c5e 434 goto bad_sdlkey;
435
83b5751b 436 osdl_evdev_map[kc] = i;
437 return;
438
439bad_ev_key:
440 err("can't resolve evdev key '%s'", kname);
3cb98c5e 441 return;
442
443bad_sdlkey:
444 err("can't resolve SDL key '%s'", sdlname);
445}
446
83b5751b 447#define KEYBITS_BIT(keybits, x) (keybits[(x)/sizeof(keybits[0])/8] & \
448 (1 << ((x) & (sizeof(keybits[0])*8-1))))
449
b78828bf 450void omapsdl_input_init(void)
3cb98c5e 451{
83b5751b 452 long keybits[KEY_CNT / sizeof(long) / 8];
17e19802 453 ino_t touchscreen_ino = (ino_t)-1;
454 struct stat stat_buf;
83b5751b 455 int i;
456
17e19802 457#if SDL_INPUT_TSLIB
458 /* start with touchscreen so that we can skip it later */
459 osdl_tslib_dev = ts_open(SDL_getenv("TSLIB_TSDEVICE"), 1);
460 if (ts_config(osdl_tslib_dev) < 0) {
461 ts_close(osdl_tslib_dev);
462 osdl_tslib_dev = NULL;
463 }
464 if (osdl_tslib_dev != NULL) {
465 osdl_tslib_fd = ts_fd(osdl_tslib_dev);
466 osdl_evdev_devs[osdl_evdev_dev_count++] = osdl_tslib_fd;
467 if (fstat(osdl_tslib_fd, &stat_buf) == -1)
7b66578c 468 err_perror("fstat ts");
17e19802 469 else
470 touchscreen_ino = stat_buf.st_ino;
7b66578c 471 log("opened tslib touchscreen");
17e19802 472 }
473#endif
474
475 /* the kernel might support and return less keys then we know about,
476 * so make sure the buffer is clear. */
83b5751b 477 memset(keybits, 0, sizeof(keybits));
478
479 for (i = 0;; i++)
480 {
481 int support = 0, count = 0;
482 int u, ret, fd;
483 char name[64];
484
485 snprintf(name, sizeof(name), "/dev/input/event%d", i);
486 fd = open(name, O_RDONLY|O_NONBLOCK);
487 if (fd == -1) {
488 if (errno == EACCES)
489 continue; /* maybe we can access next one */
490 break;
491 }
492
17e19802 493 /* touchscreen check */
494 if (touchscreen_ino != (dev_t)-1) {
495 if (fstat(fd, &stat_buf) == -1)
7b66578c 496 err_perror("fstat");
17e19802 497 else if (touchscreen_ino == stat_buf.st_ino) {
7b66578c 498 log("skip %s as ts", name);
17e19802 499 goto skip;
500 }
501 }
502
83b5751b 503 /* check supported events */
504 ret = ioctl(fd, EVIOCGBIT(0, sizeof(support)), &support);
505 if (ret == -1) {
7b66578c 506 err_perror("in_evdev: ioctl failed on %s", name);
83b5751b 507 goto skip;
508 }
509
510 if (!(support & (1 << EV_KEY)))
511 goto skip;
512
513 ret = ioctl(fd, EVIOCGBIT(EV_KEY, sizeof(keybits)), keybits);
514 if (ret == -1) {
7b66578c 515 err_perror("in_evdev: ioctl failed on %s", name);
83b5751b 516 goto skip;
517 }
518
519 /* check for interesting keys */
520 for (u = 0; u < KEY_CNT; u++) {
521 if (KEYBITS_BIT(keybits, u)) {
522 if (u != KEY_POWER && u != KEY_SLEEP && u != BTN_TOUCH)
523 count++;
524 }
525 }
526
527 if (count == 0)
528 goto skip;
529
530 osdl_evdev_devs[osdl_evdev_dev_count++] = fd;
531 ioctl(fd, EVIOCGNAME(sizeof(name)), name);
7b66578c 532 log("in_evdev: found \"%s\" with %d events (type %08x)",
83b5751b 533 name, count, support);
534 continue;
535
536skip:
537 close(fd);
538 }
539
7b66578c 540 log("found %d evdev device(s).", osdl_evdev_dev_count);
17e19802 541}
542
543void omapsdl_input_finish(void)
544{
545 int i;
546
547#if SDL_INPUT_TSLIB
548 if (osdl_tslib_dev != NULL)
549 ts_close(osdl_tslib_dev);
550#endif
551 osdl_tslib_dev = NULL;
552
553 for (i = 0; i < osdl_evdev_dev_count; i++) {
554 if (osdl_evdev_devs[i] != osdl_tslib_fd)
555 close(osdl_evdev_devs[i]);
556 }
557 osdl_evdev_dev_count = 0;
558 osdl_tslib_fd = 0;
3cb98c5e 559}
560
83b5751b 561int omapsdl_input_get_events(int timeout_ms,
b260fb56 562 int (*key_cb)(void *cb_arg, int sdl_kc, int sdl_sc, int is_pressed),
17e19802 563 int (*ts_cb)(void *cb_arg, int x, int y, unsigned int pressure),
564 void *cb_arg)
3cb98c5e 565{
83b5751b 566 struct timeval tv, *timeout = NULL;
567 struct input_event ev;
568 int i, fdmax = -1;
569 fd_set fdset;
570
571 if (timeout_ms >= 0) {
572 tv.tv_sec = timeout_ms / 1000;
573 tv.tv_usec = (timeout_ms % 1000) * 1000;
574 timeout = &tv;
575 }
3cb98c5e 576
83b5751b 577 FD_ZERO(&fdset);
578 for (i = 0; i < osdl_evdev_dev_count; i++) {
579 if (osdl_evdev_devs[i] > fdmax)
580 fdmax = osdl_evdev_devs[i];
581 FD_SET(osdl_evdev_devs[i], &fdset);
582 }
3cb98c5e 583
83b5751b 584 while (1)
585 {
586 int fd, ret, sdl_kc;
3cb98c5e 587
83b5751b 588 ret = select(fdmax + 1, &fdset, NULL, NULL, timeout);
589 if (ret == -1)
590 {
7b66578c 591 err_perror("in_evdev: select failed");
83b5751b 592 return -1;
593 }
594 else if (ret == 0)
595 return -1; /* timeout */
596
597 for (i = 0; i < osdl_evdev_dev_count; i++) {
598 if (!FD_ISSET(osdl_evdev_devs[i], &fdset))
599 continue;
600
601 fd = osdl_evdev_devs[i];
17e19802 602#if SDL_INPUT_TSLIB
5646dd9e 603 if (fd == osdl_tslib_fd && ts_cb != NULL) {
17e19802 604 while (1) {
605 struct ts_sample tss;
606 ret = ts_read(osdl_tslib_dev, &tss, 1);
607 if (ret <= 0)
608 break;
609 ret = ts_cb(cb_arg, tss.x, tss.y, tss.pressure);
610 if (ret != 0)
611 return ret;
612 }
613 continue;
614 }
5646dd9e 615 /* else read below will consume the event, even if it's from ts */
17e19802 616#endif
5646dd9e 617
83b5751b 618 while (1) {
619 ret = read(fd, &ev, sizeof(ev));
620 if (ret < (int)sizeof(ev)) {
621 if (errno != EAGAIN) {
7b66578c 622 err_perror("in_evdev: read failed");
83b5751b 623 return -1;
624 }
625 break;
626 }
627
090bcb85 628 if (ev.type != EV_KEY || key_cb == NULL)
629 continue; /* not key event or not needed */
83b5751b 630 if ((unsigned int)ev.value > 1)
631 continue; /* not key up/down */
632 if ((unsigned int)ev.code >= ARRAY_SIZE(osdl_evdev_map))
633 continue; /* keycode from future */
634 sdl_kc = osdl_evdev_map[ev.code];
635 if (sdl_kc == 0)
636 continue; /* not mapped */
b260fb56 637 /* scancode note: stock SDL doesn't do +8 in fbcon driver */
638 ret = key_cb(cb_arg, sdl_kc, ev.code + 8, ev.value);
83b5751b 639 if (ret != 0)
640 return ret;
641 }
642 }
3cb98c5e 643 }
0aab059f 644}
645
646/* SDL */
647#ifdef STANDALONE
648
649static unsigned char g_keystate[SDLK_LAST];
650
83b5751b 651struct key_event {
652 int sdl_kc;
b260fb56 653 int sdl_sc;
83b5751b 654 int is_pressed;
655};
656
b260fb56 657static int do_key_cb(void *cb_arg, int sdl_kc, int sdl_sc, int is_pressed)
83b5751b 658{
659 struct key_event *ev = cb_arg;
660 ev->sdl_kc = sdl_kc;
b260fb56 661 ev->sdl_sc = sdl_sc;
83b5751b 662 ev->is_pressed = is_pressed;
663
664 return 1; /* done */
665}
666
0aab059f 667static int do_event(SDL_Event *event, int timeout)
668{
83b5751b 669 struct key_event ev;
670 int ret;
0aab059f 671
17e19802 672 ret = omapsdl_input_get_events(timeout, do_key_cb, NULL, &ev);
83b5751b 673 if (ret < 0)
0aab059f 674 return 0;
675
83b5751b 676 g_keystate[ev.sdl_kc] = ev.is_pressed;
3cb98c5e 677
678 if (event == NULL)
679 return 1; // FIXME: ..but the event is lost
680
681 memset(event, 0, sizeof(event->key));
83b5751b 682 event->type = ev.is_pressed ? SDL_KEYDOWN : SDL_KEYUP;
3cb98c5e 683 // event->key.which =
83b5751b 684 event->key.state = ev.is_pressed ? SDL_PRESSED : SDL_RELEASED;
685 event->key.keysym.sym = ev.sdl_kc;
b260fb56 686 event->key.keysym.scancode = ev.sdl_sc;
3cb98c5e 687 // event->key.keysym.mod
688
689 return 1;
690}
691
3cb98c5e 692DECLSPEC int SDLCALL
693SDL_WaitEvent(SDL_Event *event)
694{
695 trace("%p", event);
696
0aab059f 697 return do_event(event, -1);
3cb98c5e 698}
699
700DECLSPEC int SDLCALL
701SDL_PollEvent(SDL_Event *event)
702{
703 trace("%p", event);
704
0aab059f 705 return do_event(event, 0);
3cb98c5e 706}
707
708DECLSPEC Uint8 * SDLCALL
709SDL_GetKeyState(int *numkeys)
710{
711 trace("%p", numkeys);
712
713 if (numkeys != NULL)
714 *numkeys = ARRAY_SIZE(g_keystate);
715 return g_keystate;
716}
717
718DECLSPEC char * SDLCALL
719SDL_GetKeyName(SDLKey key)
720{
721 trace("%d", key);
722
723 if ((unsigned int)key < ARRAY_SIZE(sdl_keynames))
724 return (char *)sdl_keynames[key];
725 else
726 return "";
727}
728
729DECLSPEC int SDLCALL
730SDL_EnableUNICODE(int enable)
731{
732 trace("%d", enable);
733
734 if (enable > 0)
735 not_supported();
736
737 return 0;
738}
739
740DECLSPEC int SDLCALL
741SDL_EnableKeyRepeat(int delay, int interval)
742{
743 trace("%d, %d", delay, interval);
744
745 if (delay)
746 not_supported();
747 return 0;
748}
749
750DECLSPEC void SDLCALL
751SDL_GetKeyRepeat(int *delay, int *interval)
752{
753 trace("%p, %p", delay, interval);
754
755 if (delay)
756 *delay = 0;
757 if (interval)
758 *interval = 0;
759}
760
761DECLSPEC SDLMod SDLCALL
762SDL_GetModState(void)
763{
764 static const short syms[] = { SDLK_LSHIFT, SDLK_RSHIFT, SDLK_LCTRL, SDLK_RCTRL, SDLK_LALT,
765 SDLK_RALT, SDLK_LMETA, SDLK_RMETA, SDLK_NUMLOCK, SDLK_CAPSLOCK, SDLK_MODE };
766 static const short mods[] = { KMOD_LSHIFT, KMOD_RSHIFT, KMOD_LCTRL, KMOD_RCTRL, KMOD_LALT,
767 KMOD_RALT, KMOD_LMETA, KMOD_RMETA, KMOD_NUM, KMOD_CAPS, KMOD_MODE };
768 SDLMod ret = KMOD_NONE;
769 int i;
770
771 trace("");
772
773 for (i = 0; i < ARRAY_SIZE(syms); i++)
774 if (g_keystate[syms[i]])
775 ret |= mods[i];
776
777 return ret;
778}
779
780/* Joysticks */
781DECLSPEC int SDLCALL
782SDL_NumJoysticks(void)
783{
784 trace("");
785 return 0;
786}
787
788DECLSPEC SDL_Joystick * SDLCALL
789SDL_JoystickOpen(int device_index)
790{
791 trace("%d", device_index);
792 return NULL;
793}
794
b78828bf 795#endif // STANDALONE