View | Details | Raw Unified | Return to bug 196678 | Differences between
and this patch

Collapse All | Expand All

(-)/usr/ports/x11-servers/xorg-server/Makefile (-11 / +4 lines)
Lines 51-57 Link Here
51
		--without-xmlto --disable-docs --disable-devel-docs \
51
		--without-xmlto --disable-docs --disable-devel-docs \
52
		--localstatedir=/var --without-dtrace --disable-xephyr \
52
		--localstatedir=/var --without-dtrace --disable-xephyr \
53
		--enable-record=yes --disable-dri3 --disable-xwayland \
53
		--enable-record=yes --disable-dri3 --disable-xwayland \
54
		--enable-glamor
54
		--enable-glamor --enable-config-devd=yes
55
INSTALL_TARGET=	install-strip
55
INSTALL_TARGET=	install-strip
56
56
57
.if ${SLAVE_PORT} == "no"
57
.if ${SLAVE_PORT} == "no"
Lines 118-134 Link Here
118
		-e 's|^LTLIBRARIES = |LTLIBRARIES = libglx.la |g' \
118
		-e 's|^LTLIBRARIES = |LTLIBRARIES = libglx.la |g' \
119
		${WRKSRC}/hw/xfree86/dixmods/Makefile.in
119
		${WRKSRC}/hw/xfree86/dixmods/Makefile.in
120
120
121
post-configure:
121
post-install:
122
.if ${PORT_OPTIONS:MDEVD}
123
	@${REINPLACE_CMD} -e 's|config\.c|config.c devd.c|g' \
124
		-e 's|config\.lo|config.lo devd.lo|g' \
125
		${WRKSRC}/config/Makefile
126
	@${REINPLACE_CMD} -e 's|^/\* #undef CONFIG_UDEV \*/|#define CONFIG_DEVD 1|' \
127
		${WRKSRC}/include/dix-config.h
128
.endif
129
130
.if ${SLAVE_PORT} == "no"
122
.if ${SLAVE_PORT} == "no"
131
post-install:
132
# The .xorg dir because else the xorg-server might not load the correct
123
# The .xorg dir because else the xorg-server might not load the correct
133
# libglx module.
124
# libglx module.
134
	@${MKDIR} ${STAGEDIR}${PREFIX}/lib/xorg/modules/extensions/.xorg
125
	@${MKDIR} ${STAGEDIR}${PREFIX}/lib/xorg/modules/extensions/.xorg
Lines 136-140 Link Here
136
		${STAGEDIR}${PREFIX}/lib/xorg/modules/extensions/.xorg/
127
		${STAGEDIR}${PREFIX}/lib/xorg/modules/extensions/.xorg/
137
	@${MKDIR} ${STAGEDIR}${PREFIX}/etc/X11/xorg.conf.d
128
	@${MKDIR} ${STAGEDIR}${PREFIX}/etc/X11/xorg.conf.d
138
.endif # ! SLAVE_PORT
129
.endif # ! SLAVE_PORT
130
	@${MV} ${STAGEDIR}${PREFIX}/lib/pkgconfig/xorg-server.pc \
131
		${STAGEDIR}${PREFIX}/libdata/pkgconfig/xorg-server.pc
139
132
140
.include <bsd.port.post.mk>
133
.include <bsd.port.post.mk>
(-)/usr/ports/x11-servers/xorg-server/files/patch-config_Makefile.am (+19 lines)
Line 0 Link Here
1
--- config/Makefile.am.orig	2015-10-27 23:12:00.000000000 +0300
2
+++ config/Makefile.am	2016-10-09 23:45:14.589652000 +0300
3
@@ -32,7 +32,15 @@
4
 
5
 if CONFIG_WSCONS
6
 libconfig_la_SOURCES += wscons.c
7
-endif # CONFIG_WSCONS
8
+
9
+else
10
+
11
+if CONFIG_DEVD
12
+libconfig_la_SOURCES += devd.c
13
+libconfig_la_LIBADD += -lusbhid
14
+endif # CONFIG_DEVD
15
+
16
+endif # !CONFIG_WSCONS
17
 
18
 endif # !CONFIG_HAL
19
 
