renamed evdev
[libpicofe.git] / linux / in_evdev.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 "../common/input.h"
12 #include "event.h"
13
14 #define BIT(x) (keybits[(x)/sizeof(keybits[0])/8] & \
15         (1 << ((x) & (sizeof(keybits[0])*8-1))))
16
17 int in_evdev_probe(void)
18 {
19         int i;
20
21         for (i = 0;; i++)
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) {
35                         printf("in_evdev: ioctl failed on %s\n", name);
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) {
44                         printf("in_evdev: ioctl failed on %s\n", name);
45                         goto skip;
46                 }
47
48                 /* check for interesting keys */
49                 for (u = 0; u < KEY_MAX; u++) {
50                         if (BIT(u) && u != KEY_POWER && u != KEY_SLEEP)
51                                 count++;
52                 }
53
54                 if (count == 0)
55                         goto skip;
56
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);
62                 continue;
63
64 skip:
65                 close(fd);
66         }
67
68         return 0;
69 }
70
71 void in_evdev_free(void *drv_data)
72 {
73         close((int)drv_data);
74 }
75
76 int in_evdev_bind_count(void)
77 {
78         return 512;
79 }
80
81 int in_evdev_update(void *drv_data, int *binds)
82 {
83         struct input_event ev[16];
84         int keybits[KEY_MAX/sizeof(int)];
85         int fd = (int)drv_data;
86         int result = 0, changed = 0;
87         int rd, ret, u;
88
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;
95                 }
96
97                 changed = 1;
98         }
99
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         }
109
110         printf("#%d: ", fd);
111         for (u = 0; u < KEY_MAX; u++) {
112                 if (BIT(u)) {
113                         printf(" %d", u);
114                         result |= binds[u];
115                 }
116         }
117         printf("\n");
118
119         return result;
120 }
121