d92ea048 |
1 | #include <stdio.h> |
2 | #include <string.h> |
3 | #include <sys/types.h> |
4 | #include <sys/stat.h> |
5 | #include <fcntl.h> |
6 | #include <sys/ioctl.h> |
7 | #include <unistd.h> |
8 | #include <linux/input.h> |
9 | #include <errno.h> |
10 | |
2258f158 |
11 | #include "../common/input.h" |
d92ea048 |
12 | #include "event.h" |
13 | |
d92ea048 |
14 | #define BIT(x) (keybits[(x)/sizeof(keybits[0])/8] & \ |
15 | (1 << ((x) & (sizeof(keybits[0])*8-1)))) |
16 | |
2258f158 |
17 | int in_evdev_probe(void) |
d92ea048 |
18 | { |
19 | int i; |
20 | |
2258f158 |
21 | for (i = 0;; i++) |
d92ea048 |
22 | { |
23 | int u, ret, fd, keybits[KEY_MAX/sizeof(int)]; |
24 | int support = 0, count = 0; |
25 | char name[64]; |
26 | |
27 | snprintf(name, sizeof(name), "/dev/input/event%d", i); |
28 | fd = open(name, O_RDONLY|O_NONBLOCK); |
29 | if (fd == -1) |
30 | break; |
31 | |
32 | /* check supported events */ |
33 | ret = ioctl(fd, EVIOCGBIT(0, sizeof(support)), &support); |
34 | if (ret == -1) { |
2258f158 |
35 | printf("in_evdev: ioctl failed on %s\n", name); |
d92ea048 |
36 | goto skip; |
37 | } |
38 | |
39 | if (!(support & (1 << EV_KEY))) |
40 | goto skip; |
41 | |
42 | ret = ioctl(fd, EVIOCGBIT(EV_KEY, sizeof(keybits)), keybits); |
43 | if (ret == -1) { |
2258f158 |
44 | printf("in_evdev: ioctl failed on %s\n", name); |
d92ea048 |
45 | goto skip; |
46 | } |
47 | |
d92ea048 |
48 | /* check for interesting keys */ |
49 | for (u = 0; u < KEY_MAX; u++) { |
2258f158 |
50 | if (BIT(u) && u != KEY_POWER && u != KEY_SLEEP) |
d92ea048 |
51 | count++; |
52 | } |
53 | |
54 | if (count == 0) |
55 | goto skip; |
56 | |
2258f158 |
57 | strcpy(name, "evdev:"); |
58 | ioctl(fd, EVIOCGNAME(sizeof(name)-6), name+6); |
59 | printf("in_evdev: found \"%s\" with %d events (type %08x)\n", |
60 | name+6, count, support); |
61 | in_register(name, IN_DRVID_EVDEV, (void *)fd); |
d92ea048 |
62 | continue; |
63 | |
64 | skip: |
65 | close(fd); |
66 | } |
67 | |
d92ea048 |
68 | return 0; |
69 | } |
70 | |
2258f158 |
71 | void in_evdev_free(void *drv_data) |
72 | { |
73 | close((int)drv_data); |
74 | } |
75 | |
76 | int in_evdev_bind_count(void) |
d92ea048 |
77 | { |
2258f158 |
78 | return 512; |
d92ea048 |
79 | } |
80 | |
2258f158 |
81 | int in_evdev_update(void *drv_data, int *binds) |
d92ea048 |
82 | { |
83 | struct input_event ev[16]; |
2258f158 |
84 | int keybits[KEY_MAX/sizeof(int)]; |
85 | int fd = (int)drv_data; |
86 | int result = 0, changed = 0; |
87 | int rd, ret, u; |
d92ea048 |
88 | |
2258f158 |
89 | while (1) { |
90 | rd = read(fd, ev, sizeof(ev)); |
91 | if (rd < (int)sizeof(ev[0])) { |
92 | if (errno != EAGAIN) |
93 | perror("in_evdev: read failed"); |
94 | break; |
d92ea048 |
95 | } |
96 | |
2258f158 |
97 | changed = 1; |
98 | } |
d92ea048 |
99 | |
2258f158 |
100 | /* |
101 | if (!changed) |
102 | return 0; |
103 | */ |
104 | ret = ioctl(fd, EVIOCGKEY(sizeof(keybits)), keybits); |
105 | if (ret == -1) { |
106 | perror("in_evdev: ioctl failed"); |
107 | return 0; |
108 | } |
d92ea048 |
109 | |
2258f158 |
110 | printf("#%d: ", fd); |
111 | for (u = 0; u < KEY_MAX; u++) { |
112 | if (BIT(u)) { |
113 | printf(" %d", u); |
114 | result |= binds[u]; |
d92ea048 |
115 | } |
d92ea048 |
116 | } |
2258f158 |
117 | printf("\n"); |
d92ea048 |
118 | |
119 | return result; |
120 | } |
121 | |