(-)/usr/ports/x11-servers/xorg-server/files/patch-config_devd.c (-316 / +745 lines)
Lines 1-11 Link Here
1
--- config/devd.c.orig	2015-05-19 19:41:49 UTC
1
--- config/devd.c.orig	2015-05-19 19:41:49 UTC
2
+++ config/devd.c
2
+++ config/devd.c
3
@@ -0,0 +1,531 @@
3
@@ -0,0 +1,960 @@
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
7
+ * Copyright (c) 2014 Robert Millan
7
+ * Copyright (c) 2014 Robert Millan
8
+ * Copyright (c) 2014 Jean-Sebastien Pedron
8
+ * Copyright (c) 2014 Jean-Sebastien Pedron
9
+ * Copyright (c) 2015 - 2016 Rozhuk Ivan
9
+ *
10
+ *
10
+ * Permission is hereby granted, free of charge, to any person obtaining a
11
+ * Permission is hereby granted, free of charge, to any person obtaining a
11
+ * copy of this software and associated documentation files (the "Software"),
12
+ * copy of this software and associated documentation files (the "Software"),
Lines 39-46 Link Here
39
+#include <sys/stat.h>
40
+#include <sys/stat.h>
40
+#include <sys/sysctl.h>
41
+#include <sys/sysctl.h>
41
+#include <sys/un.h>
42
+#include <sys/un.h>
43
+#include <sys/mouse.h>
44
+#include <sys/consio.h>
45
+#include <sys/ioctl.h>
46
+#include <dev/usb/usb_ioctl.h>
47
+#include <dev/usb/usbhid.h>
42
+
48
+
43
+#include <ctype.h>
49
+#include <ctype.h>
50
+#include <dirent.h>
44
+#include <errno.h>
51
+#include <errno.h>
45
+#include <fcntl.h>
52
+#include <fcntl.h>
46
+#include <stdlib.h>
53
+#include <stdlib.h>
Lines 47-52 Link Here
47
+#include <stdio.h>
54
+#include <stdio.h>
48
+#include <stdbool.h>
55
+#include <stdbool.h>
49
+#include <unistd.h>
56
+#include <unistd.h>
57
+#include <string.h>
58
+#include <paths.h>
59
+#include <usbhid.h>
50
+
60
+
51
+#include "input.h"
61
+#include "input.h"
52
+#include "inputstr.h"
62
+#include "inputstr.h"
Lines 54-479 Link Here
54
+#include "config-backends.h"
64
+#include "config-backends.h"
55
+#include "os.h"
65
+#include "os.h"
56
+
66
+
57
+#define DEVD_SOCK_PATH "/var/run/devd.pipe"
58
+
67
+
68
+/* from: <linux/input.h> */
69
+#define	_IOC_READ   IOC_OUT
70
+struct input_id {
71
+	uint16_t bustype;
72
+	uint16_t vendor;
73
+	uint16_t product;
74
+	uint16_t version;
75
+};
76
+
77
+#define	EVIOCGBIT(ev, len)	_IOC(_IOC_READ, 'E', 0x20 + (ev), (len))
78
+#define	EVIOCGID		_IOR('E', 0x02, struct input_id)
79
+#define	EVIOCGNAME(len)		_IOC(_IOC_READ, 'E', 0x06, (len))
80
+#define	EVIOCGPHYS(len)		_IOC(_IOC_READ, 'E', 0x07, (len))
81
+
82
+#define	EV_KEY			0x01
83
+#define	EV_REL			0x02
84
+#define	EV_ABS			0x03
85
+#define	BTN_MISC		0x100
86
+#define	BTN_LEFT		0x110
87
+#define	BTN_RIGHT		0x111
88
+#define	BTN_MIDDLE		0x112
89
+#define	BTN_JOYSTICK		0x120
90
+#define	BTN_TOOL_PEN		0x140
91
+#define	BTN_TOOL_FINGER		0x145
92
+#define	BTN_TOUCH		0x14a
93
+#define	BTN_STYLUS		0x14b
94
+#define	BTN_STYLUS2		0x14c
95
+#define	KEY_MAX			0x2ff
96
+#define	KEY_CNT			(KEY_MAX + 1)
97
+#define	REL_X			0x00
98
+#define	REL_Y			0x01
99
+#define	REL_MAX			0x0f
100
+#define	REL_CNT			(REL_MAX + 1)
101
+#define	ABS_X			0x00
102
+#define	ABS_Y			0x01
103
+#define	ABS_PRESSURE		0x18
104
+#define	ABS_MT_SLOT		0x2f
105
+#define	ABS_MAX			0x3f
106
+#define	ABS_CNT			(ABS_MAX + 1)
107
+
108
+#define	U32_BITS		(sizeof(uint32_t) * 8)
109
+#define	U32_CNT(__x)		(((__x) + U32_BITS - 1) / U32_BITS)
110
+#define U32_IS_BIT_SET(__x, __bit) (((((const uint32_t*)(__x))[((__bit) >> 5)] >> ((__bit) & 0x1f))) & 0x01)
111
+
112
+/* from: <linux/joystick.h> */
113
+#define JSIOCGNAME(len)		_IOC(_IOC_READ, 'j', 0x13, len)		/* get identifier string */
114
+
115
+/* WebCamD specific. */
116
+#define WEBCAMD_IOCTL_GET_USB_VENDOR_ID _IOR('q', 250, unsigned short)
117
+#define WEBCAMD_IOCTL_GET_USB_PRODUCT_ID _IOR('q', 251, unsigned short)
118
+#define WEBCAMD_IOCTL_GET_USB_SPEED	_IOR('q', 252, unsigned int)
119
+
120
+#ifdef COMPAT_32BIT
121
+#	define hid_pass_ptr(ptr)	((uint64_t)(uintptr_t)(ptr))
122
+#else
123
+#	define hid_pass_ptr(ptr)	(ptr)
124
+#endif
125
+
126
+#define _PATH_DEV_LEN		(sizeof(_PATH_DEV) - 1)
127
+#define DEVD_PATH_DEV		"devd:" _PATH_DEV
128
+#define DEVD_PATH_DEV_LEN	(sizeof(DEVD_PATH_DEV) - 1)
129
+
130
+#define DEVD_SOCK_PATH		_PATH_VARRUN "devd.pipe"
131
+
59
+#define DEVD_EVENT_ADD		'+'
132
+#define DEVD_EVENT_ADD		'+'
60
+#define DEVD_EVENT_REMOVE	'-'
133
+#define DEVD_EVENT_REMOVE	'-'
134
+#define DEVD_EVENT_NOTIFY	'!'
61
+
135
+
62
+#define RECONNECT_DELAY		5 * 1000
136
+#define RECONNECT_DELAY		(5 * 1000)
63
+
137
+
64
+static int sock_devd;
138
+
65
+static bool is_console_kbd = false;
139
+#define is_meuqual(__v1, __v1sz, __v2, __v2sz)				\
66
+static bool is_kbdmux = false;
140
+	((__v1sz) == (__v2sz) && NULL != (__v1) && NULL != (__v2) &&	\
141
+	 0 == memcmp((__v1), (__v2), (__v1sz)))
142
+
143
+#define is_meuqual_cstr(__cstr, __v, __vsz)				\
144
+	is_meuqual(__cstr, (sizeof(__cstr) - 1), __v, __vsz)
145
+
146
+#define is_de_euqual_cstr(__de, __cstr)					\
147
+	(NULL != (__de) &&						\
148
+	 is_meuqual((__de)->d_name, (__de)->d_namlen, __cstr, (sizeof(__cstr) - 1)))
149
+
150
+#define devd_get_val_cstr(__cstr, __buf, __bufsz, __valsz)		\
151
+	devd_get_val((__buf), (__bufsz), __cstr, (sizeof(__cstr) - 1),	\
152
+	(__valsz))
153
+
154
+
155
+static int devd_skt;
156
+static char devd_buf[4096];
157
+static size_t devd_buf_used = 0;
158
+static int is_kbdmux = 0;
67
+OsTimerPtr rtimer;
159
+OsTimerPtr rtimer;
68
+
160
+
69
+struct hw_type {
161
+
70
+	const char *driver;
162
+/* Input devices. */
71
+	int flag;
163
+typedef struct hw_type_s {
72
+	const char *xdriver;
164
+	const char	*dev_name;
165
+	size_t		dev_name_size;
166
+	size_t		path_offset;
167
+	int		flags;
168
+	const char	*xdriver; 
169
+} hw_type_t, *hw_type_p;
170
+
171
+/* xdriver can be set via config "InputClass" section.
172
+ * Do not set xdriver name if device have more than one
173
+ * xf86-input-* drivers.
174
+ * "input/event" can be hadled by: xf86-input-evdev and
175
+ * xf86-input-wacom, let user chooses.
176
+ */
177
+static hw_type_t hw_types[] = {
178
+	{ "uhid",	4, 0, 0, NULL },
179
+	{ "ukbd",	4, 0, ATTR_KEYBOARD, "kbd" },
180
+	{ "atkbd",	5, 0, ATTR_KEYBOARD, "kbd" },
181
+	{ "kbdmux",	6, 0, ATTR_KEYBOARD, "kbd" },
182
+	{ "sysmouse",	8, 0, ATTR_POINTER, "mouse" },
183
+	{ "ums",	3, 0, ATTR_POINTER, "mouse" },
184
+	{ "psm",	3, 0, ATTR_POINTER, "mouse" },
185
+	{ "vboxguest",	9, 0, ATTR_POINTER, "vboxmouse" },
186
+	{ "joy",	3, 0, ATTR_JOYSTICK, NULL },
187
+	{ "atp",	3, 0, ATTR_TOUCHPAD, NULL },
188
+	{ "uep",	3, 0, ATTR_TOUCHSCREEN, NULL },
189
+	{ "input/event",5, 6, 0, NULL },
190
+	{ "input/js",	2, 6, ATTR_JOYSTICK, NULL },
191
+	{ NULL,		0, 0, 0, NULL },
73
+};
192
+};
74
+
193
+
75
+static struct hw_type hw_types[] = {
194
+/* Input devices paths. */
76
+	{ "ukbd", ATTR_KEYBOARD, "kbd" },
195
+static hw_type_t hw_type_path[] = {
77
+	{ "atkbd", ATTR_KEYBOARD, "kbd" },
196
+	{ "input/",	0, 6, 0, NULL },
78
+	{ "kbdmux", ATTR_KEYBOARD, "kbd" },
197
+	{ NULL,		0, 0, 0, NULL },
79
+	{ "sysmouse", ATTR_POINTER, "mouse" },
80
+	{ "ums", ATTR_POINTER, "mouse" },
81
+	{ "psm", ATTR_POINTER, "mouse" },
82
+	{ "vboxguest", ATTR_POINTER, "vboxmouse" },
83
+	{ "joy", ATTR_JOYSTICK, NULL },
84
+	{ "atp", ATTR_TOUCHPAD, NULL },
85
+	{ "uep", ATTR_TOUCHSCREEN, NULL },
86
+	{ NULL, -1, NULL },
87
+};
198
+};
88
+
199
+
89
+static bool
200
+
90
+sysctl_exists(const struct hw_type *device, int unit,
201
+static size_t
91
+	char *devname, size_t devname_len)
202
+bits_calc(const uint32_t *bits, size_t off_start, size_t off_stop)
92
+{
203
+{
93
+	char sysctlname[PATH_MAX];
204
+	size_t i, count = 0;
94
+	size_t len;
95
+	int ret;
96
+
205
+
97
+	if (device == NULL || device->driver == NULL)
206
+	for (i = off_start; i < off_stop; i ++) {
98
+		return false;
207
+		if (U32_IS_BIT_SET(bits, i)) {
208
+			count ++;
209
+		}
210
+	}
211
+	return (count);
212
+}
99
+
213
+
100
+	/* Check if a sysctl exists. */
214
+static hw_type_p
101
+	snprintf(sysctlname, sizeof(sysctlname), "dev.%s.%i.%%desc",
215
+get_dev_type_by_name(const char *dev_name, size_t dev_name_size)
102
+	    device->driver, unit);
216
+{
103
+	ret = sysctlbyname(sysctlname, NULL, &len, NULL, 0);
217
+	size_t i;
104
+
218
+
105
+	if (ret == 0 && len > 0) {
219
+	if (NULL == dev_name || 0 == dev_name_size)
106
+		snprintf(devname, devname_len, "%s%i", device->driver, unit);
220
+		return (NULL);
107
+		return true;
221
+	for (i = 0; NULL != hw_types[i].dev_name; i ++) {
222
+		if (dev_name_size >= (hw_types[i].dev_name_size + hw_types[i].path_offset) &&
223
+		    0 == memcmp(dev_name, hw_types[i].dev_name,
224
+		    (hw_types[i].path_offset + hw_types[i].dev_name_size))) {
225
+			return (&hw_types[i]);
226
+		}
108
+	}
227
+	}
228
+	return (NULL);
229
+}
109
+
230
+
110
+	return false;
231
+/* From: sys/dev/usb/usb_hid.c */
232
+static int
233
+hid_is_collection(report_desc_t s, uint32_t usage)
234
+{
235
+	struct hid_data *hd;
236
+	struct hid_item hi;
237
+	int rc;
238
+
239
+	hd = hid_start_parse(s, ~0, -1);
240
+	if (hd == NULL)
241
+		return (0);
242
+
243
+	while ((rc = hid_get_item(hd, &hi))) {
244
+		 if (hi.kind == hid_collection &&
245
+		     hi.usage == usage)
246
+			break;
247
+	}
248
+	hid_end_parse(hd);
249
+	return (rc);
111
+}
250
+}
112
+
251
+
113
+static bool
252
+static int
114
+devpath_exists(const struct hw_type *device,
253
+hid_is_mouse(report_desc_t s)
115
+	char *devname, size_t devname_len)
116
+{
254
+{
117
+	char *devpath;
255
+	struct hid_data *hd;
118
+	struct stat st;
256
+	struct hid_item hi;
119
+	int ret;
257
+	int mdepth;
258
+	int found;
120
+
259
+
121
+	if (device == NULL || device->driver == NULL)
260
+	hd = hid_start_parse(s, (1 << hid_input), -1);
122
+		return false;
261
+	if (hd == NULL)
262
+		return (0);
123
+
263
+
124
+	/* Check if /dev/$driver exists. */
264
+	mdepth = 0;
125
+	asprintf(&devpath, "/dev/%s", device->driver);
265
+	found = 0;
126
+	if (devpath == NULL)
127
+		return false;
128
+
266
+
129
+	ret = stat(devpath, &st);
267
+	while (hid_get_item(hd, &hi)) {
130
+	free(devpath);
268
+		switch (hi.kind) {
269
+		case hid_collection:
270
+			if (mdepth != 0)
271
+				mdepth ++;
272
+			else if (hi.collection == 1 &&
273
+			     hi.usage ==
274
+			      HID_USAGE2(HUP_GENERIC_DESKTOP, HUG_MOUSE))
275
+				mdepth ++;
276
+			break;
277
+		case hid_endcollection:
278
+			if (mdepth != 0)
279
+				mdepth --;
280
+			break;
281
+		case hid_input:
282
+			if (mdepth == 0)
283
+				break;
284
+			if (hi.usage ==
285
+			     HID_USAGE2(HUP_GENERIC_DESKTOP, HUG_X) &&
286
+			    (hi.flags & (HIO_CONST|HIO_RELATIVE)) == HIO_RELATIVE)
287
+				found ++;
288
+			if (hi.usage ==
289
+			     HID_USAGE2(HUP_GENERIC_DESKTOP, HUG_Y) &&
290
+			    (hi.flags & (HIO_CONST|HIO_RELATIVE)) == HIO_RELATIVE)
291
+				found ++;
292
+			break;
293
+		default:
294
+			break;
295
+		}
296
+	}
297
+	hid_end_parse(hd);
298
+	return (found);
299
+}
131
+
300
+
132
+	if (ret == 0) {
301
+
133
+		strncpy(devname, device->driver, devname_len);
302
+static hw_type_p
134
+		return true;
303
+get_dev_type_by_path(const char *dev_name, size_t dev_name_size,
304
+    hw_type_p hw_type_cust)
305
+{
306
+	size_t i;
307
+
308
+	if (NULL == dev_name || 0 == dev_name_size || NULL == hw_type_cust)
309
+		return (NULL);
310
+	for (i = 0; NULL != hw_type_path[i].dev_name; i ++) {
311
+		if (dev_name_size <= hw_type_path[i].path_offset ||
312
+		    0 != memcmp(dev_name, hw_type_path[i].dev_name,
313
+		    hw_type_path[i].path_offset))
314
+			continue;
315
+		/* Path in white list. */
316
+		hw_type_cust->dev_name = dev_name;
317
+		hw_type_cust->path_offset = hw_type_path[i].path_offset;
318
+		for (i = hw_type_cust->path_offset; i < dev_name_size; i ++) {
319
+			if (isdigit(dev_name[i]))
320
+				break;
321
+		}
322
+		hw_type_cust->dev_name_size = (i - hw_type_cust->path_offset);
323
+		hw_type_cust->flags = hw_type_path[i].flags;
324
+		hw_type_cust->xdriver = hw_type_path[i].xdriver;
325
+		return (hw_type_cust);
135
+	}
326
+	}
327
+	return (NULL);
328
+}
136
+
329
+
137
+	return false;
330
+static int
331
+is_kbdmux_enabled(void)
332
+{
333
+	/* Xorg uses /dev/ttyv0 as a console device */
334
+	/* const char device[]="/dev/console"; */
335
+	int fd;
336
+	const char *device = _PATH_TTY "v0";
337
+	keyboard_info_t info;
338
+
339
+	fd = open(device, O_RDONLY);
340
+	if (0 > fd)
341
+		return (0);
342
+	if (-1 == ioctl(fd, KDGKBINFO, &info) ||
343
+	    0 != memcmp(info.kb_name, "kbdmux", 6)) {
344
+		close(fd);
345
+		return (0);
346
+	}
347
+	close(fd);
348
+	return (1);
138
+}
349
+}
139
+
350
+
140
+static char *
351
+static char *
141
+sysctl_get_str(const char *sysctlname)
352
+sysctl_get_str(const char *sysctlname, size_t *size_ret)
142
+{
353
+{
143
+	char *dest = NULL;
354
+	char *dest;
144
+	size_t len;
355
+	size_t len;
145
+
356
+
146
+	if (sysctlname == NULL)
357
+	if (NULL == sysctlname)
147
+		return NULL;
358
+		return (NULL);
359
+	if (0 != sysctlbyname(sysctlname, NULL, &len, NULL, 0))
360
+		return (NULL);
361
+	dest = malloc(len + 4);
362
+	if (NULL == dest)
363
+		return (NULL);
364
+	if (0 != sysctlbyname(sysctlname, dest, &len, NULL, 0)) {
365
+		free(dest);
366
+		return (NULL);
367
+	}
368
+	dest[len] = 0;
369
+	if (NULL != size_ret)
370
+		(*size_ret) = len;
371
+	return (dest);
372
+}
148
+
373
+
149
+	if (sysctlbyname(sysctlname, NULL, &len, NULL, 0) == 0) {
374
+static char *
150
+		dest = malloc(len + 1);
375
+devd_get_val(char *buf, size_t buf_size, const char *val_name,
151
+		if (dest) {
376
+    size_t val_name_size, size_t *val_size)
152
+			if (sysctlbyname(sysctlname, dest, &len, NULL, 0) == 0)
377
+{
153
+				dest[len] = '\0';
378
+	char *ret, *buf_end, *ptr;
154
+			else {
379
+
155
+				free(dest);
380
+	buf_end = (buf + buf_size);
156
+				dest = NULL;
381
+	for (ret = buf; ret != NULL && ret < buf_end;) {
157
+			}
382
+		ret = memmem(ret, (buf_end - ret), val_name, val_name_size);
383
+		if (ret == NULL)
384
+			return (NULL);
385
+		/* Found. */
386
+		/* Check: space before or buf+1. */
387
+		if ((buf + 1) < ret && ret[-1] != ' ') {
388
+			ret += val_name_size;
389
+			continue;
158
+		}
390
+		}
391
+		/* Check: = after name and size for value. */
392
+		ret += val_name_size;
393
+		if ((ret + 1) >= buf_end)
394
+			return (NULL);
395
+		if ('=' != ret[0])
396
+			continue;
397
+		ret ++;
398
+		break;
159
+	}
399
+	}
160
+
400
+	if (ret == NULL || val_size == NULL)
161
+	return dest;
401
+		return (ret);
402
+	/* Calc value data size. */
403
+	ptr = memchr(ret, ' ', (buf_end - ret));
404
+	if (ptr == NULL) /* End of string/last value. */
405
+		ptr = buf_end;
406
+	(*val_size) = (ptr - ret);
407
+	return (ret);
162
+}
408
+}
163
+
409
+
164
+static void
410
+static void
165
+device_added(const char *devname)
411
+device_added(const char *dev_name, size_t dev_name_size, int allow_no_device)
166
+{
412
+{
167
+	char path[PATH_MAX];
413
+	int fd;
168
+	char sysctlname[PATH_MAX];
169
+	char *vendor;
170
+	char *product = NULL;
171
+	char *config_info = NULL;
172
+	char *walk;
173
+	InputOption *options = NULL;
414
+	InputOption *options = NULL;
174
+	InputAttributes attrs = { };
415
+	InputAttributes attrs;
175
+	DeviceIntPtr dev = NULL;
416
+	DeviceIntPtr dev_iptr = NULL;
176
+	int i;
417
+	keyboard_info_t kbdi;
177
+	int fd;
418
+	mousehw_t mshw;
419
+	struct input_id iid;
420
+	report_desc_t rep_desc;
421
+	struct usb_device_info usb_dev_info;
422
+	size_t has_keys = 0, has_buttons = 0, has_lmr = 0;
423
+	size_t has_rel_axes = 0, has_abs_axes = 0, has_mt = 0;
424
+	uint32_t key_bits[U32_CNT(KEY_CNT)];
425
+	uint32_t rel_bits[U32_CNT(REL_CNT)];
426
+	uint32_t abs_bits[U32_CNT(ABS_CNT)];
427
+	char *dev_path, config_info[(PATH_MAX + 32)];
428
+	char sysctlname[PATH_MAX], *sdata, *ptr_pid, *ptr_vid;
429
+	char pnp_usb_id[PATH_MAX], vendor[PATH_MAX], product[PATH_MAX];
430
+	size_t sdata_size, pid_size, vid_size;
431
+	hw_type_t *hwtype, hwtype_cust;
432
+	unsigned short vid, pid;
178
+
433
+
179
+	for (i = 0; hw_types[i].driver != NULL; i++) {
180
+		size_t len;
181
+
434
+
182
+		len = strlen(hw_types[i].driver);
435
+	if (NULL == dev_name || 0 == dev_name_size || PATH_MAX < dev_name_size)
183
+		if (strcmp(devname, hw_types[i].driver) == 0 ||
436
+		return;
184
+			(strncmp(devname, hw_types[i].driver, len) == 0 &&
437
+	/* Make dev_name null ended string. */
185
+				isnumber(*(devname + len)))) {
438
+	snprintf(config_info, sizeof(config_info), DEVD_PATH_DEV"%.*s",
186
+			attrs.flags |= hw_types[i].flag;
439
+	    (int)dev_name_size, dev_name);
187
+			break;
440
+	/* Set / update pointers to dev_name and dev_path. */
188
+		}
441
+	dev_path = (config_info + 5); /* Skip: "devd:" */
442
+	dev_name = (dev_path + _PATH_DEV_LEN); /* Skip: "/dev/" */
443
+
444
+	/* Is known input device or path? */
445
+	hwtype = get_dev_type_by_name(dev_name, dev_name_size);
446
+	if (NULL == hwtype) {
447
+		hwtype = get_dev_type_by_path(dev_name, dev_name_size,
448
+		    &hwtype_cust);
189
+	}
449
+	}
190
+
450
+	if (NULL == hwtype) /* Not found in white list. */
191
+	if (hw_types[i].driver == NULL || hw_types[i].xdriver == NULL) {
192
+		LogMessage(X_INFO, "config/devd: ignoring device %s\n",
193
+				devname);
194
+		return;
451
+		return;
195
+	}
452
+	/* Init and set attributes. */
453
+	memset(&attrs, 0, sizeof(attrs));
454
+	attrs.device = dev_path;
455
+	attrs.flags = hwtype->flags;
196
+
456
+
197
+	/* Skip keyboard devices if kbdmux is enabled */
457
+	/* Skip keyboard devices if kbdmux is enabled */
198
+	if (is_kbdmux && is_console_kbd && hw_types[i].flag & ATTR_KEYBOARD) {
458
+	if (is_kbdmux && 0 == allow_no_device && (hwtype->flags & ATTR_KEYBOARD)) {
459
+skip_kbd_dev:
199
+		LogMessage(X_INFO, "config/devd: kbdmux is enabled, ignoring device %s\n",
460
+		LogMessage(X_INFO, "config/devd: kbdmux is enabled, ignoring device %s\n",
200
+				devname);
461
+		    dev_name);
201
+		return;
462
+		return;
202
+	}
463
+	}
203
+
464
+	/* Skip duplicate devices. */
204
+	snprintf(path, sizeof(path), "/dev/%s", devname);
465
+	if (device_is_duplicate(config_info)) {
205
+
466
+		LogMessage(X_WARNING, "config/devd: device %s already added. ignoring\n",
206
+	options = input_option_new(NULL, "_source", "server/devd");
467
+		    dev_path);
207
+	if (!options)
208
+		return;
468
+		return;
209
+
210
+	snprintf(sysctlname, sizeof(sysctlname), "dev.%s.%s.%%desc",
211
+	    hw_types[i].driver, devname + strlen(hw_types[i].driver));
212
+	vendor = sysctl_get_str(sysctlname);
213
+	if (vendor == NULL) {
214
+		options = input_option_new(options, "name", devname);
215
+	}
469
+	}
216
+	else {
217
+		if ((walk = strchr(vendor, ' ')) != NULL) {
218
+			walk[0] = '\0';
219
+			walk++;
220
+			product = walk;
221
+			if ((walk = strchr(product, ',')) != NULL)
222
+				walk[0] = '\0';
223
+		}
224
+
470
+
225
+		attrs.vendor = strdup(vendor);
471
+	/* Try to open device. */
226
+		if (product) {
472
+	fd = open(dev_path, O_RDONLY);
227
+			attrs.product = strdup(product);
473
+	if (0 > fd) {
228
+			options = input_option_new(options, "name", product);
474
+		if (0 == (hwtype->flags & ATTR_KEYBOARD)) {
229
+		}
230
+		else
231
+			options = input_option_new(options, "name", "(unnamed)");
232
+
233
+		free(vendor);
234
+	}
235
+
236
+	/* XXX implement usb_id */
237
+	attrs.usb_id = NULL;
238
+	attrs.device = strdup(path);
239
+	options = input_option_new(options, "driver", hw_types[i].xdriver);
240
+
241
+	fd = open(path, O_RDONLY);
242
+	if (fd > 0) {
243
+		close(fd);
244
+		options = input_option_new(options, "device", path);
245
+	}
246
+	else {
247
+		if (attrs.flags & ~ATTR_KEYBOARD) {
248
+			LogMessage(X_INFO, "config/devd: device %s already opened\n",
475
+			LogMessage(X_INFO, "config/devd: device %s already opened\n",
249
+					 path);
476
+			    dev_path);
250
+
251
+			/*
477
+			/*
252
+			 * Fail if cannot open device, it breaks AllowMouseOpenFail,
478
+			 * Fail if cannot open device, it breaks AllowMouseOpenFail,
253
+			 * but it should not matter when config/devd enabled
479
+			 * but it should not matter when config/devd enabled
254
+			 */
480
+			 */
255
+			goto unwind;
481
+			return;
256
+		}
482
+		}
257
+
483
+		if (0 == allow_no_device) {
258
+		if (is_console_kbd) {
259
+			/*
484
+			/*
260
+			 * There can be only one keyboard attached to console and
485
+			 * There can be only one keyboard attached to console and
261
+			 * it is already added.
486
+			 * it is already added.
262
+			 */
487
+			 */
263
+			LogMessage(X_WARNING, "config/devd: console keyboard is "
488
+			LogMessage(X_WARNING, "config/devd: console keyboard is "
264
+					"already added, ignoring %s (%s)\n",
489
+			    "already added, ignoring %s\n",
265
+					attrs.product, path);
490
+			    dev_path);
266
+			goto unwind;
491
+			return;
267
+		}
492
+		}
268
+		else
493
+		/*
269
+			/*
494
+		 * Don't pass "device" option if the keyboard is already
270
+			 * Don't pass "device" option if the keyboard is already
495
+		 * attached to the console (ie. open() fails).
271
+			 * attached to the console (ie. open() fails).
496
+		 * This would activate a special logic in xf86-input-keyboard.
272
+			 * This would activate a special logic in xf86-input-keyboard.
497
+		 * Prevent any other attached to console keyboards being
273
+			 * Prevent any other attached to console keyboards being
498
+		 * processed. There can be only one such device.
274
+			 * processed. There can be only one such device.
499
+		 */
275
+			 */
500
+		goto skip_ioctl;
276
+			is_console_kbd = true;
277
+	}
501
+	}
278
+
502
+
279
+	if (asprintf(&config_info, "devd:%s", devname) == -1) {
503
+	/* Try to get device info via ioctl(). */
280
+		config_info = NULL;
504
+	if (-1 != ioctl(fd, KDGKBINFO, &kbdi)) { /* Is this keyboard? */
281
+		goto unwind;
505
+		memcpy(product, kbdi.kb_name, sizeof(kbdi.kb_name));
506
+		attrs.product = product;
507
+		attrs.flags = ATTR_KEYBOARD;
508
+		LogMessage(X_INFO, "config/devd: detected keyboard: %s, kb_index=%i, kb_unit=%i, kb_type=%i, kb_config=%i\n",
509
+		    kbdi.kb_name, kbdi.kb_index, kbdi.kb_unit, kbdi.kb_type, kbdi.kb_config);
510
+	} else if (-1 != ioctl(fd, MOUSE_GETHWINFO, &mshw)) { /* Is this mouse? */
511
+#ifdef notyet /* FreeBSD mouse drivers does not return real vid+pid. */
512
+		/* construct USB ID in lowercase hex - "0000:ffff" */
513
+		snprintf(pnp_usb_id, sizeof(pnp_usb_id), "%04x:%04x",
514
+		    mshw.hwid, mshw.model);
515
+		attrs.usb_id = pnp_usb_id;
516
+#endif
517
+
518
+		switch (mshw.type) {
519
+		case MOUSE_MOUSE:
520
+		case MOUSE_TRACKBALL:
521
+		case MOUSE_STICK:
522
+			attrs.flags = ATTR_POINTER;
523
+			break;
524
+		case MOUSE_PAD:
525
+			attrs.flags = ATTR_TOUCHPAD;		
526
+			break;
527
+		}
528
+		LogMessage(X_INFO, "config/devd: detected mouse: hwid=%04x, model=%04x, type=%04x, iftype=%04x, buttons=%04x\n",
529
+		    mshw.hwid, mshw.model, mshw.type, mshw.iftype, mshw.buttons);
530
+	} else if (-1 != ioctl(fd, JSIOCGNAME((sizeof(product) - 1)), product)) { /* Is this joystick? */
531
+		attrs.product = product;
532
+		attrs.flags = ATTR_JOYSTICK;
533
+		LogMessage(X_INFO, "config/devd: detected joystick: %s\n",
534
+		    product);
535
+	} else if (-1 != ioctl(fd, EVIOCGID, &iid) &&
536
+	    -1 != ioctl(fd, EVIOCGNAME((sizeof(product) - 1)), product)) { /* Is this event? */
537
+		/* construct USB ID in lowercase hex - "0000:ffff" */
538
+		snprintf(pnp_usb_id, sizeof(pnp_usb_id), "%04x:%04x",
539
+		    iid.vendor, iid.product);
540
+		attrs.usb_id = pnp_usb_id;
541
+		attrs.product = product;
542
+
543
+		/* Detect device type. */
544
+		if (-1 != ioctl(fd, EVIOCGBIT(EV_KEY, sizeof(key_bits)), key_bits)) {
545
+			has_keys = bits_calc(key_bits, 0, BTN_MISC);
546
+			has_buttons = bits_calc(key_bits, BTN_MISC, BTN_JOYSTICK);
547
+			has_lmr = bits_calc(key_bits, BTN_LEFT, BTN_MIDDLE);
548
+		}
549
+		if (-1 != ioctl(fd, EVIOCGBIT(EV_REL, sizeof(rel_bits)), rel_bits)) {
550
+			has_rel_axes = bits_calc(rel_bits, 0, REL_MAX);
551
+		}
552
+		if (-1 != ioctl(fd, EVIOCGBIT(EV_ABS, sizeof(abs_bits)), abs_bits)) {
553
+			has_abs_axes = bits_calc(abs_bits, 0, ABS_MAX);
554
+			has_mt = bits_calc(abs_bits, ABS_MT_SLOT, ABS_MAX);
555
+		}
556
+
557
+		if (has_abs_axes) {
558
+			if (has_mt) {
559
+				if (0 == has_buttons) {
560
+					/*
561
+					 * XXX: I'm not sure that joystick detection is
562
+					 * done right. xf86-evdev does not support them.
563
+					 */
564
+					if (U32_IS_BIT_SET(key_bits, BTN_JOYSTICK)) {
565
+						attrs.flags = ATTR_JOYSTICK;
566
+						goto event_done;
567
+					} else {
568
+						has_buttons ++;
569
+					}
570
+				}
571
+			}
572
+			if (U32_IS_BIT_SET(abs_bits, ABS_X) &&
573
+			    U32_IS_BIT_SET(abs_bits, ABS_Y)) {
574
+				if (U32_IS_BIT_SET(key_bits, BTN_TOOL_PEN) ||
575
+				    U32_IS_BIT_SET(key_bits, BTN_STYLUS) ||
576
+				    U32_IS_BIT_SET(key_bits, BTN_STYLUS2)) {
577
+					attrs.flags = ATTR_TABLET;
578
+					goto event_done;
579
+				} else if (U32_IS_BIT_SET(abs_bits, ABS_PRESSURE) ||
580
+					   U32_IS_BIT_SET(key_bits, BTN_TOUCH)) {
581
+					if (has_lmr ||
582
+					    U32_IS_BIT_SET(key_bits, BTN_TOOL_FINGER)) {
583
+						attrs.flags = ATTR_TOUCHPAD;
584
+					} else {
585
+						attrs.flags = ATTR_TOUCHSCREEN;
586
+					}
587
+					goto event_done;
588
+				} else if (!(U32_IS_BIT_SET(rel_bits, REL_X) &&
589
+					     U32_IS_BIT_SET(rel_bits, REL_Y)) &&
590
+					    has_lmr) {
591
+					/* some touchscreens use BTN_LEFT rather than BTN_TOUCH */
592
+					attrs.flags = ATTR_TOUCHSCREEN;
593
+					goto event_done;
594
+				}
595
+			}
596
+		}
597
+		if (has_keys) {
598
+			if (is_kbdmux) {
599
+				close(fd);
600
+				goto skip_kbd_dev;
601
+			}
602
+			attrs.flags = ATTR_KEYBOARD;
603
+		} else if (has_rel_axes || has_abs_axes || has_buttons) {
604
+			attrs.flags = ATTR_POINTER;			
605
+		}
606
+event_done:
607
+		LogMessage(X_INFO, "config/devd: detected event: %s, bustype=%04x, vendor=%04x, product=%04x, version=%04x\n",
608
+		    product, iid.bustype, iid.vendor, iid.product, iid.version);
609
+	} else if (0 != (rep_desc = hid_get_report_desc(fd))) { /* Is USB HID? */
610
+		if (hid_is_mouse(rep_desc)) {
611
+			attrs.flags = ATTR_POINTER;
612
+		} else if (hid_is_collection(rep_desc, HID_USAGE2(HUP_GENERIC_DESKTOP, HUG_KEYBOARD))) {
613
+			/* Skip keyboard devices if kbdmux is enabled */
614
+			if (is_kbdmux) {
615
+				hid_dispose_report_desc(rep_desc);
616
+				close(fd);
617
+				goto skip_kbd_dev;
618
+			}
619
+			attrs.flags = ATTR_KEYBOARD;
620
+		} else if (hid_is_collection(rep_desc, HID_USAGE2(HUP_GENERIC_DESKTOP, HUG_JOYSTICK)) ||
621
+		    hid_is_collection(rep_desc, HID_USAGE2(HUP_GENERIC_DESKTOP, HUG_GAME_PAD))) {
622
+			attrs.flags = ATTR_JOYSTICK;
623
+		}
624
+
625
+		hid_dispose_report_desc(rep_desc);
626
+		LogMessage(X_INFO, "config/devd: detected USB HID...\n");
282
+	}
627
+	}
283
+
628
+
284
+	if (device_is_duplicate(config_info)) {
629
+	if (NULL == attrs.usb_id) { /* Is this webcamd device? */
285
+		LogMessage(X_WARNING, "config/devd: device %s (%s) already added. "
630
+		if (-1 != ioctl(fd, WEBCAMD_IOCTL_GET_USB_VENDOR_ID, &vid) &&
286
+				"ignoring\n", attrs.product, path);
631
+		    -1 != ioctl(fd, WEBCAMD_IOCTL_GET_USB_PRODUCT_ID, &pid)) {
287
+		goto unwind;
632
+			snprintf(pnp_usb_id, sizeof(pnp_usb_id),
633
+			    "%04x:%04x", vid, pid);
634
+			attrs.usb_id = pnp_usb_id;
635
+			LogMessage(X_INFO, "config/devd: WebCamD device: %s\n", pnp_usb_id);
636
+		}
288
+	}
637
+	}
289
+
638
+
639
+	close(fd);
640
+
641
+skip_ioctl:
642
+	/* Try to get device info via sysctl(). */
643
+	if (NULL == attrs.usb_id && NULL == attrs.pnp_id) {
644
+		snprintf(sysctlname, sizeof(sysctlname), "dev.%.*s.%s.%%pnpinfo",
645
+		    (int)hwtype->dev_name_size, (hwtype->dev_name + hwtype->path_offset),
646
+		    (dev_name + hwtype->path_offset + hwtype->dev_name_size));
647
+		sdata = sysctl_get_str(sysctlname, &sdata_size);
648
+		if (NULL != sdata) {
649
+			ptr_vid = devd_get_val_cstr("vendor",
650
+			    sdata, sdata_size, &vid_size);
651
+			ptr_pid = devd_get_val_cstr("product",
652
+			    sdata, sdata_size, &pid_size);
653
+			if (NULL != ptr_vid && NULL != ptr_pid) { /* usb_id */
654
+				ptr_vid[vid_size] = 0;
655
+				ptr_pid[pid_size] = 0;
656
+				snprintf(pnp_usb_id, sizeof(pnp_usb_id),
657
+				    "%s:%s", ptr_vid, ptr_pid);
658
+				attrs.usb_id = pnp_usb_id;
659
+				LogMessage(X_INFO, "config/devd: [sysctl] usb_id: %s\n", pnp_usb_id);
660
+			} else { /* pnp_id */
661
+				strlcpy(pnp_usb_id, sdata, sizeof(pnp_usb_id));
662
+				attrs.pnp_id = pnp_usb_id;
663
+			}
664
+			free(sdata);
665
+		}
666
+	}
667
+	if (NULL == attrs.vendor || NULL == attrs.product) {
668
+		snprintf(sysctlname, sizeof(sysctlname), "dev.%.*s.%s.%%desc",
669
+		    (int)hwtype->dev_name_size, (hwtype->dev_name + hwtype->path_offset),
670
+		    (dev_name + hwtype->path_offset + hwtype->dev_name_size));
671
+		sdata = sysctl_get_str(sysctlname, &sdata_size);
672
+		if (NULL != sdata) {
673
+			/* Vendor. */
674
+			ptr_pid = memchr(sdata, ' ', sdata_size);
675
+			if (NULL != ptr_pid)
676
+				ptr_pid[0] = 0;
677
+			strlcpy(vendor, sdata, sizeof(vendor));
678
+			attrs.vendor = vendor;
679
+			/* Product. */
680
+			if (NULL == attrs.product && NULL != ptr_pid) {
681
+				ptr_pid ++;
682
+				ptr_vid = memchr(ptr_pid, ',',
683
+				    (sdata_size - (ptr_pid - sdata)));
684
+				if (NULL != ptr_vid)
685
+					ptr_vid[0] = 0;
686
+				strlcpy(product, ptr_pid, sizeof(product));
687
+				attrs.product = product;
688
+			} else {
689
+				product[0] = 0;
690
+			}
691
+			free(sdata);
692
+			LogMessage(X_INFO, "config/devd: [sysctl] vendor: %s, product: %s\n", vendor, product);
693
+		}
694
+	}
695
+
696
+	/* Init options. */
697
+	options = input_option_new(NULL, "_source", "server/devd");
698
+	if (NULL == options)
699
+		goto err_out;
700
+
290
+	options = input_option_new(options, "config_info", config_info);
701
+	options = input_option_new(options, "config_info", config_info);
291
+	LogMessage(X_INFO, "config/devd: adding input device %s (%s)\n",
702
+	if (NULL == options)
292
+			attrs.product, path);
703
+		goto err_out;
293
+
704
+
294
+	NewInputDeviceRequest(options, &attrs, &dev);
705
+	options = input_option_new(options, "name",
706
+	    ((NULL != attrs.product) ? attrs.product : dev_name));
707
+	if (NULL == options)
708
+		goto err_out;
295
+
709
+
296
+unwind:
710
+	if (fd >= 0) {
297
+	free(config_info);
711
+		options = input_option_new(options, "device", dev_path);
712
+		if (NULL == options)
713
+			goto err_out;
714
+	}
715
+
716
+	if (NULL != hwtype->xdriver) {
717
+		options = input_option_new(options, "driver", hwtype->xdriver);
718
+		if (NULL == options)
719
+			goto err_out;
720
+	}
721
+
722
+	LogMessage(X_INFO, "config/devd: adding input device %s\n", dev_path);
723
+	NewInputDeviceRequest(options, &attrs, &dev_iptr);
724
+	goto done;
725
+
726
+err_out:
727
+	LogMessage(X_INFO, "config/devd: error adding device '%s'\n",
728
+	    dev_path);
729
+done:
298
+	input_option_free_list(&options);
730
+	input_option_free_list(&options);
299
+	free(attrs.usb_id);
300
+	free(attrs.product);
301
+	free(attrs.device);
302
+	free(attrs.vendor);
303
+}
731
+}
304
+
732
+
305
+static void
733
+static void
306
+device_removed(char *devname)
734
+device_removed(const char *dev_name, size_t dev_name_size)
307
+{
735
+{
308
+	char *config_info;
736
+	char config_info[(PATH_MAX + 32)];
737
+	hw_type_t hwtype_cust;
309
+
738
+
310
+	if (asprintf(&config_info, "devd:%s", devname) == -1)
739
+	if (NULL == dev_name || 0 == dev_name_size || PATH_MAX < dev_name_size)
311
+		return;
740
+		return;
312
+
741
+	if (NULL == get_dev_type_by_name(dev_name, dev_name_size) &&
742
+	    NULL == get_dev_type_by_path(dev_name, dev_name_size, &hwtype_cust))
743
+		return; /* Device not in list - unknown. */
744
+	snprintf(config_info, sizeof(config_info), DEVD_PATH_DEV"%.*s",
745
+	    (int)dev_name_size, dev_name);
746
+	/* Skip non added devices. */
747
+	if (device_is_duplicate(config_info)) {
748
+		LogMessage(X_INFO, "config/devd: removing input device '%s'\n",
749
+		    (config_info + DEVD_PATH_DEV_LEN));
750
+	}
313
+	remove_devices("devd", config_info);
751
+	remove_devices("devd", config_info);
314
+
315
+	free(config_info);
316
+}
752
+}
317
+
753
+
318
+static bool is_kbdmux_enabled(void)
319
+{
320
+	/* Xorg uses /dev/ttyv0 as a console device */
321
+	/* const char device[]="/dev/console"; */
322
+	const char device[]="/dev/ttyv0";
323
+	keyboard_info_t info;
324
+	int fd;
325
+
754
+
326
+	fd = open(device, O_RDONLY);
327
+
328
+	if (fd < 0)
329
+		return false;
330
+
331
+	if (ioctl(fd, KDGKBINFO, &info) == -1) {
332
+		close(fd);
333
+		return false;
334
+	}
335
+
336
+	close(fd);
337
+
338
+	if (!strncmp(info.kb_name, "kbdmux", 6))
339
+		return true;
340
+
341
+	return false;
342
+}
343
+
344
+static void
755
+static void
345
+disconnect_devd(int sock)
756
+disconnect_devd(int sock)
346
+{
757
+{
347
+	if (sock >= 0) {
758
+	if (0 > sock)
348
+		RemoveGeneralSocket(sock);
759
+		return;
349
+		close(sock);
760
+	RemoveGeneralSocket(sock);
350
+	}
761
+	close(sock);
351
+}
762
+}
352
+
763
+
353
+static int
764
+static int
354
+connect_devd(void)
765
+connect_devd(void)
355
+{
766
+{
767
+	int sock;
356
+	struct sockaddr_un devd;
768
+	struct sockaddr_un devd;
357
+	int sock;
358
+
769
+
359
+	sock = socket(AF_UNIX, SOCK_STREAM, 0);
770
+	sock = socket(AF_UNIX, SOCK_STREAM, 0);
360
+	if (sock < 0) {
771
+	if (0 > sock) {
361
+		LogMessage(X_ERROR, "config/devd: fail opening stream socket\n");
772
+		LogMessage(X_ERROR, "config/devd: fail opening stream socket\n");
362
+		return -1;
773
+		return (-1);
363
+	}
774
+	}
364
+
775
+
365
+	devd.sun_family = AF_UNIX;
776
+	devd.sun_family = AF_UNIX;
366
+	strlcpy(devd.sun_path, DEVD_SOCK_PATH, sizeof(devd.sun_path));
777
+	memcpy(devd.sun_path, DEVD_SOCK_PATH, sizeof(DEVD_SOCK_PATH));
367
+
778
+	if (0 > connect(sock, (struct sockaddr*)&devd, sizeof(devd))) {
368
+	if (connect(sock, (struct sockaddr *) &devd, sizeof(devd)) < 0) {
369
+		close(sock);
779
+		close(sock);
370
+		LogMessage(X_ERROR, "config/devd: fail to connect to devd\n");
780
+		LogMessage(X_ERROR, "config/devd: fail to connect to devd\n");
371
+		return -1;
781
+		return (-1);
372
+	}
782
+	}
373
+
783
+
374
+	AddGeneralSocket(sock);
784
+	AddGeneralSocket(sock);
375
+
785
+
376
+	return	sock;
786
+	return (sock);
377
+}
787
+}
378
+
788
+
379
+static CARD32
789
+static CARD32
380
+reconnect_handler(OsTimerPtr timer, CARD32 time, void *arg)
790
+reconnect_handler(OsTimerPtr timer, CARD32 time, void *arg)
381
+{
791
+{
382
+	int newsock;
792
+	devd_buf_used = 0;
793
+	devd_skt = connect_devd();
794
+	if (-1 == devd_skt) /* Try again after RECONNECT_DELAY */
795
+		return (RECONNECT_DELAY);
796
+	TimerFree(rtimer);
797
+	rtimer = NULL;
798
+	LogMessage(X_INFO, "config/devd: reopening devd socket\n");
383
+
799
+
384
+	if ((newsock = connect_devd()) > 0) {
800
+	return (0);
385
+		sock_devd = newsock;
386
+		TimerFree(rtimer);
387
+		rtimer = NULL;
388
+		LogMessage(X_INFO, "config/devd: reopening devd socket\n");
389
+		return 0;
390
+	}
391
+
392
+	/* Try again after RECONNECT_DELAY */
393
+	return RECONNECT_DELAY;
394
+}
801
+}
395
+
802
+
396
+static ssize_t
803
+static void
397
+socket_getline(int fd, char **out)
804
+wakeup_handler(void *data, int err, void *read_mask)
398
+{
805
+{
399
+	char *buf, *newbuf;
806
+	int error;
400
+	ssize_t ret, cap, sz = 0;
807
+	char *ptr, *line, *val, *cdev;
401
+	char c;
808
+	size_t line_size, val_size, cdev_size;
809
+	ssize_t ios;
402
+
810
+
403
+	cap = 1024;
811
+	if (0 > err)
404
+	buf = malloc(cap * sizeof(char));
812
+		return;
405
+	if (!buf)
813
+	if (!FD_ISSET(devd_skt, (fd_set*)read_mask))
406
+		return -1;
814
+		return;
407
+
815
+	/* Read new data. */
408
+	for (;;) {
816
+	for (;;) {
409
+		ret = read(sock_devd, &c, 1);
817
+		ios = recv(devd_skt, (devd_buf + devd_buf_used), 
410
+		if (ret < 0) {
818
+		    (sizeof(devd_buf) - devd_buf_used), MSG_DONTWAIT);
411
+			if (errno == EINTR)
819
+		if (0 < ios) { /* Read OK. */
412
+				continue;
820
+			devd_buf_used += ios;
413
+			free(buf);
821
+			continue; /* Try to read more. */
414
+			return -1;
415
+		/* EOF - devd socket is lost */
416
+		} else if (ret == 0) {
417
+			disconnect_devd(sock_devd);
418
+			rtimer = TimerSet(NULL, 0, 1, reconnect_handler, NULL);
419
+			LogMessage(X_WARNING, "config/devd: devd socket is lost\n");
420
+			return -1;
421
+		}
822
+		}
422
+		if (c == '\n')
823
+		/* Something wrong. */
423
+			break;
824
+		error = errno;
424
+
825
+		if (error == EAGAIN)
425
+		if (sz + 1 >= cap) {
826
+			break; /* All avaible data readed. */
426
+			cap *= 2;
827
+		if (error == EINTR)
427
+			newbuf = realloc(buf, cap * sizeof(char));
828
+			continue;
428
+			if (!newbuf) {
829
+		if (sizeof(devd_buf) == devd_buf_used) { /* Message to long, reset buf. */
429
+				free(buf);
830
+			devd_buf_used = 0;
430
+				return -1;
831
+			continue;
431
+			}
432
+			buf = newbuf;
433
+		}
832
+		}
434
+		buf[sz] = c;
833
+		/* devd socket is lost */
435
+		sz++;
834
+		disconnect_devd(devd_skt);
835
+		rtimer = TimerSet(NULL, 0, 1, reconnect_handler, NULL);
836
+		LogMessage(X_WARNING, "config/devd: devd socket read error: %i - %s\n", error, strerror(error));
837
+		return;
436
+	}
838
+	}
839
+	ptr = memchr(devd_buf, '\n', devd_buf_used);
840
+	if (NULL == ptr)
841
+		return;
437
+
842
+
438
+	buf[sz] = '\0';
843
+	/* Process data. */
439
+	if (sz >= 0)
844
+	line = (devd_buf + 1);
440
+		*out = buf;
845
+	for (;;) {
441
+	else
846
+		line_size = (ptr - line);
442
+		free(buf);
847
+		if (DEVD_EVENT_NOTIFY != (*(line - 1)))
848
+			goto move_next_event; /* Handle only notify. */
849
+		/* Check: is system=DEVFS. */
850
+		val = devd_get_val_cstr("system", line, line_size, &val_size);
851
+		if (!is_meuqual_cstr("DEVFS", val, val_size))
852
+			goto move_next_event;
853
+		/* Check: is subsystem=CDEV. */
854
+		val = devd_get_val_cstr("subsystem", line, line_size, &val_size);
855
+		if (!is_meuqual_cstr("CDEV", val, val_size))
856
+			goto move_next_event;
857
+		/* Get device name. */
858
+		cdev = devd_get_val_cstr("cdev", line, line_size, &cdev_size);
859
+		if (NULL == cdev)
860
+			goto move_next_event;
861
+		/* Get event type. */
862
+		val = devd_get_val_cstr("type", line, line_size, &val_size);
863
+		if (is_meuqual_cstr("CREATE", val, val_size)) {
864
+			device_added(cdev, cdev_size, 0);
865
+		} else if (is_meuqual_cstr("DESTROY", val, val_size)) {
866
+			device_removed(cdev, cdev_size);
867
+		}
443
+
868
+
444
+	/* Number of bytes in the line, not counting the line break */
869
+move_next_event:
445
+	return sz;
870
+		line += (line_size + 2); /* Skip '\n' and event type byte. */
446
+}
871
+		line_size = (line - devd_buf);
447
+
872
+		if (devd_buf_used <= line_size) {
448
+static void
873
+			devd_buf_used = 0;
449
+wakeup_handler(void *data, int err, void *read_mask)
450
+{
451
+	char *line = NULL;
452
+	char *walk;
453
+
454
+	if (err < 0)
455
+		return;
456
+
457
+	if (FD_ISSET(sock_devd, (fd_set *) read_mask)) {
458
+		if (socket_getline(sock_devd, &line) < 0)
459
+			return;
874
+			return;
460
+
875
+		}
461
+		walk = strchr(line + 1, ' ');
876
+		ptr = memchr(line, '\n', (devd_buf_used - line_size));
462
+		if (walk != NULL)
877
+		if (NULL == ptr)
463
+			walk[0] = '\0';
464
+
465
+		switch (*line) {
466
+		case DEVD_EVENT_ADD:
467
+			device_added(line + 1);
468
+			break;
878
+			break;
469
+		case DEVD_EVENT_REMOVE:
470
+			device_removed(line + 1);
471
+			break;
472
+		default:
473
+			break;
474
+		}
475
+		free(line);
476
+	}
879
+	}
880
+	/* Save line without end marker. */
881
+	devd_buf_used -= (line_size - 1);
882
+	memmove(devd_buf, (line - 1), devd_buf_used);
477
+}
883
+}
478
+
884
+
479
+static void
885
+static void
Lines 484-491 Link Here
484
+int
890
+int
485
+config_devd_init(void)
891
+config_devd_init(void)
486
+{
892
+{
487
+	char devicename[1024];
893
+	size_t i, j, dir_cnt, sdir_cnt, tm;
488
+	int i, j;
894
+	char devicename[PATH_MAX];
895
+	struct dirent *de, **namelist, *sde, **snamelist;
489
+
896
+
490
+	LogMessage(X_INFO, "config/devd: probing input devices...\n");
897
+	LogMessage(X_INFO, "config/devd: probing input devices...\n");
491
+
898
+
Lines 493-519 Link Here
493
+	 * Add fake keyboard and give up on keyboards management
900
+	 * Add fake keyboard and give up on keyboards management
494
+	 * if kbdmux is enabled
901
+	 * if kbdmux is enabled
495
+	 */
902
+	 */
496
+	if ((is_kbdmux = is_kbdmux_enabled()) == true)
903
+	is_kbdmux = is_kbdmux_enabled();
497
+		device_added("kbdmux");
904
+	if (is_kbdmux)
905
+		device_added("kbdmux0", 7, 1);
498
+
906
+
499
+	for (i = 0; hw_types[i].driver != NULL; i++) {
907
+	/* Scan /dev/ for devices. */
500
+		/* First scan the sysctl to determine the hardware */
908
+	dir_cnt = scandir(_PATH_DEV, &namelist, 0, alphasort);
501
+		for (j = 0; j < 16; j++) {
909
+	for (i = 0; i < dir_cnt; i ++) {
502
+			if (sysctl_exists(&hw_types[i], j,
910
+		de = namelist[i];
503
+					devicename, sizeof(devicename)) != 0)
911
+		if (is_de_euqual_cstr(de, ".") ||
504
+				device_added(devicename);
912
+		    is_de_euqual_cstr(de, "..")) {
913
+			free(de);
914
+			continue;
505
+		}
915
+		}
506
+
916
+		if (DT_DIR != de->d_type) {
507
+		if (devpath_exists(&hw_types[i], devicename, sizeof(devicename)) != 0)
917
+			device_added(de->d_name, de->d_namlen, 0);
508
+			device_added(devicename);
918
+		} else { /* Sub folder. */
919
+			snprintf(devicename, sizeof(devicename),
920
+			    _PATH_DEV "%s", de->d_name);
921
+			sdir_cnt = scandir(devicename, &snamelist, 0, alphasort);
922
+			for (j = 0; j < sdir_cnt; j ++) {
923
+				sde = snamelist[j];
924
+				if (!is_de_euqual_cstr(sde, ".") &&
925
+				    !is_de_euqual_cstr(sde, "..") &&
926
+				    DT_DIR != sde->d_type) {
927
+					tm = snprintf(devicename, sizeof(devicename),
928
+					    "%s/%s", de->d_name, sde->d_name);
929
+					device_added(devicename, tm, 0);
930
+				}
931
+				free(sde);
932
+			}
933
+			free(snamelist);
934
+		}
935
+		free(de);
509
+	}
936
+	}
937
+	free(namelist);
510
+
938
+
511
+	if ((sock_devd = connect_devd()) < 0)
939
+	devd_buf_used = 0;
512
+		return 0;
940
+	devd_skt = connect_devd();
941
+	if (-1 == devd_skt)
942
+		return (0);
513
+
943
+
944
+	/* Register wakeup handler */
514
+	RegisterBlockAndWakeupHandlers(block_handler, wakeup_handler, NULL);
945
+	RegisterBlockAndWakeupHandlers(block_handler, wakeup_handler, NULL);
515
+
946
+
516
+	return 1;
947
+	return (1);
517
+}
948
+}
518
+
949
+
519
+void
950
+void
Lines 526-534 Link Here
526
+		rtimer = NULL;
957
+		rtimer = NULL;
527
+	}
958
+	}
528
+
959
+
529
+	disconnect_devd(sock_devd);
960
+	disconnect_devd(devd_skt);
530
+
961
+
531
+	RemoveBlockAndWakeupHandlers(block_handler, wakeup_handler, NULL);
962
+	RemoveBlockAndWakeupHandlers(block_handler, wakeup_handler, NULL);
532
+
533
+	is_console_kbd = false;
534
+}
963
+}
(-)/usr/ports/x11-servers/xorg-server/files/patch-configure (-1 / +100 lines)
Lines 1-5 Link Here
1
--- configure.orig	2015-06-16 17:43:10.000000000 +0200
1
--- configure.orig	2015-06-16 17:43:10.000000000 +0200
2
+++ configure	2015-10-21 23:07:22.017310000 +0200
2
+++ configure	2015-10-21 23:07:22.017310000 +0200
3
@@ -1032,6 +1032,8 @@
4
 CONFIG_UDEV_TRUE
