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