2258f158 |
1 | #include <stdio.h> |
2 | #include <stdlib.h> |
3 | #include <string.h> |
4 | |
5 | #include "input.h" |
6 | #include "../linux/event.h" |
7 | |
8 | typedef 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 | |
20 | static in_dev_t in_devices[IN_MAX_DEVS]; |
21 | static int in_dev_count = 0; |
22 | |
23 | static int in_bind_count(int drv_id) |
24 | { |
25 | int count = 0; |
26 | #ifdef IN_EVDEV |
27 | if (drv_id == IN_DRVID_EVDEV) |
28 | count = in_evdev_bind_count(); |
29 | #endif |
30 | if (count <= 0) |
31 | printf("input: failed to get bind count for drv %d\n", drv_id); |
32 | |
33 | return count; |
34 | } |
35 | |
36 | static int *in_alloc_binds(int drv_id) |
37 | { |
38 | int count, *ret; |
39 | |
40 | count = in_bind_count(drv_id); |
41 | if (count <= 0) { |
42 | printf("input: failed to get bind count for drv %d\n", drv_id); |
43 | return NULL; |
44 | } |
45 | |
46 | ret = malloc(count * sizeof(*ret)); |
47 | return ret; |
48 | } |
49 | |
50 | static void in_free(in_dev_t *dev) |
51 | { |
52 | if (dev->probed) { |
53 | #ifdef IN_EVDEV |
54 | if (dev->drv_id == IN_DRVID_EVDEV) |
55 | in_evdev_free(dev->drv_data); |
56 | #endif |
57 | } |
58 | dev->probed = 0; |
59 | dev->drv_data = NULL; |
60 | free(dev->name); |
61 | dev->name = NULL; |
62 | free(dev->binds); |
63 | dev->binds = NULL; |
64 | } |
65 | |
66 | /* to be called by drivers */ |
67 | void in_register(const char *nname, int drv_id, void *drv_data) |
68 | { |
69 | int i, dupe_count = 0, *binds; |
70 | char name[256], *name_end, *tmp; |
71 | |
72 | strncpy(name, nname, sizeof(name)); |
73 | name[sizeof(name)-12] = 0; |
74 | name_end = name + strlen(name); |
75 | |
76 | for (i = 0; i < in_dev_count; i++) |
77 | { |
78 | if (in_devices[i].name == NULL) |
79 | continue; |
80 | if (strcmp(in_devices[i].name, name) == 0) |
81 | { |
82 | if (in_devices[i].probed) { |
83 | dupe_count++; |
84 | sprintf(name_end, " [%d]", dupe_count); |
85 | continue; |
86 | } |
87 | goto update; |
88 | } |
89 | } |
90 | |
91 | if (i >= IN_MAX_DEVS) |
92 | { |
93 | /* try to find unused device */ |
94 | for (i = 0; i < IN_MAX_DEVS; i++) |
95 | if (!in_devices[i].probed) break; |
96 | if (i >= IN_MAX_DEVS) { |
97 | printf("input: too many devices, can't add %s\n", name); |
98 | return; |
99 | } |
100 | in_free(&in_devices[i]); |
101 | } |
102 | |
103 | tmp = strdup(name); |
104 | if (tmp == NULL) |
105 | return; |
106 | |
107 | binds = in_alloc_binds(drv_id); |
108 | if (binds == NULL) { |
109 | free(tmp); |
110 | return; |
111 | } |
112 | |
113 | in_devices[i].name = tmp; |
114 | in_devices[i].binds = binds; |
115 | if (i + 1 > in_dev_count) |
116 | in_dev_count = i + 1; |
117 | |
118 | printf("input: new device #%d \"%s\"\n", i, name); |
119 | update: |
120 | in_devices[i].probed = 1; |
121 | in_devices[i].drv_id = drv_id; |
122 | in_devices[i].drv_data = drv_data; |
123 | } |
124 | |
125 | void in_probe(void) |
126 | { |
127 | int i; |
128 | for (i = 0; i < in_dev_count; i++) |
129 | in_devices[i].probed = 0; |
130 | |
131 | #ifdef IN_EVDEV |
132 | in_evdev_probe(); |
133 | #endif |
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 | |
148 | void 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 | |
160 | int 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) { |
166 | #ifdef IN_EVDEV |
167 | result |= in_evdev_update(in_devices[i].drv_data, in_devices[i].binds); |
168 | #endif |
169 | } |
170 | } |
171 | |
172 | return result; |
173 | } |
174 | |
175 | void in_init(void) |
176 | { |
177 | memset(in_devices, 0, sizeof(in_devices)); |
178 | in_dev_count = 0; |
179 | } |
180 | |
181 | int main(void) |
182 | { |
183 | in_init(); |
184 | in_probe(); |
185 | |
186 | while (1) { |
187 | in_update(); |
188 | sleep(1); |
189 | } |
190 | |
191 | return 0; |
192 | } |
193 | |