5
 UDEV_LIBS
6
 UDEV_CFLAGS
7
+CONFIG_DEVD_FALSE
8
+CONFIG_DEVD_TRUE
9
 HAVE_SYSTEMD_DAEMON_FALSE
10
 HAVE_SYSTEMD_DAEMON_TRUE
11
 SYSTEMD_DAEMON_LIBS
12
@@ -1364,6 +1368,7 @@
13
 enable_config_udev_kms
14
 enable_config_hal
15
 enable_config_wscons
16
+enable_config_devd
17
 enable_xfree86_utils
18
 enable_vgahw
19
 enable_vbe
20
@@ -2193,6 +2199,7 @@
21
                           Build udev kms support (default: auto)
22
   --disable-config-hal    Build HAL support (default: auto)
23
   --enable-config-wscons  Build wscons config support (default: auto)
24
+  --enable-config-devd    Build devd support (default: auto)
25
   --enable-xfree86-utils  Build xfree86 DDX utilities (default: enabled)
26
   --enable-vgahw          Build Xorg with vga access (default: enabled)
27
   --enable-vbe            Build Xorg with VBE module (default: enabled)
3
@@ -22640,6 +22640,11 @@
28
@@ -22640,6 +22640,11 @@
4
   arm*)
29
   arm*)
