2258f158 |
1 | #include <stdio.h> |
2 | #include <stdlib.h> |
3 | #include <string.h> |
4 | |
fce20e73 |
5 | #include "common.h" |
2258f158 |
6 | #include "input.h" |
34581c95 |
7 | #include "../linux/in_evdev.h" |
2258f158 |
8 | |
9 | typedef struct |
10 | { |
11 | int drv_id; |
7f022a8d |
12 | int drv_fd_hnd; |
2258f158 |
13 | void *drv_data; |
2258f158 |
14 | char *name; |
906bdc9f |
15 | int *binds; |
2258f158 |
16 | int probed:1; |
2258f158 |
17 | } in_dev_t; |
18 | |
da767bd5 |
19 | static in_drv_t in_drivers[IN_DRVID_COUNT]; |
2258f158 |
20 | static in_dev_t in_devices[IN_MAX_DEVS]; |
21 | static int in_dev_count = 0; |
22 | |
da767bd5 |
23 | #define DRV(id) in_drivers[(unsigned)(id) < IN_DRVID_COUNT ? (id) : 0] |
24 | |
2258f158 |
25 | static int in_bind_count(int drv_id) |
26 | { |
da767bd5 |
27 | int count = DRV(drv_id).get_bind_count(); |
2258f158 |
28 | if (count <= 0) |
29 | printf("input: failed to get bind count for drv %d\n", drv_id); |
30 | |
31 | return count; |
32 | } |
33 | |
34 | static int *in_alloc_binds(int drv_id) |
35 | { |
da767bd5 |
36 | int count, *binds; |
2258f158 |
37 | |
38 | count = in_bind_count(drv_id); |
da767bd5 |
39 | if (count <= 0) |
2258f158 |
40 | return NULL; |
2258f158 |
41 | |
da767bd5 |
42 | binds = calloc(count * 2, sizeof(binds[0])); |
43 | if (binds == NULL) |
44 | return NULL; |
45 | |
46 | DRV(drv_id).get_def_binds(binds + count); |
47 | memcpy(binds, binds + count, count * sizeof(binds[0])); |
48 | |
49 | return binds; |
2258f158 |
50 | } |
51 | |
52 | static void in_free(in_dev_t *dev) |
53 | { |
da767bd5 |
54 | if (dev->probed) |
55 | DRV(dev->drv_id).free(dev->drv_data); |
2258f158 |
56 | dev->probed = 0; |
57 | dev->drv_data = NULL; |
58 | free(dev->name); |
59 | dev->name = NULL; |
60 | free(dev->binds); |
61 | dev->binds = NULL; |
62 | } |
63 | |
64 | /* to be called by drivers */ |
7f022a8d |
65 | void in_register(const char *nname, int drv_id, int drv_fd_hnd, void *drv_data) |
2258f158 |
66 | { |
da767bd5 |
67 | int i, ret, dupe_count = 0, *binds; |
2258f158 |
68 | char name[256], *name_end, *tmp; |
69 | |
70 | strncpy(name, nname, sizeof(name)); |
71 | name[sizeof(name)-12] = 0; |
72 | name_end = name + strlen(name); |
73 | |
74 | for (i = 0; i < in_dev_count; i++) |
75 | { |
76 | if (in_devices[i].name == NULL) |
77 | continue; |
78 | if (strcmp(in_devices[i].name, name) == 0) |
79 | { |
80 | if (in_devices[i].probed) { |
81 | dupe_count++; |
82 | sprintf(name_end, " [%d]", dupe_count); |
83 | continue; |
84 | } |
85 | goto update; |
86 | } |
87 | } |
88 | |
89 | if (i >= IN_MAX_DEVS) |
90 | { |
91 | /* try to find unused device */ |
92 | for (i = 0; i < IN_MAX_DEVS; i++) |
93 | if (!in_devices[i].probed) break; |
94 | if (i >= IN_MAX_DEVS) { |
95 | printf("input: too many devices, can't add %s\n", name); |
96 | return; |
97 | } |
98 | in_free(&in_devices[i]); |
99 | } |
100 | |
101 | tmp = strdup(name); |
102 | if (tmp == NULL) |
103 | return; |
104 | |
105 | binds = in_alloc_binds(drv_id); |
106 | if (binds == NULL) { |
107 | free(tmp); |
108 | return; |
109 | } |
110 | |
111 | in_devices[i].name = tmp; |
112 | in_devices[i].binds = binds; |
113 | if (i + 1 > in_dev_count) |
114 | in_dev_count = i + 1; |
115 | |
116 | printf("input: new device #%d \"%s\"\n", i, name); |
117 | update: |
118 | in_devices[i].probed = 1; |
119 | in_devices[i].drv_id = drv_id; |
7f022a8d |
120 | in_devices[i].drv_fd_hnd = drv_fd_hnd; |
2258f158 |
121 | in_devices[i].drv_data = drv_data; |
da767bd5 |
122 | |
123 | if (in_devices[i].binds != NULL) { |
124 | ret = DRV(drv_id).clean_binds(drv_data, in_devices[i].binds); |
125 | if (ret == 0) { |
126 | /* no useable binds */ |
127 | free(in_devices[i].binds); |
128 | in_devices[i].binds = NULL; |
129 | } |
130 | } |
2258f158 |
131 | } |
132 | |
133 | void in_probe(void) |
134 | { |
135 | int i; |
136 | for (i = 0; i < in_dev_count; i++) |
137 | in_devices[i].probed = 0; |
138 | |
da767bd5 |
139 | for (i = 1; i < IN_DRVID_COUNT; i++) |
140 | in_drivers[i].probe(); |
2258f158 |
141 | |
142 | /* get rid of devs without binds and probes */ |
143 | for (i = 0; i < in_dev_count; i++) { |
144 | if (!in_devices[i].probed && in_devices[i].binds == NULL) { |
145 | in_dev_count--; |
146 | if (i < in_dev_count) { |
147 | free(in_devices[i].name); |
148 | memmove(&in_devices[i], &in_devices[i+1], |
149 | (in_dev_count - i) * sizeof(in_devices[0])); |
150 | } |
151 | } |
152 | } |
153 | } |
154 | |
7f022a8d |
155 | /* async update */ |
2258f158 |
156 | int in_update(void) |
157 | { |
158 | int i, result = 0; |
159 | |
160 | for (i = 0; i < in_dev_count; i++) { |
906bdc9f |
161 | in_dev_t *dev = &in_devices[i]; |
906bdc9f |
162 | if (dev->probed && dev->binds != NULL) { |
163 | switch (dev->drv_id) { |
da767bd5 |
164 | #ifdef IN_EVDEV |
595491c4 |
165 | case IN_DRVID_EVDEV: |
86883f7f |
166 | result |= in_evdev_update(dev->drv_data, dev->binds); |
595491c4 |
167 | break; |
da767bd5 |
168 | #endif |
595491c4 |
169 | } |
2258f158 |
170 | } |
171 | } |
172 | |
173 | return result; |
174 | } |
175 | |
906bdc9f |
176 | static int menu_key_state = 0; |
177 | |
595491c4 |
178 | void in_set_blocking(int is_blocking) |
179 | { |
180 | int i; |
181 | |
182 | for (i = 0; i < in_dev_count; i++) { |
da767bd5 |
183 | if (in_devices[i].probed) |
184 | DRV(in_devices[i].drv_id).set_blocking(in_devices[i].drv_data, is_blocking); |
595491c4 |
185 | } |
906bdc9f |
186 | |
187 | menu_key_state = 0; |
188 | /* flush events */ |
fce20e73 |
189 | in_update_keycode(NULL, NULL, 0); |
595491c4 |
190 | } |
191 | |
7f022a8d |
192 | /* TODO: move.. */ |
193 | #include <unistd.h> |
194 | |
34581c95 |
195 | /* |
7f022a8d |
196 | * update with wait for a press, always return some keycode |
34581c95 |
197 | */ |
906bdc9f |
198 | int in_update_keycode(int *dev_id_out, int *is_down_out, int timeout_ms) |
34581c95 |
199 | { |
fce20e73 |
200 | int result = 0, dev_id = 0, is_down, result_menu; |
7f022a8d |
201 | int fds_hnds[IN_MAX_DEVS]; |
202 | int i, ret, count = 0; |
203 | in_drv_t *drv; |
204 | |
205 | for (i = 0; i < in_dev_count; i++) { |
206 | if (in_devices[i].probed) |
207 | fds_hnds[count++] = in_devices[i].drv_fd_hnd; |
208 | } |
34581c95 |
209 | |
210 | if (count == 0) { |
211 | /* don't deadlock, fail */ |
212 | printf("input: failed to find devices to read\n"); |
213 | exit(1); |
214 | } |
215 | |
7f022a8d |
216 | again: |
217 | /* TODO: move this block to platform/linux */ |
218 | { |
219 | struct timeval tv, *timeout = NULL; |
220 | int fdmax = -1; |
221 | fd_set fdset; |
222 | |
223 | if (timeout_ms >= 0) { |
224 | tv.tv_sec = timeout_ms / 1000; |
225 | tv.tv_usec = (timeout_ms % 1000) * 1000; |
226 | timeout = &tv; |
227 | } |
595491c4 |
228 | |
7f022a8d |
229 | FD_ZERO(&fdset); |
230 | for (i = 0; i < count; i++) { |
231 | if (fds_hnds[i] > fdmax) fdmax = fds_hnds[i]; |
232 | FD_SET(fds_hnds[i], &fdset); |
233 | } |
234 | |
235 | ret = select(fdmax + 1, &fdset, NULL, NULL, timeout); |
236 | if (ret == -1) |
237 | { |
238 | perror("input: select failed"); |
239 | sleep(1); |
240 | return 0; |
241 | } |
242 | |
243 | if (ret == 0) |
244 | return 0; /* timeout */ |
245 | |
246 | for (i = 0; i < count; i++) |
247 | if (FD_ISSET(fds_hnds[i], &fdset)) |
248 | ret = fds_hnds[i]; |
249 | } |
250 | |
251 | for (i = 0; i < in_dev_count; i++) { |
252 | if (in_devices[i].drv_fd_hnd == ret) { |
906bdc9f |
253 | dev_id = i; |
254 | break; |
595491c4 |
255 | } |
256 | } |
7f022a8d |
257 | |
258 | drv = &DRV(in_devices[dev_id].drv_id); |
259 | result = drv->update_keycode(in_devices[dev_id].drv_data, &is_down); |
260 | |
261 | /* update_keycode() might return 0 when some not interesting |
262 | * event happened, like sync event for evdev. |
263 | * XXX: timeout restarts.. */ |
264 | if (result == 0) |
265 | goto again; |
34581c95 |
266 | |
906bdc9f |
267 | /* keep track of menu key state, to allow mixing |
fce20e73 |
268 | * in_update_keycode() and in_menu_wait_any() calls */ |
7f022a8d |
269 | result_menu = drv->menu_translate(result); |
906bdc9f |
270 | if (result_menu != 0) { |
271 | if (is_down) |
272 | menu_key_state |= result_menu; |
273 | else |
274 | menu_key_state &= ~result_menu; |
275 | } |
276 | |
277 | if (dev_id_out != NULL) |
278 | *dev_id_out = dev_id; |
279 | if (is_down_out != NULL) |
280 | *is_down_out = is_down; |
34581c95 |
281 | return result; |
282 | } |
283 | |
fce20e73 |
284 | /* same as above, only return bitfield of PBTN_* */ |
285 | int in_menu_wait_any(int timeout_ms) |
595491c4 |
286 | { |
906bdc9f |
287 | int keys_old = menu_key_state; |
595491c4 |
288 | |
289 | while (1) |
290 | { |
da767bd5 |
291 | int code, is_down = 0, dev_id = 0; |
595491c4 |
292 | |
906bdc9f |
293 | code = in_update_keycode(&dev_id, &is_down, timeout_ms); |
294 | code = DRV(in_devices[dev_id].drv_id).menu_translate(code); |
595491c4 |
295 | |
fce20e73 |
296 | if (timeout_ms >= 0) |
906bdc9f |
297 | break; |
298 | if (code == 0) |
299 | continue; |
300 | if (keys_old != menu_key_state) |
595491c4 |
301 | break; |
302 | } |
303 | |
906bdc9f |
304 | return menu_key_state; |
595491c4 |
305 | } |
306 | |
fce20e73 |
307 | /* wait for menu input, do autorepeat */ |
308 | int in_menu_wait(int interesting) |
309 | { |
310 | static int inp_prev = 0; |
6c263f30 |
311 | static int repeats = 0; |
312 | int ret, release = 0, wait = 666; |
fce20e73 |
313 | |
6c263f30 |
314 | if (repeats) |
315 | wait = 33; |
fce20e73 |
316 | |
6c263f30 |
317 | ret = in_menu_wait_any(wait); |
318 | if (ret == inp_prev) |
319 | repeats++; |
fce20e73 |
320 | |
321 | while (!(ret & interesting)) { |
322 | ret = in_menu_wait_any(-1); |
323 | release = 1; |
324 | } |
325 | |
6c263f30 |
326 | if (release || ret != inp_prev) |
fce20e73 |
327 | repeats = 0; |
6c263f30 |
328 | |
fce20e73 |
329 | inp_prev = ret; |
330 | |
6c263f30 |
331 | /* we don't need diagonals in menus */ |
fce20e73 |
332 | if ((ret & PBTN_UP) && (ret & PBTN_LEFT)) ret &= ~PBTN_LEFT; |
333 | if ((ret & PBTN_UP) && (ret & PBTN_RIGHT)) ret &= ~PBTN_RIGHT; |
334 | if ((ret & PBTN_DOWN) && (ret & PBTN_LEFT)) ret &= ~PBTN_LEFT; |
335 | if ((ret & PBTN_DOWN) && (ret & PBTN_RIGHT)) ret &= ~PBTN_RIGHT; |
336 | |
337 | return ret; |
338 | } |
339 | |
da767bd5 |
340 | const int *in_get_dev_binds(int dev_id) |
341 | { |
342 | if (dev_id < 0 || dev_id >= IN_MAX_DEVS) |
343 | return NULL; |
344 | |
345 | return in_devices[dev_id].binds; |
346 | } |
347 | |
348 | const int *in_get_dev_def_binds(int dev_id) |
349 | { |
350 | int count; |
351 | |
352 | if (dev_id < 0 || dev_id >= IN_MAX_DEVS) |
353 | return NULL; |
354 | |
355 | count = in_bind_count(in_devices[dev_id].drv_id); |
356 | return in_devices[dev_id].binds + count; |
357 | } |
358 | |
359 | int in_get_dev_bind_count(int dev_id) |
360 | { |
361 | if (dev_id < 0 || dev_id >= IN_MAX_DEVS) |
362 | return 0; |
363 | |
364 | return in_bind_count(in_devices[dev_id].drv_id); |
365 | } |
366 | |
fce20e73 |
367 | const char *in_get_dev_name(int dev_id, int must_be_active) |
da767bd5 |
368 | { |
369 | if (dev_id < 0 || dev_id >= IN_MAX_DEVS) |
370 | return NULL; |
371 | |
fce20e73 |
372 | if (must_be_active && !in_devices[dev_id].probed) |
373 | return NULL; |
da767bd5 |
374 | return in_devices[dev_id].name; |
375 | } |
376 | |
906bdc9f |
377 | /* never returns NULL */ |
595491c4 |
378 | const char *in_get_key_name(int dev_id, int keycode) |
379 | { |
906bdc9f |
380 | static char xname[16]; |
381 | const char *name; |
382 | |
595491c4 |
383 | if (dev_id < 0 || dev_id >= IN_MAX_DEVS) |
384 | return "Unkn0"; |
da767bd5 |
385 | |
906bdc9f |
386 | name = DRV(in_devices[dev_id].drv_id).get_key_name(keycode); |
387 | if (name != NULL) |
388 | return name; |
389 | |
390 | /* assume scancode */ |
391 | if ((keycode >= '0' && keycode <= '9') || (keycode >= 'a' && keycode <= 'z') |
392 | || (keycode >= 'A' && keycode <= 'Z')) |
393 | sprintf(xname, "%c", keycode); |
394 | else |
395 | sprintf(xname, "\\x%02X", keycode); |
396 | return xname; |
397 | } |
398 | |
399 | int in_bind_key(int dev_id, int keycode, int mask, int force_unbind) |
400 | { |
401 | int ret, count; |
402 | in_dev_t *dev; |
403 | |
404 | if (dev_id < 0 || dev_id >= IN_MAX_DEVS) |
405 | return -1; |
406 | dev = &in_devices[dev_id]; |
407 | |
408 | if (dev->binds == NULL) { |
409 | if (force_unbind) |
410 | return 0; |
411 | dev->binds = in_alloc_binds(dev->drv_id); |
412 | if (dev->binds == NULL) |
413 | return -1; |
414 | } |
415 | |
416 | count = in_bind_count(dev->drv_id); |
417 | if (keycode < 0 || keycode >= count) |
418 | return -1; |
419 | |
420 | if (force_unbind) |
421 | dev->binds[keycode] &= ~mask; |
422 | else |
423 | dev->binds[keycode] ^= mask; |
424 | |
425 | ret = DRV(dev->drv_id).clean_binds(dev->drv_data, dev->binds); |
426 | if (ret == 0) { |
427 | free(dev->binds); |
428 | dev->binds = NULL; |
429 | } |
430 | |
431 | return 0; |
da767bd5 |
432 | } |
433 | |
434 | /* returns device id, or -1 on error */ |
435 | int in_config_parse_dev(const char *name) |
436 | { |
437 | int drv_id = -1, i; |
438 | |
439 | for (i = 0; i < IN_DRVID_COUNT; i++) { |
440 | int len = strlen(in_drivers[i].prefix); |
441 | if (strncmp(name, in_drivers[i].prefix, len) == 0) { |
442 | drv_id = i; |
443 | break; |
444 | } |
445 | } |
446 | |
447 | if (drv_id < 0) { |
448 | printf("input: missing driver for %s\n", name); |
449 | return -1; |
450 | } |
451 | |
452 | for (i = 0; i < in_dev_count; i++) |
453 | { |
454 | if (in_devices[i].name == NULL) |
455 | continue; |
456 | if (strcmp(in_devices[i].name, name) == 0) |
457 | return i; |
458 | } |
459 | |
460 | if (i >= IN_MAX_DEVS) |
461 | { |
462 | /* try to find unused device */ |
463 | for (i = 0; i < IN_MAX_DEVS; i++) |
464 | if (in_devices[i].name == NULL) break; |
465 | if (i >= IN_MAX_DEVS) { |
466 | printf("input: too many devices, can't add %s\n", name); |
467 | return -1; |
468 | } |
469 | } |
470 | |
471 | memset(&in_devices[i], 0, sizeof(in_devices[i])); |
472 | |
473 | in_devices[i].name = strdup(name); |
474 | if (in_devices[i].name == NULL) |
475 | return -1; |
476 | |
477 | if (i + 1 > in_dev_count) |
478 | in_dev_count = i + 1; |
479 | in_devices[i].drv_id = drv_id; |
480 | |
481 | return i; |
482 | } |
483 | |
6c263f30 |
484 | /* |
485 | * To reduce size of game specific configs, default binds are not saved. |
486 | * So we mark default binds in in_config_start(), override them in in_config_bind_key(), |
487 | * and restore whatever default binds are left in in_config_end(). |
488 | */ |
da767bd5 |
489 | void in_config_start(void) |
490 | { |
491 | int i; |
492 | |
493 | /* mark all default binds, so they get overwritten by func below */ |
494 | for (i = 0; i < IN_MAX_DEVS; i++) { |
495 | int n, count, *binds, *def_binds; |
496 | |
906bdc9f |
497 | binds = in_devices[i].binds; |
498 | if (binds == NULL) |
da767bd5 |
499 | continue; |
500 | |
501 | count = in_bind_count(in_devices[i].drv_id); |
da767bd5 |
502 | def_binds = binds + count; |
503 | |
504 | for (n = 0; n < count; n++) |
505 | if (binds[n] == def_binds[n]) |
506 | binds[n] = -1; |
507 | } |
508 | } |
509 | |
510 | int in_config_bind_key(int dev_id, const char *key, int binds) |
511 | { |
906bdc9f |
512 | int count, kc; |
513 | in_dev_t *dev; |
da767bd5 |
514 | |
515 | if (dev_id < 0 || dev_id >= IN_MAX_DEVS) |
516 | return -1; |
906bdc9f |
517 | dev = &in_devices[dev_id]; |
da767bd5 |
518 | |
906bdc9f |
519 | count = in_bind_count(dev->drv_id); |
520 | |
521 | /* maybe a raw code? */ |
522 | if (key[0] == '\\' && key[1] == 'x') { |
523 | char *p = NULL; |
524 | kc = (int)strtoul(key + 2, &p, 16); |
525 | if (p == NULL || *p != 0) |
526 | kc = -1; |
527 | } |
528 | else { |
529 | /* device specific key name */ |
530 | if (dev->binds == NULL) { |
531 | dev->binds = in_alloc_binds(dev->drv_id); |
532 | if (dev->binds == NULL) |
533 | return -1; |
534 | in_config_start(); |
535 | } |
536 | |
537 | kc = DRV(dev->drv_id).get_key_code(key); |
538 | if (kc < 0 && strlen(key) == 1) { |
539 | /* assume scancode */ |
540 | kc = key[0]; |
541 | } |
da767bd5 |
542 | } |
543 | |
906bdc9f |
544 | if (kc < 0 || kc >= count) { |
da767bd5 |
545 | printf("input: bad key: %s\n", key); |
546 | return -1; |
595491c4 |
547 | } |
548 | |
906bdc9f |
549 | if (dev->binds[kc] == -1) |
550 | dev->binds[kc] = 0; |
551 | dev->binds[kc] |= binds; |
da767bd5 |
552 | |
553 | return 0; |
554 | } |
555 | |
556 | void in_config_end(void) |
557 | { |
558 | int i; |
559 | |
560 | for (i = 0; i < IN_MAX_DEVS; i++) { |
561 | int n, ret, count, *binds, *def_binds; |
906bdc9f |
562 | in_dev_t *dev = &in_devices[i]; |
da767bd5 |
563 | |
906bdc9f |
564 | if (dev->binds == NULL) |
da767bd5 |
565 | continue; |
566 | |
906bdc9f |
567 | count = in_bind_count(dev->drv_id); |
568 | binds = dev->binds; |
da767bd5 |
569 | def_binds = binds + count; |
570 | |
571 | for (n = 0; n < count; n++) |
572 | if (binds[n] == -1) |
573 | binds[n] = def_binds[n]; |
574 | |
906bdc9f |
575 | if (dev->drv_data == NULL) |
da767bd5 |
576 | continue; |
577 | |
906bdc9f |
578 | ret = DRV(dev->drv_id).clean_binds(dev->drv_data, binds); |
da767bd5 |
579 | if (ret == 0) { |
580 | /* no useable binds */ |
906bdc9f |
581 | free(dev->binds); |
582 | dev->binds = NULL; |
da767bd5 |
583 | } |
584 | } |
595491c4 |
585 | } |
586 | |
da767bd5 |
587 | void in_debug_dump(void) |
588 | { |
589 | int i; |
590 | |
591 | printf("# drv probed binds name\n"); |
592 | for (i = 0; i < IN_MAX_DEVS; i++) { |
593 | in_dev_t *d = &in_devices[i]; |
594 | if (!d->probed && d->name == NULL && d->binds == NULL) |
595 | continue; |
596 | printf("%d %3d %6c %5c %s\n", i, d->drv_id, d->probed ? 'y' : 'n', |
597 | d->binds ? 'y' : 'n', d->name); |
598 | } |
599 | } |
600 | |
601 | /* handlers for unknown/not_preset drivers */ |
602 | |
603 | static void in_def_probe(void) {} |
604 | static void in_def_free(void *drv_data) {} |
605 | static int in_def_get_bind_count(void) { return 0; } |
606 | static void in_def_get_def_binds(int *binds) {} |
607 | static int in_def_clean_binds(void *drv_data, int *binds) { return 0; } |
608 | static void in_def_set_blocking(void *data, int y) {} |
7f022a8d |
609 | static int in_def_update_keycode(void *drv_data, int *is_down) { return 0; } |
da767bd5 |
610 | static int in_def_menu_translate(int keycode) { return keycode; } |
611 | static int in_def_get_key_code(const char *key_name) { return 0; } |
612 | static const char *in_def_get_key_name(int keycode) { return NULL; } |
613 | |
2258f158 |
614 | void in_init(void) |
615 | { |
da767bd5 |
616 | int i; |
617 | |
618 | memset(in_drivers, 0, sizeof(in_drivers)); |
2258f158 |
619 | memset(in_devices, 0, sizeof(in_devices)); |
620 | in_dev_count = 0; |
da767bd5 |
621 | |
622 | for (i = 0; i < IN_DRVID_COUNT; i++) { |
623 | in_drivers[i].prefix = "none:"; |
624 | in_drivers[i].probe = in_def_probe; |
625 | in_drivers[i].free = in_def_free; |
626 | in_drivers[i].get_bind_count = in_def_get_bind_count; |
627 | in_drivers[i].get_def_binds = in_def_get_def_binds; |
628 | in_drivers[i].clean_binds = in_def_clean_binds; |
629 | in_drivers[i].set_blocking = in_def_set_blocking; |
7f022a8d |
630 | in_drivers[i].update_keycode = in_def_update_keycode; |
da767bd5 |
631 | in_drivers[i].menu_translate = in_def_menu_translate; |
632 | in_drivers[i].get_key_code = in_def_get_key_code; |
633 | in_drivers[i].get_key_name = in_def_get_key_name; |
634 | } |
635 | |
636 | #ifdef IN_EVDEV |
637 | in_evdev_init(&in_drivers[IN_DRVID_EVDEV]); |
638 | #endif |
2258f158 |
639 | } |
640 | |
da767bd5 |
641 | #if 0 |
2258f158 |
642 | int main(void) |
643 | { |
34581c95 |
644 | int ret; |
645 | |
2258f158 |
646 | in_init(); |
647 | in_probe(); |
648 | |
595491c4 |
649 | in_set_blocking(1); |
650 | |
651 | #if 1 |
652 | while (1) { |
653 | int dev = 0, down; |
654 | ret = in_update_keycode(&dev, &down); |
655 | printf("#%i: %i %i (%s)\n", dev, down, ret, in_get_key_name(dev, ret)); |
656 | } |
657 | #else |
2258f158 |
658 | while (1) { |
fce20e73 |
659 | ret = in_menu_wait_any(); |
34581c95 |
660 | printf("%08x\n", ret); |
2258f158 |
661 | } |
595491c4 |
662 | #endif |
2258f158 |
663 | |
664 | return 0; |
665 | } |
da767bd5 |
666 | #endif |