dea507274e1ceed7bce62e197bc0e951d5e74ebb
[libpicofe.git] / linux / event.c
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
11 #include "event.h"
12
13 #define NUM_DEVS        8
14 #define NUM_KEYS_DOWN   16
15
16 #define BIT(x) (keybits[(x)/sizeof(keybits[0])/8] & \
17         (1 << ((x) & (sizeof(keybits[0])*8-1))))
18
19 static int event_fds[NUM_DEVS];
20 static int event_fd_count = 0;
21
22 int in_event_init(void)
23 {
24         int i;
25
26         in_event_exit();
27
28         for (i = 0; event_fd_count < NUM_DEVS; i++)
29         {
30                 int u, ret, fd, keybits[KEY_MAX/sizeof(int)];
31                 int support = 0, count = 0;
32                 char name[64];
33
34                 snprintf(name, sizeof(name), "/dev/input/event%d", i);
35                 fd = open(name, O_RDONLY|O_NONBLOCK);
36                 if (fd == -1)
37                         break;
38
39                 /* check supported events */
40                 ret = ioctl(fd, EVIOCGBIT(0, sizeof(support)), &support);
41                 if (ret == -1) {
42                         printf("in_event: ioctl failed on %s\n", name);
43                         goto skip;
44                 }
45
46                 if (!(support & (1 << EV_KEY)))
47                         goto skip;
48
49                 ret = ioctl(fd, EVIOCGBIT(EV_KEY, sizeof(keybits)), keybits);
50                 if (ret == -1) {
51                         printf("in_event: ioctl failed on %s\n", name);
52                         goto skip;
53                 }
54
55                 printf("%s: %08x\n", name, support);
56
57                 /* check for interesting keys */
58                 for (u = 0; u < KEY_MAX; u++) {
59                         if (BIT(u) && u != KEY_POWER)
60                                 count++;
61                 }
62
63                 if (count == 0)
64                         goto skip;
65
66                 ioctl(fd, EVIOCGNAME(sizeof(name)), name);
67                 printf("event: %d: using \"%s\" with %d events\n",
68                         event_fd_count, name, count);
69                 event_fds[event_fd_count++] = fd;
70                 continue;
71
72 skip:
73                 close(fd);
74         }
75
76         printf("event: %d devices found.\n", event_fd_count);
77         return 0;
78 }
79
80 void in_event_exit(void)
81 {
82         for (; event_fd_count > 0; event_fd_count--)
83                 close(event_fds[event_fd_count - 1]);
84 }
85
86 int in_event_update(int binds[512])
87 {
88         struct input_event ev[16];
89         int d, rd, ret;
90         int result = 0;
91
92         for (d = 0; d < event_fd_count; d++)
93         {
94                 int keybits[KEY_MAX/sizeof(int)];
95                 int fd = event_fds[d];
96                 int u, changed = 0;
97
98                 while (1) {
99                         rd = read(fd, ev, sizeof(ev));
100                         if (rd < (int)sizeof(ev[0])) {
101                                 if (errno != EAGAIN)
102                                         perror("event: read failed");
103                                 break;
104                         }
105
106                         changed = 1;
107                 }
108
109                 if (!changed)
110                         continue;
111
112                 ret = ioctl(fd, EVIOCGKEY(sizeof(keybits)), keybits);
113                 if (ret == -1) {
114                         printf("in_event: ioctl failed on %d\n", d);
115                         continue;
116                 }
117
118                 for (u = 0; u < KEY_MAX; u++) {
119                         if (BIT(u)) {
120                                 printf(" %d", u);
121                                 result |= binds[u];
122                         }
123                 }
124                 printf("\n");
125         }
126
127         return result;
128 }
129
130 int main()
131 {
132         in_event_init();
133
134         while (1) {
135                 int b[512];
136                 in_event_update(b);
137                 sleep(1);
138         }
139
140         return 0;
141 }
142