5
 	ARM_VIDEO=yes
30
 	ARM_VIDEO=yes
Lines 12-18 Link Here
12
 	;;
37
 	;;
13
   i*86)
38
   i*86)
14
 	I386_VIDEO=yes
39
 	I386_VIDEO=yes
15
@@ -25559,7 +25564,7 @@
40
@@ -22760,6 +23255,9 @@
41
 
42
 $as_echo "#define SYSCONS_SUPPORT 1" >>confdefs.h
43
 
44
+
45
+$as_echo "#define CONFIG_DEVD 1" >>confdefs.h
46
+
47
 	DRI=yes
48
 	;;
49
   *netbsd*)
50
@@ -23517,6 +24015,13 @@
51
   CONFIG_WSCONS=auto
52
 fi
53
 
54
+# Check whether --enable-config-devd was given.
55
+if test "${enable_config_devd+set}" = set; then :
56
+  enableval=$enable_config_devd; CONFIG_DEVD=$enableval
57
+else
58
+  CONFIG_DEVD=auto
59
+fi
60
+
61
 # Check whether --enable-xfree86-utils was given.
62
 if test "${enable_xfree86_utils+set}" = set; then :
63
   enableval=$enable_xfree86_utils; XF86UTILS=$enableval
64
@@ -24239,6 +24744,7 @@
65
 		CONFIG_HAL=no
