don't depend on system SDL headers
[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 #ifdef STANDALONE
18 #include <SDL/SDL.h>
19 #else
20 #include "SDL.h"
21 #endif
22 #if SDL_INPUT_TSLIB
23 #include <tslib.h>
24 #endif
25
26 #include "omapsdl.h"
27
28 /* XXX: these should go to private data */
29 static int osdl_evdev_devs[32];
30 static int osdl_evdev_dev_count;
31 static int osdl_tslib_fd;
32 static struct tsdev *osdl_tslib_dev;
33
34 static short osdl_evdev_map[KEY_CNT] = {
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] */
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,
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,
74         [KEY_FN]        = SDLK_MODE,
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, /* ; */
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,
90         [KEY_MENU]      = 147,          /* match default SDL here */
91         [KEY_RIGHTSHIFT]= SDLK_RSHIFT,
92         [KEY_RIGHTCTRL] = SDLK_RCTRL,
93 };
94
95 static 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
180 #define DNKEY(x) [SDLK_##x] = #x
181 static const char * const sdl_keynames[SDLK_LAST] = {
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
405 void omapsdl_input_bind(const char *kname, const char *sdlname)
406 {
407         int i, kc;
408
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;
417         }
418
419         if (i >= ARRAY_SIZE(osdl_evdev_keys))
420                 goto bad_ev_key;
421         kc = i;
422
423         if (sdlname == NULL || strncasecmp(sdlname, "SDLK_", 5) != 0)
424                 goto bad_sdlkey;
425
426         for (i = 0; i < ARRAY_SIZE(sdl_keynames); i++) {
427                 if (sdl_keynames[i] == NULL)
428                         continue;
429                 if (strcasecmp(sdl_keynames[i], sdlname + 5) == 0)
430                         break;
431         }
432
433         if (i >= ARRAY_SIZE(sdl_keynames))
434                 goto bad_sdlkey;
435
436         osdl_evdev_map[kc] = i;
437         return;
438
439 bad_ev_key:
440         err("can't resolve evdev key '%s'", kname);
441         return;
442
443 bad_sdlkey:
444         err("can't resolve SDL key '%s'", sdlname);
445 }
446
447 #define KEYBITS_BIT(keybits, x) (keybits[(x)/sizeof(keybits[0])/8] & \
448         (1 << ((x) & (sizeof(keybits[0])*8-1))))
449
450 void omapsdl_input_init(void)
451 {
452         long keybits[KEY_CNT / sizeof(long) / 8];
453         ino_t touchscreen_ino = (ino_t)-1;
454         struct stat stat_buf;
455         int i;
456
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)
468                         err_perror("fstat ts");
469                 else
470                         touchscreen_ino = stat_buf.st_ino;
471                 log("opened tslib touchscreen");
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. */
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
493                 /* touchscreen check */
494                 if (touchscreen_ino != (dev_t)-1) {
495                         if (fstat(fd, &stat_buf) == -1)
496                                 err_perror("fstat");
497                         else if (touchscreen_ino == stat_buf.st_ino) {
498                                 log("skip %s as ts", name);
499                                 goto skip;
500                         }
501                 }
502
503                 /* check supported events */
504                 ret = ioctl(fd, EVIOCGBIT(0, sizeof(support)), &support);
505                 if (ret == -1) {
506                         err_perror("in_evdev: ioctl failed on %s", name);
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) {
515                         err_perror("in_evdev: ioctl failed on %s", name);
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);
532                 log("in_evdev: found \"%s\" with %d events (type %08x)",
533                         name, count, support);
534                 continue;
535
536 skip:
537                 close(fd);
538         }
539
540         log("found %d evdev device(s).", osdl_evdev_dev_count);
541 }
542
543 void 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;
559 }
560
561 int omapsdl_input_get_events(int timeout_ms,
562                 int (*key_cb)(void *cb_arg, int sdl_kc, int is_pressed),
563                 int (*ts_cb)(void *cb_arg, int x, int y, unsigned int pressure),
564                 void *cb_arg)
565 {
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         }
576
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         }
583
584         while (1)
585         {
586                 int fd, ret, sdl_kc;
587
588                 ret = select(fdmax + 1, &fdset, NULL, NULL, timeout);
589                 if (ret == -1)
590                 {
591                         err_perror("in_evdev: select failed");
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];
602 #if SDL_INPUT_TSLIB
603                         if (fd == osdl_tslib_fd && ts_cb != NULL) {
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                         }
615                         /* else read below will consume the event, even if it's from ts */
616 #endif
617
618                         while (1) {
619                                 ret = read(fd, &ev, sizeof(ev));
620                                 if (ret < (int)sizeof(ev)) {
621                                         if (errno != EAGAIN) {
622                                                 err_perror("in_evdev: read failed");
623                                                 return -1;
624                                         }
625                                         break;
626                                 }
627
628                                 if (ev.type != EV_KEY)
629                                         continue; /* not key event */
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 */
637                                 ret = key_cb(cb_arg, sdl_kc, ev.value);
638                                 if (ret != 0)
639                                         return ret;
640                         }
641                 }
642         }
643 }
644
645 /* SDL */
646 #ifdef STANDALONE
647
648 static unsigned char g_keystate[SDLK_LAST];
649
650 struct key_event {
651         int sdl_kc;
652         int is_pressed;
653 };
654
655 static int do_key_cb(void *cb_arg, int sdl_kc, int is_pressed)
656 {
657         struct key_event *ev = cb_arg;
658         ev->sdl_kc = sdl_kc;
659         ev->is_pressed = is_pressed;
660
661         return 1; /* done */
662 }
663
664 static int do_event(SDL_Event *event, int timeout)
665 {
666         struct key_event ev;
667         int ret;
668
669         ret = omapsdl_input_get_events(timeout, do_key_cb, NULL, &ev);
670         if (ret < 0)
671                 return 0;
672
673         g_keystate[ev.sdl_kc] = ev.is_pressed;
674
675         if (event == NULL)
676                 return 1; // FIXME: ..but the event is lost
677
678         memset(event, 0, sizeof(event->key));
679         event->type = ev.is_pressed ? SDL_KEYDOWN : SDL_KEYUP;
680         // event->key.which =
681         event->key.state = ev.is_pressed ? SDL_PRESSED : SDL_RELEASED;
682         event->key.keysym.sym = ev.sdl_kc;
683         // event->key.keysym.mod
684
685         return 1;
686 }
687
688 DECLSPEC int SDLCALL
689 SDL_WaitEvent(SDL_Event *event)
690 {
691         trace("%p", event);
692
693         return do_event(event, -1);
694 }
695
696 DECLSPEC int SDLCALL
697 SDL_PollEvent(SDL_Event *event)
698 {
699         trace("%p", event);
700
701         return do_event(event, 0);
702 }
703
704 DECLSPEC Uint8 * SDLCALL
705 SDL_GetKeyState(int *numkeys)
706 {
707         trace("%p", numkeys);
708
709         if (numkeys != NULL)
710                 *numkeys = ARRAY_SIZE(g_keystate);
711         return g_keystate;
712 }
713
714 DECLSPEC char * SDLCALL
715 SDL_GetKeyName(SDLKey key)
716 {
717         trace("%d", key);
718
719         if ((unsigned int)key < ARRAY_SIZE(sdl_keynames))
720                 return (char *)sdl_keynames[key];
721         else
722                 return "";
723 }
724
725 DECLSPEC int SDLCALL
726 SDL_EnableUNICODE(int enable)
727 {
728         trace("%d", enable);
729
730         if (enable > 0)
731                 not_supported();
732
733         return 0;
734 }
735
736 DECLSPEC int SDLCALL
737 SDL_EnableKeyRepeat(int delay, int interval)
738 {
739         trace("%d, %d", delay, interval);
740
741         if (delay)
742                 not_supported();
743         return 0;
744 }
745
746 DECLSPEC void SDLCALL
747 SDL_GetKeyRepeat(int *delay, int *interval)
748 {
749         trace("%p, %p", delay, interval);
750
751         if (delay)
752                 *delay = 0;
753         if (interval)
754                 *interval = 0;
755 }
756
757 DECLSPEC SDLMod SDLCALL
758 SDL_GetModState(void)
759 {
760         static const short syms[] = { SDLK_LSHIFT, SDLK_RSHIFT, SDLK_LCTRL, SDLK_RCTRL, SDLK_LALT,
761                                 SDLK_RALT, SDLK_LMETA, SDLK_RMETA, SDLK_NUMLOCK, SDLK_CAPSLOCK, SDLK_MODE };
762         static const short mods[] = { KMOD_LSHIFT, KMOD_RSHIFT, KMOD_LCTRL, KMOD_RCTRL, KMOD_LALT,
763                                 KMOD_RALT, KMOD_LMETA, KMOD_RMETA, KMOD_NUM, KMOD_CAPS, KMOD_MODE };
764         SDLMod ret = KMOD_NONE;
765         int i;
766
767         trace("");
768
769         for (i = 0; i < ARRAY_SIZE(syms); i++)
770                 if (g_keystate[syms[i]])
771                         ret |= mods[i];
772
773         return ret;
774 }
775
776 /* Joysticks */
777 DECLSPEC int SDLCALL
778 SDL_NumJoysticks(void)
779 {
780         trace("");
781         return 0;
782 }
783
784 DECLSPEC SDL_Joystick * SDLCALL
785 SDL_JoystickOpen(int device_index)
786 {
787         trace("%d", device_index);
788         return NULL;
789 }
790
791 #endif // STANDALONE