Lines 1-6
Link Here
|
1 |
--- config/devd.c.orig 2014-12-16 23:03:10 UTC |
1 |
--- config/devd.c 2015-01-12 10:47:19.000000000 +0100 |
2 |
+++ config/devd.c |
2 |
+++ config/devd.c 2015-01-13 12:02:22.000000000 +0100 |
3 |
@@ -0,0 +1,530 @@ |
3 |
@@ -0,0 +1,574 @@ |
4 |
+/* |
4 |
+/* |
5 |
+ * Copyright (c) 2012 Baptiste Daroussin |
5 |
+ * Copyright (c) 2012 Baptiste Daroussin |
6 |
+ * Copyright (c) 2013, 2014 Alex Kozlov |
6 |
+ * Copyright (c) 2013, 2014 Alex Kozlov |
Lines 41-52
Link Here
|
41 |
+#include <sys/un.h> |
41 |
+#include <sys/un.h> |
42 |
+ |
42 |
+ |
43 |
+#include <ctype.h> |
43 |
+#include <ctype.h> |
|
|
44 |
+#include <dirent.h> |
44 |
+#include <errno.h> |
45 |
+#include <errno.h> |
45 |
+#include <fcntl.h> |
46 |
+#include <fcntl.h> |
46 |
+#include <stdlib.h> |
47 |
+#include <stdlib.h> |
47 |
+#include <stdio.h> |
48 |
+#include <stdio.h> |
48 |
+#include <stdbool.h> |
49 |
+#include <stdbool.h> |
49 |
+#include <unistd.h> |
50 |
+#include <unistd.h> |
|
|
51 |
+#include <paths.h> |
50 |
+ |
52 |
+ |
51 |
+#include "input.h" |
53 |
+#include "input.h" |
52 |
+#include "inputstr.h" |
54 |
+#include "inputstr.h" |
Lines 56-68
Link Here
|
56 |
+ |
58 |
+ |
57 |
+#define DEVD_SOCK_PATH "/var/run/devd.pipe" |
59 |
+#define DEVD_SOCK_PATH "/var/run/devd.pipe" |
58 |
+ |
60 |
+ |
59 |
+#define DEVD_EVENT_ADD '+' |
61 |
+#define RECONNECT_DELAY (5 * 1000) |
60 |
+#define DEVD_EVENT_REMOVE '-' |
|
|
61 |
+ |
62 |
+#define RECONNECT_DELAY 5 * 1000 |
63 |
+ |
62 |
+ |
64 |
+static int sock_devd; |
63 |
+static int sock_devd; |
65 |
+static bool is_console_kbd = false; |
|
|
66 |
+static bool is_kbdmux = false; |
64 |
+static bool is_kbdmux = false; |
67 |
+OsTimerPtr rtimer; |
65 |
+OsTimerPtr rtimer; |
68 |
+ |
66 |
+ |
Lines 70-139
Link Here
|
70 |
+ const char *driver; |
68 |
+ const char *driver; |
71 |
+ int flag; |
69 |
+ int flag; |
72 |
+ const char *xdriver; |
70 |
+ const char *xdriver; |
|
|
71 |
+ const char *sysctldesc; |
73 |
+}; |
72 |
+}; |
74 |
+ |
73 |
+ |
75 |
+static struct hw_type hw_types[] = { |
74 |
+static const struct hw_type hw_types0[] = { |
76 |
+ { "ukbd", ATTR_KEYBOARD, "kbd" }, |
75 |
+ { _PATH_DEV "sysmouse", ATTR_POINTER, "mouse", NULL }, |
77 |
+ { "atkbd", ATTR_KEYBOARD, "kbd" }, |
76 |
+ { NULL, 0, NULL, NULL }, |
78 |
+ { "kbdmux", ATTR_KEYBOARD, "kbd" }, |
|
|
79 |
+ { "sysmouse", ATTR_POINTER, "mouse" }, |
80 |
+ { "ums", ATTR_POINTER, "mouse" }, |
81 |
+ { "psm", ATTR_POINTER, "mouse" }, |
82 |
+ { "joy", ATTR_JOYSTICK, NULL }, |
83 |
+ { "atp", ATTR_TOUCHPAD, NULL }, |
84 |
+ { "uep", ATTR_TOUCHSCREEN, NULL }, |
85 |
+ { NULL, -1, NULL }, |
86 |
+}; |
77 |
+}; |
87 |
+ |
78 |
+ |
88 |
+static bool |
79 |
+static const struct hw_type hw_types1[] = { |
89 |
+sysctl_exists(const struct hw_type *device, int unit, |
80 |
+ { _PATH_DEV "ukbd%d", ATTR_KEYBOARD, "kbd", "dev.ukbd.%d.%%desc" }, |
90 |
+ char *devname, size_t devname_len) |
81 |
+ { _PATH_DEV "atkbd%d", ATTR_KEYBOARD, "kbd", "dev.atkbd.%d.%%desc" }, |
91 |
+{ |
82 |
+ { _PATH_DEV "kbdmux%d", ATTR_KEYBOARD, "kbd", NULL }, |
92 |
+ char sysctlname[PATH_MAX]; |
83 |
+ { _PATH_DEV "ums%d", ATTR_POINTER, "mouse", "dev.ums.%d.%%desc" }, |
93 |
+ size_t len; |
84 |
+ { _PATH_DEV "psm%d", ATTR_POINTER, "mouse", "dev.psm.%d.%%desc" }, |
94 |
+ int ret; |
85 |
+ { _PATH_DEV "joy%d", ATTR_JOYSTICK, "mouse", "dev.joy.%d.%%desc" }, |
95 |
+ |
86 |
+ { _PATH_DEV "atp%d", ATTR_TOUCHPAD, "mouse", "dev.atp.%d.%%desc" }, |
96 |
+ if (device == NULL || device->driver == NULL) |
87 |
+ { _PATH_DEV "wsp%d", ATTR_TOUCHPAD, "mouse", "dev.wsp.%d.%%desc" }, |
97 |
+ return false; |
88 |
+ { _PATH_DEV "uep%d", ATTR_TOUCHSCREEN, "mouse", "dev.uep.%d.%%desc" }, |
98 |
+ |
89 |
+ { _PATH_DEV "input/event%d", ATTR_TOUCHPAD, "evdev", NULL}, |
99 |
+ /* Check if a sysctl exists. */ |
90 |
+ { NULL, 0, NULL, NULL }, |
100 |
+ snprintf(sysctlname, sizeof(sysctlname), "dev.%s.%i.%%desc", |
91 |
+}; |
101 |
+ device->driver, unit); |
|
|
102 |
+ ret = sysctlbyname(sysctlname, NULL, &len, NULL, 0); |
103 |
+ |
92 |
+ |
104 |
+ if (ret == 0 && len > 0) { |
93 |
+static void |
105 |
+ snprintf(devname, devname_len, "%s%i", device->driver, unit); |
94 |
+get_usb_id(char **pptr, int fd) |
106 |
+ return true; |
95 |
+{ |
|
|
96 |
+ unsigned short vendor; |
97 |
+ unsigned short product; |
98 |
+ unsigned int speed; |
99 |
+#define WEBCAMD_IOCTL_GET_USB_VENDOR_ID _IOR('q', 250, unsigned short) |
100 |
+#define WEBCAMD_IOCTL_GET_USB_PRODUCT_ID _IOR('q', 251, unsigned short) |
101 |
+#define WEBCAMD_IOCTL_GET_USB_SPEED _IOR('q', 252, unsigned int) |
102 |
+ if (ioctl(fd, WEBCAMD_IOCTL_GET_USB_VENDOR_ID, &vendor) == 0 && |
103 |
+ ioctl(fd, WEBCAMD_IOCTL_GET_USB_PRODUCT_ID, &product) == 0 && |
104 |
+ ioctl(fd, WEBCAMD_IOCTL_GET_USB_SPEED, &speed) == 0) { |
105 |
+ if (asprintf(pptr, "%04x:%04x", vendor, product) == -1) |
106 |
+ *pptr = NULL; |
107 |
+ } |
107 |
+ } |
108 |
+ |
|
|
109 |
+ return false; |
110 |
+} |
108 |
+} |
111 |
+ |
109 |
+ |
112 |
+static bool |
110 |
+static const char * |
113 |
+devpath_exists(const struct hw_type *device, |
111 |
+skip_path_dev(const char *ptr) |
114 |
+ char *devname, size_t devname_len) |
112 |
+{ |
115 |
+{ |
113 |
+ if (strstr(ptr, _PATH_DEV) == ptr) |
116 |
+ char *devpath; |
114 |
+ ptr += strlen(_PATH_DEV); |
117 |
+ struct stat st; |
115 |
+ return (ptr); |
118 |
+ int ret; |
|
|
119 |
+ |
120 |
+ if (device == NULL || device->driver == NULL) |
121 |
+ return false; |
122 |
+ |
123 |
+ /* Check if /dev/$driver exists. */ |
124 |
+ asprintf(&devpath, "/dev/%s", device->driver); |
125 |
+ if (devpath == NULL) |
126 |
+ return false; |
127 |
+ |
128 |
+ ret = stat(devpath, &st); |
129 |
+ free(devpath); |
130 |
+ |
131 |
+ if (ret == 0) { |
132 |
+ strncpy(devname, device->driver, devname_len); |
133 |
+ return true; |
134 |
+ } |
135 |
+ |
136 |
+ return false; |
137 |
+} |
116 |
+} |
138 |
+ |
117 |
+ |
139 |
+static char * |
118 |
+static char * |
Lines 161-218
Link Here
|
161 |
+} |
140 |
+} |
162 |
+ |
141 |
+ |
163 |
+static void |
142 |
+static void |
164 |
+device_added(const char *devname) |
143 |
+device_added(const char *devicename, bool allow_no_device) |
165 |
+{ |
144 |
+{ |
166 |
+ char path[PATH_MAX]; |
|
|
167 |
+ char sysctlname[PATH_MAX]; |
168 |
+ char *vendor; |
169 |
+ char *product = NULL; |
170 |
+ char *config_info = NULL; |
171 |
+ char *walk; |
172 |
+ InputOption *options = NULL; |
173 |
+ InputAttributes attrs = { }; |
145 |
+ InputAttributes attrs = { }; |
|
|
146 |
+ InputOption *options = NULL; |
147 |
+ char *config_info = NULL; |
174 |
+ DeviceIntPtr dev = NULL; |
148 |
+ DeviceIntPtr dev = NULL; |
|
|
149 |
+ struct hw_type hw_type; |
150 |
+ char *product = NULL; |
151 |
+ char sysctlname[64]; |
152 |
+ char *vendor = NULL; |
153 |
+ int unit = 0; |
154 |
+ int fd = -1; |
155 |
+ char *walk; |
175 |
+ int i; |
156 |
+ int i; |
176 |
+ int fd; |
|
|
177 |
+ |
178 |
+ for (i = 0; hw_types[i].driver != NULL; i++) { |
179 |
+ size_t len; |
180 |
+ |
157 |
+ |
181 |
+ len = strlen(hw_types[i].driver); |
158 |
+ for (i = 0; hw_types0[i].driver != NULL; i++) { |
182 |
+ if (strcmp(devname, hw_types[i].driver) == 0 || |
159 |
+ if (strcmp(devicename, hw_types0[i].driver) == 0) { |
183 |
+ (strncmp(devname, hw_types[i].driver, len) == 0 && |
160 |
+ hw_type = hw_types0[i]; |
184 |
+ isnumber(*(devname + len)))) { |
161 |
+ goto found; |
185 |
+ attrs.flags |= hw_types[i].flag; |
|
|
186 |
+ break; |
187 |
+ } |
162 |
+ } |
188 |
+ } |
163 |
+ } |
189 |
+ |
164 |
+ for (i = 0; hw_types1[i].driver != NULL; i++) { |
190 |
+ if (hw_types[i].driver == NULL || hw_types[i].xdriver == NULL) { |
165 |
+ if (sscanf(devicename, hw_types1[i].driver, &unit) == 1) { |
191 |
+ LogMessage(X_INFO, "config/devd: ignoring device %s\n", |
166 |
+ hw_type = hw_types1[i]; |
192 |
+ devname); |
167 |
+ goto found; |
193 |
+ return; |
168 |
+ } |
194 |
+ } |
169 |
+ } |
|
|
170 |
+ goto ignore; |
195 |
+ |
171 |
+ |
196 |
+ /* Skip keyboard devices if kbdmux is enabled */ |
172 |
+found: |
197 |
+ if (is_kbdmux && is_console_kbd && hw_types[i].flag & ATTR_KEYBOARD) { |
173 |
+ if (hw_type.xdriver == NULL) |
198 |
+ LogMessage(X_INFO, "config/devd: kbdmux is enabled, ignoring device %s\n", |
174 |
+ goto ignore; |
199 |
+ devname); |
175 |
+ |
200 |
+ return; |
176 |
+ if (strcmp(hw_type.xdriver, "kbd") == 0) { |
|
|
177 |
+ bool match = (strstr(hw_type.driver, |
178 |
+ _PATH_DEV "kbdmux") == hw_type.driver); |
179 |
+ |
180 |
+ if (is_kbdmux) { |
181 |
+ if (!match) |
182 |
+ goto ignore; |
183 |
+ } else { |
184 |
+ if (match) |
185 |
+ goto ignore; |
186 |
+ } |
201 |
+ } |
187 |
+ } |
202 |
+ |
188 |
+ |
203 |
+ snprintf(path, sizeof(path), "/dev/%s", devname); |
|
|
204 |
+ |
205 |
+ options = input_option_new(NULL, "_source", "server/devd"); |
189 |
+ options = input_option_new(NULL, "_source", "server/devd"); |
206 |
+ if (!options) |
190 |
+ if (options == NULL) |
207 |
+ return; |
191 |
+ goto error; |
208 |
+ |
192 |
+ |
209 |
+ snprintf(sysctlname, sizeof(sysctlname), "dev.%s.%s.%%desc", |
193 |
+ if (hw_type.sysctldesc != NULL) { |
210 |
+ hw_types[i].driver, devname + strlen(hw_types[i].driver)); |
194 |
+ snprintf(sysctlname, sizeof(sysctlname), |
211 |
+ vendor = sysctl_get_str(sysctlname); |
195 |
+ hw_type.sysctldesc, unit); |
212 |
+ if (vendor == NULL) { |
196 |
+ vendor = sysctl_get_str(sysctlname); |
213 |
+ options = input_option_new(options, "name", devname); |
|
|
214 |
+ } |
197 |
+ } |
215 |
+ else { |
198 |
+ |
|
|
199 |
+ if (vendor == NULL) { |
200 |
+ options = input_option_new(options, "name", |
201 |
+ skip_path_dev(devicename)); |
202 |
+ } else { |
216 |
+ if ((walk = strchr(vendor, ' ')) != NULL) { |
203 |
+ if ((walk = strchr(vendor, ' ')) != NULL) { |
217 |
+ walk[0] = '\0'; |
204 |
+ walk[0] = '\0'; |
218 |
+ walk++; |
205 |
+ walk++; |
Lines 222-314
Link Here
|
222 |
+ } |
209 |
+ } |
223 |
+ |
210 |
+ |
224 |
+ attrs.vendor = strdup(vendor); |
211 |
+ attrs.vendor = strdup(vendor); |
225 |
+ if (product) { |
212 |
+ if (product != NULL) { |
226 |
+ attrs.product = strdup(product); |
213 |
+ attrs.product = strdup(product); |
227 |
+ options = input_option_new(options, "name", product); |
214 |
+ options = input_option_new(options, |
|
|
215 |
+ "name", product); |
216 |
+ } else { |
217 |
+ options = input_option_new(options, |
218 |
+ "name", "Unknown"); |
228 |
+ } |
219 |
+ } |
229 |
+ else |
|
|
230 |
+ options = input_option_new(options, "name", "(unnamed)"); |
231 |
+ |
232 |
+ free(vendor); |
233 |
+ } |
220 |
+ } |
|
|
221 |
+ attrs.device = strdup(devicename); |
234 |
+ |
222 |
+ |
235 |
+ /* XXX implement usb_id */ |
223 |
+ fd = open(devicename, O_RDONLY); |
236 |
+ attrs.usb_id = NULL; |
224 |
+ if (fd > -1) { |
237 |
+ attrs.device = strdup(path); |
225 |
+ get_usb_id(&attrs.usb_id, fd); |
238 |
+ options = input_option_new(options, "driver", hw_types[i].xdriver); |
|
|
239 |
+ |
240 |
+ fd = open(path, O_RDONLY); |
241 |
+ if (fd > 0) { |
242 |
+ close(fd); |
226 |
+ close(fd); |
243 |
+ options = input_option_new(options, "device", path); |
227 |
+ options = input_option_new(options, "device", devicename); |
244 |
+ } |
228 |
+ if (options == NULL) |
245 |
+ else { |
229 |
+ goto error; |
246 |
+ if (attrs.flags & ~ATTR_KEYBOARD) { |
230 |
+ } else if (allow_no_device) { |
247 |
+ LogMessage(X_INFO, "config/devd: device %s already opened\n", |
231 |
+ /* |
248 |
+ path); |
232 |
+ * Don't pass "device" option if the keyboard is |
249 |
+ |
233 |
+ * already attached to the console (ie. open() fails). |
250 |
+ /* |
234 |
+ * This would activate a special logic in |
251 |
+ * Fail if cannot open device, it breaks AllowMouseOpenFail, |
235 |
+ * xf86-input-keyboard. Prevent any other attached to |
252 |
+ * but it should not matter when config/devd enabled |
236 |
+ * console keyboards being processed. There can be |
253 |
+ */ |
237 |
+ * only one such device. |
254 |
+ goto unwind; |
238 |
+ */ |
255 |
+ } |
239 |
+ } else { |
256 |
+ |
240 |
+ goto ignore; |
257 |
+ if (is_console_kbd) { |
241 |
+ } |
258 |
+ /* |
242 |
+ |
259 |
+ * There can be only one keyboard attached to console and |
243 |
+ options = input_option_new(options, "driver", hw_type.xdriver); |
260 |
+ * it is already added. |
244 |
+ if (options == NULL) |
261 |
+ */ |
245 |
+ goto error; |
262 |
+ LogMessage(X_WARNING, "config/devd: console keyboard is " |
|
|
263 |
+ "already added, ignoring %s (%s)\n", |
264 |
+ attrs.product, path); |
265 |
+ goto unwind; |
266 |
+ } |
267 |
+ else |
268 |
+ /* |
269 |
+ * Don't pass "device" option if the keyboard is already |
270 |
+ * attached to the console (ie. open() fails). |
271 |
+ * This would activate a special logic in xf86-input-keyboard. |
272 |
+ * Prevent any other attached to console keyboards being |
273 |
+ * processed. There can be only one such device. |
274 |
+ */ |
275 |
+ is_console_kbd = true; |
276 |
+ } |
277 |
+ |
246 |
+ |
278 |
+ if (asprintf(&config_info, "devd:%s", devname) == -1) { |
247 |
+ if (asprintf(&config_info, "devd:%s", |
|
|
248 |
+ skip_path_dev(devicename)) == -1) { |
279 |
+ config_info = NULL; |
249 |
+ config_info = NULL; |
280 |
+ goto unwind; |
250 |
+ goto error; |
281 |
+ } |
251 |
+ } |
282 |
+ |
252 |
+ |
283 |
+ if (device_is_duplicate(config_info)) { |
253 |
+ if (device_is_duplicate(config_info)) |
284 |
+ LogMessage(X_WARNING, "config/devd: device %s (%s) already added. " |
254 |
+ goto duplicate; |
285 |
+ "ignoring\n", attrs.product, path); |
|
|
286 |
+ goto unwind; |
287 |
+ } |
288 |
+ |
255 |
+ |
289 |
+ options = input_option_new(options, "config_info", config_info); |
256 |
+ options = input_option_new(options, "config_info", config_info); |
290 |
+ LogMessage(X_INFO, "config/devd: adding input device %s (%s)\n", |
257 |
+ if (options == NULL) |
291 |
+ attrs.product, path); |
258 |
+ goto error; |
|
|
259 |
+ |
260 |
+ LogMessage(X_INFO, "config/devd: adding input device '%s'\n", |
261 |
+ devicename); |
292 |
+ |
262 |
+ |
293 |
+ NewInputDeviceRequest(options, &attrs, &dev); |
263 |
+ NewInputDeviceRequest(options, &attrs, &dev); |
|
|
264 |
+ goto done; |
265 |
+ |
266 |
+duplicate: |
267 |
+ LogMessage(X_WARNING, "config/devd: device '%s' already " |
268 |
+ "added. Ignoring\n", devicename); |
269 |
+ goto done; |
270 |
+ |
271 |
+error: |
272 |
+ LogMessage(X_INFO, "config/devd: error adding device '%s'\n", |
273 |
+ devicename); |
274 |
+ goto done; |
275 |
+ |
276 |
+ignore: |
277 |
+ LogMessage(X_INFO, "config/devd: ignoring device '%s'\n", |
278 |
+ devicename); |
279 |
+ goto done; |
294 |
+ |
280 |
+ |
295 |
+unwind: |
281 |
+done: |
296 |
+ free(config_info); |
282 |
+ free(config_info); |
297 |
+ input_option_free_list(&options); |
283 |
+ input_option_free_list(&options); |
298 |
+ free(attrs.usb_id); |
284 |
+ free(attrs.usb_id); |
299 |
+ free(attrs.product); |
285 |
+ free(attrs.product); |
300 |
+ free(attrs.device); |
286 |
+ free(attrs.device); |
301 |
+ free(attrs.vendor); |
287 |
+ free(attrs.vendor); |
|
|
288 |
+ free(vendor); |
289 |
+} |
290 |
+ |
291 |
+static void |
292 |
+devpath_scan_sub(char *path, int off, int rem) |
293 |
+{ |
294 |
+ struct dirent *entry; |
295 |
+ DIR *dp; |
296 |
+ |
297 |
+ if ((dp = opendir(path)) == NULL) { |
298 |
+ LogMessage(X_INFO, "Cannot open directory '%s'\n", path); |
299 |
+ return; |
300 |
+ } |
301 |
+ while ((entry = readdir(dp)) != NULL) { |
302 |
+ int len = strlen(entry->d_name); |
303 |
+ if (len > rem) |
304 |
+ continue; |
305 |
+ strcpy(path + off, entry->d_name); |
306 |
+ off += len; |
307 |
+ rem -= len; |
308 |
+ switch (entry->d_type) { |
309 |
+ case DT_DIR: |
310 |
+ if (strcmp(entry->d_name, ".") == 0 || |
311 |
+ strcmp(entry->d_name, "..") == 0) |
312 |
+ break; |
313 |
+ if (rem < 1) |
314 |
+ break; |
315 |
+ path[off] = '/'; |
316 |
+ path[off+1] = '\0'; |
317 |
+ off++; |
318 |
+ rem--; |
319 |
+ /* recurse */ |
320 |
+ devpath_scan_sub(path, off, rem); |
321 |
+ off--; |
322 |
+ rem++; |
323 |
+ break; |
324 |
+ case DT_SOCK: |
325 |
+ case DT_FIFO: |
326 |
+ case DT_LNK: |
327 |
+ case DT_CHR: |
328 |
+ /* add device, if any */ |
329 |
+ device_added(path, false); |
330 |
+ break; |
331 |
+ default: |
332 |
+ break; |
333 |
+ } |
334 |
+ off -= len; |
335 |
+ rem += len; |
336 |
+ } |
337 |
+ closedir(dp); |
302 |
+} |
338 |
+} |
303 |
+ |
339 |
+ |
304 |
+static void |
340 |
+static void |
305 |
+device_removed(char *devname) |
341 |
+devpath_scan(void) |
|
|
342 |
+{ |
343 |
+ char path[PATH_MAX + 1]; |
344 |
+ |
345 |
+ strlcpy(path, _PATH_DEV, sizeof(path)); |
346 |
+ |
347 |
+ devpath_scan_sub(path, strlen(path), PATH_MAX - strlen(path)); |
348 |
+} |
349 |
+ |
350 |
+static void |
351 |
+device_removed(char *devicename) |
306 |
+{ |
352 |
+{ |
307 |
+ char *config_info; |
353 |
+ char *config_info; |
308 |
+ |
354 |
+ |
309 |
+ if (asprintf(&config_info, "devd:%s", devname) == -1) |
355 |
+ if (asprintf(&config_info, "devd:%s", |
|
|
356 |
+ skip_path_dev(devicename)) == -1) |
310 |
+ return; |
357 |
+ return; |
311 |
+ |
358 |
+ |
|
|
359 |
+ if (device_is_duplicate(config_info)) { |
360 |
+ LogMessage(X_INFO, "config/devd: removing input device '%s'\n", |
361 |
+ devicename); |
362 |
+ } |
312 |
+ remove_devices("devd", config_info); |
363 |
+ remove_devices("devd", config_info); |
313 |
+ |
364 |
+ |
314 |
+ free(config_info); |
365 |
+ free(config_info); |
Lines 317-324
Link Here
|
317 |
+static bool is_kbdmux_enabled(void) |
368 |
+static bool is_kbdmux_enabled(void) |
318 |
+{ |
369 |
+{ |
319 |
+ /* Xorg uses /dev/ttyv0 as a console device */ |
370 |
+ /* Xorg uses /dev/ttyv0 as a console device */ |
320 |
+ /* const char device[]="/dev/console"; */ |
371 |
+ static const char device[]= { _PATH_DEV "ttyv0" }; |
321 |
+ const char device[]="/dev/ttyv0"; |
|
|
322 |
+ keyboard_info_t info; |
372 |
+ keyboard_info_t info; |
323 |
+ int fd; |
373 |
+ int fd; |
324 |
+ |
374 |
+ |
Lines 447-453
Link Here
|
447 |
+static void |
497 |
+static void |
448 |
+wakeup_handler(void *data, int err, void *read_mask) |
498 |
+wakeup_handler(void *data, int err, void *read_mask) |
449 |
+{ |
499 |
+{ |
|
|
500 |
+ static const char cdev_create[] = { "!system=DEVFS subsystem=CDEV type=CREATE cdev=" }; |
501 |
+ static const char cdev_destroy[] = { "!system=DEVFS subsystem=CDEV type=DESTROY cdev=" }; |
502 |
+ static const char cdev_path[] = { _PATH_DEV }; |
450 |
+ char *line = NULL; |
503 |
+ char *line = NULL; |
|
|
504 |
+ char *devicename; |
451 |
+ char *walk; |
505 |
+ char *walk; |
452 |
+ |
506 |
+ |
453 |
+ if (err < 0) |
507 |
+ if (err < 0) |
Lines 456-475
Link Here
|
456 |
+ if (FD_ISSET(sock_devd, (fd_set *) read_mask)) { |
510 |
+ if (FD_ISSET(sock_devd, (fd_set *) read_mask)) { |
457 |
+ if (socket_getline(sock_devd, &line) < 0) |
511 |
+ if (socket_getline(sock_devd, &line) < 0) |
458 |
+ return; |
512 |
+ return; |
459 |
+ |
513 |
+ if (strstr(line, cdev_create) == line) { |
460 |
+ walk = strchr(line + 1, ' '); |
514 |
+ devicename = line + strlen(cdev_create) - strlen(cdev_path); |
461 |
+ if (walk != NULL) |
515 |
+ memcpy(devicename, cdev_path, strlen(cdev_path)); |
462 |
+ walk[0] = '\0'; |
516 |
+ walk = strchr(devicename, ' '); |
463 |
+ |
517 |
+ if (walk != NULL) |
464 |
+ switch (*line) { |
518 |
+ walk[0] = '\0'; |
465 |
+ case DEVD_EVENT_ADD: |
519 |
+ device_added(devicename, false); |
466 |
+ device_added(line + 1); |
520 |
+ } else if (strstr(line, cdev_destroy) == line) { |
467 |
+ break; |
521 |
+ devicename = line + strlen(cdev_destroy) - strlen(cdev_path); |
468 |
+ case DEVD_EVENT_REMOVE: |
522 |
+ memcpy(devicename, cdev_path, strlen(cdev_path)); |
469 |
+ device_removed(line + 1); |
523 |
+ walk = strchr(devicename, ' '); |
470 |
+ break; |
524 |
+ if (walk != NULL) |
471 |
+ default: |
525 |
+ walk[0] = '\0'; |
472 |
+ break; |
526 |
+ device_removed(devicename); |
473 |
+ } |
527 |
+ } |
474 |
+ free(line); |
528 |
+ free(line); |
475 |
+ } |
529 |
+ } |
Lines 483-516
Link Here
|
483 |
+int |
537 |
+int |
484 |
+config_devd_init(void) |
538 |
+config_devd_init(void) |
485 |
+{ |
539 |
+{ |
486 |
+ char devicename[1024]; |
|
|
487 |
+ int i, j; |
488 |
+ |
489 |
+ LogMessage(X_INFO, "config/devd: probing input devices...\n"); |
540 |
+ LogMessage(X_INFO, "config/devd: probing input devices...\n"); |
490 |
+ |
541 |
+ |
491 |
+ /* |
542 |
+ /* Check if kbdmux is enabled */ |
492 |
+ * Add fake keyboard and give up on keyboards management |
543 |
+ is_kbdmux = is_kbdmux_enabled(); |
493 |
+ * if kbdmux is enabled |
|
|
494 |
+ */ |
495 |
+ if ((is_kbdmux = is_kbdmux_enabled()) == true) |
496 |
+ device_added("kbdmux"); |
497 |
+ |
498 |
+ for (i = 0; hw_types[i].driver != NULL; i++) { |
499 |
+ /* First scan the sysctl to determine the hardware */ |
500 |
+ for (j = 0; j < 16; j++) { |
501 |
+ if (sysctl_exists(&hw_types[i], j, |
502 |
+ devicename, sizeof(devicename)) != 0) |
503 |
+ device_added(devicename); |
504 |
+ } |
505 |
+ |
544 |
+ |
506 |
+ if (devpath_exists(&hw_types[i], devicename, sizeof(devicename)) != 0) |
545 |
+ /* Try to add kbdmux device first */ |
507 |
+ device_added(devicename); |
546 |
+ if (is_kbdmux) |
508 |
+ } |
547 |
+ device_added(_PATH_DEV "kbdmux0", true); |
509 |
+ |
548 |
+ |
|
|
549 |
+ /* Connect to devd, so that we don't loose any events */ |
510 |
+ if ((sock_devd = connect_devd()) < 0) |
550 |
+ if ((sock_devd = connect_devd()) < 0) |
511 |
+ return 0; |
551 |
+ return 0; |
512 |
+ |
552 |
+ |
513 |
+ RegisterBlockAndWakeupHandlers(block_handler, wakeup_handler, NULL); |
553 |
+ /* Scan what is currently connected */ |
|
|
554 |
+ devpath_scan(); |
555 |
+ |
556 |
+ /* Register wakeup handler */ |
557 |
+ RegisterBlockAndWakeupHandlers(block_handler, |
558 |
+ wakeup_handler, NULL); |
514 |
+ |
559 |
+ |
515 |
+ return 1; |
560 |
+ return 1; |
516 |
+} |
561 |
+} |
Lines 527-533
Link Here
|
527 |
+ |
572 |
+ |
528 |
+ disconnect_devd(sock_devd); |
573 |
+ disconnect_devd(sock_devd); |
529 |
+ |
574 |
+ |
530 |
+ RemoveBlockAndWakeupHandlers(block_handler, wakeup_handler, NULL); |
575 |
+ RemoveBlockAndWakeupHandlers(block_handler, |
531 |
+ |
576 |
+ wakeup_handler, NULL); |
532 |
+ is_console_kbd = false; |
|
|
533 |
+} |
577 |
+} |