66
 		CONFIG_UDEV=no
67
 		CONFIG_UDEV_KMS=no
68
+		CONFIG_DEVD=no
69
 		DGA=no
70
 		DRM=no
71
 		DRI2=no
72
@@ -24568,6 +25074,30 @@
73
 fi
74
 
75
 
76
+if test "x$CONFIG_DEVD" = xauto; then
77
+	case $host_os in
78
+		*freebsd*)
79
+			CONFIG_DEVD=yes;
80
+			;;
81
+		*)
82
+			CONFIG_DEVD=no;
83
+			;;
84
+	esac
85
+fi
86
+ if test "x$CONFIG_DEVD" = xyes; then
87
+  CONFIG_DEVD_TRUE=
88
+  CONFIG_DEVD_FALSE='#'
89
+else
90
+  CONFIG_DEVD_TRUE='#'
91
+  CONFIG_DEVD_FALSE=
92
+fi
93
+
94
+if test "x$CONFIG_DEVD" = xyes; then
95
+
96
+$as_echo "#define CONFIG_DEVD 1" >>confdefs.h
97
+
98
+fi
99
+
100
 if test "x$CONFIG_UDEV" = xyes && test "x$CONFIG_HAL" = xyes; then
101
 	as_fn_error $? "Hotplugging through both libudev and hal not allowed" "$LINENO" 5
