FreeBSD Bugzilla – Attachment 175616 Details for
Bug 196678
x11-servers/xorg-server: Update to 1.20.7 + make config/devd recognize /dev/input/eventX from multimedia/webcamd
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
devd: support webcamd, evdev, uhid, all from /dev/input
1.patch (text/plain), 44.52 KB, created by
Ivan Rozhuk
on 2016-10-11 11:36:17 UTC
(
hide
)
Description:
devd: support webcamd, evdev, uhid, all from /dev/input
Filename:
MIME Type:
Creator:
Ivan Rozhuk
Created:
2016-10-11 11:36:17 UTC
Size:
44.52 KB
patch
obsolete
>Index: /usr/ports/x11-servers/xorg-server/Makefile >=================================================================== >--- /usr/ports/x11-servers/xorg-server/Makefile (revision 423642) >+++ /usr/ports/x11-servers/xorg-server/Makefile (working copy) >@@ -51,7 +51,7 @@ > --without-xmlto --disable-docs --disable-devel-docs \ > --localstatedir=/var --without-dtrace --disable-xephyr \ > --enable-record=yes --disable-dri3 --disable-xwayland \ >- --enable-glamor >+ --enable-glamor --enable-config-devd=yes > INSTALL_TARGET= install-strip > > .if ${SLAVE_PORT} == "no" >@@ -118,17 +118,8 @@ > -e 's|^LTLIBRARIES = |LTLIBRARIES = libglx.la |g' \ > ${WRKSRC}/hw/xfree86/dixmods/Makefile.in > >-post-configure: >-.if ${PORT_OPTIONS:MDEVD} >- @${REINPLACE_CMD} -e 's|config\.c|config.c devd.c|g' \ >- -e 's|config\.lo|config.lo devd.lo|g' \ >- ${WRKSRC}/config/Makefile >- @${REINPLACE_CMD} -e 's|^/\* #undef CONFIG_UDEV \*/|#define CONFIG_DEVD 1|' \ >- ${WRKSRC}/include/dix-config.h >-.endif >- >+post-install: > .if ${SLAVE_PORT} == "no" >-post-install: > # The .xorg dir because else the xorg-server might not load the correct > # libglx module. > @${MKDIR} ${STAGEDIR}${PREFIX}/lib/xorg/modules/extensions/.xorg >@@ -136,5 +127,7 @@ > ${STAGEDIR}${PREFIX}/lib/xorg/modules/extensions/.xorg/ > @${MKDIR} ${STAGEDIR}${PREFIX}/etc/X11/xorg.conf.d > .endif # ! SLAVE_PORT >+ @${MV} ${STAGEDIR}${PREFIX}/lib/pkgconfig/xorg-server.pc \ >+ ${STAGEDIR}${PREFIX}/libdata/pkgconfig/xorg-server.pc > > .include <bsd.port.post.mk> >Index: /usr/ports/x11-servers/xorg-server/files/patch-config_Makefile.am >=================================================================== >--- /usr/ports/x11-servers/xorg-server/files/patch-config_Makefile.am (nonexistent) >+++ /usr/ports/x11-servers/xorg-server/files/patch-config_Makefile.am (working copy) >@@ -0,0 +1,19 @@ >+--- config/Makefile.am.orig 2015-10-27 23:12:00.000000000 +0300 >++++ config/Makefile.am 2016-10-09 23:45:14.589652000 +0300 >+@@ -32,7 +32,15 @@ >+ >+ if CONFIG_WSCONS >+ libconfig_la_SOURCES += wscons.c >+-endif # CONFIG_WSCONS >++ >++else >++ >++if CONFIG_DEVD >++libconfig_la_SOURCES += devd.c >++libconfig_la_LIBADD += -lusbhid >++endif # CONFIG_DEVD >++ >++endif # !CONFIG_WSCONS >+ >+ endif # !CONFIG_HAL >+ >Index: /usr/ports/x11-servers/xorg-server/files/patch-config_devd.c >=================================================================== >--- /usr/ports/x11-servers/xorg-server/files/patch-config_devd.c (revision 423642) >+++ /usr/ports/x11-servers/xorg-server/files/patch-config_devd.c (working copy) >@@ -1,11 +1,12 @@ > --- config/devd.c.orig 2015-05-19 19:41:49 UTC > +++ config/devd.c >-@@ -0,0 +1,531 @@ >+@@ -0,0 +1,960 @@ > +/* > + * Copyright (c) 2012 Baptiste Daroussin > + * Copyright (c) 2013, 2014 Alex Kozlov > + * Copyright (c) 2014 Robert Millan > + * Copyright (c) 2014 Jean-Sebastien Pedron >++ * Copyright (c) 2015 - 2016 Rozhuk Ivan > + * > + * Permission is hereby granted, free of charge, to any person obtaining a > + * copy of this software and associated documentation files (the "Software"), >@@ -39,8 +40,14 @@ > +#include <sys/stat.h> > +#include <sys/sysctl.h> > +#include <sys/un.h> >++#include <sys/mouse.h> >++#include <sys/consio.h> >++#include <sys/ioctl.h> >++#include <dev/usb/usb_ioctl.h> >++#include <dev/usb/usbhid.h> > + > +#include <ctype.h> >++#include <dirent.h> > +#include <errno.h> > +#include <fcntl.h> > +#include <stdlib.h> >@@ -47,6 +54,9 @@ > +#include <stdio.h> > +#include <stdbool.h> > +#include <unistd.h> >++#include <string.h> >++#include <paths.h> >++#include <usbhid.h> > + > +#include "input.h" > +#include "inputstr.h" >@@ -54,426 +64,822 @@ > +#include "config-backends.h" > +#include "os.h" > + >-+#define DEVD_SOCK_PATH "/var/run/devd.pipe" > + >++/* from: <linux/input.h> */ >++#define _IOC_READ IOC_OUT >++struct input_id { >++ uint16_t bustype; >++ uint16_t vendor; >++ uint16_t product; >++ uint16_t version; >++}; >++ >++#define EVIOCGBIT(ev, len) _IOC(_IOC_READ, 'E', 0x20 + (ev), (len)) >++#define EVIOCGID _IOR('E', 0x02, struct input_id) >++#define EVIOCGNAME(len) _IOC(_IOC_READ, 'E', 0x06, (len)) >++#define EVIOCGPHYS(len) _IOC(_IOC_READ, 'E', 0x07, (len)) >++ >++#define EV_KEY 0x01 >++#define EV_REL 0x02 >++#define EV_ABS 0x03 >++#define BTN_MISC 0x100 >++#define BTN_LEFT 0x110 >++#define BTN_RIGHT 0x111 >++#define BTN_MIDDLE 0x112 >++#define BTN_JOYSTICK 0x120 >++#define BTN_TOOL_PEN 0x140 >++#define BTN_TOOL_FINGER 0x145 >++#define BTN_TOUCH 0x14a >++#define BTN_STYLUS 0x14b >++#define BTN_STYLUS2 0x14c >++#define KEY_MAX 0x2ff >++#define KEY_CNT (KEY_MAX + 1) >++#define REL_X 0x00 >++#define REL_Y 0x01 >++#define REL_MAX 0x0f >++#define REL_CNT (REL_MAX + 1) >++#define ABS_X 0x00 >++#define ABS_Y 0x01 >++#define ABS_PRESSURE 0x18 >++#define ABS_MT_SLOT 0x2f >++#define ABS_MAX 0x3f >++#define ABS_CNT (ABS_MAX + 1) >++ >++#define U32_BITS (sizeof(uint32_t) * 8) >++#define U32_CNT(__x) (((__x) + U32_BITS - 1) / U32_BITS) >++#define U32_IS_BIT_SET(__x, __bit) (((((const uint32_t*)(__x))[((__bit) >> 5)] >> ((__bit) & 0x1f))) & 0x01) >++ >++/* from: <linux/joystick.h> */ >++#define JSIOCGNAME(len) _IOC(_IOC_READ, 'j', 0x13, len) /* get identifier string */ >++ >++/* WebCamD specific. */ >++#define WEBCAMD_IOCTL_GET_USB_VENDOR_ID _IOR('q', 250, unsigned short) >++#define WEBCAMD_IOCTL_GET_USB_PRODUCT_ID _IOR('q', 251, unsigned short) >++#define WEBCAMD_IOCTL_GET_USB_SPEED _IOR('q', 252, unsigned int) >++ >++#ifdef COMPAT_32BIT >++# define hid_pass_ptr(ptr) ((uint64_t)(uintptr_t)(ptr)) >++#else >++# define hid_pass_ptr(ptr) (ptr) >++#endif >++ >++#define _PATH_DEV_LEN (sizeof(_PATH_DEV) - 1) >++#define DEVD_PATH_DEV "devd:" _PATH_DEV >++#define DEVD_PATH_DEV_LEN (sizeof(DEVD_PATH_DEV) - 1) >++ >++#define DEVD_SOCK_PATH _PATH_VARRUN "devd.pipe" >++ > +#define DEVD_EVENT_ADD '+' > +#define DEVD_EVENT_REMOVE '-' >++#define DEVD_EVENT_NOTIFY '!' > + >-+#define RECONNECT_DELAY 5 * 1000 >++#define RECONNECT_DELAY (5 * 1000) > + >-+static int sock_devd; >-+static bool is_console_kbd = false; >-+static bool is_kbdmux = false; >++ >++#define is_meuqual(__v1, __v1sz, __v2, __v2sz) \ >++ ((__v1sz) == (__v2sz) && NULL != (__v1) && NULL != (__v2) && \ >++ 0 == memcmp((__v1), (__v2), (__v1sz))) >++ >++#define is_meuqual_cstr(__cstr, __v, __vsz) \ >++ is_meuqual(__cstr, (sizeof(__cstr) - 1), __v, __vsz) >++ >++#define is_de_euqual_cstr(__de, __cstr) \ >++ (NULL != (__de) && \ >++ is_meuqual((__de)->d_name, (__de)->d_namlen, __cstr, (sizeof(__cstr) - 1))) >++ >++#define devd_get_val_cstr(__cstr, __buf, __bufsz, __valsz) \ >++ devd_get_val((__buf), (__bufsz), __cstr, (sizeof(__cstr) - 1), \ >++ (__valsz)) >++ >++ >++static int devd_skt; >++static char devd_buf[4096]; >++static size_t devd_buf_used = 0; >++static int is_kbdmux = 0; > +OsTimerPtr rtimer; > + >-+struct hw_type { >-+ const char *driver; >-+ int flag; >-+ const char *xdriver; >++ >++/* Input devices. */ >++typedef struct hw_type_s { >++ const char *dev_name; >++ size_t dev_name_size; >++ size_t path_offset; >++ int flags; >++ const char *xdriver; >++} hw_type_t, *hw_type_p; >++ >++/* xdriver can be set via config "InputClass" section. >++ * Do not set xdriver name if device have more than one >++ * xf86-input-* drivers. >++ * "input/event" can be hadled by: xf86-input-evdev and >++ * xf86-input-wacom, let user chooses. >++ */ >++static hw_type_t hw_types[] = { >++ { "uhid", 4, 0, 0, NULL }, >++ { "ukbd", 4, 0, ATTR_KEYBOARD, "kbd" }, >++ { "atkbd", 5, 0, ATTR_KEYBOARD, "kbd" }, >++ { "kbdmux", 6, 0, ATTR_KEYBOARD, "kbd" }, >++ { "sysmouse", 8, 0, ATTR_POINTER, "mouse" }, >++ { "ums", 3, 0, ATTR_POINTER, "mouse" }, >++ { "psm", 3, 0, ATTR_POINTER, "mouse" }, >++ { "vboxguest", 9, 0, ATTR_POINTER, "vboxmouse" }, >++ { "joy", 3, 0, ATTR_JOYSTICK, NULL }, >++ { "atp", 3, 0, ATTR_TOUCHPAD, NULL }, >++ { "uep", 3, 0, ATTR_TOUCHSCREEN, NULL }, >++ { "input/event",5, 6, 0, NULL }, >++ { "input/js", 2, 6, ATTR_JOYSTICK, NULL }, >++ { NULL, 0, 0, 0, NULL }, > +}; > + >-+static struct hw_type hw_types[] = { >-+ { "ukbd", ATTR_KEYBOARD, "kbd" }, >-+ { "atkbd", ATTR_KEYBOARD, "kbd" }, >-+ { "kbdmux", ATTR_KEYBOARD, "kbd" }, >-+ { "sysmouse", ATTR_POINTER, "mouse" }, >-+ { "ums", ATTR_POINTER, "mouse" }, >-+ { "psm", ATTR_POINTER, "mouse" }, >-+ { "vboxguest", ATTR_POINTER, "vboxmouse" }, >-+ { "joy", ATTR_JOYSTICK, NULL }, >-+ { "atp", ATTR_TOUCHPAD, NULL }, >-+ { "uep", ATTR_TOUCHSCREEN, NULL }, >-+ { NULL, -1, NULL }, >++/* Input devices paths. */ >++static hw_type_t hw_type_path[] = { >++ { "input/", 0, 6, 0, NULL }, >++ { NULL, 0, 0, 0, NULL }, > +}; > + >-+static bool >-+sysctl_exists(const struct hw_type *device, int unit, >-+ char *devname, size_t devname_len) >++ >++static size_t >++bits_calc(const uint32_t *bits, size_t off_start, size_t off_stop) > +{ >-+ char sysctlname[PATH_MAX]; >-+ size_t len; >-+ int ret; >++ size_t i, count = 0; > + >-+ if (device == NULL || device->driver == NULL) >-+ return false; >++ for (i = off_start; i < off_stop; i ++) { >++ if (U32_IS_BIT_SET(bits, i)) { >++ count ++; >++ } >++ } >++ return (count); >++} > + >-+ /* Check if a sysctl exists. */ >-+ snprintf(sysctlname, sizeof(sysctlname), "dev.%s.%i.%%desc", >-+ device->driver, unit); >-+ ret = sysctlbyname(sysctlname, NULL, &len, NULL, 0); >++static hw_type_p >++get_dev_type_by_name(const char *dev_name, size_t dev_name_size) >++{ >++ size_t i; > + >-+ if (ret == 0 && len > 0) { >-+ snprintf(devname, devname_len, "%s%i", device->driver, unit); >-+ return true; >++ if (NULL == dev_name || 0 == dev_name_size) >++ return (NULL); >++ for (i = 0; NULL != hw_types[i].dev_name; i ++) { >++ if (dev_name_size >= (hw_types[i].dev_name_size + hw_types[i].path_offset) && >++ 0 == memcmp(dev_name, hw_types[i].dev_name, >++ (hw_types[i].path_offset + hw_types[i].dev_name_size))) { >++ return (&hw_types[i]); >++ } > + } >++ return (NULL); >++} > + >-+ return false; >++/* From: sys/dev/usb/usb_hid.c */ >++static int >++hid_is_collection(report_desc_t s, uint32_t usage) >++{ >++ struct hid_data *hd; >++ struct hid_item hi; >++ int rc; >++ >++ hd = hid_start_parse(s, ~0, -1); >++ if (hd == NULL) >++ return (0); >++ >++ while ((rc = hid_get_item(hd, &hi))) { >++ if (hi.kind == hid_collection && >++ hi.usage == usage) >++ break; >++ } >++ hid_end_parse(hd); >++ return (rc); > +} > + >-+static bool >-+devpath_exists(const struct hw_type *device, >-+ char *devname, size_t devname_len) >++static int >++hid_is_mouse(report_desc_t s) > +{ >-+ char *devpath; >-+ struct stat st; >-+ int ret; >++ struct hid_data *hd; >++ struct hid_item hi; >++ int mdepth; >++ int found; > + >-+ if (device == NULL || device->driver == NULL) >-+ return false; >++ hd = hid_start_parse(s, (1 << hid_input), -1); >++ if (hd == NULL) >++ return (0); > + >-+ /* Check if /dev/$driver exists. */ >-+ asprintf(&devpath, "/dev/%s", device->driver); >-+ if (devpath == NULL) >-+ return false; >++ mdepth = 0; >++ found = 0; > + >-+ ret = stat(devpath, &st); >-+ free(devpath); >++ while (hid_get_item(hd, &hi)) { >++ switch (hi.kind) { >++ case hid_collection: >++ if (mdepth != 0) >++ mdepth ++; >++ else if (hi.collection == 1 && >++ hi.usage == >++ HID_USAGE2(HUP_GENERIC_DESKTOP, HUG_MOUSE)) >++ mdepth ++; >++ break; >++ case hid_endcollection: >++ if (mdepth != 0) >++ mdepth --; >++ break; >++ case hid_input: >++ if (mdepth == 0) >++ break; >++ if (hi.usage == >++ HID_USAGE2(HUP_GENERIC_DESKTOP, HUG_X) && >++ (hi.flags & (HIO_CONST|HIO_RELATIVE)) == HIO_RELATIVE) >++ found ++; >++ if (hi.usage == >++ HID_USAGE2(HUP_GENERIC_DESKTOP, HUG_Y) && >++ (hi.flags & (HIO_CONST|HIO_RELATIVE)) == HIO_RELATIVE) >++ found ++; >++ break; >++ default: >++ break; >++ } >++ } >++ hid_end_parse(hd); >++ return (found); >++} > + >-+ if (ret == 0) { >-+ strncpy(devname, device->driver, devname_len); >-+ return true; >++ >++static hw_type_p >++get_dev_type_by_path(const char *dev_name, size_t dev_name_size, >++ hw_type_p hw_type_cust) >++{ >++ size_t i; >++ >++ if (NULL == dev_name || 0 == dev_name_size || NULL == hw_type_cust) >++ return (NULL); >++ for (i = 0; NULL != hw_type_path[i].dev_name; i ++) { >++ if (dev_name_size <= hw_type_path[i].path_offset || >++ 0 != memcmp(dev_name, hw_type_path[i].dev_name, >++ hw_type_path[i].path_offset)) >++ continue; >++ /* Path in white list. */ >++ hw_type_cust->dev_name = dev_name; >++ hw_type_cust->path_offset = hw_type_path[i].path_offset; >++ for (i = hw_type_cust->path_offset; i < dev_name_size; i ++) { >++ if (isdigit(dev_name[i])) >++ break; >++ } >++ hw_type_cust->dev_name_size = (i - hw_type_cust->path_offset); >++ hw_type_cust->flags = hw_type_path[i].flags; >++ hw_type_cust->xdriver = hw_type_path[i].xdriver; >++ return (hw_type_cust); > + } >++ return (NULL); >++} > + >-+ return false; >++static int >++is_kbdmux_enabled(void) >++{ >++ /* Xorg uses /dev/ttyv0 as a console device */ >++ /* const char device[]="/dev/console"; */ >++ int fd; >++ const char *device = _PATH_TTY "v0"; >++ keyboard_info_t info; >++ >++ fd = open(device, O_RDONLY); >++ if (0 > fd) >++ return (0); >++ if (-1 == ioctl(fd, KDGKBINFO, &info) || >++ 0 != memcmp(info.kb_name, "kbdmux", 6)) { >++ close(fd); >++ return (0); >++ } >++ close(fd); >++ return (1); > +} > + > +static char * >-+sysctl_get_str(const char *sysctlname) >++sysctl_get_str(const char *sysctlname, size_t *size_ret) > +{ >-+ char *dest = NULL; >++ char *dest; > + size_t len; > + >-+ if (sysctlname == NULL) >-+ return NULL; >++ if (NULL == sysctlname) >++ return (NULL); >++ if (0 != sysctlbyname(sysctlname, NULL, &len, NULL, 0)) >++ return (NULL); >++ dest = malloc(len + 4); >++ if (NULL == dest) >++ return (NULL); >++ if (0 != sysctlbyname(sysctlname, dest, &len, NULL, 0)) { >++ free(dest); >++ return (NULL); >++ } >++ dest[len] = 0; >++ if (NULL != size_ret) >++ (*size_ret) = len; >++ return (dest); >++} > + >-+ if (sysctlbyname(sysctlname, NULL, &len, NULL, 0) == 0) { >-+ dest = malloc(len + 1); >-+ if (dest) { >-+ if (sysctlbyname(sysctlname, dest, &len, NULL, 0) == 0) >-+ dest[len] = '\0'; >-+ else { >-+ free(dest); >-+ dest = NULL; >-+ } >++static char * >++devd_get_val(char *buf, size_t buf_size, const char *val_name, >++ size_t val_name_size, size_t *val_size) >++{ >++ char *ret, *buf_end, *ptr; >++ >++ buf_end = (buf + buf_size); >++ for (ret = buf; ret != NULL && ret < buf_end;) { >++ ret = memmem(ret, (buf_end - ret), val_name, val_name_size); >++ if (ret == NULL) >++ return (NULL); >++ /* Found. */ >++ /* Check: space before or buf+1. */ >++ if ((buf + 1) < ret && ret[-1] != ' ') { >++ ret += val_name_size; >++ continue; > + } >++ /* Check: = after name and size for value. */ >++ ret += val_name_size; >++ if ((ret + 1) >= buf_end) >++ return (NULL); >++ if ('=' != ret[0]) >++ continue; >++ ret ++; >++ break; > + } >-+ >-+ return dest; >++ if (ret == NULL || val_size == NULL) >++ return (ret); >++ /* Calc value data size. */ >++ ptr = memchr(ret, ' ', (buf_end - ret)); >++ if (ptr == NULL) /* End of string/last value. */ >++ ptr = buf_end; >++ (*val_size) = (ptr - ret); >++ return (ret); > +} > + > +static void >-+device_added(const char *devname) >++device_added(const char *dev_name, size_t dev_name_size, int allow_no_device) > +{ >-+ char path[PATH_MAX]; >-+ char sysctlname[PATH_MAX]; >-+ char *vendor; >-+ char *product = NULL; >-+ char *config_info = NULL; >-+ char *walk; >++ int fd; > + InputOption *options = NULL; >-+ InputAttributes attrs = { }; >-+ DeviceIntPtr dev = NULL; >-+ int i; >-+ int fd; >++ InputAttributes attrs; >++ DeviceIntPtr dev_iptr = NULL; >++ keyboard_info_t kbdi; >++ mousehw_t mshw; >++ struct input_id iid; >++ report_desc_t rep_desc; >++ struct usb_device_info usb_dev_info; >++ size_t has_keys = 0, has_buttons = 0, has_lmr = 0; >++ size_t has_rel_axes = 0, has_abs_axes = 0, has_mt = 0; >++ uint32_t key_bits[U32_CNT(KEY_CNT)]; >++ uint32_t rel_bits[U32_CNT(REL_CNT)]; >++ uint32_t abs_bits[U32_CNT(ABS_CNT)]; >++ char *dev_path, config_info[(PATH_MAX + 32)]; >++ char sysctlname[PATH_MAX], *sdata, *ptr_pid, *ptr_vid; >++ char pnp_usb_id[PATH_MAX], vendor[PATH_MAX], product[PATH_MAX]; >++ size_t sdata_size, pid_size, vid_size; >++ hw_type_t *hwtype, hwtype_cust; >++ unsigned short vid, pid; > + >-+ for (i = 0; hw_types[i].driver != NULL; i++) { >-+ size_t len; > + >-+ len = strlen(hw_types[i].driver); >-+ if (strcmp(devname, hw_types[i].driver) == 0 || >-+ (strncmp(devname, hw_types[i].driver, len) == 0 && >-+ isnumber(*(devname + len)))) { >-+ attrs.flags |= hw_types[i].flag; >-+ break; >-+ } >++ if (NULL == dev_name || 0 == dev_name_size || PATH_MAX < dev_name_size) >++ return; >++ /* Make dev_name null ended string. */ >++ snprintf(config_info, sizeof(config_info), DEVD_PATH_DEV"%.*s", >++ (int)dev_name_size, dev_name); >++ /* Set / update pointers to dev_name and dev_path. */ >++ dev_path = (config_info + 5); /* Skip: "devd:" */ >++ dev_name = (dev_path + _PATH_DEV_LEN); /* Skip: "/dev/" */ >++ >++ /* Is known input device or path? */ >++ hwtype = get_dev_type_by_name(dev_name, dev_name_size); >++ if (NULL == hwtype) { >++ hwtype = get_dev_type_by_path(dev_name, dev_name_size, >++ &hwtype_cust); > + } >-+ >-+ if (hw_types[i].driver == NULL || hw_types[i].xdriver == NULL) { >-+ LogMessage(X_INFO, "config/devd: ignoring device %s\n", >-+ devname); >++ if (NULL == hwtype) /* Not found in white list. */ > + return; >-+ } >++ /* Init and set attributes. */ >++ memset(&attrs, 0, sizeof(attrs)); >++ attrs.device = dev_path; >++ attrs.flags = hwtype->flags; > + > + /* Skip keyboard devices if kbdmux is enabled */ >-+ if (is_kbdmux && is_console_kbd && hw_types[i].flag & ATTR_KEYBOARD) { >++ if (is_kbdmux && 0 == allow_no_device && (hwtype->flags & ATTR_KEYBOARD)) { >++skip_kbd_dev: > + LogMessage(X_INFO, "config/devd: kbdmux is enabled, ignoring device %s\n", >-+ devname); >++ dev_name); > + return; > + } >-+ >-+ snprintf(path, sizeof(path), "/dev/%s", devname); >-+ >-+ options = input_option_new(NULL, "_source", "server/devd"); >-+ if (!options) >++ /* Skip duplicate devices. */ >++ if (device_is_duplicate(config_info)) { >++ LogMessage(X_WARNING, "config/devd: device %s already added. ignoring\n", >++ dev_path); > + return; >-+ >-+ snprintf(sysctlname, sizeof(sysctlname), "dev.%s.%s.%%desc", >-+ hw_types[i].driver, devname + strlen(hw_types[i].driver)); >-+ vendor = sysctl_get_str(sysctlname); >-+ if (vendor == NULL) { >-+ options = input_option_new(options, "name", devname); > + } >-+ else { >-+ if ((walk = strchr(vendor, ' ')) != NULL) { >-+ walk[0] = '\0'; >-+ walk++; >-+ product = walk; >-+ if ((walk = strchr(product, ',')) != NULL) >-+ walk[0] = '\0'; >-+ } > + >-+ attrs.vendor = strdup(vendor); >-+ if (product) { >-+ attrs.product = strdup(product); >-+ options = input_option_new(options, "name", product); >-+ } >-+ else >-+ options = input_option_new(options, "name", "(unnamed)"); >-+ >-+ free(vendor); >-+ } >-+ >-+ /* XXX implement usb_id */ >-+ attrs.usb_id = NULL; >-+ attrs.device = strdup(path); >-+ options = input_option_new(options, "driver", hw_types[i].xdriver); >-+ >-+ fd = open(path, O_RDONLY); >-+ if (fd > 0) { >-+ close(fd); >-+ options = input_option_new(options, "device", path); >-+ } >-+ else { >-+ if (attrs.flags & ~ATTR_KEYBOARD) { >++ /* Try to open device. */ >++ fd = open(dev_path, O_RDONLY); >++ if (0 > fd) { >++ if (0 == (hwtype->flags & ATTR_KEYBOARD)) { > + LogMessage(X_INFO, "config/devd: device %s already opened\n", >-+ path); >-+ >++ dev_path); > + /* > + * Fail if cannot open device, it breaks AllowMouseOpenFail, > + * but it should not matter when config/devd enabled > + */ >-+ goto unwind; >++ return; > + } >-+ >-+ if (is_console_kbd) { >++ if (0 == allow_no_device) { > + /* > + * There can be only one keyboard attached to console and > + * it is already added. > + */ > + LogMessage(X_WARNING, "config/devd: console keyboard is " >-+ "already added, ignoring %s (%s)\n", >-+ attrs.product, path); >-+ goto unwind; >++ "already added, ignoring %s\n", >++ dev_path); >++ return; > + } >-+ else >-+ /* >-+ * Don't pass "device" option if the keyboard is already >-+ * attached to the console (ie. open() fails). >-+ * This would activate a special logic in xf86-input-keyboard. >-+ * Prevent any other attached to console keyboards being >-+ * processed. There can be only one such device. >-+ */ >-+ is_console_kbd = true; >++ /* >++ * Don't pass "device" option if the keyboard is already >++ * attached to the console (ie. open() fails). >++ * This would activate a special logic in xf86-input-keyboard. >++ * Prevent any other attached to console keyboards being >++ * processed. There can be only one such device. >++ */ >++ goto skip_ioctl; > + } > + >-+ if (asprintf(&config_info, "devd:%s", devname) == -1) { >-+ config_info = NULL; >-+ goto unwind; >++ /* Try to get device info via ioctl(). */ >++ if (-1 != ioctl(fd, KDGKBINFO, &kbdi)) { /* Is this keyboard? */ >++ memcpy(product, kbdi.kb_name, sizeof(kbdi.kb_name)); >++ attrs.product = product; >++ attrs.flags = ATTR_KEYBOARD; >++ LogMessage(X_INFO, "config/devd: detected keyboard: %s, kb_index=%i, kb_unit=%i, kb_type=%i, kb_config=%i\n", >++ kbdi.kb_name, kbdi.kb_index, kbdi.kb_unit, kbdi.kb_type, kbdi.kb_config); >++ } else if (-1 != ioctl(fd, MOUSE_GETHWINFO, &mshw)) { /* Is this mouse? */ >++#ifdef notyet /* FreeBSD mouse drivers does not return real vid+pid. */ >++ /* construct USB ID in lowercase hex - "0000:ffff" */ >++ snprintf(pnp_usb_id, sizeof(pnp_usb_id), "%04x:%04x", >++ mshw.hwid, mshw.model); >++ attrs.usb_id = pnp_usb_id; >++#endif >++ >++ switch (mshw.type) { >++ case MOUSE_MOUSE: >++ case MOUSE_TRACKBALL: >++ case MOUSE_STICK: >++ attrs.flags = ATTR_POINTER; >++ break; >++ case MOUSE_PAD: >++ attrs.flags = ATTR_TOUCHPAD; >++ break; >++ } >++ LogMessage(X_INFO, "config/devd: detected mouse: hwid=%04x, model=%04x, type=%04x, iftype=%04x, buttons=%04x\n", >++ mshw.hwid, mshw.model, mshw.type, mshw.iftype, mshw.buttons); >++ } else if (-1 != ioctl(fd, JSIOCGNAME((sizeof(product) - 1)), product)) { /* Is this joystick? */ >++ attrs.product = product; >++ attrs.flags = ATTR_JOYSTICK; >++ LogMessage(X_INFO, "config/devd: detected joystick: %s\n", >++ product); >++ } else if (-1 != ioctl(fd, EVIOCGID, &iid) && >++ -1 != ioctl(fd, EVIOCGNAME((sizeof(product) - 1)), product)) { /* Is this event? */ >++ /* construct USB ID in lowercase hex - "0000:ffff" */ >++ snprintf(pnp_usb_id, sizeof(pnp_usb_id), "%04x:%04x", >++ iid.vendor, iid.product); >++ attrs.usb_id = pnp_usb_id; >++ attrs.product = product; >++ >++ /* Detect device type. */ >++ if (-1 != ioctl(fd, EVIOCGBIT(EV_KEY, sizeof(key_bits)), key_bits)) { >++ has_keys = bits_calc(key_bits, 0, BTN_MISC); >++ has_buttons = bits_calc(key_bits, BTN_MISC, BTN_JOYSTICK); >++ has_lmr = bits_calc(key_bits, BTN_LEFT, BTN_MIDDLE); >++ } >++ if (-1 != ioctl(fd, EVIOCGBIT(EV_REL, sizeof(rel_bits)), rel_bits)) { >++ has_rel_axes = bits_calc(rel_bits, 0, REL_MAX); >++ } >++ if (-1 != ioctl(fd, EVIOCGBIT(EV_ABS, sizeof(abs_bits)), abs_bits)) { >++ has_abs_axes = bits_calc(abs_bits, 0, ABS_MAX); >++ has_mt = bits_calc(abs_bits, ABS_MT_SLOT, ABS_MAX); >++ } >++ >++ if (has_abs_axes) { >++ if (has_mt) { >++ if (0 == has_buttons) { >++ /* >++ * XXX: I'm not sure that joystick detection is >++ * done right. xf86-evdev does not support them. >++ */ >++ if (U32_IS_BIT_SET(key_bits, BTN_JOYSTICK)) { >++ attrs.flags = ATTR_JOYSTICK; >++ goto event_done; >++ } else { >++ has_buttons ++; >++ } >++ } >++ } >++ if (U32_IS_BIT_SET(abs_bits, ABS_X) && >++ U32_IS_BIT_SET(abs_bits, ABS_Y)) { >++ if (U32_IS_BIT_SET(key_bits, BTN_TOOL_PEN) || >++ U32_IS_BIT_SET(key_bits, BTN_STYLUS) || >++ U32_IS_BIT_SET(key_bits, BTN_STYLUS2)) { >++ attrs.flags = ATTR_TABLET; >++ goto event_done; >++ } else if (U32_IS_BIT_SET(abs_bits, ABS_PRESSURE) || >++ U32_IS_BIT_SET(key_bits, BTN_TOUCH)) { >++ if (has_lmr || >++ U32_IS_BIT_SET(key_bits, BTN_TOOL_FINGER)) { >++ attrs.flags = ATTR_TOUCHPAD; >++ } else { >++ attrs.flags = ATTR_TOUCHSCREEN; >++ } >++ goto event_done; >++ } else if (!(U32_IS_BIT_SET(rel_bits, REL_X) && >++ U32_IS_BIT_SET(rel_bits, REL_Y)) && >++ has_lmr) { >++ /* some touchscreens use BTN_LEFT rather than BTN_TOUCH */ >++ attrs.flags = ATTR_TOUCHSCREEN; >++ goto event_done; >++ } >++ } >++ } >++ if (has_keys) { >++ if (is_kbdmux) { >++ close(fd); >++ goto skip_kbd_dev; >++ } >++ attrs.flags = ATTR_KEYBOARD; >++ } else if (has_rel_axes || has_abs_axes || has_buttons) { >++ attrs.flags = ATTR_POINTER; >++ } >++event_done: >++ LogMessage(X_INFO, "config/devd: detected event: %s, bustype=%04x, vendor=%04x, product=%04x, version=%04x\n", >++ product, iid.bustype, iid.vendor, iid.product, iid.version); >++ } else if (0 != (rep_desc = hid_get_report_desc(fd))) { /* Is USB HID? */ >++ if (hid_is_mouse(rep_desc)) { >++ attrs.flags = ATTR_POINTER; >++ } else if (hid_is_collection(rep_desc, HID_USAGE2(HUP_GENERIC_DESKTOP, HUG_KEYBOARD))) { >++ /* Skip keyboard devices if kbdmux is enabled */ >++ if (is_kbdmux) { >++ hid_dispose_report_desc(rep_desc); >++ close(fd); >++ goto skip_kbd_dev; >++ } >++ attrs.flags = ATTR_KEYBOARD; >++ } else if (hid_is_collection(rep_desc, HID_USAGE2(HUP_GENERIC_DESKTOP, HUG_JOYSTICK)) || >++ hid_is_collection(rep_desc, HID_USAGE2(HUP_GENERIC_DESKTOP, HUG_GAME_PAD))) { >++ attrs.flags = ATTR_JOYSTICK; >++ } >++ >++ hid_dispose_report_desc(rep_desc); >++ LogMessage(X_INFO, "config/devd: detected USB HID...\n"); > + } > + >-+ if (device_is_duplicate(config_info)) { >-+ LogMessage(X_WARNING, "config/devd: device %s (%s) already added. " >-+ "ignoring\n", attrs.product, path); >-+ goto unwind; >++ if (NULL == attrs.usb_id) { /* Is this webcamd device? */ >++ if (-1 != ioctl(fd, WEBCAMD_IOCTL_GET_USB_VENDOR_ID, &vid) && >++ -1 != ioctl(fd, WEBCAMD_IOCTL_GET_USB_PRODUCT_ID, &pid)) { >++ snprintf(pnp_usb_id, sizeof(pnp_usb_id), >++ "%04x:%04x", vid, pid); >++ attrs.usb_id = pnp_usb_id; >++ LogMessage(X_INFO, "config/devd: WebCamD device: %s\n", pnp_usb_id); >++ } > + } > + >++ close(fd); >++ >++skip_ioctl: >++ /* Try to get device info via sysctl(). */ >++ if (NULL == attrs.usb_id && NULL == attrs.pnp_id) { >++ snprintf(sysctlname, sizeof(sysctlname), "dev.%.*s.%s.%%pnpinfo", >++ (int)hwtype->dev_name_size, (hwtype->dev_name + hwtype->path_offset), >++ (dev_name + hwtype->path_offset + hwtype->dev_name_size)); >++ sdata = sysctl_get_str(sysctlname, &sdata_size); >++ if (NULL != sdata) { >++ ptr_vid = devd_get_val_cstr("vendor", >++ sdata, sdata_size, &vid_size); >++ ptr_pid = devd_get_val_cstr("product", >++ sdata, sdata_size, &pid_size); >++ if (NULL != ptr_vid && NULL != ptr_pid) { /* usb_id */ >++ ptr_vid[vid_size] = 0; >++ ptr_pid[pid_size] = 0; >++ snprintf(pnp_usb_id, sizeof(pnp_usb_id), >++ "%s:%s", ptr_vid, ptr_pid); >++ attrs.usb_id = pnp_usb_id; >++ LogMessage(X_INFO, "config/devd: [sysctl] usb_id: %s\n", pnp_usb_id); >++ } else { /* pnp_id */ >++ strlcpy(pnp_usb_id, sdata, sizeof(pnp_usb_id)); >++ attrs.pnp_id = pnp_usb_id; >++ } >++ free(sdata); >++ } >++ } >++ if (NULL == attrs.vendor || NULL == attrs.product) { >++ snprintf(sysctlname, sizeof(sysctlname), "dev.%.*s.%s.%%desc", >++ (int)hwtype->dev_name_size, (hwtype->dev_name + hwtype->path_offset), >++ (dev_name + hwtype->path_offset + hwtype->dev_name_size)); >++ sdata = sysctl_get_str(sysctlname, &sdata_size); >++ if (NULL != sdata) { >++ /* Vendor. */ >++ ptr_pid = memchr(sdata, ' ', sdata_size); >++ if (NULL != ptr_pid) >++ ptr_pid[0] = 0; >++ strlcpy(vendor, sdata, sizeof(vendor)); >++ attrs.vendor = vendor; >++ /* Product. */ >++ if (NULL == attrs.product && NULL != ptr_pid) { >++ ptr_pid ++; >++ ptr_vid = memchr(ptr_pid, ',', >++ (sdata_size - (ptr_pid - sdata))); >++ if (NULL != ptr_vid) >++ ptr_vid[0] = 0; >++ strlcpy(product, ptr_pid, sizeof(product)); >++ attrs.product = product; >++ } else { >++ product[0] = 0; >++ } >++ free(sdata); >++ LogMessage(X_INFO, "config/devd: [sysctl] vendor: %s, product: %s\n", vendor, product); >++ } >++ } >++ >++ /* Init options. */ >++ options = input_option_new(NULL, "_source", "server/devd"); >++ if (NULL == options) >++ goto err_out; >++ > + options = input_option_new(options, "config_info", config_info); >-+ LogMessage(X_INFO, "config/devd: adding input device %s (%s)\n", >-+ attrs.product, path); >++ if (NULL == options) >++ goto err_out; > + >-+ NewInputDeviceRequest(options, &attrs, &dev); >++ options = input_option_new(options, "name", >++ ((NULL != attrs.product) ? attrs.product : dev_name)); >++ if (NULL == options) >++ goto err_out; > + >-+unwind: >-+ free(config_info); >++ if (fd >= 0) { >++ options = input_option_new(options, "device", dev_path); >++ if (NULL == options) >++ goto err_out; >++ } >++ >++ if (NULL != hwtype->xdriver) { >++ options = input_option_new(options, "driver", hwtype->xdriver); >++ if (NULL == options) >++ goto err_out; >++ } >++ >++ LogMessage(X_INFO, "config/devd: adding input device %s\n", dev_path); >++ NewInputDeviceRequest(options, &attrs, &dev_iptr); >++ goto done; >++ >++err_out: >++ LogMessage(X_INFO, "config/devd: error adding device '%s'\n", >++ dev_path); >++done: > + input_option_free_list(&options); >-+ free(attrs.usb_id); >-+ free(attrs.product); >-+ free(attrs.device); >-+ free(attrs.vendor); > +} > + > +static void >-+device_removed(char *devname) >++device_removed(const char *dev_name, size_t dev_name_size) > +{ >-+ char *config_info; >++ char config_info[(PATH_MAX + 32)]; >++ hw_type_t hwtype_cust; > + >-+ if (asprintf(&config_info, "devd:%s", devname) == -1) >++ if (NULL == dev_name || 0 == dev_name_size || PATH_MAX < dev_name_size) > + return; >-+ >++ if (NULL == get_dev_type_by_name(dev_name, dev_name_size) && >++ NULL == get_dev_type_by_path(dev_name, dev_name_size, &hwtype_cust)) >++ return; /* Device not in list - unknown. */ >++ snprintf(config_info, sizeof(config_info), DEVD_PATH_DEV"%.*s", >++ (int)dev_name_size, dev_name); >++ /* Skip non added devices. */ >++ if (device_is_duplicate(config_info)) { >++ LogMessage(X_INFO, "config/devd: removing input device '%s'\n", >++ (config_info + DEVD_PATH_DEV_LEN)); >++ } > + remove_devices("devd", config_info); >-+ >-+ free(config_info); > +} > + >-+static bool is_kbdmux_enabled(void) >-+{ >-+ /* Xorg uses /dev/ttyv0 as a console device */ >-+ /* const char device[]="/dev/console"; */ >-+ const char device[]="/dev/ttyv0"; >-+ keyboard_info_t info; >-+ int fd; > + >-+ fd = open(device, O_RDONLY); >-+ >-+ if (fd < 0) >-+ return false; >-+ >-+ if (ioctl(fd, KDGKBINFO, &info) == -1) { >-+ close(fd); >-+ return false; >-+ } >-+ >-+ close(fd); >-+ >-+ if (!strncmp(info.kb_name, "kbdmux", 6)) >-+ return true; >-+ >-+ return false; >-+} >-+ > +static void > +disconnect_devd(int sock) > +{ >-+ if (sock >= 0) { >-+ RemoveGeneralSocket(sock); >-+ close(sock); >-+ } >++ if (0 > sock) >++ return; >++ RemoveGeneralSocket(sock); >++ close(sock); > +} > + > +static int > +connect_devd(void) > +{ >++ int sock; > + struct sockaddr_un devd; >-+ int sock; > + > + sock = socket(AF_UNIX, SOCK_STREAM, 0); >-+ if (sock < 0) { >++ if (0 > sock) { > + LogMessage(X_ERROR, "config/devd: fail opening stream socket\n"); >-+ return -1; >++ return (-1); > + } > + > + devd.sun_family = AF_UNIX; >-+ strlcpy(devd.sun_path, DEVD_SOCK_PATH, sizeof(devd.sun_path)); >-+ >-+ if (connect(sock, (struct sockaddr *) &devd, sizeof(devd)) < 0) { >++ memcpy(devd.sun_path, DEVD_SOCK_PATH, sizeof(DEVD_SOCK_PATH)); >++ if (0 > connect(sock, (struct sockaddr*)&devd, sizeof(devd))) { > + close(sock); > + LogMessage(X_ERROR, "config/devd: fail to connect to devd\n"); >-+ return -1; >++ return (-1); > + } > + > + AddGeneralSocket(sock); > + >-+ return sock; >++ return (sock); > +} > + > +static CARD32 > +reconnect_handler(OsTimerPtr timer, CARD32 time, void *arg) > +{ >-+ int newsock; >++ devd_buf_used = 0; >++ devd_skt = connect_devd(); >++ if (-1 == devd_skt) /* Try again after RECONNECT_DELAY */ >++ return (RECONNECT_DELAY); >++ TimerFree(rtimer); >++ rtimer = NULL; >++ LogMessage(X_INFO, "config/devd: reopening devd socket\n"); > + >-+ if ((newsock = connect_devd()) > 0) { >-+ sock_devd = newsock; >-+ TimerFree(rtimer); >-+ rtimer = NULL; >-+ LogMessage(X_INFO, "config/devd: reopening devd socket\n"); >-+ return 0; >-+ } >-+ >-+ /* Try again after RECONNECT_DELAY */ >-+ return RECONNECT_DELAY; >++ return (0); > +} > + >-+static ssize_t >-+socket_getline(int fd, char **out) >++static void >++wakeup_handler(void *data, int err, void *read_mask) > +{ >-+ char *buf, *newbuf; >-+ ssize_t ret, cap, sz = 0; >-+ char c; >++ int error; >++ char *ptr, *line, *val, *cdev; >++ size_t line_size, val_size, cdev_size; >++ ssize_t ios; > + >-+ cap = 1024; >-+ buf = malloc(cap * sizeof(char)); >-+ if (!buf) >-+ return -1; >-+ >++ if (0 > err) >++ return; >++ if (!FD_ISSET(devd_skt, (fd_set*)read_mask)) >++ return; >++ /* Read new data. */ > + for (;;) { >-+ ret = read(sock_devd, &c, 1); >-+ if (ret < 0) { >-+ if (errno == EINTR) >-+ continue; >-+ free(buf); >-+ return -1; >-+ /* EOF - devd socket is lost */ >-+ } else if (ret == 0) { >-+ disconnect_devd(sock_devd); >-+ rtimer = TimerSet(NULL, 0, 1, reconnect_handler, NULL); >-+ LogMessage(X_WARNING, "config/devd: devd socket is lost\n"); >-+ return -1; >++ ios = recv(devd_skt, (devd_buf + devd_buf_used), >++ (sizeof(devd_buf) - devd_buf_used), MSG_DONTWAIT); >++ if (0 < ios) { /* Read OK. */ >++ devd_buf_used += ios; >++ continue; /* Try to read more. */ > + } >-+ if (c == '\n') >-+ break; >-+ >-+ if (sz + 1 >= cap) { >-+ cap *= 2; >-+ newbuf = realloc(buf, cap * sizeof(char)); >-+ if (!newbuf) { >-+ free(buf); >-+ return -1; >-+ } >-+ buf = newbuf; >++ /* Something wrong. */ >++ error = errno; >++ if (error == EAGAIN) >++ break; /* All avaible data readed. */ >++ if (error == EINTR) >++ continue; >++ if (sizeof(devd_buf) == devd_buf_used) { /* Message to long, reset buf. */ >++ devd_buf_used = 0; >++ continue; > + } >-+ buf[sz] = c; >-+ sz++; >++ /* devd socket is lost */ >++ disconnect_devd(devd_skt); >++ rtimer = TimerSet(NULL, 0, 1, reconnect_handler, NULL); >++ LogMessage(X_WARNING, "config/devd: devd socket read error: %i - %s\n", error, strerror(error)); >++ return; > + } >++ ptr = memchr(devd_buf, '\n', devd_buf_used); >++ if (NULL == ptr) >++ return; > + >-+ buf[sz] = '\0'; >-+ if (sz >= 0) >-+ *out = buf; >-+ else >-+ free(buf); >++ /* Process data. */ >++ line = (devd_buf + 1); >++ for (;;) { >++ line_size = (ptr - line); >++ if (DEVD_EVENT_NOTIFY != (*(line - 1))) >++ goto move_next_event; /* Handle only notify. */ >++ /* Check: is system=DEVFS. */ >++ val = devd_get_val_cstr("system", line, line_size, &val_size); >++ if (!is_meuqual_cstr("DEVFS", val, val_size)) >++ goto move_next_event; >++ /* Check: is subsystem=CDEV. */ >++ val = devd_get_val_cstr("subsystem", line, line_size, &val_size); >++ if (!is_meuqual_cstr("CDEV", val, val_size)) >++ goto move_next_event; >++ /* Get device name. */ >++ cdev = devd_get_val_cstr("cdev", line, line_size, &cdev_size); >++ if (NULL == cdev) >++ goto move_next_event; >++ /* Get event type. */ >++ val = devd_get_val_cstr("type", line, line_size, &val_size); >++ if (is_meuqual_cstr("CREATE", val, val_size)) { >++ device_added(cdev, cdev_size, 0); >++ } else if (is_meuqual_cstr("DESTROY", val, val_size)) { >++ device_removed(cdev, cdev_size); >++ } > + >-+ /* Number of bytes in the line, not counting the line break */ >-+ return sz; >-+} >-+ >-+static void >-+wakeup_handler(void *data, int err, void *read_mask) >-+{ >-+ char *line = NULL; >-+ char *walk; >-+ >-+ if (err < 0) >-+ return; >-+ >-+ if (FD_ISSET(sock_devd, (fd_set *) read_mask)) { >-+ if (socket_getline(sock_devd, &line) < 0) >++move_next_event: >++ line += (line_size + 2); /* Skip '\n' and event type byte. */ >++ line_size = (line - devd_buf); >++ if (devd_buf_used <= line_size) { >++ devd_buf_used = 0; > + return; >-+ >-+ walk = strchr(line + 1, ' '); >-+ if (walk != NULL) >-+ walk[0] = '\0'; >-+ >-+ switch (*line) { >-+ case DEVD_EVENT_ADD: >-+ device_added(line + 1); >++ } >++ ptr = memchr(line, '\n', (devd_buf_used - line_size)); >++ if (NULL == ptr) > + break; >-+ case DEVD_EVENT_REMOVE: >-+ device_removed(line + 1); >-+ break; >-+ default: >-+ break; >-+ } >-+ free(line); > + } >++ /* Save line without end marker. */ >++ devd_buf_used -= (line_size - 1); >++ memmove(devd_buf, (line - 1), devd_buf_used); > +} > + > +static void >@@ -484,8 +890,9 @@ > +int > +config_devd_init(void) > +{ >-+ char devicename[1024]; >-+ int i, j; >++ size_t i, j, dir_cnt, sdir_cnt, tm; >++ char devicename[PATH_MAX]; >++ struct dirent *de, **namelist, *sde, **snamelist; > + > + LogMessage(X_INFO, "config/devd: probing input devices...\n"); > + >@@ -493,27 +900,51 @@ > + * Add fake keyboard and give up on keyboards management > + * if kbdmux is enabled > + */ >-+ if ((is_kbdmux = is_kbdmux_enabled()) == true) >-+ device_added("kbdmux"); >++ is_kbdmux = is_kbdmux_enabled(); >++ if (is_kbdmux) >++ device_added("kbdmux0", 7, 1); > + >-+ for (i = 0; hw_types[i].driver != NULL; i++) { >-+ /* First scan the sysctl to determine the hardware */ >-+ for (j = 0; j < 16; j++) { >-+ if (sysctl_exists(&hw_types[i], j, >-+ devicename, sizeof(devicename)) != 0) >-+ device_added(devicename); >++ /* Scan /dev/ for devices. */ >++ dir_cnt = scandir(_PATH_DEV, &namelist, 0, alphasort); >++ for (i = 0; i < dir_cnt; i ++) { >++ de = namelist[i]; >++ if (is_de_euqual_cstr(de, ".") || >++ is_de_euqual_cstr(de, "..")) { >++ free(de); >++ continue; > + } >-+ >-+ if (devpath_exists(&hw_types[i], devicename, sizeof(devicename)) != 0) >-+ device_added(devicename); >++ if (DT_DIR != de->d_type) { >++ device_added(de->d_name, de->d_namlen, 0); >++ } else { /* Sub folder. */ >++ snprintf(devicename, sizeof(devicename), >++ _PATH_DEV "%s", de->d_name); >++ sdir_cnt = scandir(devicename, &snamelist, 0, alphasort); >++ for (j = 0; j < sdir_cnt; j ++) { >++ sde = snamelist[j]; >++ if (!is_de_euqual_cstr(sde, ".") && >++ !is_de_euqual_cstr(sde, "..") && >++ DT_DIR != sde->d_type) { >++ tm = snprintf(devicename, sizeof(devicename), >++ "%s/%s", de->d_name, sde->d_name); >++ device_added(devicename, tm, 0); >++ } >++ free(sde); >++ } >++ free(snamelist); >++ } >++ free(de); > + } >++ free(namelist); > + >-+ if ((sock_devd = connect_devd()) < 0) >-+ return 0; >++ devd_buf_used = 0; >++ devd_skt = connect_devd(); >++ if (-1 == devd_skt) >++ return (0); > + >++ /* Register wakeup handler */ > + RegisterBlockAndWakeupHandlers(block_handler, wakeup_handler, NULL); > + >-+ return 1; >++ return (1); > +} > + > +void >@@ -526,9 +957,7 @@ > + rtimer = NULL; > + } > + >-+ disconnect_devd(sock_devd); >++ disconnect_devd(devd_skt); > + > + RemoveBlockAndWakeupHandlers(block_handler, wakeup_handler, NULL); >-+ >-+ is_console_kbd = false; > +} >Index: /usr/ports/x11-servers/xorg-server/files/patch-configure >=================================================================== >--- /usr/ports/x11-servers/xorg-server/files/patch-configure (revision 423642) >+++ /usr/ports/x11-servers/xorg-server/files/patch-configure (working copy) >@@ -1,5 +1,30 @@ > --- configure.orig 2015-06-16 17:43:10.000000000 +0200 > +++ configure 2015-10-21 23:07:22.017310000 +0200 >+@@ -1032,6 +1032,8 @@ >+ CONFIG_UDEV_TRUE >+ UDEV_LIBS >+ UDEV_CFLAGS >++CONFIG_DEVD_FALSE >++CONFIG_DEVD_TRUE >+ HAVE_SYSTEMD_DAEMON_FALSE >+ HAVE_SYSTEMD_DAEMON_TRUE >+ SYSTEMD_DAEMON_LIBS >+@@ -1364,6 +1368,7 @@ >+ enable_config_udev_kms >+ enable_config_hal >+ enable_config_wscons >++enable_config_devd >+ enable_xfree86_utils >+ enable_vgahw >+ enable_vbe >+@@ -2193,6 +2199,7 @@ >+ Build udev kms support (default: auto) >+ --disable-config-hal Build HAL support (default: auto) >+ --enable-config-wscons Build wscons config support (default: auto) >++ --enable-config-devd Build devd support (default: auto) >+ --enable-xfree86-utils Build xfree86 DDX utilities (default: enabled) >+ --enable-vgahw Build Xorg with vga access (default: enabled) >+ --enable-vbe Build Xorg with VBE module (default: enabled) > @@ -22640,6 +22640,11 @@ > arm*) > ARM_VIDEO=yes >@@ -12,7 +37,70 @@ > ;; > i*86) > I386_VIDEO=yes >-@@ -25559,7 +25564,7 @@ >+@@ -22760,6 +23255,9 @@ >+ >+ $as_echo "#define SYSCONS_SUPPORT 1" >>confdefs.h >+ >++ >++$as_echo "#define CONFIG_DEVD 1" >>confdefs.h >++ >+ DRI=yes >+ ;; >+ *netbsd*) >+@@ -23517,6 +24015,13 @@ >+ CONFIG_WSCONS=auto >+ fi >+ >++# Check whether --enable-config-devd was given. >++if test "${enable_config_devd+set}" = set; then : >++ enableval=$enable_config_devd; CONFIG_DEVD=$enableval >++else >++ CONFIG_DEVD=auto >++fi >++ >+ # Check whether --enable-xfree86-utils was given. >+ if test "${enable_xfree86_utils+set}" = set; then : >+ enableval=$enable_xfree86_utils; XF86UTILS=$enableval >+@@ -24239,6 +24744,7 @@ >+ CONFIG_HAL=no >+ CONFIG_UDEV=no >+ CONFIG_UDEV_KMS=no >++ CONFIG_DEVD=no >+ DGA=no >+ DRM=no >+ DRI2=no >+@@ -24568,6 +25074,30 @@ >+ fi >+ >+ >++if test "x$CONFIG_DEVD" = xauto; then >++ case $host_os in >++ *freebsd*) >++ CONFIG_DEVD=yes; >++ ;; >++ *) >++ CONFIG_DEVD=no; >++ ;; >++ esac >++fi >++ if test "x$CONFIG_DEVD" = xyes; then >++ CONFIG_DEVD_TRUE= >++ CONFIG_DEVD_FALSE='#' >++else >++ CONFIG_DEVD_TRUE='#' >++ CONFIG_DEVD_FALSE= >++fi >++ >++if test "x$CONFIG_DEVD" = xyes; then >++ >++$as_echo "#define CONFIG_DEVD 1" >>confdefs.h >++ >++fi >++ >+ if test "x$CONFIG_UDEV" = xyes && test "x$CONFIG_HAL" = xyes; then >+ as_fn_error $? "Hotplugging through both libudev and hal not allowed" "$LINENO" 5 >+ fi >+@@ -25559,7 +26089,7 @@ > case "x$XTRANS_SEND_FDS" in > xauto) > case "$host_os" in >@@ -21,3 +109,14 @@ > XTRANS_SEND_FDS=yes > ;; > *) >+@@ -32051,6 +32581,10 @@ >+ as_fn_error $? "conditional \"HAVE_SYSTEMD_DAEMON\" was never defined. >+ Usually this means the macro was only invoked conditionally." "$LINENO" 5 >+ fi >++if test -z "${CONFIG_DEVD_TRUE}" && test -z "${CONFIG_DEVD_FALSE}"; then >++ as_fn_error $? "conditional \"CONFIG_DEVD\" was never defined. >++Usually this means the macro was only invoked conditionally." "$LINENO" 5 >++fi >+ if test -z "${CONFIG_UDEV_TRUE}" && test -z "${CONFIG_UDEV_FALSE}"; then >+ as_fn_error $? "conditional \"CONFIG_UDEV\" was never defined. >+ Usually this means the macro was only invoked conditionally." "$LINENO" 5 >Index: /usr/ports/x11-servers/xorg-server/files/patch-configure.ac >=================================================================== >--- /usr/ports/x11-servers/xorg-server/files/patch-configure.ac (nonexistent) >+++ /usr/ports/x11-servers/xorg-server/files/patch-configure.ac (working copy) >@@ -0,0 +1,61 @@ >+--- configure.ac.orig 2016-10-10 01:08:54.601937000 +0300 >++++ configure.ac 2016-10-10 01:06:41.728139000 +0300 >+@@ -307,6 +307,11 @@ >+ ARM_VIDEO=yes >+ DEFAULT_INT10="stub" >++ case $host_os in >++ *freebsd*) >++ $as_echo "#define USE_DEV_IO 1" >>confdefs.h >++ ;; >++ esac >+ ;; >+ i*86) >+ I386_VIDEO=yes >+ case $host_os in >+@@ -604,6 +611,7 @@ >+ 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]) >+ AC_ARG_ENABLE(config-hal, AS_HELP_STRING([--disable-config-hal], [Build HAL support (default: auto)]), [CONFIG_HAL=$enableval], [CONFIG_HAL=auto]) >+ AC_ARG_ENABLE(config-wscons, AS_HELP_STRING([--enable-config-wscons], [Build wscons config support (default: auto)]), [CONFIG_WSCONS=$enableval], [CONFIG_WSCONS=auto]) >++AC_ARG_ENABLE(config-devd, AS_HELP_STRING([--enable-config-devd], [Build devd support (default: auto)]), [CONFIG_DEVD=$enableval], [CONFIG_DEVD=auto]) >+ AC_ARG_ENABLE(xfree86-utils, AS_HELP_STRING([--enable-xfree86-utils], [Build xfree86 DDX utilities (default: enabled)]), [XF86UTILS=$enableval], [XF86UTILS=yes]) >+ AC_ARG_ENABLE(vgahw, AS_HELP_STRING([--enable-vgahw], [Build Xorg with vga access (default: enabled)]), [VGAHW=$enableval], [VGAHW=yes]) >+ AC_ARG_ENABLE(vbe, AS_HELP_STRING([--enable-vbe], [Build Xorg with VBE module (default: enabled)]), [VBE=$enableval], [VBE=yes]) >+@@ -697,6 +705,7 @@ >+ CONFIG_HAL=no >+ CONFIG_UDEV=no >+ CONFIG_UDEV_KMS=no >++ CONFIG_DEVD=no >+ DGA=no >+ DRM=no >+ DRI2=no >+@@ -845,6 +854,21 @@ >+ fi >+ AM_CONDITIONAL([HAVE_SYSTEMD_DAEMON], [test "x$HAVE_SYSTEMD_DAEMON" = "xyes"]) >+ >++if test "x$CONFIG_DEVD" = xauto; then >++ case $host_os in >++ *freebsd*) >++ CONFIG_DEVD=yes; >++ ;; >++ *) >++ CONFIG_DEVD=no; >++ ;; >++ esac >++fi >++AM_CONDITIONAL(CONFIG_DEVD, [test "x$CONFIG_DEVD" = xyes]) >++if test "x$CONFIG_DEVD" = xyes; then >++ AC_DEFINE(CONFIG_DEVD, 1, [Use devd for input auto configuration]) >++fi >++ >+ if test "x$CONFIG_UDEV" = xyes && test "x$CONFIG_HAL" = xyes; then >+ AC_MSG_ERROR([Hotplugging through both libudev and hal not allowed]) >+ fi >+@@ -1165,7 +1189,7 @@ >+ case "x$XTRANS_SEND_FDS" in >+ xauto) >+ case "$host_os" in >+- linux*|solaris*) >++ linux*|solaris*|freebsd*|dragonfly*) >+ XTRANS_SEND_FDS=yes >+ ;; >+ *) >Index: /usr/ports/x11-servers/xorg-server/files/patch-include_dix-config.h.in >=================================================================== >--- /usr/ports/x11-servers/xorg-server/files/patch-include_dix-config.h.in (nonexistent) >+++ /usr/ports/x11-servers/xorg-server/files/patch-include_dix-config.h.in (working copy) >@@ -0,0 +1,12 @@ >+--- include/dix-config.h.in.orig 2015-10-27 23:12:01.000000000 +0300 >++++ include/dix-config.h.in 2016-10-10 03:51:05.267830000 +0300 >+@@ -430,6 +430,9 @@ >+ /* Use udev_enumerate_add_match_tag() */ >+ #undef HAVE_UDEV_ENUMERATE_ADD_MATCH_TAG >+ >++/* Use devd for input hotplug */ >++#undef CONFIG_DEVD >++ >+ /* Enable D-Bus core */ >+ #undef NEED_DBUS >+
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 196678
:
151548
|
151549
|
160696
|
160697
|
161034
|
161035
|
166727
|
167354
|
167426
|
167594
|
172378
|
175616
|
179892
|
180700
|
180710
|
180880
|
191592
|
195909
|
196037
|
197417
|
198703
|
203086
|
209380
|
211620
|
211740
|
211748
|
211749
|
211907