--- x11-servers/xorg-server/Makefile (revision 433920) +++ x11-servers/xorg-server/Makefile (working copy) @@ -83,6 +83,12 @@ CONFIGURE_ARGS+= --disable-config-hal .endif +.if ${PORT_OPTIONS:MDEVD} +CONFIGURE_ARGS+= --enable-config-devd +.else +CONFIGURE_ARGS+= --disable-config-devd +.endif + # We handle Xorg setuid in the plist. This allows to build xorg-server as a user. CONFIGURE_ARGS+=--disable-install-setuid @@ -114,15 +120,6 @@ -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 - .if ${SLAVE_PORT} == "no" post-install: # The .xorg dir because else the xorg-server might not load the correct --- x11-servers/xorg-server/files/patch-config_Makefile.am (nonexistent) +++ x11-servers/xorg-server/files/patch-config_Makefile.am (working copy) @@ -0,0 +1,19 @@ +--- config/Makefile.am.orig 2016-07-15 16:18:11 UTC ++++ config/Makefile.am +@@ -32,7 +32,15 @@ else + + 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 + --- x11-servers/xorg-server/files/patch-config_devd.c (revision 433920) +++ x11-servers/xorg-server/files/patch-config_devd.c (working copy) @@ -1,11 +1,12 @@ ---- config/devd.c.orig 2017-01-19 15:20:42 UTC +--- config/devd.c.orig 2017-02-11 23:47:35 UTC +++ config/devd.c -@@ -0,0 +1,532 @@ +@@ -0,0 +1,959 @@ +/* + * 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 - 2017 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 +#include +#include ++#include ++#include ++#include ++#include ++#include + +#include ++#include +#include +#include +#include @@ -47,6 +54,9 @@ +#include +#include +#include ++#include ++#include ++#include + +#include "input.h" +#include "inputstr.h" @@ -54,427 +64,821 @@ +#include "config-backends.h" +#include "os.h" + -+#define DEVD_SOCK_PATH "/var/run/devd.pipe" + ++/* from: */ ++#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: */ ++#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; -+static OsTimerPtr rtimer = NULL; + -+struct hw_type { -+ const char *driver; -+ int flag; -+ const char *xdriver; ++#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; ++ ++ ++/* 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; ++ 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"); -+ free(buf); -+ 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 @@ -485,8 +889,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"); + @@ -494,27 +899,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 @@ -527,9 +956,7 @@ + rtimer = NULL; + } + -+ disconnect_devd(sock_devd); ++ disconnect_devd(devd_skt); + + RemoveBlockAndWakeupHandlers(block_handler, wakeup_handler, NULL); -+ -+ is_console_kbd = false; +} --- x11-servers/xorg-server/files/patch-configure (revision 433920) +++ x11-servers/xorg-server/files/patch-configure (working copy) @@ -1,6 +1,31 @@ --- configure.orig 2016-07-19 17:27:31 UTC +++ configure -@@ -23168,9 +23168,14 @@ $as_echo "#define USE_ALPHA_PIO 1" >>con +@@ -1030,6 +1030,8 @@ CONFIG_UDEV_FALSE + 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 +1366,7 @@ enable_config_udev + enable_config_udev_kms + enable_config_hal + enable_config_wscons ++enable_config_devd + enable_xfree86_utils + enable_vgahw + enable_vbe +@@ -2189,6 +2192,7 @@ Optional Features: + 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) +@@ -23168,9 +23172,14 @@ $as_echo "#define USE_ALPHA_PIO 1" >>con esac GLX_ARCH_DEFINES="-D__GLX_ALIGN64 -mieee" ;; @@ -16,7 +41,70 @@ ;; i*86) I386_VIDEO=yes -@@ -26057,7 +26062,7 @@ fi +@@ -23291,6 +23300,9 @@ $as_echo "#define PCVT_SUPPORT 1" >>conf + + $as_echo "#define SYSCONS_SUPPORT 1" >>confdefs.h + ++ ++$as_echo "#define CONFIG_DEVD 1" >>confdefs.h ++ + DRI=yes + ;; + *netbsd*) +@@ -23968,6 +23980,13 @@ else + 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 +@@ -24681,6 +24700,7 @@ case $host_os in + CONFIG_HAL=no + CONFIG_UDEV=no + CONFIG_UDEV_KMS=no ++ CONFIG_DEVD=no + DGA=no + DRM=no + DRI2=no +@@ -25157,6 +25177,30 @@ else + 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 +@@ -26057,7 +26101,7 @@ fi case "x$XTRANS_SEND_FDS" in xauto) case "$host_os" in @@ -25,3 +113,14 @@ XTRANS_SEND_FDS=yes ;; *) +@@ -32398,6 +32442,10 @@ if test -z "${HAVE_SYSTEMD_DAEMON_TRUE}" + 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 --- x11-servers/xorg-server/files/patch-configure.ac (nonexistent) +++ x11-servers/xorg-server/files/patch-configure.ac (working copy) @@ -0,0 +1,61 @@ +--- configure.ac.orig 2016-07-19 17:27:07 UTC ++++ configure.ac +@@ -325,6 +325,11 @@ case $host_cpu in + arm*) + 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 +@@ -618,6 +623,7 @@ AC_ARG_ENABLE(config-udev, AS_HELP_ST + 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]) +@@ -708,6 +714,7 @@ case $host_os in + CONFIG_HAL=no + CONFIG_UDEV=no + CONFIG_UDEV_KMS=no ++ CONFIG_DEVD=no + DGA=no + DRM=no + DRI2=no +@@ -866,6 +873,21 @@ if test "x$WITH_SYSTEMD_DAEMON" = "xyes" + 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 +@@ -1184,7 +1206,7 @@ AC_ARG_ENABLE(xtrans-send-fds, AS_HELP_S + case "x$XTRANS_SEND_FDS" in + xauto) + case "$host_os" in +- linux*|solaris*) ++ linux*|solaris*|freebsd*|dragonfly*) + XTRANS_SEND_FDS=yes + ;; + *) --- x11-servers/xorg-server/files/patch-include_dix-config.h.in (nonexistent) +++ 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 +