102
 fi
103
@@ -25559,7 +26089,7 @@
16
 case "x$XTRANS_SEND_FDS" in
104
 case "x$XTRANS_SEND_FDS" in
17
 xauto)
105
 xauto)
18
 	case "$host_os" in
106
 	case "$host_os" in
Lines 21-23 Link Here
21
 		XTRANS_SEND_FDS=yes
109
 		XTRANS_SEND_FDS=yes
22
 		;;
110
 		;;
23
 	*)
111
 	*)
112
@@ -32051,6 +32581,10 @@
113
   as_fn_error $? "conditional \"HAVE_SYSTEMD_DAEMON\" was never defined.
114
 Usually this means the macro was only invoked conditionally." "$LINENO" 5
115
 fi
116
+if test -z "${CONFIG_DEVD_TRUE}" && test -z "${CONFIG_DEVD_FALSE}"; then
117
+  as_fn_error $? "conditional \"CONFIG_DEVD\" was never defined.
118
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
119
+fi
120
 if test -z "${CONFIG_UDEV_TRUE}" && test -z "${CONFIG_UDEV_FALSE}"; then
121
   as_fn_error $? "conditional \"CONFIG_UDEV\" was never defined.
122
 Usually this means the macro was only invoked conditionally." "$LINENO" 5
