]> git.ipfire.org Git - people/pmueller/ipfire-2.x.git/blob - src/hwinfo/src/hd/input.c
Signierten GPG-Schluessel importiert.
[people/pmueller/ipfire-2.x.git] / src / hwinfo / src / hd / input.c
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h>
4 #include <unistd.h>
5 #include <fcntl.h>
6 #include <sys/stat.h>
7 #include <sys/types.h>
8 #include <linux/input.h>
9
10 #include "hd.h"
11 #include "hd_int.h"
12 #include "hddb.h"
13 #include "input.h"
14
15 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
16 * input devs
17 *
18 * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
19 */
20
21 static void get_input_devices(hd_data_t *hd_data);
22 static char *all_bits(char *str);
23 static int test_bit(char *str, unsigned bit);
24
25 void hd_scan_input(hd_data_t *hd_data)
26 {
27 if(!hd_probe_feature(hd_data, pr_input)) return;
28
29 hd_data->module = mod_input;
30
31 /* some clean-up */
32 remove_hd_entries(hd_data);
33
34 PROGRESS(1, 0, "joydev mod");
35 load_module(hd_data, "joydev");
36
37 PROGRESS(1, 1, "evdev mod");
38 load_module(hd_data, "evdev");
39
40 PROGRESS(2, 0, "input");
41
42 get_input_devices(hd_data);
43 }
44
45
46 #define INP_NAME "N: Name="
47 #define INP_HANDLERS "H: Handlers="
48 #define INP_KEY "B: KEY="
49 #define INP_REL "B: REL="
50
51 void get_input_devices(hd_data_t *hd_data)
52 {
53 hd_t *hd;
54 str_list_t *input, *sl, *sl1;
55 char *s;
56 unsigned ok, u;
57 unsigned bus, vendor, product, version;
58 unsigned mouse_buttons, mouse_wheels;
59 char *name = NULL, *handlers = NULL, *key = NULL, *rel = NULL;
60 size_t len;
61 str_list_t *handler_list;
62 hd_dev_num_t dev_num = { type: 'c', range: 1 };
63
64 input = read_file("/proc/bus/input/devices", 0, 0);
65
66 ADD2LOG("----- /proc/bus/input/devices -----\n");
67 for(sl = input; sl; sl = sl->next) {
68 ADD2LOG(" %s", sl->str);
69 }
70 ADD2LOG("----- /proc/bus/input/devices end -----\n");
71
72 for(ok = 0, sl = input; sl; sl = sl->next) {
73 if(*sl->str == '\n') {
74 ADD2LOG("bus = %u, name = %s\n", bus, name);
75 if(handlers) ADD2LOG(" handlers = %s\n", handlers);
76 if(key) ADD2LOG(" key = %s\n", key);
77 if(rel) ADD2LOG(" rel = %s\n", rel);
78
79 mouse_buttons = 0;
80 if(key) {
81 for(u = BTN_MOUSE; u < BTN_MOUSE + 8; u++) {
82 if(test_bit(key, u)) mouse_buttons++;
83 }
84 }
85 ADD2LOG(" mouse buttons = %u\n", mouse_buttons);
86
87 mouse_wheels = 0;
88 if(rel) {
89 for(u = REL_HWHEEL; u <= REL_MAX; u++) {
90 if(test_bit(rel, u)) mouse_wheels++;
91 }
92 }
93 ADD2LOG(" mouse wheels = %u\n", mouse_wheels);
94
95 if(ok && handlers) {
96 handler_list = hd_split(' ', handlers);
97
98 if(bus == BUS_USB) {
99 s = NULL;
100 for(sl1 = handler_list; sl1; sl1 = sl1->next) {
101 if(sscanf(sl1->str, "mouse%u", &u) == 1) {
102 str_printf(&s, 0, "/dev/input/mouse%u", u);
103 break;
104 }
105 }
106
107 if(s) {
108 for(hd = hd_data->hd; hd; hd = hd->next) {
109 if(hd->unix_dev_name2 && !strcmp(hd->unix_dev_name2, s)) {
110 hd->compat_vendor.id = MAKE_ID(TAG_SPECIAL, 0x0210);
111 hd->compat_device.id = MAKE_ID(TAG_SPECIAL, (mouse_wheels << 4) + mouse_buttons);
112 }
113 }
114 }
115
116 s = free_mem(s);
117 }
118 else {
119 if(search_str_list(handler_list, "kbd") && test_bit(key, KEY_1)) {
120 hd = add_hd_entry(hd_data, __LINE__, 0);
121 hd->base_class.id = bc_keyboard;
122 hd->sub_class.id = sc_keyboard_kbd;
123 hd->bus.id = bus_ps2;
124
125 hd->vendor.id = MAKE_ID(TAG_SPECIAL, 0x0211);
126 hd->device.id = MAKE_ID(TAG_SPECIAL, 0x0001);
127 hd->device.name = new_str(name);
128
129 for(sl1 = handler_list; sl1; sl1 = sl1->next) {
130 if(sscanf(sl1->str, "event%u", &u) == 1) {
131 str_printf(&hd->unix_dev_name, 0, "/dev/input/event%u", u);
132 dev_num.major = 13;
133 dev_num.minor = 64 + u;
134 hd->unix_dev_num = dev_num;
135 break;
136 }
137 }
138 }
139 else if(strstr(handlers, "mouse")) {
140 hd = add_hd_entry(hd_data, __LINE__, 0);
141 hd->base_class.id = bc_mouse;
142 hd->sub_class.id = sc_mou_ps2;
143 hd->bus.id = bus_ps2;
144
145 hd->vendor.id = MAKE_ID(TAG_SPECIAL, 0x0210);
146 hd->device.id = MAKE_ID(TAG_SPECIAL, (mouse_wheels << 4) + mouse_buttons);
147 hd->device.name = new_str(name);
148
149 /* Synaptics/Alps TouchPad */
150 if(vendor == 2 && (product == 7 || product == 8)) {
151 hd->compat_vendor.id = hd->vendor.id;
152 hd->compat_device.id = hd->device.id;
153 hd->vendor.id = MAKE_ID(TAG_SPECIAL, 0x0212);
154 hd->device.id = MAKE_ID(TAG_SPECIAL, product - 6);
155 }
156
157 hd->unix_dev_name = new_str(DEV_MICE);
158 dev_num.major = 13;
159 dev_num.minor = 63;
160 hd->unix_dev_num = dev_num;
161
162 for(sl1 = handler_list; sl1; sl1 = sl1->next) {
163 if(sscanf(sl1->str, "mouse%u", &u) == 1) {
164 str_printf(&hd->unix_dev_name2, 0, "/dev/input/mouse%u", u);
165 dev_num.major = 13;
166 dev_num.minor = 32 + u;
167 hd->unix_dev_num2 = dev_num;
168 break;
169 }
170 }
171
172 }
173 }
174
175 handler_list = free_str_list(handler_list);
176 }
177
178 ok = 0;
179
180 name = free_mem(name);
181 handlers = free_mem(handlers);
182 key = free_mem(key);
183 rel = free_mem(rel);
184 }
185
186 if(sscanf(sl->str, "I: Bus=%04x Vendor=%04x Product=%04x Version=%04x", &bus, &vendor, &product, &version) == 4) {
187 ok = 1;
188 continue;
189 }
190
191 if(!strncmp(sl->str, INP_NAME, sizeof INP_NAME - 1)) {
192 s = sl->str + sizeof INP_NAME;
193 len = strlen(s);
194 if(len > 2) {
195 name = canon_str(s, len - 2);
196 }
197 continue;
198 }
199
200 if(!strncmp(sl->str, INP_HANDLERS, sizeof INP_HANDLERS - 1)) {
201 s = sl->str + sizeof INP_HANDLERS - 1;
202 handlers = canon_str(s, strlen(s));
203 continue;
204 }
205
206 if(!strncmp(sl->str, INP_KEY, sizeof INP_KEY - 1)) {
207 s = sl->str + sizeof INP_KEY - 1;
208 key = canon_str(s, strlen(s));
209 key = all_bits(key);
210 continue;
211 }
212
213 if(!strncmp(sl->str, INP_REL, sizeof INP_REL - 1)) {
214 s = sl->str + sizeof INP_REL - 1;
215 rel = canon_str(s, strlen(s));
216 rel = all_bits(rel);
217 continue;
218 }
219 }
220
221 free_str_list(input);
222
223 }
224
225
226 char *all_bits(char *str)
227 {
228 str_list_t *sl, *sl0;
229 char *s = NULL;
230 unsigned u;
231
232 if(!str) return NULL;
233
234 sl = sl0 = hd_split(' ', str);
235 for(; sl; sl = sl->next) {
236 u = strtoul(sl->str, NULL, 16);
237 str_printf(&s, -1, "%08x", u);
238 }
239 free_str_list(sl0);
240 free_mem(str);
241
242 return s;
243 }
244
245
246 int test_bit(char *str, unsigned bit)
247 {
248 size_t len, ofs;
249 unsigned u, mask;
250
251 if(!str) return 0;
252
253 len = strlen(str);
254
255 ofs = bit >> 2;
256 mask = 1 << (bit & 3);
257
258 if(ofs >= len) return 0;
259
260 ofs = len - ofs - 1;
261
262 u = str[ofs] >= 'a' ? str[ofs] - 'a' + 10 : str[ofs] - '0';
263
264 return (u & mask) ? 1 : 0;
265 }
266
267