Commit | Line | Data |
---|---|---|
7217e0ca ML |
1 | >From d96e2bd2a2b48ede527ad7071d3e0eeda9861b73 Mon Sep 17 00:00:00 2001 |
2 | From: Robert Millan <rmh@debian.org> | |
3 | Date: Mon, 24 Feb 2014 23:22:57 +0100 | |
4 | Subject: [PATCH] Add devd config backend for FreeBSD (and GNU/kFreeBSD) | |
5 | ||
6 | Based on original code by Baptiste Daroussin, with some fixes made | |
7 | by Koop Mast and myself. | |
8 | ||
9 | Signed-off-by: Robert Millan <rmh@freebsd.org> | |
10 | --- | |
11 | config/Makefile.am | 4 + | |
12 | config/config-backends.h | 5 + | |
13 | config/config.c | 5 + | |
14 | config/devd.c | 387 +++++++++++++++++++++++++++++++++++++++ | |
15 | configure.ac | 16 ++ | |
16 | hw/xfree86/common/xf86Config.c | 7 +- | |
17 | hw/xfree86/common/xf86Globals.c | 3 +- | |
18 | include/dix-config.h.in | 3 + | |
19 | 8 files changed, 427 insertions(+), 3 deletions(-) | |
20 | create mode 100644 config/devd.c | |
21 | ||
22 | Index: xorg-server/config/Makefile.am | |
23 | =================================================================== | |
24 | --- xorg-server.orig/config/Makefile.am | |
25 | +++ xorg-server/config/Makefile.am | |
26 | @@ -40,6 +40,10 @@ if CONFIG_WSCONS | |
27 | libconfig_la_SOURCES += wscons.c | |
28 | endif # CONFIG_WSCONS | |
29 | ||
30 | +if CONFIG_DEVD | |
31 | +libconfig_la_SOURCES += devd.c | |
32 | +endif | |
33 | + | |
34 | endif # CONFIG_NEED_DBUS | |
35 | ||
36 | endif # !CONFIG_UDEV | |
37 | Index: xorg-server/config/config-backends.h | |
38 | =================================================================== | |
39 | --- xorg-server.orig/config/config-backends.h | |
40 | +++ xorg-server/config/config-backends.h | |
41 | @@ -75,3 +75,8 @@ void config_hal_fini(void); | |
42 | int config_wscons_init(void); | |
43 | void config_wscons_fini(void); | |
44 | #endif | |
45 | + | |
46 | +#ifdef CONFIG_DEVD | |
47 | +int config_devd_init(void); | |
48 | +void config_devd_fini(void); | |
49 | +#endif | |
50 | Index: xorg-server/config/config.c | |
51 | =================================================================== | |
52 | --- xorg-server.orig/config/config.c | |
53 | +++ xorg-server/config/config.c | |
54 | @@ -64,6 +64,9 @@ config_init(void) | |
55 | #elif defined(CONFIG_WSCONS) | |
56 | if (!config_wscons_init()) | |
57 | ErrorF("[config] failed to initialise wscons\n"); | |
58 | +#elif defined(CONFIG_DEVD) | |
59 | + if (!config_devd_init()) | |
60 | + ErrorF("[config] failed to initialise devd\n"); | |
61 | #endif | |
62 | } | |
63 | ||
64 | @@ -82,6 +85,8 @@ config_fini(void) | |
65 | config_dbus_core_fini(); | |
66 | #elif defined(CONFIG_WSCONS) | |
67 | config_wscons_fini(); | |
68 | +#elif defined(CONFIG_DEVD) | |
69 | + config_devd_fini(); | |
70 | #endif | |
71 | } | |
72 | ||
73 | Index: xorg-server/config/devd.c | |
74 | =================================================================== | |
75 | --- /dev/null | |
76 | +++ xorg-server/config/devd.c | |
77 | @@ -0,0 +1,387 @@ | |
78 | +/* | |
79 | + * Copyright © 2012 Baptiste Daroussin | |
80 | + * Copyright © 2014 Robert Millan | |
81 | + * | |
82 | + * Permission is hereby granted, free of charge, to any person obtaining a | |
83 | + * copy of this software and associated documentation files (the "Software"), | |
84 | + * to deal in the Software without restriction, including without limitation | |
85 | + * the rights to use, copy, modify, merge, publish, distribute, sublicense, | |
86 | + * and/or sell copies of the Software, and to permit persons to whom the | |
87 | + * Software is furnished to do so, subject to the following conditions: | |
88 | + * | |
89 | + * The above copyright notice and this permission notice (including the next | |
90 | + * paragraph) shall be included in all copies or substantial portions of the | |
91 | + * Software. | |
92 | + * | |
93 | + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
94 | + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
95 | + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | |
96 | + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |
97 | + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | |
98 | + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER | |
99 | + * DEALINGS IN THE SOFTWARE. | |
100 | + * | |
101 | + * Author: Baptiste Daroussin <bapt@FreeBSD.org> | |
102 | + */ | |
103 | + | |
104 | +#ifdef HAVE_DIX_CONFIG_H | |
105 | +#include <dix-config.h> | |
106 | +#endif | |
107 | + | |
108 | +#include <sys/types.h> | |
109 | +#include <sys/socket.h> | |
110 | +#include <sys/sysctl.h> | |
111 | +#include <sys/un.h> | |
112 | + | |
113 | +#include <ctype.h> | |
114 | +#include <errno.h> | |
115 | +#include <fcntl.h> | |
116 | +#include <stdlib.h> | |
117 | +#include <stdio.h> | |
118 | +#include <stdarg.h> | |
119 | +#include <stdbool.h> | |
120 | +#include <unistd.h> | |
121 | + | |
122 | +#include "input.h" | |
123 | +#include "inputstr.h" | |
124 | +#include "hotplug.h" | |
125 | +#include "config-backends.h" | |
126 | +#include "os.h" | |
127 | + | |
128 | +#define DEVD_SOCK_PATH "/var/run/devd.pipe" | |
129 | + | |
130 | +#define DEVD_EVENT_ADD '+' | |
131 | +#define DEVD_EVENT_REMOVE '-' | |
132 | + | |
133 | +static int sock_devd = -1; | |
134 | + | |
135 | +struct hw_type { | |
136 | + const char *driver; | |
137 | + int flag; | |
138 | + const char *xdriver; | |
139 | +}; | |
140 | + | |
141 | +static struct hw_type hw_types[] = { | |
142 | + {"ukbd", ATTR_KEYBOARD, "kbd"}, | |
143 | + {"atkbd", ATTR_KEYBOARD, "kbd"}, | |
144 | + {"ums", ATTR_POINTER, "mouse"}, | |
145 | + {"psm", ATTR_POINTER, "mouse"}, | |
146 | + {"uhid", ATTR_POINTER, "mouse"}, | |
147 | + {"joy", ATTR_JOYSTICK, NULL}, | |
148 | + {"atp", ATTR_TOUCHPAD, NULL}, | |
149 | + {"uep", ATTR_TOUCHSCREEN, NULL}, | |
150 | + {NULL, -1, NULL}, | |
151 | +}; | |
152 | + | |
153 | +static bool | |
154 | +sysctl_exists(const char *format, ...) | |
155 | +{ | |
156 | + va_list args; | |
157 | + char *name = NULL; | |
158 | + size_t len; | |
159 | + int ret; | |
160 | + | |
161 | + if (format == NULL) | |
162 | + return false; | |
163 | + | |
164 | + va_start(args, format); | |
165 | + vasprintf(&name, format, args); | |
166 | + va_end(args); | |
167 | + | |
168 | + ret = sysctlbyname(name, NULL, &len, NULL, 0); | |
169 | + | |
170 | + if (ret == -1) | |
171 | + len = 0; | |
172 | + | |
173 | + free(name); | |
174 | + return (len > 0); | |
175 | +} | |
176 | + | |
177 | +static char * | |
178 | +sysctl_get_str(const char *format, ...) | |
179 | +{ | |
180 | + va_list args; | |
181 | + char *name = NULL; | |
182 | + char *dest = NULL; | |
183 | + size_t len; | |
184 | + | |
185 | + if (format == NULL) | |
186 | + return NULL; | |
187 | + | |
188 | + va_start(args, format); | |
189 | + vasprintf(&name, format, args); | |
190 | + va_end(args); | |
191 | + | |
192 | + if (sysctlbyname(name, NULL, &len, NULL, 0) == 0) { | |
193 | + dest = malloc(len + 1); | |
194 | + if (!dest) | |
195 | + goto unwind; | |
196 | + if (sysctlbyname(name, dest, &len, NULL, 0) == 0) | |
197 | + dest[len] = '\0'; | |
198 | + else { | |
199 | + free(dest); | |
200 | + dest = NULL; | |
201 | + } | |
202 | + } | |
203 | + | |
204 | + unwind: | |
205 | + free(name); | |
206 | + return dest; | |
207 | +} | |
208 | + | |
209 | +static void | |
210 | +device_added(char *devname) | |
211 | +{ | |
212 | + char path[PATH_MAX]; | |
213 | + char *vendor; | |
214 | + char *product = NULL; | |
215 | + char *config_info = NULL; | |
216 | + char *walk; | |
217 | + InputOption *options = NULL; | |
218 | + InputAttributes attrs = { }; | |
219 | + DeviceIntPtr dev = NULL; | |
220 | + int i, rc; | |
221 | + int fd; | |
222 | + | |
223 | + for (i = 0; hw_types[i].driver != NULL; i++) { | |
224 | + if (strncmp(devname, hw_types[i].driver, | |
225 | + strlen(hw_types[i].driver)) == 0 && | |
226 | + isdigit(*(devname + strlen(hw_types[i].driver)))) { | |
227 | + attrs.flags |= hw_types[i].flag; | |
228 | + break; | |
229 | + } | |
230 | + } | |
231 | + if (hw_types[i].driver == NULL) { | |
232 | + LogMessageVerb(X_INFO, 10, "config/devd: ignoring device %s\n", | |
233 | + devname); | |
234 | + return; | |
235 | + } | |
236 | + if (hw_types[i].xdriver == NULL) { | |
237 | + LogMessageVerb(X_INFO, 10, "config/devd: ignoring device %s\n", | |
238 | + devname); | |
239 | + return; | |
240 | + } | |
241 | + snprintf(path, sizeof(path), "/dev/%s", devname); | |
242 | + | |
243 | + options = input_option_new(NULL, "_source", "server/devd"); | |
244 | + if (!options) | |
245 | + return; | |
246 | + | |
247 | + vendor = | |
248 | + sysctl_get_str("dev.%s.%s.%%desc", hw_types[i].driver, | |
249 | + devname + strlen(hw_types[i].driver)); | |
250 | + if (vendor == NULL) { | |
251 | + attrs.vendor = strdup("(unnamed)"); | |
252 | + attrs.product = strdup("(unnamed)"); | |
253 | + } | |
254 | + else { | |
255 | + if ((walk = strchr(vendor, ' ')) != NULL) { | |
256 | + walk[0] = '\0'; | |
257 | + walk++; | |
258 | + product = walk; | |
259 | + if ((walk = strchr(product, ',')) != NULL) | |
260 | + walk[0] = '\0'; | |
261 | + } | |
262 | + | |
263 | + attrs.vendor = strdup(vendor); | |
264 | + if (product) | |
265 | + attrs.product = strdup(product); | |
266 | + else | |
267 | + attrs.product = strdup("(unnamed)"); | |
268 | + | |
269 | + options = input_option_new(options, "name", xstrdup(attrs.product)); | |
270 | + | |
271 | + free(vendor); | |
272 | + } | |
273 | + attrs.usb_id = NULL; | |
274 | + attrs.device = strdup(path); | |
275 | + options = input_option_new(options, "driver", hw_types[i].xdriver); | |
276 | + if (attrs.flags & ATTR_KEYBOARD) { | |
277 | + /* | |
278 | + * Don't pass device option if keyboard is attached to console (open fails), | |
279 | + * thus activating special logic in xf86-input-keyboard. | |
280 | + */ | |
281 | + fd = open(path, O_RDONLY | O_NONBLOCK | O_EXCL); | |
282 | + if (fd > 0) { | |
283 | + close(fd); | |
284 | + options = input_option_new(options, "device", xstrdup(path)); | |
285 | + } | |
286 | + } | |
287 | + else { | |
288 | + options = input_option_new(options, "device", xstrdup(path)); | |
289 | + } | |
290 | + | |
291 | + if (asprintf(&config_info, "devd:%s", devname) == -1) { | |
292 | + config_info = NULL; | |
293 | + goto unwind; | |
294 | + } | |
295 | + | |
296 | + if (device_is_duplicate(config_info)) { | |
297 | + LogMessage(X_WARNING, "config/devd: device %s already added. " | |
298 | + "Ignoring.\n", attrs.product); | |
299 | + goto unwind; | |
300 | + } | |
301 | + | |
302 | + options = input_option_new(options, "config_info", config_info); | |
303 | + LogMessage(X_INFO, "config/devd: adding input device %s (%s)\n", | |
304 | + attrs.product, path); | |
305 | + | |
306 | + rc = NewInputDeviceRequest(options, &attrs, &dev); | |
307 | + | |
308 | + if (rc != Success) | |
309 | + goto unwind; | |
310 | + | |
311 | + unwind: | |
312 | + free(config_info); | |
313 | + input_option_free_list(&options); | |
314 | + | |
315 | + free(attrs.usb_id); | |
316 | + free(attrs.product); | |
317 | + free(attrs.device); | |
318 | + free(attrs.vendor); | |
319 | +} | |
320 | + | |
321 | +static void | |
322 | +device_removed(char *devname) | |
323 | +{ | |
324 | + char *value; | |
325 | + | |
326 | + if (asprintf(&value, "devd:%s", devname) == -1) | |
327 | + return; | |
328 | + | |
329 | + remove_devices("devd", value); | |
330 | + | |
331 | + free(value); | |
332 | +} | |
333 | + | |
334 | +static ssize_t | |
335 | +socket_getline(int fd, char **out) | |
336 | +{ | |
337 | + char *buf, *newbuf; | |
338 | + ssize_t ret, cap, sz = 0; | |
339 | + char c; | |
340 | + | |
341 | + cap = 1024; | |
342 | + buf = malloc(cap * sizeof(char)); | |
343 | + if (!buf) | |
344 | + return -1; | |
345 | + | |
346 | + for (;;) { | |
347 | + ret = read(sock_devd, &c, 1); | |
348 | + if (ret < 1) { | |
349 | + if (errno == EINTR) | |
350 | + continue; | |
351 | + free(buf); | |
352 | + return -1; | |
353 | + } | |
354 | + | |
355 | + if (c == '\n') | |
356 | + break; | |
357 | + | |
358 | + if (sz + 1 >= cap) { | |
359 | + cap *= 2; | |
360 | + newbuf = realloc(buf, cap * sizeof(char)); | |
361 | + if (!newbuf) { | |
362 | + free(buf); | |
363 | + return -1; | |
364 | + } | |
365 | + buf = newbuf; | |
366 | + } | |
367 | + buf[sz] = c; | |
368 | + sz++; | |
369 | + } | |
370 | + | |
371 | + buf[sz] = '\0'; | |
372 | + if (sz >= 0) | |
373 | + *out = buf; | |
374 | + else | |
375 | + free(buf); | |
376 | + | |
377 | + return sz; /* number of bytes in the line, not counting the line break */ | |
378 | +} | |
379 | + | |
380 | +static void | |
381 | +wakeup_handler(void *data, int err, void *read_mask) | |
382 | +{ | |
383 | + char *line = NULL; | |
384 | + char *walk; | |
385 | + | |
386 | + if (err < 0) | |
387 | + return; | |
388 | + | |
389 | + if (FD_ISSET(sock_devd, (fd_set *) read_mask)) { | |
390 | + if (socket_getline(sock_devd, &line) < 0) | |
391 | + return; | |
392 | + | |
393 | + walk = strchr(line + 1, ' '); | |
394 | + if (walk != NULL) | |
395 | + walk[0] = '\0'; | |
396 | + | |
397 | + switch (*line) { | |
398 | + case DEVD_EVENT_ADD: | |
399 | + device_added(line + 1); | |
400 | + break; | |
401 | + case DEVD_EVENT_REMOVE: | |
402 | + device_removed(line + 1); | |
403 | + break; | |
404 | + default: | |
405 | + break; | |
406 | + } | |
407 | + free(line); | |
408 | + } | |
409 | +} | |
410 | + | |
411 | +static void | |
412 | +block_handler(void *data, struct timeval **tv, void *read_mask) | |
413 | +{ | |
414 | +} | |
415 | + | |
416 | +int | |
417 | +config_devd_init(void) | |
418 | +{ | |
419 | + struct sockaddr_un devd; | |
420 | + char devicename[1024]; | |
421 | + int i, j; | |
422 | + | |
423 | + /* first scan the sysctl to determine the hardware if needed */ | |
424 | + | |
425 | + for (i = 0; hw_types[i].driver != NULL; i++) { | |
426 | + for (j = 0; sysctl_exists("dev.%s.%i.%%desc", hw_types[i].driver, j); | |
427 | + j++) { | |
428 | + snprintf(devicename, sizeof(devicename), "%s%i", hw_types[i].driver, | |
429 | + j); | |
430 | + device_added(devicename); | |
431 | + } | |
432 | + | |
433 | + } | |
434 | + sock_devd = socket(AF_UNIX, SOCK_STREAM, 0); | |
435 | + if (sock_devd < 0) { | |
436 | + ErrorF("config/devd: Fail opening stream socket"); | |
437 | + return 0; | |
438 | + } | |
439 | + | |
440 | + devd.sun_family = AF_UNIX; | |
441 | + strlcpy(devd.sun_path, DEVD_SOCK_PATH, sizeof(devd.sun_path)); | |
442 | + | |
443 | + if (connect(sock_devd, (struct sockaddr *) &devd, sizeof(devd)) < 0) { | |
444 | + close(sock_devd); | |
445 | + ErrorF("config/devd: Fail to connect to devd"); | |
446 | + return 0; | |
447 | + } | |
448 | + | |
449 | + RegisterBlockAndWakeupHandlers(block_handler, wakeup_handler, NULL); | |
450 | + AddGeneralSocket(sock_devd); | |
451 | + | |
452 | + return 1; | |
453 | +} | |
454 | + | |
455 | +void | |
456 | +config_devd_fini(void) | |
457 | +{ | |
458 | + if (sock_devd < 0) | |
459 | + return; | |
460 | + | |
461 | + RemoveGeneralSocket(sock_devd); | |
462 | + RemoveBlockAndWakeupHandlers(block_handler, wakeup_handler, NULL); | |
463 | + close(sock_devd); | |
464 | +} | |
465 | Index: xorg-server/configure.ac | |
466 | =================================================================== | |
467 | --- xorg-server.orig/configure.ac | |
468 | +++ xorg-server/configure.ac | |
469 | @@ -618,6 +618,7 @@ AC_ARG_ENABLE(config-udev, AS_HELP_ST | |
470 | AC_ARG_ENABLE(config-udev-kms, AS_HELP_STRING([--enable-config-udev-kms], [Build udev kms support (default: auto)]), [CONFIG_UDEV_KMS=$enableval], [CONFIG_UDEV_KMS=auto]) | |
471 | AC_ARG_ENABLE(config-dbus, AS_HELP_STRING([--enable-config-dbus], [Build D-BUS API support (default: no)]), [CONFIG_DBUS_API=$enableval], [CONFIG_DBUS_API=no]) | |
472 | AC_ARG_ENABLE(config-hal, AS_HELP_STRING([--disable-config-hal], [Build HAL support (default: auto)]), [CONFIG_HAL=$enableval], [CONFIG_HAL=auto]) | |
473 | +AC_ARG_ENABLE(config-devd, AS_HELP_STRING([--disable-config-devd], [Build devd support (default: auto)]), [CONFIG_DEVD=$enableval], [CONFIG_DEVD=auto]) | |
474 | AC_ARG_ENABLE(config-wscons, AS_HELP_STRING([--enable-config-wscons], [Build wscons config support (default: auto)]), [CONFIG_WSCONS=$enableval], [CONFIG_WSCONS=auto]) | |
475 | AC_ARG_ENABLE(xfree86-utils, AS_HELP_STRING([--enable-xfree86-utils], [Build xfree86 DDX utilities (default: enabled)]), [XF86UTILS=$enableval], [XF86UTILS=yes]) | |
476 | AC_ARG_ENABLE(vgahw, AS_HELP_STRING([--enable-vgahw], [Build Xorg with vga access (default: enabled)]), [VGAHW=$enableval], [VGAHW=yes]) | |
477 | @@ -922,6 +923,21 @@ if test "x$CONFIG_WSCONS" = xyes; then | |
478 | AC_DEFINE(CONFIG_WSCONS, 1, [Use wscons for input auto configuration]) | |
479 | fi | |
480 | ||
481 | +if test "x$CONFIG_DEVD" = xauto; then | |
482 | + case $host_os in | |
483 | + freebsd* | kfreebsd*-gnu) | |
484 | + CONFIG_DEVD=yes; | |
485 | + ;; | |
486 | + *) | |
487 | + CONFIG_DEVD=no; | |
488 | + ;; | |
489 | + esac | |
490 | +fi | |
491 | +AM_CONDITIONAL(CONFIG_DEVD, [test "x$CONFIG_DEVD" = xyes]) | |
492 | +if test "x$CONFIG_DEVD" = xyes; then | |
493 | + AC_DEFINE(CONFIG_DEVD, 1, [Use devd for input auto configuration]) | |
494 | +fi | |
495 | + | |
496 | if test "x$USE_SIGIO_BY_DEFAULT" = xyes; then | |
497 | USE_SIGIO_BY_DEFAULT_VALUE=TRUE | |
498 | else | |
499 | Index: xorg-server/hw/xfree86/common/xf86Config.c | |
500 | =================================================================== | |
501 | --- xorg-server.orig/hw/xfree86/common/xf86Config.c | |
502 | +++ xorg-server/hw/xfree86/common/xf86Config.c | |
503 | @@ -1377,15 +1377,18 @@ checkCoreInputDevices(serverLayoutPtr se | |
504 | } | |
505 | ||
506 | if (!xf86Info.forceInputDevices && !(foundPointer && foundKeyboard)) { | |
507 | -#if defined(CONFIG_HAL) || defined(CONFIG_UDEV) || defined(CONFIG_WSCONS) | |
508 | +#if defined(CONFIG_HAL) || defined(CONFIG_UDEV) || defined(CONFIG_WSCONS) || \ | |
509 | + defined(CONFIG_DEVD) | |
510 | const char *config_backend; | |
511 | ||
512 | #if defined(CONFIG_HAL) | |
513 | config_backend = "HAL"; | |
514 | #elif defined(CONFIG_UDEV) | |
515 | config_backend = "udev"; | |
516 | -#else | |
517 | +#elif defined(CONFIG_WSCONS) | |
518 | config_backend = "wscons"; | |
519 | +#elif defined(CONFIG_DEVD) | |
520 | + config_backend = "devd"; | |
521 | #endif | |
522 | xf86Msg(X_INFO, "The server relies on %s to provide the list of " | |
523 | "input devices.\n\tIf no devices become available, " | |
524 | Index: xorg-server/hw/xfree86/common/xf86Globals.c | |
525 | =================================================================== | |
526 | --- xorg-server.orig/hw/xfree86/common/xf86Globals.c | |
527 | +++ xorg-server/hw/xfree86/common/xf86Globals.c | |
528 | @@ -123,7 +123,8 @@ xf86InfoRec xf86Info = { | |
529 | .log = LogNone, | |
530 | .disableRandR = FALSE, | |
531 | .randRFrom = X_DEFAULT, | |
532 | -#if defined(CONFIG_HAL) || defined(CONFIG_UDEV) || defined(CONFIG_WSCONS) | |
533 | +#if defined(CONFIG_HAL) || defined(CONFIG_UDEV) || defined(CONFIG_WSCONS) || \ | |
534 | + defined(CONFIG_DEVD) | |
535 | .forceInputDevices = FALSE, | |
536 | .autoAddDevices = TRUE, | |
537 | .autoEnableDevices = TRUE, | |
538 | Index: xorg-server/include/dix-config.h.in | |
539 | =================================================================== | |
540 | --- xorg-server.orig/include/dix-config.h.in | |
541 | +++ xorg-server/include/dix-config.h.in | |
542 | @@ -420,6 +420,9 @@ | |
543 | /* Support HAL for hotplug */ | |
544 | #undef CONFIG_HAL | |
545 | ||
546 | +/* Support devd for hotplug */ | |
547 | +#undef CONFIG_DEVD | |
548 | + | |
549 | /* Have a monotonic clock from clock_gettime() */ | |
550 | #undef MONOTONIC_CLOCK | |
551 |