(-)/usr/ports/x11-servers/xorg-server/files/patch-configure.ac (+61 lines)
Line 0 Link Here
1
--- configure.ac.orig	2016-10-10 01:08:54.601937000 +0300
2
+++ configure.ac	2016-10-10 01:06:41.728139000 +0300
3
@@ -307,6 +307,11 @@
4
 	ARM_VIDEO=yes
5
 	DEFAULT_INT10="stub"
6
+	case $host_os in
7
+		*freebsd*)
8
+			$as_echo "#define USE_DEV_IO 1" >>confdefs.h
9
+		 ;;
10
+	esac
11
 	;;
12
   i*86)
13
 	I386_VIDEO=yes
14
 	case $host_os in
15
@@ -604,6 +611,7 @@
16
 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])
17
 AC_ARG_ENABLE(config-hal,     AS_HELP_STRING([--disable-config-hal], [Build HAL support (default: auto)]), [CONFIG_HAL=$enableval], [CONFIG_HAL=auto])
18
 AC_ARG_ENABLE(config-wscons,  AS_HELP_STRING([--enable-config-wscons], [Build wscons config support (default: auto)]), [CONFIG_WSCONS=$enableval], [CONFIG_WSCONS=auto])
19
+AC_ARG_ENABLE(config-devd,    AS_HELP_STRING([--enable-config-devd], [Build devd support (default: auto)]), [CONFIG_DEVD=$enableval], [CONFIG_DEVD=auto])
20
 AC_ARG_ENABLE(xfree86-utils,     AS_HELP_STRING([--enable-xfree86-utils], [Build xfree86 DDX utilities (default: enabled)]), [XF86UTILS=$enableval], [XF86UTILS=yes])
