94994d1f89ced1eb40962e20ab160bbcabaf9092
[sdl_omap.git] / src / video / omapdss / osdl_input.c
1 /*
2  * (C) Gražvydas "notaz" Ignotas, 2010-2012
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 "osdl.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_WORLD_95,
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 sdl_sc, 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                                 /* scancode note: stock SDL doesn't do +8 in fbcon driver */
638                                 ret = key_cb(cb_arg, sdl_kc, ev.code + 8, ev.value);
639                                 if (ret != 0)
640                                         return ret;
641                         }
642                 }
643         }
644 }
645
646 /* SDL */
647 #ifdef STANDALONE
648
649 static unsigned char g_keystate[SDLK_LAST];
650
651 struct key_event {
652         int sdl_kc;
653         int sdl_sc;
654         int is_pressed;
655 };
656
657 static int do_key_cb(void *cb_arg, int sdl_kc, int sdl_sc, int is_pressed)
658 {
659         struct key_event *ev = cb_arg;
660         ev->sdl_kc = sdl_kc;
661         ev->sdl_sc = sdl_sc;
662         ev->is_pressed = is_pressed;
663
664         return 1; /* done */
665 }
666
667 static int do_event(SDL_Event *event, int timeout)
668 {
669         struct key_event ev;
670         int ret;
671
672         ret = omapsdl_input_get_events(timeout, do_key_cb, NULL, &ev);
673         if (ret < 0)
674                 return 0;
675
676         g_keystate[ev.sdl_kc] = ev.is_pressed;
677
678         if (event == NULL)
679                 return 1; // FIXME: ..but the event is lost
680
681         memset(event, 0, sizeof(event->key));
682         event->type = ev.is_pressed ? SDL_KEYDOWN : SDL_KEYUP;
683         // event->key.which =
684         event->key.state = ev.is_pressed ? SDL_PRESSED : SDL_RELEASED;
685         event->key.keysym.sym = ev.sdl_kc;
686         event->key.keysym.scancode = ev.sdl_sc;
687         // event->key.keysym.mod
688
689         return 1;
690 }
691
692 DECLSPEC int SDLCALL
693 SDL_WaitEvent(SDL_Event *event)
694 {
695         trace("%p", event);
696
697         return do_event(event, -1);
698 }
699
700 DECLSPEC int SDLCALL
701 SDL_PollEvent(SDL_Event *event)
702 {
703         trace("%p", event);
704
705         return do_event(event, 0);
706 }
707
708 DECLSPEC Uint8 * SDLCALL
709 SDL_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
718 DECLSPEC char * SDLCALL
719 SDL_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
729 DECLSPEC int SDLCALL
730 SDL_EnableUNICODE(int enable)
731 {
732         trace("%d", enable);
733
734         if (enable > 0)
735                 not_supported();
736
737         return 0;
738 }
739
740 DECLSPEC int SDLCALL
741 SDL_EnableKeyRepeat(int delay, int interval)
742 {
743         trace("%d, %d", delay, interval);
744
745         if (delay)
746                 not_supported();
747         return 0;
748 }
749
750 DECLSPEC void SDLCALL
751 SDL_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
761 DECLSPEC SDLMod SDLCALL
762 SDL_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 */
781 DECLSPEC int SDLCALL
782 SDL_NumJoysticks(void)
783 {
784         trace("");
785         return 0;
786 }
787
788 DECLSPEC SDL_Joystick * SDLCALL
789 SDL_JoystickOpen(int device_index)
790 {
791         trace("%d", device_index);
792         return NULL;
793 }
794
795 #endif // STANDALONE