loader: try to make input generic, with caanoo support
[ginge.git] / loader / host_pnd.c
1 // vim:shiftwidth=2:expandtab
2
3 struct in_default_bind in_evdev_defbinds[] = {
4   { KEY_UP,         IN_BINDTYPE_PLAYER12, GP2X_UP },
5   { KEY_PAGEUP,     IN_BINDTYPE_PLAYER12, GP2X_Y },
6   { KEY_END,        IN_BINDTYPE_PLAYER12, GP2X_B },
7   { KEY_PAGEDOWN,   IN_BINDTYPE_PLAYER12, GP2X_X },
8   { KEY_HOME,       IN_BINDTYPE_PLAYER12, GP2X_A },
9   { KEY_RIGHTSHIFT, IN_BINDTYPE_PLAYER12, GP2X_L },
10   { KEY_RIGHTCTRL,  IN_BINDTYPE_PLAYER12, GP2X_R },
11   { KEY_LEFTALT,    IN_BINDTYPE_PLAYER12, GP2X_START },
12   { KEY_LEFTCTRL,   IN_BINDTYPE_PLAYER12, GP2X_SELECT },
13   { KEY_COMMA,      IN_BINDTYPE_PLAYER12, GP2X_VOL_DOWN },
14   { KEY_DOT,        IN_BINDTYPE_PLAYER12, GP2X_VOL_UP },
15   { KEY_1,          IN_BINDTYPE_PLAYER12, GP2X_PUSH },
16   { KEY_Q,          IN_BINDTYPE_EMU, 0 },
17   { 0, 0, 0 },
18 };
19
20 static void host_actions(int actions[IN_BINDTYPE_COUNT])
21 {
22   if (actions[IN_BINDTYPE_EMU] & 1)
23     host_forced_exit();
24 }
25
26 // todo: rm when generic code works
27 #if 0
28 #define _GNU_SOURCE
29 #include <stdio.h>
30 #include <string.h>
31 #include <sys/types.h>
32 #include <sys/stat.h>
33 #include <fcntl.h>
34 #include <unistd.h>
35 #include <sys/ioctl.h>
36 #include <errno.h>
37 #include <linux/input.h>
38
39 #include "header.h"
40 #include "realfuncs.h"
41
42 static int ifds[2] = { -1, -1 };
43 static int keystate;
44
45 int host_init(void)
46 {
47   char buff[64];
48   int i, ifd, ret;
49
50   for (ifd = -1, i = 0; ifds[0] == -1 || ifds[1] == -1; i++) {
51     snprintf(buff, sizeof(buff), "/dev/input/event%i", i);
52     ifd = open(buff, O_RDONLY | O_NONBLOCK);
53     if (ifd == -1)
54       break;
55
56     ret = ioctl(ifd, EVIOCGNAME(sizeof(buff)), buff);
57     if (ret < 0)
58       break;
59
60     if (strcasestr(buff, "gpio") != NULL) {
61       ifds[0] = ifd;
62       continue;
63     }
64     if (strcasestr(buff, "keypad") != NULL) {
65       ifds[1] = ifd;
66       continue;
67     }
68     close(ifd);
69   }
70
71   if (ifds[0] < 0)
72     fprintf(stderr, PFX "missing buttons\n");
73   if (ifds[1] < 0)
74     fprintf(stderr, PFX "missing keypad\n");
75
76   return 0;
77 }
78
79 static const struct {
80   unsigned short key;
81   unsigned short btn;
82 } key_map[] = {
83   { KEY_LEFT,       GP2X_LEFT },
84   { KEY_RIGHT,      GP2X_RIGHT },
85   { KEY_UP,         GP2X_UP },
86   { KEY_DOWN,       GP2X_DOWN },
87   { KEY_PAGEUP,     GP2X_Y },
88   { BTN_BASE,       GP2X_Y },
89   { KEY_END,        GP2X_B },
90   { BTN_BASE2,      GP2X_B },
91   { KEY_PAGEDOWN,   GP2X_X },
92   { BTN_BASE3,      GP2X_X },
93   { KEY_HOME,       GP2X_A },
94   { BTN_BASE4,      GP2X_A },
95   { KEY_RIGHTSHIFT, GP2X_L },
96   { BTN_TL,         GP2X_L },
97   { KEY_RIGHTCTRL,  GP2X_R },
98   { BTN_TR,         GP2X_R },
99   { KEY_LEFTALT,    GP2X_START },
100   { BTN_START,      GP2X_START },
101   { KEY_LEFTCTRL,   GP2X_SELECT },
102   { BTN_SELECT,     GP2X_SELECT },
103   { KEY_COMMA,      GP2X_VOL_DOWN },
104   { KEY_DOT,        GP2X_VOL_UP },
105   { KEY_1,          GP2X_PUSH },
106 };
107
108 int host_read_btns(void)
109 {
110   struct input_event ev;
111   int i, ret;
112
113   while (1)
114   {
115     ret = read(ifds[0], &ev, sizeof(ev));
116     if (ret < (int) sizeof(ev)) {
117       if (errno != EAGAIN && errno != EWOULDBLOCK)
118         perror(PFX "read error");
119
120       ret = read(ifds[1], &ev, sizeof(ev));
121       if (ret < (int) sizeof(ev))
122         if (errno != EAGAIN && errno != EWOULDBLOCK)
123           perror(PFX "read error");
124     }
125
126     if (ret < (int) sizeof(ev))
127       return keystate;
128
129     if (ev.type != EV_KEY)
130       continue;
131
132     if (ev.code == KEY_Q && ev.value) {
133       // exit() might not be enough because loader and app data is out of sync,
134       // and other threads (which are really processes) might not exit properly.
135       system("killall ginge_sloader");
136       usleep(300000);
137       system("killall -9 ginge_sloader");
138       exit(1);
139     }
140
141     for (i = 0; i < sizeof(key_map) / sizeof(key_map[0]); i++) {
142       if (key_map[i].key != ev.code)
143         continue;
144       if (ev.value)
145         keystate |=  (1 << key_map[i].btn);
146       else
147         keystate &= ~(1 << key_map[i].btn);
148       break;
149     }
150   }
151
152   return keystate;
153 }
154 #endif