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