21
 AC_ARG_ENABLE(vgahw,          AS_HELP_STRING([--enable-vgahw], [Build Xorg with vga access (default: enabled)]), [VGAHW=$enableval], [VGAHW=yes])
22
 AC_ARG_ENABLE(vbe,            AS_HELP_STRING([--enable-vbe], [Build Xorg with VBE module (default: enabled)]), [VBE=$enableval], [VBE=yes])
23
@@ -697,6 +705,7 @@
24
 		CONFIG_HAL=no
25
 		CONFIG_UDEV=no
26
 		CONFIG_UDEV_KMS=no
27
+		CONFIG_DEVD=no
28
 		DGA=no
29
 		DRM=no
30
 		DRI2=no
31
@@ -845,6 +854,21 @@
32
 fi
33
 AM_CONDITIONAL([HAVE_SYSTEMD_DAEMON], [test "x$HAVE_SYSTEMD_DAEMON" = "xyes"])
34
 
35
+if test "x$CONFIG_DEVD" = xauto; then
36
+	case $host_os in
37
+		*freebsd*)
38
+			CONFIG_DEVD=yes;
39
+			;;
40
+		*)
41
+			CONFIG_DEVD=no;
42
+			;;
43
+	esac
44
+fi
45
+AM_CONDITIONAL(CONFIG_DEVD, [test "x$CONFIG_DEVD" = xyes])
46
+if test "x$CONFIG_DEVD" = xyes; then
47
+	AC_DEFINE(CONFIG_DEVD, 1, [Use devd for input auto configuration])
48
+fi
49
+
50
 if test "x$CONFIG_UDEV" = xyes && test "x$CONFIG_HAL" = xyes; then
51
 	AC_MSG_ERROR([Hotplugging through both libudev and hal not allowed])
52
 fi
53
@@ -1165,7 +1189,7 @@
54
 case "x$XTRANS_SEND_FDS" in
55
 xauto)
56
 	case "$host_os" in
57
-	linux*|solaris*)
58
+	linux*|solaris*|freebsd*|dragonfly*)
59
 		XTRANS_SEND_FDS=yes
60
 		;;
61
 	*)
(-)/usr/ports/x11-servers/xorg-server/files/patch-include_dix-config.h.in (+12 lines)
Line 0 Link Here
1
--- include/dix-config.h.in.orig	2015-10-27 23:12:01.000000000 +0300
2
+++ include/dix-config.h.in	2016-10-10 03:51:05.267830000 +0300
3
@@ -430,6 +430,9 @@
4
 /* Use udev_enumerate_add_match_tag() */
5
 #undef HAVE_UDEV_ENUMERATE_ADD_MATCH_TAG
6
 
7
+/* Use devd for input hotplug */
8
+#undef CONFIG_DEVD
9
+
10
 /* Enable D-Bus core */
11
 #undef NEED_DBUS
12
 

Return to bug 196678