Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F136348189
D7588.id19748.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
57 KB
Referenced Files
None
Subscribers
None
D7588.id19748.diff
View Options
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
Details
Attached
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)
Attached To
Mode
D7588: Ports support for coming input events interface
Attached
Detach File
Event Timeline
Log In to Comment