Page MenuHomeFreeBSD

D7588.id19748.diff
No OneTemporary

D7588.id19748.diff

Index: Mk/Uses/evdev.mk
===================================================================
--- Mk/Uses/evdev.mk
+++ Mk/Uses/evdev.mk
@@ -0,0 +1,122 @@
+# $FreeBSD$
+#
+# Handle Input event device headers patches and dependencies
+#
+# Feature: evdev
+# Usage: USES=evdev
+# Valid ARGS: ports base bundled
+#
+# 1. ports - introduces build dependence on devel/libevdev-headers port.
+# It has more IOCTL definitions than we support but libevdev handles
+# that at runtime.
+# 2. base - port compiles with evdev headers from base system. sed script is
+# provided for conversion of include paths in source files in that case.
+# 3. bundled - port (currently devel/libevdev and devel/libevdev-headers)
+# compiles with bundled evdev headers. sed script for header conversion
+# from Linux to FreeBSD is provided in that case.
+#
+# 1 implies 3 for some strange software like libinput that has both bundled
+# evdev headers and external evdev headers dependency.
+#
+# default: ports
+#
+# EVDEV_WRKSRC top-level path for evdev headers and directory traversal
+# default: ${WRKSRC}
+#
+# Provide support to convert port-supplied copies of evdev headers from Linux
+# EVDEV_INCLUDE top-level path for port-supplied evdev headers
+# default: ${EVDEV_WRKSRC}/include
+# EVDEV_INPUT_H path to port-supplied input.h header
+# default: ${EVDEV_INCLUDE}/linux/input.h
+# EVDEV_UINPUT_H path to port-supplied uinput.h header
+# default: ${EVDEV_INCLUDE}/linux/uinput.h
+#
+# This variables can be defined to convert sources from using port system supplied
+# headers to base system supplied ones.
+# EVDEV_SOURCE_REGEX a regular expression to match files that needs to be converted
+# EVDEV_SOURCE_FILES list of files relative to ${EVDEV_WRKSRC}
+# EVDEV_SOURCE_GLOB list of glob pattern find(1) will match with
+#
+# MAINTAINER: portmgr@FreeBSD.org
+
+.if !defined(_INCLUDE_USES_EVDEV_MK)
+_INCLUDE_USES_EVDEV_MK= yes
+
+_valid_ARGS= ports base bundled
+
+.if empty(evdev_ARGS)
+evdev_ARGS= ports
+.endif
+
+# Sanity checks
+.for _arg in ${evdev_ARGS}
+. if ! ${_valid_ARGS:M${_arg}}
+IGNORE= Incorrect 'USES+= evdev:${evdev_ARGS}' usage: argument [${_arg}] is not recognized
+. endif
+.endfor
+
+.if ${evdev_ARGS} == ports
+BUILD_DEPENDS+= ${LOCALBASE}/include/linux/input.h:devel/libevdev-headers
+CFLAGS+= -I${LOCALBASE}/include
+CXXFLAGS+= -I${LOCALBASE}/include
+.endif
+
+EVDEV_WRKSRC?= ${WRKSRC}
+EVDEV_INCLUDE?= ${EVDEV_WRKSRC}/include
+EVDEV_INPUT_H?= ${EVDEV_INCLUDE}/linux/input.h
+EVDEV_UINPUT_H?= ${EVDEV_INCLUDE}/linux/uinput.h
+
+EVDEV_HEADER_PATTERN= '/^ *\# *include/s|[<"]linux(/u?input\.h)[>"]|<dev/evdev\1>|'
+
+_USES_patch+= 700:evdev-post-patch
+
+evdev-post-patch:
+.if ${evdev_ARGS} != base
+# Patch port-bundled input.h and uinput.h to be FreeBSD-compatible
+ @if [ -f "${EVDEV_INPUT_H}" ]; then \
+ ${REINPLACE_CMD} -i '' -E -e \
+ 's/__u([[:digit:]]+)/uint\1_t/g ; \
+ s/__s([[:digit:]]+)/int\1_t/g ; \
+ /# *include/ s|<sys/ioctl.h>|<sys/ioccom.h>| ; \
+ /# *include[[:space:]]+<linux\/types.h>/d ; \
+ /EVIOC(RMFF|GRAB|REVOKE)/ s/_IOW(.*), *int/_IOWINT\1/ ; \
+ /EVIOCGKEYCODE/ s/_IOR/_IOWR/ ; \
+ /EVIOCGMASK/ s/_IOR/_IOW/ ; \
+ /EVIOCGMTSLOTS/ s/_IOC_READ/IOC_INOUT/ ; \
+ /#define/ s/_IOC_READ/IOC_OUT/ ; \
+ /#define/ s/_IOC_WRITE/IOC_IN/' \
+ "${EVDEV_INPUT_H}"; \
+ fi
+ @if [ -f "${EVDEV_UINPUT_H}" ]; then \
+ ${REINPLACE_CMD} -i '' -E -e \
+ 's/__u([[:digit:]]+)/uint\1_t/g ; \
+ s/__s([[:digit:]]+)/int\1_t/g ; \
+ /# *include/s|<linux/types.h>|<sys/types.h>| ; \
+ /#define/ s/_IOW(.*), *int/_IOWINT\1/ ; \
+ /#define/ s/_IOW(.*), *char\*/_IO\1/ ; \
+ /#define/ s/_IOC_READ/IOC_OUT/ ; \
+ /UI_GET_SYSNAME/ s/300/44/ ; \
+ /UI_GET_VERSION/ s/301/45/' \
+ "${EVDEV_UINPUT_H}"; \
+ fi
+.else
+# Patch port sources to include dev/evdev/ files instead of linux/
+. if exists(/usr/include/dev/evdev/input.h)
+. if defined(EVDEV_SOURCE_FILES)
+ @cd ${EVDEV_WRKSRC}; \
+ ${REINPLACE_CMD} -i '' -E -e ${EVDEV_HEADER_PATTERN} \
+ ${EVDEV_SOURCE_FILES}
+. elif defined(EVDEV_SOURCE_REGEX)
+ @${FIND} -E ${EVDEV_WRKSRC} -type f -iregex '${EVDEV_SOURCE_REGEX}' \
+ -print0 | ${XARGS} -0 \
+ ${REINPLACE_CMD} -i '' -E -e ${EVDEV_HEADER_PATTERN}
+. else
+. for f in ${EVDEV_SOURCE_GLOB}
+ @${FIND} ${EVDEV_WRKSRC} -type f -name '${f}' -print0 | ${XARGS} -0 \
+ ${REINPLACE_CMD} -i '' -E -e ${EVDEV_HEADER_PATTERN}
+. endfor
+. endif
+. endif
+.endif
+
+.endif
Index: comms/lirc/Makefile
===================================================================
--- comms/lirc/Makefile
+++ comms/lirc/Makefile
@@ -11,10 +11,8 @@
MAINTAINER= ports@FreeBSD.org
COMMENT= Linux Infrared Remote Control
-BUILD_DEPENDS= v4l_compat>=1.0.20110603:multimedia/v4l_compat
-
INSTALL_TARGET= install-strip
-USES= alias autoreconf gmake libtool python tar:bzip2
+USES= alias autoreconf gmake libtool python tar:bzip2 evdev
USE_XORG= sm x11
USE_CSTD= gnu89
USE_LDCONFIG= yes
Index: comms/svxlink/Makefile
===================================================================
--- comms/svxlink/Makefile
+++ comms/svxlink/Makefile
@@ -17,14 +17,12 @@
libsigc-2.0.so:devel/libsigc++20 \
libpopt.so:devel/popt \
libopus.so:audio/opus
-BUILD_DEPENDS= pkg-config:devel/pkgconf \
- ${LOCALBASE}/include/linux/input.h:multimedia/v4l_compat
USE_GITHUB= yes
GH_ACCOUNT= sm0svx
GH_PROJECT= svxlink
-USES= cmake tcl
+USES= cmake tcl pkgconfig evdev
CMAKE_SOURCE_PATH= ${WRKSRC}/src
CMAKE_ARGS+= -DMAN_INSTALL_DIR:FILEPATH=${MANDIRS} \
-DLOCAL_STATE_DIR=/var
Index: devel/evemu/Makefile
===================================================================
--- devel/evemu/Makefile
+++ devel/evemu/Makefile
@@ -0,0 +1,43 @@
+# Created by: Vladimir Kondratiev <wulf@cicgroup.ru>
+# $FreeBSD$
+
+PORTNAME= evemu
+PORTVERSION= 2.4.0
+CATEGORIES= devel
+MASTER_SITES= http://www.freedesktop.org/software/${PORTNAME}/
+
+MAINTAINER= wulf@cicgroup.ru
+COMMENT= Records and replays EVDEV descriptions and events
+
+LICENSE= GPLv3
+
+LIB_DEPENDS= libevdev.so:devel/libevdev
+
+USES= tar:xz python pathfix libtool pkgconfig evdev
+
+OPTIONS_DEFINE= MANPAGES
+OPTIONS_DEFAULT=MANPAGES
+OPTIONS_SUB= yes
+
+# evemu-event.1, evemu-play.1 and evemu-record.1 manpages are broken
+# due to docbook-xsl bug: https://sourceforge.net/p/docbook/bugs/1058/
+MANPAGES_BUILD_DEPENDS= xmlto:textproc/xmlto \
+ asciidoc:textproc/asciidoc
+MANPAGES_CONFIGURE_ENV_OFF= ac_cv_path_XMLTO="" \
+ ac_cv_path_ASCIIDOC=""
+
+GNU_CONFIGURE= yes
+CFLAGS+= -D_WITH_DPRINTF
+USE_LDCONFIG= yes
+INSTALL_TARGET= install-strip
+
+TEST_TARGET= check
+TEST_WRKSRC= ${WRKSRC}/test
+
+post-patch:
+ ${REINPLACE_CMD} -e 's|program_invocation_short_name|getprogname()|' \
+ ${WRKSRC}/tools/evemu-event.c ${WRKSRC}/tools/evemu-record.c
+ ${REINPLACE_CMD} -e 's/versionsort/alphasort/' \
+ ${WRKSRC}/tools/find_event_devices.c
+
+.include <bsd.port.mk>
Index: devel/evemu/distinfo
===================================================================
--- devel/evemu/distinfo
+++ devel/evemu/distinfo
@@ -0,0 +1,2 @@
+SHA256 (evemu-2.4.0.tar.xz) = 0706ea5a830203f9cdb30c0e10c8c41d2427128ba9041543a5ae157fa3b4a30e
+SIZE (evemu-2.4.0.tar.xz) = 505848
Index: devel/evemu/files/patch-src_evemu.c
===================================================================
--- devel/evemu/files/patch-src_evemu.c
+++ devel/evemu/files/patch-src_evemu.c
@@ -0,0 +1,21 @@
+--- src/evemu.c.orig 2016-02-25 09:00:31 UTC
++++ src/evemu.c
+@@ -430,16 +430,13 @@ int evemu_write(const struct evemu_devic
+ static int parse_name(struct evemu_device *dev, const char *line)
+ {
+ int matched;
+- char *devname = NULL;
++ char devname[UINPUT_MAX_NAME_SIZE];
+
+- if ((matched = sscanf(line, "N: %m[^\n]\n", &devname)) > 0) {
++ if ((matched = sscanf(line, "N: %[^\n]\n", devname)) > 0) {
+ if (strlen(evemu_get_name(dev)) == 0)
+ evemu_set_name(dev, devname);
+ }
+
+- if (devname != NULL)
+- free(devname);
+-
+ if (matched <= 0)
+ error(FATAL, "Expected device name, but got: %s", line);
+
Index: devel/evemu/pkg-descr
===================================================================
--- devel/evemu/pkg-descr
+++ devel/evemu/pkg-descr
@@ -0,0 +1,8 @@
+Tools and bindings for kernel input event device emulation and data capture
+and replay.
+
+Evemu provides a programmatic API to access the kernel input event devices.
+The original and intended purpose is for supporting multi-touch input,
+especially with regard to the Ubuntu touch and gesture stack.
+
+WWW: http://www.freedesktop.org/wiki/Evemu
Index: devel/evemu/pkg-plist
===================================================================
--- devel/evemu/pkg-plist
+++ devel/evemu/pkg-plist
@@ -0,0 +1,28 @@
+bin/evemu-describe
+bin/evemu-device
+bin/evemu-event
+bin/evemu-play
+bin/evemu-record
+include/evemu.h
+lib/libevemu.a
+lib/libevemu.so
+lib/libevemu.so.3
+lib/libevemu.so.3.0.1
+%%PYTHON_SITELIBDIR%%/evemu/__init__.py
+%%PYTHON_SITELIBDIR%%/evemu/__init__.pyc
+%%PYTHON_SITELIBDIR%%/evemu/__init__.pyo
+%%PYTHON_SITELIBDIR%%/evemu/base.py
+%%PYTHON_SITELIBDIR%%/evemu/base.pyc
+%%PYTHON_SITELIBDIR%%/evemu/base.pyo
+%%PYTHON_SITELIBDIR%%/evemu/const.py
+%%PYTHON_SITELIBDIR%%/evemu/const.pyc
+%%PYTHON_SITELIBDIR%%/evemu/const.pyo
+%%PYTHON_SITELIBDIR%%/evemu/exception.py
+%%PYTHON_SITELIBDIR%%/evemu/exception.pyc
+%%PYTHON_SITELIBDIR%%/evemu/exception.pyo
+libdata/pkgconfig/evemu.pc
+%%MANPAGES%%man/man1/evemu-describe.1.gz
+%%MANPAGES%%man/man1/evemu-device.1.gz
+%%MANPAGES%%man/man1/evemu-event.1.gz
+%%MANPAGES%%man/man1/evemu-play.1.gz
+%%MANPAGES%%man/man1/evemu-record.1.gz
Index: devel/libevdev-headers/Makefile
===================================================================
--- devel/libevdev-headers/Makefile
+++ devel/libevdev-headers/Makefile
@@ -0,0 +1,29 @@
+# $FreeBSD$
+
+PORTNAME= libevdev
+PORTREVISION= 0
+PKGNAMESUFFIX= -headers
+
+COMMENT= Event device IOCTL header files
+
+LICENSE= GPLv2
+
+NO_BUILD= yes
+NO_ARCH= yes
+
+MASTERDIR= ${.CURDIR}/../../devel/libevdev
+DESCR= ${.CURDIR}/pkg-descr
+PLIST= ${.CURDIR}/pkg-plist
+LIBEVDEV_SLAVE= headers
+
+HEADERS= input.h input-event-codes.h uinput.h
+PLIST_FILES= ${HEADERS:S|^|include/linux/|}
+
+do-install:
+ @${MKDIR} ${STAGEDIR}${PREFIX}/include/linux/
+.for i in ${HEADERS}
+ ${INSTALL_DATA} ${WRKSRC}/include/linux/${i} \
+ ${STAGEDIR}${PREFIX}/include/linux/
+.endfor
+
+.include "${MASTERDIR}/Makefile"
Index: devel/libevdev-headers/pkg-descr
===================================================================
--- devel/libevdev-headers/pkg-descr
+++ devel/libevdev-headers/pkg-descr
@@ -0,0 +1 @@
+This port installs the event device header files.
Index: devel/libevdev/Makefile
===================================================================
--- devel/libevdev/Makefile
+++ devel/libevdev/Makefile
@@ -1,32 +1,46 @@
# $FreeBSD$
PORTNAME= libevdev
-PORTVERSION= 1.4.4
+PORTVERSION= 1.5.2
CATEGORIES= devel
MASTER_SITES= http://freedesktop.org/software/${PORTNAME}/
MAINTAINER= hselasky@FreeBSD.org
COMMENT= Linux Event Device library
-LICENSE= MIT # without linux/*.h
-LICENSE_FILE= ${WRKSRC}/COPYING
+LICENSE?= MIT # without linux/*.h
+
+LIBEVDEV_SLAVE?= no
-BUILD_DEPENDS= v4l_compat>=1.0.20110603:multimedia/v4l_compat
-RUN_DEPENDS= v4l_compat>=1.0.20110603:multimedia/v4l_compat
+USES+= tar:xz evdev:bundled
-USES= gmake libtool pathfix python:build tar:xz
-EXTRACT_AFTER_ARGS= --exclude include # v4l_compat
+.if ${LIBEVDEV_SLAVE} != headers
+LICENSE_FILE= ${WRKSRC}/COPYING
+USES+= gmake libtool pathfix python:build
GNU_CONFIGURE= yes
CONFIGURE_ENV= ac_cv_path_DOXYGEN=""
-CPPFLAGS+= -I${LOCALBASE}/include # v4l_compat
INSTALL_TARGET= install-strip
USE_LDCONFIG= yes
+OPTIONS_DEFINE+= TEST
+TEST_USES+= pkgconfig
+TEST_LIB_DEPENDS= libcheck.so:devel/libcheck
+TEST_TARGET= check
+TEST_WRKSRC= ${WRKSRC}/test
+
+# XXX test requires /dev/uinput and should be run as root
+#.if ! exists(/usr/include/dev/evdev/input.h)
+# test-libevdev current results: "98%: Checks: 115, Failures: 2, Errors: 0"
+OPTIONS_EXCLUDE= TEST
+#.endif
+.endif
+
post-patch:
- @${REINPLACE_CMD} -e '/input\.h/s,top_srcdir,LOCALBASE,' \
- ${WRKSRC}/libevdev/Makefile.in
-# XXX tools require signalfd(2), test require /dev/uinput
- @${REINPLACE_CMD} -e '/^SUBDIRS/s,tools test,,' \
+ @${REINPLACE_CMD} -e 's|program_invocation_short_name|getprogname()|' \
+ ${WRKSRC}/tools/libevdev-tweak-device.c
+
+post-patch-TEST-off:
+ ${REINPLACE_CMD} -e '/^SUBDIRS/s,test,,' \
${WRKSRC}/Makefile.in
.include <bsd.port.mk>
Index: devel/libevdev/distinfo
===================================================================
--- devel/libevdev/distinfo
+++ devel/libevdev/distinfo
@@ -1,2 +1,3 @@
-SHA256 (libevdev-1.4.4.tar.xz) = ed9979369b6a6e28f5897d099538549ecffb2b7c00c1b717eb77c31d85bc45a9
-SIZE (libevdev-1.4.4.tar.xz) = 409856
+TIMESTAMP = 1467541593
+SHA256 (libevdev-1.5.2.tar.xz) = 5ee2163656a61f5703cb5c08a05c9471ffb7b640bfbe2c55194ea50d908f629b
+SIZE (libevdev-1.5.2.tar.xz) = 397848
Index: devel/libevdev/files/patch-libevdev_libevdev-uinput.c
===================================================================
--- devel/libevdev/files/patch-libevdev_libevdev-uinput.c
+++ devel/libevdev/files/patch-libevdev_libevdev-uinput.c
@@ -0,0 +1,40 @@
+--- libevdev/libevdev-uinput.c.orig 2016-04-28 00:40:58 UTC
++++ libevdev/libevdev-uinput.c
+@@ -182,6 +182,7 @@ libevdev_uinput_get_fd(const struct libe
+ return uinput_dev->fd;
+ }
+
++#if defined(linux)
+ static int is_event_device(const struct dirent *dent) {
+ return strncmp("event", dent->d_name, 5) == 0;
+ }
+@@ -213,10 +214,12 @@ fetch_device_node(const char *path)
+ static int is_input_device(const struct dirent *dent) {
+ return strncmp("input", dent->d_name, 5) == 0;
+ }
++#endif
+
+ static int
+ fetch_syspath_and_devnode(struct libevdev_uinput *uinput_dev)
+ {
++#if defined(linux)
+ struct dirent **namelist;
+ int ndev, i;
+ int rc;
+@@ -290,6 +293,16 @@ fetch_syspath_and_devnode(struct libevde
+ free(namelist);
+
+ return uinput_dev->devnode ? 0 : -1;
++#elif defined(__FreeBSD__)
++ char devnode[80];
++ if (ioctl(uinput_dev->fd, UI_GET_SYSNAME(sizeof(devnode)), devnode) < 0)
++ return -1;
++ asprintf(&uinput_dev->devnode, "/dev/input/%s", devnode);
++ uinput_dev->syspath = strdup(uinput_dev->devnode);
++ return 0;
++#else
++ return -1;
++#endif
+ }
+
+ static int
Index: devel/libevdev/files/patch-test_test-libevdev-events.c
===================================================================
--- devel/libevdev/files/patch-test_test-libevdev-events.c
+++ devel/libevdev/files/patch-test_test-libevdev-events.c
@@ -0,0 +1,20 @@
+--- test/test-libevdev-events.c.orig 2016-04-28 00:40:58 UTC
++++ test/test-libevdev-events.c
+@@ -1057,7 +1057,7 @@ START_TEST(test_syn_delta_late_sync)
+ } while (rc >= 0);
+
+ /* force enough events to trigger a SYN_DROPPED */
+- for (i = 0; i < 100; i++) {
++ for (i = 0; i < 200; i++) {
+ uinput_device_event(uidev, EV_ABS, ABS_X, 100 + i);
+ uinput_device_event(uidev, EV_ABS, ABS_Y, 500 + i);
+ uinput_device_event(uidev, EV_ABS, ABS_MT_POSITION_X, 100 + i);
+@@ -1152,7 +1152,7 @@ START_TEST(test_syn_delta_late_sync)
+ } while (rc >= 0);
+
+ /* force enough events to trigger a SYN_DROPPED */
+- for (i = 0; i < 100; i++) {
++ for (i = 0; i < 200; i++) {
+ uinput_device_event(uidev, EV_ABS, ABS_X, 100 + i);
+ uinput_device_event(uidev, EV_ABS, ABS_Y, 500 + i);
+ uinput_device_event(uidev, EV_ABS, ABS_MT_POSITION_X, 100 + i);
Index: devel/libevdev/files/patch-test_test-libevdev-init.c
===================================================================
--- devel/libevdev/files/patch-test_test-libevdev-init.c
+++ devel/libevdev/files/patch-test_test-libevdev-init.c
@@ -0,0 +1,11 @@
+--- test/test-libevdev-init.c.orig 2016-04-28 00:40:58 UTC
++++ test/test-libevdev-init.c
+@@ -490,7 +490,7 @@ START_TEST(test_set_clock_id)
+ rc = libevdev_set_clock_id(dev, CLOCK_MONOTONIC);
+ ck_assert_int_eq(rc, 0);
+
+- rc = libevdev_set_clock_id(dev, CLOCK_MONOTONIC_RAW);
++ rc = libevdev_set_clock_id(dev, CLOCK_MONOTONIC_FAST);
+ ck_assert_int_eq(rc, -EINVAL);
+
+ uinput_device_free(uidev);
Index: devel/libevdev/files/patch-test_test-main.c
===================================================================
--- devel/libevdev/files/patch-test_test-main.c
+++ devel/libevdev/files/patch-test_test-main.c
@@ -0,0 +1,26 @@
+--- test/test-main.c.orig 2015-06-10 04:49:41 UTC
++++ test/test-main.c
+@@ -41,6 +41,7 @@ extern Suite *uinput_suite(void);
+ static int
+ is_debugger_attached(void)
+ {
++#if defined (linux)
+ int status;
+ int rc;
+ int pid = fork();
+@@ -64,6 +65,15 @@ is_debugger_attached(void)
+ }
+
+ return rc;
++#else
++ /*
++ * Skip useless gdb test as setting CK_FORK environment variable in
++ * absence of attached debugger gives no harm to user.
++ * Moreover this test is broken on most nonlinux systems, look at
++ * discussion here: http://stackoverflow.com/questions/3596781/
++ */
++ return 1;
++#endif
+ }
+
+ int main(int argc, char **argv)
Index: devel/libevdev/files/patch-tools_mouse-dpi-tool.c
===================================================================
--- devel/libevdev/files/patch-tools_mouse-dpi-tool.c
+++ devel/libevdev/files/patch-tools_mouse-dpi-tool.c
@@ -0,0 +1,59 @@
+--- tools/mouse-dpi-tool.c.orig 2016-04-28 00:40:58 UTC
++++ tools/mouse-dpi-tool.c
+@@ -26,7 +26,6 @@
+ #endif
+
+ #include <libevdev/libevdev.h>
+-#include <sys/signalfd.h>
+ #include <errno.h>
+ #include <fcntl.h>
+ #include <limits.h>
+@@ -47,9 +46,18 @@ struct measurements {
+ uint64_t us;
+ };
+
++
++static volatile int sigint_catched = 0;
++static void
++sigint_handler(int signo)
++{
++ if (signo == SIGINT)
++ sigint_catched = 1;
++}
++
+ static int
+ usage(void) {
+- printf("Usage: %s /dev/input/event0\n", program_invocation_short_name);
++ printf("Usage: %s /dev/input/event0\n", getprogname());
+ printf("\n");
+ printf("This tool reads relative events from the kernel and calculates\n"
+ "the distance covered and maximum frequency of the incoming events.\n"
+@@ -128,24 +136,18 @@ handle_event(struct measurements *m, con
+
+ static int
+ mainloop(struct libevdev *dev, struct measurements *m) {
+- struct pollfd fds[2];
+- sigset_t mask;
++ struct pollfd fds[1];
+
+ fds[0].fd = libevdev_get_fd(dev);
+ fds[0].events = POLLIN;
+
+- sigemptyset(&mask);
+- sigaddset(&mask, SIGINT);
+- fds[1].fd = signalfd(-1, &mask, SFD_NONBLOCK);
+- fds[1].events = POLLIN;
+-
+- sigprocmask(SIG_BLOCK, &mask, NULL);
++ signal(SIGINT, sigint_handler);
+
+- while (poll(fds, 2, -1)) {
++ while (poll(fds, 1, -1)) {
+ struct input_event ev;
+ int rc;
+
+- if (fds[1].revents)
++ if (sigint_catched)
+ break;
+
+ do {
Index: devel/libevdev/files/patch-tools_touchpad-edge-detector.c
===================================================================
--- devel/libevdev/files/patch-tools_touchpad-edge-detector.c
+++ devel/libevdev/files/patch-tools_touchpad-edge-detector.c
@@ -0,0 +1,63 @@
+--- tools/touchpad-edge-detector.c.orig 2016-04-28 00:40:58 UTC
++++ tools/touchpad-edge-detector.c
+@@ -26,7 +26,6 @@
+ #endif
+
+ #include <libevdev/libevdev.h>
+-#include <sys/signalfd.h>
+ #include <errno.h>
+ #include <fcntl.h>
+ #include <limits.h>
+@@ -43,7 +42,7 @@
+
+ static int
+ usage(void) {
+- printf("Usage: %s /dev/input/event0\n", program_invocation_short_name);
++ printf("Usage: %s /dev/input/event0\n", getprogname());
+ printf("\n");
+ printf("This tool reads the touchpad events from the kernel and calculates\n "
+ "the minimum and maximum for the x and y coordinates, respectively.\n");
+@@ -54,6 +53,14 @@ struct dimensions {
+ int top, bottom, left, right;
+ };
+
++static volatile int sigint_catched = 0;
++static void
++sigint_handler(int signo)
++{
++ if (signo == SIGINT)
++ sigint_catched = 1;
++}
++
+ static int
+ print_current_values(const struct dimensions *d)
+ {
+@@ -99,24 +106,18 @@ handle_event(struct dimensions *d, const
+
+ static int
+ mainloop(struct libevdev *dev, struct dimensions *dim) {
+- struct pollfd fds[2];
+- sigset_t mask;
++ struct pollfd fds[1];
+
+ fds[0].fd = libevdev_get_fd(dev);
+ fds[0].events = POLLIN;
+
+- sigemptyset(&mask);
+- sigaddset(&mask, SIGINT);
+- fds[1].fd = signalfd(-1, &mask, SFD_NONBLOCK);
+- fds[1].events = POLLIN;
+-
+- sigprocmask(SIG_BLOCK, &mask, NULL);
++ signal(SIGINT, sigint_handler);
+
+- while (poll(fds, 2, -1)) {
++ while (poll(fds, 1, -1)) {
+ struct input_event ev;
+ int rc;
+
+- if (fds[1].revents)
++ if (sigint_catched)
+ break;
+
+ do {
Index: devel/libevdev/pkg-plist
===================================================================
--- devel/libevdev/pkg-plist
+++ devel/libevdev/pkg-plist
@@ -1,8 +1,11 @@
+bin/libevdev-tweak-device
+bin/mouse-dpi-tool
+bin/touchpad-edge-detector
include/libevdev-1.0/libevdev/libevdev-uinput.h
include/libevdev-1.0/libevdev/libevdev.h
lib/libevdev.a
lib/libevdev.so
lib/libevdev.so.2
-lib/libevdev.so.2.1.10
+lib/libevdev.so.2.1.14
libdata/pkgconfig/libevdev.pc
man/man3/libevdev.3.gz
Index: devel/libmtdev/Makefile
===================================================================
--- devel/libmtdev/Makefile
+++ devel/libmtdev/Makefile
@@ -12,12 +12,8 @@
LICENSE= MIT
LICENSE_FILE= ${WRKSRC}/COPYING
-BUILD_DEPENDS= v4l_compat>=1.0.20110603:multimedia/v4l_compat
-RUN_DEPENDS= v4l_compat>=1.0.20110603:multimedia/v4l_compat
-
-USES= libtool pathfix tar:bz2
+USES= libtool pathfix tar:bz2 evdev
GNU_CONFIGURE= yes
-CPPFLAGS+= -I${LOCALBASE}/include # v4l_compat
INSTALL_TARGET= install-strip
USE_LDCONFIG= yes
Index: devel/libmtdev/files/patch-test-mtdev-test.c
===================================================================
--- devel/libmtdev/files/patch-test-mtdev-test.c
+++ devel/libmtdev/files/patch-test-mtdev-test.c
@@ -0,0 +1,16 @@
+--- test/mtdev-test.c.orig 2014-02-28 22:48:23.000000000 +0400
++++ test/mtdev-test.c 2015-04-03 02:57:56.890923000 +0300
+@@ -28,11 +28,12 @@
+
+ #include <mtdev.h>
+ #include <stdio.h>
++#include <stdint.h>
+ #include <unistd.h>
+ #include <fcntl.h>
+
+ /* year-proof millisecond event time */
+-typedef __u64 mstime_t;
++typedef uint64_t mstime_t;
+
+ static int use_event(const struct input_event *ev)
+ {
Index: devel/py-evdev/Makefile
===================================================================
--- devel/py-evdev/Makefile
+++ devel/py-evdev/Makefile
@@ -1,7 +1,7 @@
# $FreeBSD$
PORTNAME= evdev
-PORTVERSION= 0.5.0
+PORTVERSION= 0.6.1
CATEGORIES= devel python
MASTER_SITES= CHEESESHOP
PKGNAMEPREFIX= ${PYTHON_PKGNAMEPREFIX}
@@ -12,15 +12,18 @@
LICENSE= BSD3CLAUSE
LICENSE_FILE= ${WRKSRC}/LICENSE
-BUILD_DEPENDS= v4l_compat>=1.0.20110603:multimedia/v4l_compat
-
-USES= python
+USES= python evdev
USE_PYTHON= autoplist distutils
-CPPFLAGS+= -I${LOCALBASE}/include # v4l_compat
-post-patch:
- @${REINPLACE_CMD} -e '/header/s,/usr,${LOCALBASE},' \
- ${WRKSRC}/${PYSETUP}
+EVDEV_INCLUDES= ${LOCALBASE}/include
+
+PYDISTUTILS_BUILD_TARGET= build_ext
+PYDISTUTILS_BUILDARGS+= --include-dirs ${EVDEV_INCLUDES}/ \
+ --evdev-headers ${EVDEV_INCLUDES}/linux/input.h:${EVDEV_INCLUDES}/linux/input-event-codes.h
+
+# Supply install target with evdev headers path
+PYDISTUTILS_INSTALL_TARGET= ${PYDISTUTILS_BUILD_TARGET} \
+ ${PYDISTUTILS_BUILDARGS} install
post-install:
${FIND} ${STAGEDIR}${PYTHONPREFIX_SITELIBDIR} \
Index: devel/py-evdev/distinfo
===================================================================
--- devel/py-evdev/distinfo
+++ devel/py-evdev/distinfo
@@ -1,2 +1,3 @@
-SHA256 (evdev-0.5.0.tar.gz) = 509f0f6ce5a12315fcad0b7f9b41cbdfc5c5f49a7cecdd6a88ce5c1d04f6827c
-SIZE (evdev-0.5.0.tar.gz) = 23931
+TIMESTAMP = 1469963738
+SHA256 (evdev-0.6.1.tar.gz) = 67b3c71461e5ce191a34cd4ec17f6b3d59e66f6013f98f84c2fba817b8738a3b
+SIZE (evdev-0.6.1.tar.gz) = 22034
Index: multimedia/v4l_compat/Makefile
===================================================================
--- multimedia/v4l_compat/Makefile
+++ multimedia/v4l_compat/Makefile
@@ -8,14 +8,15 @@
NO_BUILD= yes
NO_ARCH= yes
+RUN_DEPENDS= ${LOCALBASE}/include/linux/input.h:devel/libevdev-headers
+
MASTERDIR= ${.CURDIR}/../../multimedia/libv4l
EXTRADIR= ${WRKSRC}/../linux
DESCR= ${.CURDIR}/pkg-descr
PLIST= ${.CURDIR}/pkg-plist
LIBV4L_SLAVE= compat
-BASE_HEADERS= input.h uinput.h ivtv.h v4l2-controls.h \
- v4l2-common.h videodev2.h
+BASE_HEADERS= ivtv.h v4l2-controls.h v4l2-common.h videodev2.h
DVB_HEADERS= audio.h dmx.h frontend.h video.h
EXTRA_HEADERS= ca.h osd.h version.h
Index: multimedia/v4l_compat/pkg-plist
===================================================================
--- multimedia/v4l_compat/pkg-plist
+++ multimedia/v4l_compat/pkg-plist
@@ -5,9 +5,7 @@
include/linux/dvb/osd.h
include/linux/dvb/version.h
include/linux/dvb/video.h
-include/linux/input.h
include/linux/ivtv.h
-include/linux/uinput.h
include/linux/v4l2-common.h
include/linux/v4l2-controls.h
include/linux/videodev.h
Index: multimedia/webcamd/Makefile
===================================================================
--- multimedia/webcamd/Makefile
+++ multimedia/webcamd/Makefile
@@ -2,7 +2,7 @@
# $FreeBSD$
PORTNAME= webcamd
-PORTVERSION= 4.2.0.9
+PORTVERSION= 4.8.0.4
CATEGORIES= multimedia
MASTER_SITES= http://www.selasky.org/hans_petter/distfiles/ \
http://home.selasky.org:8192/distfiles/
@@ -21,7 +21,7 @@
SUB_FILES= webcamd.conf
USE_LDCONFIG= yes
-OPTIONS_DEFINE= CUSE DEBUG HAL VT_CLIENT VT_SERVER DVB INPUT RADIO WEBCAM
+OPTIONS_DEFINE= CUSE DEBUG HAL VT_CLIENT VT_SERVER DVB INPUT KEYBOARD MOUSE RADIO WEBCAM
OPTIONS_DEFAULT=DVB HAL INPUT RADIO WEBCAM
.if exists(/usr/lib/libcuse.so)
@@ -59,6 +59,12 @@
INPUT_DESC= Build with USB input support (tablet, joystick, HID, IR, ...)
INPUT_MAKE_ARGS= HAVE_INPUT_DRV="YES"
+KEYBOARD_DESC= Build with USB keyboard support
+KEYBOARD_MAKE_ARGS= HAVE_KEYBOARD_DRV="YES"
+
+MOUSE_DESC= Build with USB mouse support
+MOUSE_MAKE_ARGS= HAVE_MOUSE_DRV="YES"
+
RADIO_DESC= Build with USB radio support
RADIO_MAKE_ARGS= HAVE_RADIO_DRV="YES"
Index: multimedia/webcamd/distinfo
===================================================================
--- multimedia/webcamd/distinfo
+++ multimedia/webcamd/distinfo
@@ -1,2 +1,3 @@
-SHA256 (webcamd-4.2.0.9.tar.bz2) = b02958db281be2347b17db8a81604c49eb43802a5fa3a771cccc5904c9e36539
-SIZE (webcamd-4.2.0.9.tar.bz2) = 10983753
+TIMESTAMP = 1472287897
+SHA256 (webcamd-4.8.0.4.tar.bz2) = cab0166ef4df4e00ef775e4e527b1dee6e6b100c6ad002df72663e7ae8380d10
+SIZE (webcamd-4.8.0.4.tar.bz2) = 11700148
Index: x11-drivers/xf86-input-evdev/Makefile
===================================================================
--- x11-drivers/xf86-input-evdev/Makefile
+++ x11-drivers/xf86-input-evdev/Makefile
@@ -1,8 +1,7 @@
# $FreeBSD$
PORTNAME= xf86-input-evdev
-PORTVERSION= 2.9.2
-PORTREVISION= 1
+PORTVERSION= 2.10.3
CATEGORIES= x11-drivers
MAINTAINER= x11@FreeBSD.org
@@ -11,12 +10,10 @@
LICENSE= MIT # various styles
LICENSE_FILE= ${WRKSRC}/COPYING
-BUILD_DEPENDS= v4l_compat>=1.0.20110603:multimedia/v4l_compat
LIB_DEPENDS= libevdev.so:devel/libevdev
-RUN_DEPENDS= webcamd>=3.1.0.1:multimedia/webcamd
XORG_CAT= driver
-USES= pathfix
+USES= pathfix evdev
CONFIGURE_ENV= UDEV_CFLAGS=" " UDEV_LIBS=" "
INSTALL_TARGET= install-strip
Index: x11-drivers/xf86-input-evdev/distinfo
===================================================================
--- x11-drivers/xf86-input-evdev/distinfo
+++ x11-drivers/xf86-input-evdev/distinfo
@@ -1,2 +1,3 @@
-SHA256 (xorg/driver/xf86-input-evdev-2.9.2.tar.bz2) = 792329b531afc6928ccda94e4b51a5520d4ddf8ef9a00890a5d0d31898acefec
-SIZE (xorg/driver/xf86-input-evdev-2.9.2.tar.bz2) = 387095
+TIMESTAMP = 1467542089
+SHA256 (xorg/driver/xf86-input-evdev-2.10.3.tar.bz2) = 5aa21ba4be8df927e5676a99c7f4f0343abc089f5451b7e73e39536f29b332a2
+SIZE (xorg/driver/xf86-input-evdev-2.10.3.tar.bz2) = 404476
Index: x11-drivers/xf86-input-evdev/pkg-plist
===================================================================
--- x11-drivers/xf86-input-evdev/pkg-plist
+++ x11-drivers/xf86-input-evdev/pkg-plist
@@ -2,3 +2,4 @@
lib/xorg/modules/input/evdev_drv.so
libdata/pkgconfig/xorg-evdev.pc
man/man4/evdev.4x.gz
+share/X11/xorg.conf.d/10-evdev.conf
Index: x11-drivers/xf86-input-synaptics/Makefile
===================================================================
--- x11-drivers/xf86-input-synaptics/Makefile
+++ x11-drivers/xf86-input-synaptics/Makefile
@@ -1,17 +1,25 @@
# $FreeBSD$
PORTNAME= xf86-input-synaptics
-PORTVERSION= 1.8.2
-PORTREVISION= 1
+PORTVERSION= 1.8.99.1
CATEGORIES= x11-drivers
MAINTAINER= x11@FreeBSD.org
COMMENT= X.Org synaptics input driver
-CONFLICTS= synaptics-[0-9]*
+LICENSE= MIT
+LICENSE_FILE= ${WRKSRC}/COPYING
USES= pathfix
USE_XORG= x11 xtst
XORG_CAT= driver
+INSTALL_TARGET= install-strip
+
+.if exists(/usr/include/dev/evdev/input.h)
+CONFIGURE_ENV+= BUILD_EVENTCOMM=yes
+USES+= evdev
+LIB_DEPENDS+= libevdev.so:devel/libevdev
+.endif
+
.include <bsd.port.mk>
Index: x11-drivers/xf86-input-synaptics/distinfo
===================================================================
--- x11-drivers/xf86-input-synaptics/distinfo
+++ x11-drivers/xf86-input-synaptics/distinfo
@@ -1,2 +1,3 @@
-SHA256 (xorg/driver/xf86-input-synaptics-1.8.2.tar.bz2) = 7b0e164ebd02a680e0c695955e783059f37edb0c2656398e0a972adc8e698c80
-SIZE (xorg/driver/xf86-input-synaptics-1.8.2.tar.bz2) = 484261
+TIMESTAMP = 1470662930
+SHA256 (xorg/driver/xf86-input-synaptics-1.8.99.1.tar.bz2) = 4c895339fa10c4f97b27ab62d974cae2a96e19ae8d52f80ef0fa5c202c67ebaa
+SIZE (xorg/driver/xf86-input-synaptics-1.8.99.1.tar.bz2) = 500978
Index: x11-drivers/xf86-input-synaptics/files/patch-src_eventcomm.h
===================================================================
--- x11-drivers/xf86-input-synaptics/files/patch-src_eventcomm.h
+++ x11-drivers/xf86-input-synaptics/files/patch-src_eventcomm.h
@@ -0,0 +1,18 @@
+--- src/eventcomm.h.orig 2015-11-24 23:47:05 UTC
++++ src/eventcomm.h
+@@ -30,7 +30,15 @@
+ #include <xorg-server.h>
+
+ #include <linux/input.h>
++#ifdef __linux__
+ #include <linux/version.h>
++#else
++#undef BUS_NONE
++#undef BUS_PCI
++#undef BUS_SBUS
++#undef BUS_PLATFORM
++#undef BUS_last
++#endif
+ #include <xf86Xinput.h>
+ #include "synproto.h"
+
Index: x11-drivers/xf86-input-synaptics/files/patch-src_eventcomm.c
===================================================================
--- x11-drivers/xf86-input-synaptics/files/patch-src_eventcomm.c
+++ x11-drivers/xf86-input-synaptics/files/patch-src_eventcomm.c
@@ -0,0 +1,18 @@
+--- src/eventcomm.c.orig 2016-04-26 23:29:23 UTC
++++ src/eventcomm.c
+@@ -421,10 +421,15 @@ event_get_abs(struct libevdev *evdev, in
+ /* We dont trust a zero fuzz as it probably is just a lazy value */
+ if (fuzz && abs->fuzz > 0)
+ *fuzz = abs->fuzz;
++#ifdef __linux__
+ #if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,30)
+ if (res)
+ *res = abs->resolution;
+ #endif
++#elif defined(__FreeBSD__)
++ if (res)
++ *res = abs->resolution;
++#endif
+
+ return 0;
+ }
Index: x11-drivers/xf86-input-wacom/Makefile
===================================================================
--- x11-drivers/xf86-input-wacom/Makefile
+++ x11-drivers/xf86-input-wacom/Makefile
@@ -10,10 +10,9 @@
LICENSE= GPLv2+
-BUILD_DEPENDS= v4l_compat>=1.0.20110603:multimedia/v4l_compat
RUN_DEPENDS= webcamd>=3.1.0.1:multimedia/webcamd
-USES= tar:bzip2 pathfix pkgconfig libtool
+USES= tar:bzip2 pathfix pkgconfig libtool evdev
USE_XORG= xrandr xinerama
XORG_CAT= driver
USE_RC_SUBR= wacom
Index: x11-drivers/xf86-input-wacom/files/patch-src-wcmValidateDevice.c
===================================================================
--- x11-drivers/xf86-input-wacom/files/patch-src-wcmValidateDevice.c
+++ x11-drivers/xf86-input-wacom/files/patch-src-wcmValidateDevice.c
@@ -29,6 +29,15 @@
if (match)
xf86Msg(X_WARNING, "%s: device file already in use by %s. "
"Ignoring.\n", pInfo->name, pDevices->name);
+@@ -123,7 +124,7 @@ ret:
+ static struct
+ {
+ const char* type;
+- __u16 tool[3]; /* tool array is terminated by 0 */
++ uint16_t tool[3]; /* tool array is terminated by 0 */
+ } wcmType [] =
+ {
+ { "stylus", { BTN_TOOL_PEN, 0 } },
@@ -205,6 +206,10 @@ int wcmDeviceTypeKeys(InputInfoPtr pInfo
case 0x314: /* Intuos Pro S */
case 0x315: /* Intuos Pro M */
Index: x11-servers/xorg-server/files/patch-config_devd.c
===================================================================
--- x11-servers/xorg-server/files/patch-config_devd.c
+++ x11-servers/xorg-server/files/patch-config_devd.c
@@ -1,6 +1,6 @@
---- config/devd.c.orig 2015-05-19 19:41:49 UTC
-+++ config/devd.c
-@@ -0,0 +1,531 @@
+--- /dev/null 2016-08-20 16:05:18.000000000 +0300
++++ config/devd.c 2016-08-20 16:09:28.076064000 +0300
+@@ -0,0 +1,892 @@
+/*
+ * Copyright (c) 2012 Baptiste Daroussin
+ * Copyright (c) 2013, 2014 Alex Kozlov
@@ -33,20 +33,27 @@
+#include <dix-config.h>
+#endif
+
-+#include <sys/types.h>
++#include <sys/param.h>
++#include <sys/ioccom.h>
+#include <sys/kbio.h>
++#include <sys/queue.h>
+#include <sys/socket.h>
+#include <sys/stat.h>
+#include <sys/sysctl.h>
+#include <sys/un.h>
+
+#include <ctype.h>
++#include <dirent.h>
+#include <errno.h>
+#include <fcntl.h>
++#include <limits.h>
++#include <stddef.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdbool.h>
++#include <string.h>
+#include <unistd.h>
++#include <paths.h>
+
+#include "input.h"
+#include "inputstr.h"
@@ -56,260 +63,611 @@
+
+#define DEVD_SOCK_PATH "/var/run/devd.pipe"
+
-+#define DEVD_EVENT_ADD '+'
-+#define DEVD_EVENT_REMOVE '-'
-+
-+#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 bool is_kernel_evdev = false;
+OsTimerPtr rtimer;
+
+struct hw_type {
+ const char *driver;
+ int flag;
+ const char *xdriver;
++ const char *sysctldesc;
+};
+
-+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 },
++static const struct hw_type hw_types0[] = {
++ { _PATH_DEV "sysmouse", ATTR_POINTER, "mouse", NULL },
++ { _PATH_DEV "vboxguest", ATTR_POINTER, "vboxmouse", NULL },
++ { NULL, 0, NULL, NULL },
+};
+
-+static bool
-+sysctl_exists(const struct hw_type *device, int unit,
-+ char *devname, size_t devname_len)
++static const struct hw_type hw_types1[] = {
++ { _PATH_DEV "ukbd%d", ATTR_KEYBOARD, "kbd", "ukbd" },
++ { _PATH_DEV "atkbd%d", ATTR_KEYBOARD, "kbd", "atkbd" },
++ { _PATH_DEV "kbdmux%d", ATTR_KEYBOARD, "kbd", NULL },
++ { _PATH_DEV "ums%d", ATTR_POINTER, "mouse", "ums" },
++ { _PATH_DEV "psm%d", ATTR_POINTER, "mouse", "psm" },
++ { _PATH_DEV "joy%d", ATTR_JOYSTICK, "mouse", "joy" },
++ { _PATH_DEV "atp%d", ATTR_TOUCHPAD, "mouse", "atp" },
++ { _PATH_DEV "wsp%d", ATTR_TOUCHPAD, "mouse", "wsp" },
++ { _PATH_DEV "uep%d", ATTR_TOUCHSCREEN, "mouse", "uep" },
++ { _PATH_DEV "input/event%d", 0, "evdev", NULL },
++ { NULL, 0, NULL, NULL },
++};
++
++/* like basename() but returns a pointer to incoming string */
++static char *
++bname(const char *path)
+{
-+ char sysctlname[PATH_MAX];
-+ size_t len;
-+ int ret;
++ char *slash = NULL;
+
-+ if (device == NULL || device->driver == NULL)
-+ return false;
++ if (path != NULL)
++ slash = strrchr(path, '/');
++ return (slash == NULL) ? (char *)path : slash + 1;
++}
+
-+ /* Check if a sysctl exists. */
-+ snprintf(sysctlname, sizeof(sysctlname), "dev.%s.%i.%%desc",
-+ device->driver, unit);
-+ ret = sysctlbyname(sysctlname, NULL, &len, NULL, 0);
++struct dev_entry {
++ SLIST_ENTRY(dev_entry) next;
++ char name[];
++};
++SLIST_HEAD(dev_list, dev_entry);
+
-+ if (ret == 0 && len > 0) {
-+ snprintf(devname, devname_len, "%s%i", device->driver, unit);
-+ return true;
++#define dev_list_init(dev_list) SLIST_INIT(dev_list)
++#define dev_list_empty(dev_list) SLIST_EMPTY(dev_list)
++
++static void
++dev_list_insert(struct dev_list *devs, const char *dev_name)
++{
++ struct dev_entry *dev;
++
++ dev = malloc(offsetof(struct dev_entry, name) + strlen(dev_name) + 1);
++ if (dev != NULL) {
++ strcpy(dev->name, dev_name);
++ SLIST_INSERT_HEAD(devs, dev, next);
+ }
++}
+
-+ return false;
++static void
++dev_list_destroy(struct dev_list *devs)
++{
++ struct dev_entry *dev;
++
++ while (!SLIST_EMPTY(devs)) {
++ dev = SLIST_FIRST(devs);
++ SLIST_REMOVE_HEAD(devs, next);
++ free(dev);
++ }
+}
+
+static bool
-+devpath_exists(const struct hw_type *device,
-+ char *devname, size_t devname_len)
++dev_list_search(struct dev_list *devs, const char *dev_name)
+{
-+ char *devpath;
-+ struct stat st;
-+ int ret;
++ struct dev_entry *dev;
+
-+ if (device == NULL || device->driver == NULL)
-+ return false;
++ if (dev_name != NULL)
++ SLIST_FOREACH(dev, devs, next)
++ if (strcmp(dev_name, dev->name) == 0)
++ return true;
++ return false;
++}
+
-+ /* Check if /dev/$driver exists. */
-+ asprintf(&devpath, "/dev/%s", device->driver);
-+ if (devpath == NULL)
-+ return false;
++/* Some definitions from linux/input.h */
++struct input_id {
++ uint16_t bustype;
++ uint16_t vendor;
++ uint16_t product;
++ uint16_t version;
++};
+
-+ ret = stat(devpath, &st);
-+ free(devpath);
++#define EVIOCGBIT(ev,len) _IOC(IOC_OUT, 'E', 0x20 + (ev), len)
++#define EVIOCGID _IOR('E', 0x02, struct input_id)
++#define EVIOCGNAME(len) _IOC(IOC_OUT, 'E', 0x06, len)
++#define EVIOCGPHYS(len) _IOC(IOC_OUT, '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 LONG_BITS (sizeof(long) * 8)
++#define NLONGS(x) (((x) + LONG_BITS - 1) / LONG_BITS)
+
-+ if (ret == 0) {
-+ strncpy(devname, device->driver, devname_len);
-+ return true;
-+ }
++static inline bool
++bit_is_set(const unsigned long *array, int bit)
++{
++ return !!(array[bit / LONG_BITS] & (1LL << (bit % LONG_BITS)));
++}
++
++static inline bool
++bit_find(const unsigned long *array, int start, int stop)
++{
++ int i;
++
++ for (i = start; i < stop; i++)
++ if (bit_is_set(array, i))
++ return true;
+
+ return false;
+}
+
-+static char *
-+sysctl_get_str(const char *sysctlname)
++/*
++ * Event device type detection routine.
++ * Derived from EvdevProbe() function of xf86-input-evdev driver
++ */
++static void
++get_evdev_attrs(InputAttributes *attrs, const char *devicename)
+{
-+ char *dest = NULL;
-+ size_t len;
++ int fd, flags;
++ bool has_keys, has_buttons, has_lmr;
++ bool has_rel_axes, has_abs_axes, has_mt;
++ unsigned long key_bits[NLONGS(KEY_CNT)];
++ unsigned long rel_bits[NLONGS(REL_CNT)];
++ unsigned long abs_bits[NLONGS(ABS_CNT)];
++ struct input_id id;
++ char name[80];
++ char *walk;
+
-+ if (sysctlname == NULL)
-+ return NULL;
++ flags = 0;
+
-+ 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;
++ fd = open(devicename, O_RDONLY | O_CLOEXEC);
++ if (fd < 0)
++ goto out;
++ if (ioctl(fd, EVIOCGNAME(sizeof(name) - 1), name) < 0 ||
++ ioctl(fd, EVIOCGID, &id) < 0 ||
++ ioctl(fd, EVIOCGBIT(EV_REL, sizeof(rel_bits)), rel_bits) < 0 ||
++ ioctl(fd, EVIOCGBIT(EV_ABS, sizeof(abs_bits)), abs_bits) < 0 ||
++ ioctl(fd, EVIOCGBIT(EV_KEY, sizeof(key_bits)), key_bits) < 0) {
++ close(fd);
++ goto out;
++ }
++ close(fd);
++
++ if ((walk = strchr(name, ',')) != NULL)
++ *walk = '\0'; /* strip name */
++
++ attrs->product = strdup(name);
++ asprintf(&attrs->usb_id, "%04x:%04x", id.vendor, id.product);
++ asprintf(&attrs->vendor, "0x%04x", id.vendor);
++
++ has_keys = bit_find(key_bits, 0, BTN_MISC);
++ has_buttons = bit_find(key_bits, BTN_MISC, BTN_JOYSTICK);
++ has_lmr = bit_find(key_bits, BTN_LEFT, BTN_MIDDLE + 1);
++ has_rel_axes = bit_find(rel_bits, 0, REL_CNT);
++ has_abs_axes = bit_find(abs_bits, 0, ABS_CNT);
++ has_mt = bit_find(abs_bits, ABS_MT_SLOT, ABS_CNT);
++
++ if (has_abs_axes) {
++ if (has_mt) {
++ if (!has_buttons) {
++ /*
++ * XXX: I'm not sure that joystick detection is
++ * done right. xf86-evdev does not support them.
++ */
++ if (bit_is_set(key_bits, BTN_JOYSTICK)) {
++ flags = ATTR_JOYSTICK;
++ goto out;
++ } else {
++ has_buttons = true;
++ }
++ }
++ }
++
++ if (bit_is_set(abs_bits, ABS_X) &&
++ bit_is_set(abs_bits, ABS_Y)) {
++ if (bit_is_set(key_bits, BTN_TOOL_PEN) ||
++ bit_is_set(key_bits, BTN_STYLUS) ||
++ bit_is_set(key_bits, BTN_STYLUS2)) {
++ flags = ATTR_TABLET;
++ goto out;
++ } else if (bit_is_set(abs_bits, ABS_PRESSURE) ||
++ bit_is_set(key_bits, BTN_TOUCH)) {
++ if (has_lmr ||
++ bit_is_set(key_bits, BTN_TOOL_FINGER)) {
++ flags = ATTR_TOUCHPAD;
++ } else {
++ flags = ATTR_TOUCHSCREEN;
++ }
++ goto out;
++ } else if (!(bit_is_set(rel_bits, REL_X) &&
++ bit_is_set(rel_bits, REL_Y)) &&
++ has_lmr) {
++ /* some touchscreens use BTN_LEFT rather than BTN_TOUCH */
++ flags = ATTR_TOUCHSCREEN;
++ goto out;
+ }
+ }
+ }
+
-+ return dest;
++ if (has_keys)
++ flags = ATTR_KEYBOARD;
++ else if (has_rel_axes || has_abs_axes || has_buttons)
++ flags = ATTR_POINTER;
++
++out:
++ attrs->flags |= flags;
+}
+
++/* Returns list of devices supporting evdev protocol */
+static void
-+device_added(const char *devname)
++get_evdev_blacklist(struct dev_list *devs)
+{
-+ char path[PATH_MAX];
-+ char sysctlname[PATH_MAX];
-+ char *vendor;
-+ char *product = NULL;
-+ char *config_info = NULL;
-+ char *walk;
-+ InputOption *options = NULL;
-+ InputAttributes attrs = { };
-+ DeviceIntPtr dev = NULL;
-+ int i;
++ struct dirent *entry;
++ DIR *dp;
++ static const char ev_dir[] = _PATH_DEV "input";
++#define EV_LEN nitems(ev_dir)
++ char path[PATH_MAX + 1];
++ char phys[80];
+ int fd;
+
-+ for (i = 0; hw_types[i].driver != NULL; i++) {
-+ size_t len;
++ snprintf(path, sizeof(path), "%s/", ev_dir);
++ if ((dp = opendir(ev_dir)) == NULL)
++ return;
+
-+ 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;
-+ }
++ while ((entry = readdir(dp)) != NULL) {
++ if (entry->d_type != DT_CHR)
++ continue;
++ if (strncmp(entry->d_name, "event", 5) != 0)
++ continue;
++ strlcpy(path + EV_LEN, entry->d_name, sizeof(path) - EV_LEN);
++ fd = open(path, O_RDONLY | O_CLOEXEC);
++ if (fd < 0)
++ continue;
++ /* XXX: Should uinput- and cuse-backed devices be skipped? */
++ if (ioctl(fd, EVIOCGPHYS(sizeof(phys) - 1), phys) == 0 &&
++ phys[0] != 0)
++ dev_list_insert(devs, bname(phys));
++ close(fd);
+ }
++ closedir(dp);
++ return;
++}
+
-+ if (hw_types[i].driver == NULL || hw_types[i].xdriver == NULL) {
-+ LogMessage(X_INFO, "config/devd: ignoring device %s\n",
-+ devname);
-+ return;
++static void
++get_usb_id(char **pptr, int fd)
++{
++ unsigned short vendor;
++ unsigned short product;
++ unsigned int speed;
++#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)
++ if (ioctl(fd, WEBCAMD_IOCTL_GET_USB_VENDOR_ID, &vendor) == 0 &&
++ ioctl(fd, WEBCAMD_IOCTL_GET_USB_PRODUCT_ID, &product) == 0 &&
++ ioctl(fd, WEBCAMD_IOCTL_GET_USB_SPEED, &speed) == 0) {
++ if (asprintf(pptr, "%04x:%04x", vendor, product) == -1)
++ *pptr = NULL;
+ }
++}
+
-+ /* Skip keyboard devices if kbdmux is enabled */
-+ if (is_kbdmux && is_console_kbd && hw_types[i].flag & ATTR_KEYBOARD) {
-+ LogMessage(X_INFO, "config/devd: kbdmux is enabled, ignoring device %s\n",
-+ devname);
-+ return;
-+ }
++static char *
++get_prop_value(const char *buf, const char *prop, size_t *len)
++{
++ char *prop_pos, *val_pos, *walk;
++ size_t prop_len;
+
-+ snprintf(path, sizeof(path), "/dev/%s", devname);
++ prop_len = strlen(prop);
++ prop_pos = strstr(buf, prop);
++ if (prop_pos == NULL ||
++ (prop_pos != buf && prop_pos[-1] != ' ') ||
++ prop_pos[prop_len] != '=')
++ return (NULL);
++
++ val_pos = prop_pos + prop_len + 1;
++ if ((walk = strchr(val_pos, ' ')) == NULL)
++ *len = strlen(val_pos);
++ else
++ *len = walk - val_pos;
++ return (val_pos);
++}
+
-+ options = input_option_new(NULL, "_source", "server/devd");
-+ if (!options)
++static void
++get_sysctl_attrs(InputAttributes *attrs, const char* driver, int unit)
++{
++ char mib[32], name[80], pnpinfo[1024], *pnp_id, *walk;
++ const char *vendorstr, *prodstr, *devicestr;
++ size_t len, vendorlen, prodlen, devicelen, pnplen;
++ uint32_t product, vendor;
++
++ snprintf(mib, sizeof(mib), "dev.%s.%d.%%desc", driver, unit);
++ len = sizeof(name);
++ if (sysctlbyname(mib, name, &len, NULL, 0) < 0)
++ return;
++ if ((walk = strchr(name, ',')) != NULL)
++ *walk = '\0'; /* strip name */
++ attrs->product = strdup(name);
++
++ snprintf(mib, sizeof(mib), "dev.%s.%d.%%pnpinfo", driver, unit);
++ len = sizeof(pnpinfo);
++ if (sysctlbyname(mib, pnpinfo, &len, NULL, 0) < 0)
+ 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';
-+ }
++ vendorstr = get_prop_value(pnpinfo, "vendor", &vendorlen);
++ prodstr = get_prop_value(pnpinfo, "product", &prodlen);
++ devicestr = get_prop_value(pnpinfo, "device", &devicelen);
++ pnp_id = get_prop_value(pnpinfo, "_HID", &pnplen);
++ if (pnp_id != NULL && pnplen == 4 && strncmp(pnp_id, "none", 4) == 0)
++ pnp_id = NULL;
++ if (pnp_id != NULL) {
++ pnp_id[pnplen] = '\0';
++ attrs->pnp_id = strdup(pnp_id);
++ }
++ if (prodstr != NULL && vendorstr != NULL) {
++ /* bus = BUS_USB; */
++ vendor = strtol(vendorstr, NULL, 0);
++ product = strtol(prodstr, NULL, 0);
++ } else if (devicestr != NULL && vendorstr != NULL) {
++ /* bus = BUS_PCI; */
++ vendor = strtol(vendorstr, NULL, 0);
++ product = strtol(devicestr, NULL, 0);
++ } else
++ return;
+
-+ 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)");
++ asprintf(&attrs->usb_id, "%04x:%04x", vendor, product);
++ asprintf(&attrs->vendor, "0x%04x", vendor);
+
-+ free(vendor);
-+ }
++ return;
++}
+
-+ /* XXX implement usb_id */
-+ attrs.usb_id = NULL;
-+ attrs.device = strdup(path);
-+ options = input_option_new(options, "driver", hw_types[i].xdriver);
++static const char *
++skip_path_dev(const char *ptr)
++{
++ if (strstr(ptr, _PATH_DEV) == ptr)
++ ptr += strlen(_PATH_DEV);
++ return (ptr);
++}
+
-+ fd = open(path, O_RDONLY);
-+ if (fd > 0) {
-+ close(fd);
-+ options = input_option_new(options, "device", path);
++static void
++device_added(const char *devicename, struct dev_list *blacklist)
++{
++ InputAttributes attrs = { };
++ InputOption *options = NULL;
++ char *config_info = NULL;
++ DeviceIntPtr dev = NULL;
++ struct hw_type hw_type;
++ int unit = 0;
++ int fd = -1;
++ int i;
++ bool allow_no_device = false;
++
++ for (i = 0; hw_types0[i].driver != NULL; i++) {
++ if (strcmp(devicename, hw_types0[i].driver) == 0) {
++ hw_type = hw_types0[i];
++ goto found;
++ }
++ }
++ for (i = 0; hw_types1[i].driver != NULL; i++) {
++ if (sscanf(devicename, hw_types1[i].driver, &unit) == 1) {
++ hw_type = hw_types1[i];
++ goto found;
++ }
+ }
-+ else {
-+ if (attrs.flags & ~ATTR_KEYBOARD) {
-+ LogMessage(X_INFO, "config/devd: device %s already opened\n",
-+ path);
++ goto ignore;
+
++found:
++ if (hw_type.xdriver == NULL)
++ goto ignore;
++
++ /* set flags, if any */
++ attrs.flags |= hw_type.flag;
++
++ if (strcmp(hw_type.xdriver, "evdev") == 0) {
++ get_evdev_attrs(&attrs, devicename);
++ /* Set keyboard rules explicitly for libinput */
++ if (attrs.flags & ATTR_KEYBOARD) {
++ options = input_option_new(options, "xkb_rules",
++ "evdev");
++ if (options == NULL)
++ goto error;
++ }
++ } else {
++ if (is_kernel_evdev) {
++ if (dev_list_empty(blacklist))
++ get_evdev_blacklist(blacklist);
+ /*
-+ * Fail if cannot open device, it breaks AllowMouseOpenFail,
-+ * but it should not matter when config/devd enabled
++ * Prefer evdev input kernel interface to native one.
++ * Assume that both evdev 'physical path' and non-evdev
++ * character device path endings are device names so
++ * we can compare them and skip latter.
+ */
-+ goto unwind;
++ if (dev_list_search(blacklist, bname(devicename)))
++ goto ignore;
+ }
++ }
+
-+ if (is_console_kbd) {
-+ /*
-+ * 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;
++ if (strcmp(hw_type.xdriver, "kbd") == 0) {
++ bool match = (strstr(hw_type.driver,
++ _PATH_DEV "kbdmux") == hw_type.driver);
++
++ if (is_kbdmux) {
++ allow_no_device = true;
++ if (!match)
++ goto ignore;
++ } else {
++ if (match)
++ goto ignore;
+ }
-+ 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;
+ }
+
-+ if (asprintf(&config_info, "devd:%s", devname) == -1) {
++ options = input_option_new(options, "_source", "server/devd");
++ if (options == NULL)
++ goto error;
++
++ if (hw_type.sysctldesc != NULL)
++ get_sysctl_attrs(&attrs, hw_type.sysctldesc, unit);
++
++ if (attrs.product == NULL)
++ attrs.product = strdup(skip_path_dev(devicename));
++
++ options = input_option_new(options, "name", attrs.product);
++ if (options == NULL)
++ goto error;
++
++ attrs.device = strdup(devicename);
++
++ fd = open(devicename, O_RDONLY);
++ if (fd > -1) {
++ if (attrs.usb_id == NULL)
++ get_usb_id(&attrs.usb_id, fd);
++ close(fd);
++ options = input_option_new(options, "device", devicename);
++ if (options == NULL)
++ goto error;
++ } else if (allow_no_device) {
++ /*
++ * 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.
++ */
++ } else {
++ goto ignore;
++ }
++
++ options = input_option_new(options, "driver", hw_type.xdriver);
++ if (options == NULL)
++ goto error;
++
++ if (asprintf(&config_info, "devd:%s",
++ skip_path_dev(devicename)) == -1) {
+ config_info = NULL;
-+ goto unwind;
++ goto error;
+ }
+
-+ if (device_is_duplicate(config_info)) {
-+ LogMessage(X_WARNING, "config/devd: device %s (%s) already added. "
-+ "ignoring\n", attrs.product, path);
-+ goto unwind;
-+ }
++ if (device_is_duplicate(config_info))
++ goto duplicate;
+
+ options = input_option_new(options, "config_info", config_info);
-+ LogMessage(X_INFO, "config/devd: adding input device %s (%s)\n",
-+ attrs.product, path);
++ if (options == NULL)
++ goto error;
++
++ LogMessage(X_INFO, "config/devd: adding input device '%s'\n",
++ devicename);
+
+ NewInputDeviceRequest(options, &attrs, &dev);
++ goto done;
++
++duplicate:
++ LogMessage(X_WARNING, "config/devd: device '%s' already "
++ "added. Ignoring\n", devicename);
++ goto done;
++
++error:
++ LogMessage(X_INFO, "config/devd: error adding device '%s'\n",
++ devicename);
++ goto done;
++
++ignore:
++ LogMessage(X_INFO, "config/devd: ignoring device '%s'\n",
++ devicename);
++ goto done;
+
-+unwind:
++done:
+ free(config_info);
+ input_option_free_list(&options);
+ free(attrs.usb_id);
++ free(attrs.pnp_id);
+ free(attrs.product);
+ free(attrs.device);
+ free(attrs.vendor);
+}
+
+static void
-+device_removed(char *devname)
++devpath_scan_sub(char *path, int off, int rem, void *udata)
++{
++ struct dirent *entry;
++ DIR *dp;
++
++ if ((dp = opendir(path)) == NULL) {
++ LogMessage(X_INFO, "Cannot open directory '%s'\n", path);
++ return;
++ }
++ while ((entry = readdir(dp)) != NULL) {
++ int len = strlen(entry->d_name);
++ if (len > rem)
++ continue;
++ strcpy(path + off, entry->d_name);
++ off += len;
++ rem -= len;
++ switch (entry->d_type) {
++ case DT_DIR:
++ if (strcmp(entry->d_name, ".") == 0 ||
++ strcmp(entry->d_name, "..") == 0)
++ break;
++ if (rem < 1)
++ break;
++ path[off] = '/';
++ path[off+1] = '\0';
++ off++;
++ rem--;
++ /* recurse */
++ devpath_scan_sub(path, off, rem, udata);
++ off--;
++ rem++;
++ break;
++ case DT_SOCK:
++ case DT_FIFO:
++ case DT_LNK:
++ case DT_CHR:
++ /* add device, if any */
++ device_added(path, udata);
++ break;
++ default:
++ break;
++ }
++ off -= len;
++ rem += len;
++ }
++ closedir(dp);
++}
++
++static void
++devpath_scan(void *udata)
++{
++ char path[PATH_MAX + 1];
++
++ strlcpy(path, _PATH_DEV, sizeof(path));
++
++ devpath_scan_sub(path, strlen(path), PATH_MAX - strlen(path), udata);
++}
++
++static void
++device_removed(char *devicename)
+{
+ char *config_info;
+
-+ if (asprintf(&config_info, "devd:%s", devname) == -1)
++ if (asprintf(&config_info, "devd:%s",
++ skip_path_dev(devicename)) == -1)
+ return;
+
++ if (device_is_duplicate(config_info)) {
++ LogMessage(X_INFO, "config/devd: removing input device '%s'\n",
++ devicename);
++ }
+ remove_devices("devd", config_info);
+
+ free(config_info);
@@ -318,8 +676,7 @@
+static bool is_kbdmux_enabled(void)
+{
+ /* Xorg uses /dev/ttyv0 as a console device */
-+ /* const char device[]="/dev/console"; */
-+ const char device[]="/dev/ttyv0";
++ static const char device[]= { _PATH_DEV "ttyv0" };
+ keyboard_info_t info;
+ int fd;
+
@@ -377,7 +734,7 @@
+}
+
+static CARD32
-+reconnect_handler(OsTimerPtr timer, CARD32 time, void *arg)
++reconnect_handler(OsTimerPtr timer, CARD32 unused_time, void *arg)
+{
+ int newsock;
+
@@ -448,8 +805,13 @@
+static void
+wakeup_handler(void *data, int err, void *read_mask)
+{
++ static const char cdev_create[] = { "!system=DEVFS subsystem=CDEV type=CREATE cdev=" };
++ static const char cdev_destroy[] = { "!system=DEVFS subsystem=CDEV type=DESTROY cdev=" };
++ static const char cdev_path[] = { _PATH_DEV };
+ char *line = NULL;
++ char *devicename;
+ char *walk;
++ struct dev_list blacklist;
+
+ if (err < 0)
+ return;
@@ -457,20 +819,23 @@
+ if (FD_ISSET(sock_devd, (fd_set *) read_mask)) {
+ if (socket_getline(sock_devd, &line) < 0)
+ return;
-+
-+ walk = strchr(line + 1, ' ');
-+ if (walk != NULL)
-+ walk[0] = '\0';
-+
-+ switch (*line) {
-+ case DEVD_EVENT_ADD:
-+ device_added(line + 1);
-+ break;
-+ case DEVD_EVENT_REMOVE:
-+ device_removed(line + 1);
-+ break;
-+ default:
-+ break;
++ if (strstr(line, cdev_create) == line) {
++ devicename = line + strlen(cdev_create) - strlen(cdev_path);
++ memcpy(devicename, cdev_path, strlen(cdev_path));
++ walk = strchr(devicename, ' ');
++ if (walk != NULL)
++ walk[0] = '\0';
++ /* Blacklist is lazy-populated in device_added() */
++ dev_list_init(&blacklist);
++ device_added(devicename, &blacklist);
++ dev_list_destroy(&blacklist);
++ } else if (strstr(line, cdev_destroy) == line) {
++ devicename = line + strlen(cdev_destroy) - strlen(cdev_path);
++ memcpy(devicename, cdev_path, strlen(cdev_path));
++ walk = strchr(devicename, ' ');
++ if (walk != NULL)
++ walk[0] = '\0';
++ device_removed(devicename);
+ }
+ free(line);
+ }
@@ -484,34 +849,31 @@
+int
+config_devd_init(void)
+{
-+ char devicename[1024];
-+ int i, j;
++ struct dev_list blacklist;
+
+ LogMessage(X_INFO, "config/devd: probing input devices...\n");
+
-+ /*
-+ * Add fake keyboard and give up on keyboards management
-+ * if kbdmux is enabled
-+ */
-+ if ((is_kbdmux = is_kbdmux_enabled()) == true)
-+ device_added("kbdmux");
-+
-+ 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);
-+ }
++ /* Blacklist is lazy-populated in device_added() */
++ dev_list_init(&blacklist);
+
-+ if (devpath_exists(&hw_types[i], devicename, sizeof(devicename)) != 0)
-+ device_added(devicename);
-+ }
++ /* Check if kbdmux is enabled */
++ is_kbdmux = is_kbdmux_enabled();
+
++ /* Check if evdev support is compiled into kernel */
++ is_kernel_evdev = feature_present("evdev") != 0;
++
++ /* Connect to devd, so that we don't loose any events */
+ if ((sock_devd = connect_devd()) < 0)
+ return 0;
+
-+ RegisterBlockAndWakeupHandlers(block_handler, wakeup_handler, NULL);
++ /* Scan what is currently connected */
++ devpath_scan(&blacklist);
++
++ /* Register wakeup handler */
++ RegisterBlockAndWakeupHandlers(block_handler,
++ wakeup_handler, NULL);
++
++ dev_list_destroy(&blacklist);
+
+ return 1;
+}
@@ -528,7 +890,6 @@
+
+ disconnect_devd(sock_devd);
+
-+ RemoveBlockAndWakeupHandlers(block_handler, wakeup_handler, NULL);
-+
-+ is_console_kbd = false;
++ RemoveBlockAndWakeupHandlers(block_handler,
++ wakeup_handler, NULL);
+}

File Metadata

Mime Type
text/plain
Expires
Tue, Nov 18, 8:44 AM (21 h, 32 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
25494209
Default Alt Text
D7588.id19748.diff (57 KB)

Event Timeline