moved writelrom to use global path
[libpicofe.git] / common / input.c
CommitLineData
2258f158 1#include <stdio.h>
2#include <stdlib.h>
3#include <string.h>
4
5#include "input.h"
34581c95 6#include "../linux/in_evdev.h"
2258f158 7
8typedef struct
9{
10 int drv_id;
11 void *drv_data;
12 int *binds;
13 char *name;
14 int probed:1;
15 int ignore:1;
16} in_dev_t;
17
18#define IN_MAX_DEVS 10
19
20static in_dev_t in_devices[IN_MAX_DEVS];
21static int in_dev_count = 0;
22
23static int in_bind_count(int drv_id)
24{
25 int count = 0;
595491c4 26 switch (drv_id) {
27 case IN_DRVID_EVDEV:
2258f158 28 count = in_evdev_bind_count();
595491c4 29 break;
30 }
2258f158 31 if (count <= 0)
32 printf("input: failed to get bind count for drv %d\n", drv_id);
33
34 return count;
35}
36
37static int *in_alloc_binds(int drv_id)
38{
39 int count, *ret;
40
41 count = in_bind_count(drv_id);
42 if (count <= 0) {
43 printf("input: failed to get bind count for drv %d\n", drv_id);
44 return NULL;
45 }
46
47 ret = malloc(count * sizeof(*ret));
48 return ret;
49}
50
51static void in_free(in_dev_t *dev)
52{
53 if (dev->probed) {
595491c4 54 switch (dev->drv_id) {
55 case IN_DRVID_EVDEV:
2258f158 56 in_evdev_free(dev->drv_data);
595491c4 57 break;
58 }
2258f158 59 }
60 dev->probed = 0;
61 dev->drv_data = NULL;
62 free(dev->name);
63 dev->name = NULL;
64 free(dev->binds);
65 dev->binds = NULL;
66}
67
68/* to be called by drivers */
69void in_register(const char *nname, int drv_id, void *drv_data)
70{
71 int i, dupe_count = 0, *binds;
72 char name[256], *name_end, *tmp;
73
74 strncpy(name, nname, sizeof(name));
75 name[sizeof(name)-12] = 0;
76 name_end = name + strlen(name);
77
78 for (i = 0; i < in_dev_count; i++)
79 {
80 if (in_devices[i].name == NULL)
81 continue;
82 if (strcmp(in_devices[i].name, name) == 0)
83 {
84 if (in_devices[i].probed) {
85 dupe_count++;
86 sprintf(name_end, " [%d]", dupe_count);
87 continue;
88 }
89 goto update;
90 }
91 }
92
93 if (i >= IN_MAX_DEVS)
94 {
95 /* try to find unused device */
96 for (i = 0; i < IN_MAX_DEVS; i++)
97 if (!in_devices[i].probed) break;
98 if (i >= IN_MAX_DEVS) {
99 printf("input: too many devices, can't add %s\n", name);
100 return;
101 }
102 in_free(&in_devices[i]);
103 }
104
105 tmp = strdup(name);
106 if (tmp == NULL)
107 return;
108
109 binds = in_alloc_binds(drv_id);
110 if (binds == NULL) {
111 free(tmp);
112 return;
113 }
114
115 in_devices[i].name = tmp;
116 in_devices[i].binds = binds;
117 if (i + 1 > in_dev_count)
118 in_dev_count = i + 1;
119
120 printf("input: new device #%d \"%s\"\n", i, name);
121update:
122 in_devices[i].probed = 1;
123 in_devices[i].drv_id = drv_id;
124 in_devices[i].drv_data = drv_data;
125}
126
127void in_probe(void)
128{
129 int i;
130 for (i = 0; i < in_dev_count; i++)
131 in_devices[i].probed = 0;
132
2258f158 133 in_evdev_probe();
2258f158 134
135 /* get rid of devs without binds and probes */
136 for (i = 0; i < in_dev_count; i++) {
137 if (!in_devices[i].probed && in_devices[i].binds == NULL) {
138 in_dev_count--;
139 if (i < in_dev_count) {
140 free(in_devices[i].name);
141 memmove(&in_devices[i], &in_devices[i+1],
142 (in_dev_count - i) * sizeof(in_devices[0]));
143 }
144 }
145 }
146}
147
148void in_clear_binds(const char *devname)
149{
150/* int count;
151
152 count = in_bind_count(drv_id);
153 if (count <= 0) {
154 printf("input: failed to get bind count for drv %d\n", dev->drv_id);
155 return NULL;
156 }
157*/
158}
159
160int in_update(void)
161{
162 int i, result = 0;
163
164 for (i = 0; i < in_dev_count; i++) {
165 if (in_devices[i].probed && in_devices[i].binds != NULL) {
595491c4 166 switch (in_devices[i].drv_id) {
167 case IN_DRVID_EVDEV:
34581c95 168 result |= in_evdev_update(in_devices[i].drv_data, in_devices[i].binds);
595491c4 169 break;
170 }
2258f158 171 }
172 }
173
174 return result;
175}
176
595491c4 177static void **in_collect_drvdata(int drv_id, int *count)
178{
179 static void *data[IN_MAX_DEVS];
180 int i;
181
182 for (*count = i = 0; i < in_dev_count; i++) {
183 if (in_devices[i].drv_id == drv_id && in_devices[i].probed)
184 data[(*count)++] = in_devices[i].drv_data;
185 }
186
187 return data;
188}
189
190void in_set_blocking(int is_blocking)
191{
192 int i;
193
194 for (i = 0; i < in_dev_count; i++) {
195 if (in_devices[i].probed) {
196 switch (in_devices[i].drv_id) {
197 case IN_DRVID_EVDEV:
198 in_evdev_set_blocking(in_devices[i].drv_data, is_blocking);
199 break;
200 }
201 }
202 }
203}
204
34581c95 205/*
595491c4 206 * update with wait for a press, return keycode
34581c95 207 * only can use 1 drv here..
208 */
595491c4 209int in_update_keycode(int *dev_id, int *is_down)
34581c95 210{
211 int result = 0;
212#ifdef IN_EVDEV
595491c4 213 void **data;
214 int i, id = 0, count = 0;
34581c95 215
595491c4 216 data = in_collect_drvdata(IN_DRVID_EVDEV, &count);
34581c95 217 if (count == 0) {
218 /* don't deadlock, fail */
219 printf("input: failed to find devices to read\n");
220 exit(1);
221 }
222
595491c4 223 result = in_evdev_update_keycode(data, count, &id, is_down);
224
225 if (dev_id != NULL) {
226 for (i = id; i < in_dev_count; i++) {
227 if (in_devices[i].drv_data == data[id]) {
228 *dev_id = i;
229 break;
230 }
231 }
232 }
34581c95 233#else
234#error no menu read handlers
235#endif
236
237 return result;
238}
239
595491c4 240/*
241 * same as above, only return bitfield of BTN_*
242 */
243int in_update_menu(void)
244{
245 static int keys_active = 0;
246 int keys_old = keys_active;
247
248 while (1)
249 {
250 int code, is_down = 0;
251 code = in_update_keycode(NULL, &is_down);
252#ifdef IN_EVDEV
253 code = in_evdev_menu_translate(code);
254#endif
255 if (code == 0) continue;
256
257 if (is_down)
258 keys_active |= code;
259 else
260 keys_active &= ~code;
261
262 if (keys_old != keys_active)
263 break;
264 }
265
266 return keys_active;
267}
268
269const char *in_get_key_name(int dev_id, int keycode)
270{
271 if (dev_id < 0 || dev_id >= IN_MAX_DEVS)
272 return "Unkn0";
273 switch (in_devices[dev_id].drv_id) {
274 case IN_DRVID_EVDEV:
275 return in_evdev_get_key_name(keycode);
276 }
277
278 return "Unkn1";
279}
280
2258f158 281void in_init(void)
282{
283 memset(in_devices, 0, sizeof(in_devices));
284 in_dev_count = 0;
285}
286
287int main(void)
288{
34581c95 289 int ret;
290
2258f158 291 in_init();
292 in_probe();
293
595491c4 294 in_set_blocking(1);
295
296#if 1
297 while (1) {
298 int dev = 0, down;
299 ret = in_update_keycode(&dev, &down);
300 printf("#%i: %i %i (%s)\n", dev, down, ret, in_get_key_name(dev, ret));
301 }
302#else
2258f158 303 while (1) {
34581c95 304 ret = in_update_menu();
305 printf("%08x\n", ret);
2258f158 306 }
595491c4 307#endif
2258f158 308
309 return 0;
310}
311