diff --git a/COPYING b/COPYING index 16f959a9d6867d9e851a800926cb18b8b1a19e81..1974905b99e7d0d112560a0ccd5f83cf50f7c7a2 100644 --- a/COPYING +++ b/COPYING @@ -1,23 +1,26 @@ +SPDX-License-Identifier: MIT + Copyright © 2013 Red Hat, Inc. Copyright © 2013 David Herrmann -Permission to use, copy, modify, distribute, and sell this software and its -documentation for any purpose is hereby granted without fee, provided that -the above copyright notice appear in all copies and that both that copyright -notice and this permission notice appear in supporting documentation, and -that the name of the copyright holders not be used in advertising or -publicity pertaining to distribution of the software without specific, -written prior permission. The copyright holders make no representations -about the suitability of this software for any purpose. It is provided "as -is" without express or implied warranty. +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to +deal in the Software without restriction, including without limitation the +rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +sell copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice (including the next +paragraph) shall be included in all copies or substantial portions of the +Software. -THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, -INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO -EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR -CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, -DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER -TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE -OF THIS SOFTWARE. +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +IN THE SOFTWARE. The following license is from a Linux kernel header file and there is no GPL code this package links to. diff --git a/Makefile.in b/Makefile.in new file mode 100644 index 0000000000000000000000000000000000000000..dfd33c57f5d7b4700018e0208e998459bd0d22ee --- /dev/null +++ b/Makefile.in @@ -0,0 +1,911 @@ +# Makefile.in generated by automake 1.16.5 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2021 Free Software Foundation, Inc. + +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +VPATH = @srcdir@ +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +subdir = . +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/attributes.m4 \ + $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ + $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ + $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(top_srcdir)/configure \ + $(am__configure_deps) $(am__DIST_COMMON) +am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \ + configure.lineno config.status.lineno +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = config.h +CONFIG_CLEAN_FILES = libevdev.pc +CONFIG_CLEAN_VPATH_FILES = +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +SOURCES = +DIST_SOURCES = +RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ + ctags-recursive dvi-recursive html-recursive info-recursive \ + install-data-recursive install-dvi-recursive \ + install-exec-recursive install-html-recursive \ + install-info-recursive install-pdf-recursive \ + install-ps-recursive install-recursive installcheck-recursive \ + installdirs-recursive pdf-recursive ps-recursive \ + tags-recursive uninstall-recursive +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; +am__install_max = 40 +am__nobase_strip_setup = \ + srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` +am__nobase_strip = \ + for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" +am__nobase_list = $(am__nobase_strip_setup); \ + for p in $$list; do echo "$$p $$p"; done | \ + sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ + $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ + if (++n[$$2] == $(am__install_max)) \ + { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ + END { for (dir in files) print dir, files[dir] }' +am__base_list = \ + sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ + sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' +am__uninstall_files_from_dir = { \ + test -z "$$files" \ + || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ + || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ + $(am__cd) "$$dir" && rm -f $$files; }; \ + } +am__installdirs = "$(DESTDIR)$(pkgconfigdir)" +DATA = $(pkgconfig_DATA) +RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ + distclean-recursive maintainer-clean-recursive +am__recursive_targets = \ + $(RECURSIVE_TARGETS) \ + $(RECURSIVE_CLEAN_TARGETS) \ + $(am__extra_recursive_targets) +AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ + cscope distdir distdir-am dist dist-all distcheck +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) \ + config.h.in +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates. Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ + BEGIN { nonempty = 0; } \ + { items[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique. This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ + list='$(am__tagged_files)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` +DIST_SUBDIRS = $(SUBDIRS) +am__DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/config.h.in \ + $(srcdir)/libevdev.pc.in $(top_srcdir)/build-aux/compile \ + $(top_srcdir)/build-aux/config.guess \ + $(top_srcdir)/build-aux/config.sub \ + $(top_srcdir)/build-aux/install-sh \ + $(top_srcdir)/build-aux/ltmain.sh \ + $(top_srcdir)/build-aux/missing COPYING README.md \ + build-aux/compile build-aux/config.guess build-aux/config.sub \ + build-aux/install-sh build-aux/ltmain.sh build-aux/missing +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +distdir = $(PACKAGE)-$(VERSION) +top_distdir = $(distdir) +am__remove_distdir = \ + if test -d "$(distdir)"; then \ + find "$(distdir)" -type d ! -perm -200 -exec chmod u+w {} ';' \ + && rm -rf "$(distdir)" \ + || { sleep 5 && rm -rf "$(distdir)"; }; \ + else :; fi +am__post_remove_distdir = $(am__remove_distdir) +am__relativize = \ + dir0=`pwd`; \ + sed_first='s,^\([^/]*\)/.*$$,\1,'; \ + sed_rest='s,^[^/]*/*,,'; \ + sed_last='s,^.*/\([^/]*\)$$,\1,'; \ + sed_butlast='s,/*[^/]*$$,,'; \ + while test -n "$$dir1"; do \ + first=`echo "$$dir1" | sed -e "$$sed_first"`; \ + if test "$$first" != "."; then \ + if test "$$first" = ".."; then \ + dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ + dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ + else \ + first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ + if test "$$first2" = "$$first"; then \ + dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ + else \ + dir2="../$$dir2"; \ + fi; \ + dir0="$$dir0"/"$$first"; \ + fi; \ + fi; \ + dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ + done; \ + reldir="$$dir2" +GZIP_ENV = --best +DIST_ARCHIVES = $(distdir).tar.xz +DIST_TARGETS = dist-xz +# Exists only to be overridden by the user if desired. +AM_DISTCHECK_DVI_TARGET = dvi +distuninstallcheck_listfiles = find . -type f -print +am__distuninstallcheck_listfiles = $(distuninstallcheck_listfiles) \ + | sed 's|^\./|$(prefix)/|' | grep -v '$(infodir)/dir$$' +distcleancheck_listfiles = find . -type f -print +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CHECK_CFLAGS = @CHECK_CFLAGS@ +CHECK_LIBS = @CHECK_LIBS@ +CPPFLAGS = @CPPFLAGS@ +CSCOPE = @CSCOPE@ +CTAGS = @CTAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DOXYGEN = @DOXYGEN@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +ETAGS = @ETAGS@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +GCC_CFLAGS = @GCC_CFLAGS@ +GCOV_CFLAGS = @GCOV_CFLAGS@ +GCOV_LDFLAGS = @GCOV_LDFLAGS@ +GNU_LD_FLAGS = @GNU_LD_FLAGS@ +GREP = @GREP@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBEVDEV_LT_VERSION = @LIBEVDEV_LT_VERSION@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OS = @OS@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PKG_CONFIG = @PKG_CONFIG@ +PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ +PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ +PYTHON = @PYTHON@ +PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ +PYTHON_PLATFORM = @PYTHON_PLATFORM@ +PYTHON_PREFIX = @PYTHON_PREFIX@ +PYTHON_VERSION = @PYTHON_VERSION@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +VALGRIND = @VALGRIND@ +VERSION = @VERSION@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +pkgpyexecdir = @pkgpyexecdir@ +pkgpythondir = @pkgpythondir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +pyexecdir = @pyexecdir@ +pythondir = @pythondir@ +runstatedir = @runstatedir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +ACLOCAL_AMFLAGS = -I m4 ${ACLOCAL_FLAGS} +PRINT_DIRECTORY_FLAGS_1 = +PRINT_DIRECTORY_FLAGS_0 = --no-print-directory +PRINT_DIRECTORY_FLAGS_ = $(PRINT_DIRECTORY_FLAGS_$(AM_DEFAULT_VERBOSITY)) +AM_MAKEFLAGS = $(PRINT_DIRECTORY_FLAGS_$(V)) +SUBDIRS = doc libevdev tools test +pkgconfigdir = $(libdir)/pkgconfig +pkgconfig_DATA = libevdev.pc +EXTRA_DIST = libevdev.pc.in meson.build meson_options.txt +all: config.h + $(MAKE) $(AM_MAKEFLAGS) all-recursive + +.SUFFIXES: +am--refresh: Makefile + @: +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + echo ' cd $(srcdir) && $(AUTOMAKE) --foreign'; \ + $(am__cd) $(srcdir) && $(AUTOMAKE) --foreign \ + && exit 0; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --foreign Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + echo ' $(SHELL) ./config.status'; \ + $(SHELL) ./config.status;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__maybe_remake_depfiles)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__maybe_remake_depfiles);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + $(SHELL) ./config.status --recheck + +$(top_srcdir)/configure: $(am__configure_deps) + $(am__cd) $(srcdir) && $(AUTOCONF) +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + $(am__cd) $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS) +$(am__aclocal_m4_deps): + +config.h: stamp-h1 + @test -f $@ || rm -f stamp-h1 + @test -f $@ || $(MAKE) $(AM_MAKEFLAGS) stamp-h1 + +stamp-h1: $(srcdir)/config.h.in $(top_builddir)/config.status + @rm -f stamp-h1 + cd $(top_builddir) && $(SHELL) ./config.status config.h +$(srcdir)/config.h.in: $(am__configure_deps) + ($(am__cd) $(top_srcdir) && $(AUTOHEADER)) + rm -f stamp-h1 + touch $@ + +distclean-hdr: + -rm -f config.h stamp-h1 +libevdev.pc: $(top_builddir)/config.status $(srcdir)/libevdev.pc.in + cd $(top_builddir) && $(SHELL) ./config.status $@ + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +distclean-libtool: + -rm -f libtool config.lt +install-pkgconfigDATA: $(pkgconfig_DATA) + @$(NORMAL_INSTALL) + @list='$(pkgconfig_DATA)'; test -n "$(pkgconfigdir)" || list=; \ + if test -n "$$list"; then \ + echo " $(MKDIR_P) '$(DESTDIR)$(pkgconfigdir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(pkgconfigdir)" || exit 1; \ + fi; \ + for p in $$list; do \ + if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ + echo "$$d$$p"; \ + done | $(am__base_list) | \ + while read files; do \ + echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(pkgconfigdir)'"; \ + $(INSTALL_DATA) $$files "$(DESTDIR)$(pkgconfigdir)" || exit $$?; \ + done + +uninstall-pkgconfigDATA: + @$(NORMAL_UNINSTALL) + @list='$(pkgconfig_DATA)'; test -n "$(pkgconfigdir)" || list=; \ + files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ + dir='$(DESTDIR)$(pkgconfigdir)'; $(am__uninstall_files_from_dir) + +# This directory's subdirectories are mostly independent; you can cd +# into them and run 'make' without going through this Makefile. +# To change the values of 'make' variables: instead of editing Makefiles, +# (1) if the variable is set in 'config.status', edit 'config.status' +# (which will cause the Makefiles to be regenerated when you run 'make'); +# (2) otherwise, pass the desired values on the 'make' command line. +$(am__recursive_targets): + @fail=; \ + if $(am__make_keepgoing); then \ + failcom='fail=yes'; \ + else \ + failcom='exit 1'; \ + fi; \ + dot_seen=no; \ + target=`echo $@ | sed s/-recursive//`; \ + case "$@" in \ + distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ + *) list='$(SUBDIRS)' ;; \ + esac; \ + for subdir in $$list; do \ + echo "Making $$target in $$subdir"; \ + if test "$$subdir" = "."; then \ + dot_seen=yes; \ + local_target="$$target-am"; \ + else \ + local_target="$$target"; \ + fi; \ + ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ + || eval $$failcom; \ + done; \ + if test "$$dot_seen" = "no"; then \ + $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ + fi; test -z "$$fail" + +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-recursive +TAGS: tags + +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + set x; \ + here=`pwd`; \ + if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ + include_option=--etags-include; \ + empty_fix=.; \ + else \ + include_option=--include; \ + empty_fix=; \ + fi; \ + list='$(SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + test ! -f $$subdir/TAGS || \ + set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ + fi; \ + done; \ + $(am__define_uniq_tagged_files); \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: ctags-recursive + +CTAGS: ctags +ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + $(am__define_uniq_tagged_files); \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" +cscope: cscope.files + test ! -s cscope.files \ + || $(CSCOPE) -b -q $(AM_CSCOPEFLAGS) $(CSCOPEFLAGS) -i cscope.files $(CSCOPE_ARGS) +clean-cscope: + -rm -f cscope.files +cscope.files: clean-cscope cscopelist +cscopelist: cscopelist-recursive + +cscopelist-am: $(am__tagged_files) + list='$(am__tagged_files)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + -rm -f cscope.out cscope.in.out cscope.po.out cscope.files +distdir: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) distdir-am + +distdir-am: $(DISTFILES) + $(am__remove_distdir) + test -d "$(distdir)" || mkdir "$(distdir)" + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done + @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + $(am__make_dryrun) \ + || test -d "$(distdir)/$$subdir" \ + || $(MKDIR_P) "$(distdir)/$$subdir" \ + || exit 1; \ + dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ + $(am__relativize); \ + new_distdir=$$reldir; \ + dir1=$$subdir; dir2="$(top_distdir)"; \ + $(am__relativize); \ + new_top_distdir=$$reldir; \ + echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ + echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ + ($(am__cd) $$subdir && \ + $(MAKE) $(AM_MAKEFLAGS) \ + top_distdir="$$new_top_distdir" \ + distdir="$$new_distdir" \ + am__remove_distdir=: \ + am__skip_length_check=: \ + am__skip_mode_fix=: \ + distdir) \ + || exit 1; \ + fi; \ + done + -test -n "$(am__skip_mode_fix)" \ + || find "$(distdir)" -type d ! -perm -755 \ + -exec chmod u+rwx,go+rx {} \; -o \ + ! -type d ! -perm -444 -links 1 -exec chmod a+r {} \; -o \ + ! -type d ! -perm -400 -exec chmod a+r {} \; -o \ + ! -type d ! -perm -444 -exec $(install_sh) -c -m a+r {} {} \; \ + || chmod -R a+r "$(distdir)" +dist-gzip: distdir + tardir=$(distdir) && $(am__tar) | eval GZIP= gzip $(GZIP_ENV) -c >$(distdir).tar.gz + $(am__post_remove_distdir) + +dist-bzip2: distdir + tardir=$(distdir) && $(am__tar) | BZIP2=$${BZIP2--9} bzip2 -c >$(distdir).tar.bz2 + $(am__post_remove_distdir) + +dist-lzip: distdir + tardir=$(distdir) && $(am__tar) | lzip -c $${LZIP_OPT--9} >$(distdir).tar.lz + $(am__post_remove_distdir) +dist-xz: distdir + tardir=$(distdir) && $(am__tar) | XZ_OPT=$${XZ_OPT--e} xz -c >$(distdir).tar.xz + $(am__post_remove_distdir) + +dist-zstd: distdir + tardir=$(distdir) && $(am__tar) | zstd -c $${ZSTD_CLEVEL-$${ZSTD_OPT--19}} >$(distdir).tar.zst + $(am__post_remove_distdir) + +dist-tarZ: distdir + @echo WARNING: "Support for distribution archives compressed with" \ + "legacy program 'compress' is deprecated." >&2 + @echo WARNING: "It will be removed altogether in Automake 2.0" >&2 + tardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z + $(am__post_remove_distdir) + +dist-shar: distdir + @echo WARNING: "Support for shar distribution archives is" \ + "deprecated." >&2 + @echo WARNING: "It will be removed altogether in Automake 2.0" >&2 + shar $(distdir) | eval GZIP= gzip $(GZIP_ENV) -c >$(distdir).shar.gz + $(am__post_remove_distdir) + +dist-zip: distdir + -rm -f $(distdir).zip + zip -rq $(distdir).zip $(distdir) + $(am__post_remove_distdir) + +dist dist-all: + $(MAKE) $(AM_MAKEFLAGS) $(DIST_TARGETS) am__post_remove_distdir='@:' + $(am__post_remove_distdir) + +# This target untars the dist file and tries a VPATH configuration. Then +# it guarantees that the distribution is self-contained by making another +# tarfile. +distcheck: dist + case '$(DIST_ARCHIVES)' in \ + *.tar.gz*) \ + eval GZIP= gzip $(GZIP_ENV) -dc $(distdir).tar.gz | $(am__untar) ;;\ + *.tar.bz2*) \ + bzip2 -dc $(distdir).tar.bz2 | $(am__untar) ;;\ + *.tar.lz*) \ + lzip -dc $(distdir).tar.lz | $(am__untar) ;;\ + *.tar.xz*) \ + xz -dc $(distdir).tar.xz | $(am__untar) ;;\ + *.tar.Z*) \ + uncompress -c $(distdir).tar.Z | $(am__untar) ;;\ + *.shar.gz*) \ + eval GZIP= gzip $(GZIP_ENV) -dc $(distdir).shar.gz | unshar ;;\ + *.zip*) \ + unzip $(distdir).zip ;;\ + *.tar.zst*) \ + zstd -dc $(distdir).tar.zst | $(am__untar) ;;\ + esac + chmod -R a-w $(distdir) + chmod u+w $(distdir) + mkdir $(distdir)/_build $(distdir)/_build/sub $(distdir)/_inst + chmod a-w $(distdir) + test -d $(distdir)/_build || exit 0; \ + dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \ + && dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \ + && am__cwd=`pwd` \ + && $(am__cd) $(distdir)/_build/sub \ + && ../../configure \ + $(AM_DISTCHECK_CONFIGURE_FLAGS) \ + $(DISTCHECK_CONFIGURE_FLAGS) \ + --srcdir=../.. --prefix="$$dc_install_base" \ + && $(MAKE) $(AM_MAKEFLAGS) \ + && $(MAKE) $(AM_MAKEFLAGS) $(AM_DISTCHECK_DVI_TARGET) \ + && $(MAKE) $(AM_MAKEFLAGS) check \ + && $(MAKE) $(AM_MAKEFLAGS) install \ + && $(MAKE) $(AM_MAKEFLAGS) installcheck \ + && $(MAKE) $(AM_MAKEFLAGS) uninstall \ + && $(MAKE) $(AM_MAKEFLAGS) distuninstallcheck_dir="$$dc_install_base" \ + distuninstallcheck \ + && chmod -R a-w "$$dc_install_base" \ + && ({ \ + (cd ../.. && umask 077 && mkdir "$$dc_destdir") \ + && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" install \ + && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" uninstall \ + && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" \ + distuninstallcheck_dir="$$dc_destdir" distuninstallcheck; \ + } || { rm -rf "$$dc_destdir"; exit 1; }) \ + && rm -rf "$$dc_destdir" \ + && $(MAKE) $(AM_MAKEFLAGS) dist \ + && rm -rf $(DIST_ARCHIVES) \ + && $(MAKE) $(AM_MAKEFLAGS) distcleancheck \ + && cd "$$am__cwd" \ + || exit 1 + $(am__post_remove_distdir) + @(echo "$(distdir) archives ready for distribution: "; \ + list='$(DIST_ARCHIVES)'; for i in $$list; do echo $$i; done) | \ + sed -e 1h -e 1s/./=/g -e 1p -e 1x -e '$$p' -e '$$x' +distuninstallcheck: + @test -n '$(distuninstallcheck_dir)' || { \ + echo 'ERROR: trying to run $@ with an empty' \ + '$$(distuninstallcheck_dir)' >&2; \ + exit 1; \ + }; \ + $(am__cd) '$(distuninstallcheck_dir)' || { \ + echo 'ERROR: cannot chdir into $(distuninstallcheck_dir)' >&2; \ + exit 1; \ + }; \ + test `$(am__distuninstallcheck_listfiles) | wc -l` -eq 0 \ + || { echo "ERROR: files left after uninstall:" ; \ + if test -n "$(DESTDIR)"; then \ + echo " (check DESTDIR support)"; \ + fi ; \ + $(distuninstallcheck_listfiles) ; \ + exit 1; } >&2 +distcleancheck: distclean + @if test '$(srcdir)' = . ; then \ + echo "ERROR: distcleancheck can only run from a VPATH build" ; \ + exit 1 ; \ + fi + @test `$(distcleancheck_listfiles) | wc -l` -eq 0 \ + || { echo "ERROR: files left in build directory after distclean:" ; \ + $(distcleancheck_listfiles) ; \ + exit 1; } >&2 +check-am: all-am +check: check-recursive +all-am: Makefile $(DATA) config.h +installdirs: installdirs-recursive +installdirs-am: + for dir in "$(DESTDIR)$(pkgconfigdir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +install: install-recursive +install-exec: install-exec-recursive +install-data: install-data-recursive +uninstall: uninstall-recursive + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-recursive +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-recursive + +clean-am: clean-generic clean-libtool mostlyclean-am + +distclean: distclean-recursive + -rm -f $(am__CONFIG_DISTCLEAN_FILES) + -rm -f Makefile +distclean-am: clean-am distclean-generic distclean-hdr \ + distclean-libtool distclean-tags + +dvi: dvi-recursive + +dvi-am: + +html: html-recursive + +html-am: + +info: info-recursive + +info-am: + +install-data-am: install-pkgconfigDATA + +install-dvi: install-dvi-recursive + +install-dvi-am: + +install-exec-am: + +install-html: install-html-recursive + +install-html-am: + +install-info: install-info-recursive + +install-info-am: + +install-man: + +install-pdf: install-pdf-recursive + +install-pdf-am: + +install-ps: install-ps-recursive + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-recursive + -rm -f $(am__CONFIG_DISTCLEAN_FILES) + -rm -rf $(top_srcdir)/autom4te.cache + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-recursive + +mostlyclean-am: mostlyclean-generic mostlyclean-libtool + +pdf: pdf-recursive + +pdf-am: + +ps: ps-recursive + +ps-am: + +uninstall-am: uninstall-pkgconfigDATA + +.MAKE: $(am__recursive_targets) all install-am install-strip + +.PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am \ + am--refresh check check-am clean clean-cscope clean-generic \ + clean-libtool cscope cscopelist-am ctags ctags-am dist \ + dist-all dist-bzip2 dist-gzip dist-lzip dist-shar dist-tarZ \ + dist-xz dist-zip dist-zstd distcheck distclean \ + distclean-generic distclean-hdr distclean-libtool \ + distclean-tags distcleancheck distdir distuninstallcheck dvi \ + dvi-am html html-am info info-am install install-am \ + install-data install-data-am install-dvi install-dvi-am \ + install-exec install-exec-am install-html install-html-am \ + install-info install-info-am install-man install-pdf \ + install-pdf-am install-pkgconfigDATA install-ps install-ps-am \ + install-strip installcheck installcheck-am installdirs \ + installdirs-am maintainer-clean maintainer-clean-generic \ + mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \ + ps ps-am tags tags-am uninstall uninstall-am \ + uninstall-pkgconfigDATA + +.PRECIOUS: Makefile + + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/OAT.xml b/OAT.xml index 58c7dc1931e220018dc0d1745cb73e440ab8f01a..e606016c54c0421c5fd6bfecd1543839592a09c9 100644 --- a/OAT.xml +++ b/OAT.xml @@ -1,5 +1,5 @@ - - + libevdev: Compatibility and Behavior across kernel versions @@ -25,7 +25,7 @@ @@ -36,10 +36,10 @@
- + @@ -102,7 +102,7 @@ SYN_DROPPED behavior diff --git a/doc/html/deprecated.html b/doc/html/deprecated.html index 32b2d6f0bf392277942dcb0f938b632fb9bc22e6..3c2c68e9d2de567307e3e88370a8a66088eaabc6 100644 --- a/doc/html/deprecated.html +++ b/doc/html/deprecated.html @@ -6,7 +6,7 @@ - + libevdev: Deprecated List @@ -25,7 +25,7 @@ @@ -36,10 +36,10 @@
- + @@ -73,12 +73,12 @@ $(function() {
+
Global libevdev_get_log_priority (void)
+
Use per-context logging instead, see libevdev_set_device_log_function().
Global libevdev_set_log_function (libevdev_log_func_t logfunc, void *data)
Use per-context logging instead, see libevdev_set_device_log_function().
Global libevdev_set_log_priority (enum libevdev_log_priority priority)
-
Use per-context logging instead, see libevdev_set_device_log_function().
-
Global libevdev_get_log_priority (void)
-
Use per-context logging instead, see libevdev_set_device_log_function().
+
Use per-context logging instead, see libevdev_set_device_log_function().
@@ -92,7 +92,7 @@ $(function() { diff --git a/doc/html/dir_237a012ffe1a208b10d31c74b4ef545e.html b/doc/html/dir_237a012ffe1a208b10d31c74b4ef545e.html index 672a6e247fe46a7ae5c885da3a7e1635d229fcb0..5e0e7d202a8f0afc5cc01e583586381941535aba 100644 --- a/doc/html/dir_237a012ffe1a208b10d31c74b4ef545e.html +++ b/doc/html/dir_237a012ffe1a208b10d31c74b4ef545e.html @@ -6,9 +6,9 @@ - + - libevdev: /home/whot/code/libevdev/release/libevdev/build.uQTRHZxVc0/libevdev Directory Reference + libevdev: /home/whot/code/libevdev/release/libevdev/build.eXgVwUduJp/libevdev Directory Reference @@ -25,7 +25,7 @@ @@ -36,10 +36,10 @@
- + @@ -95,7 +95,7 @@ Files diff --git a/doc/html/doxygen.css b/doc/html/doxygen.css index f640966e203cc52d3a860454212a6a16c47aac7b..ffbff0224931d970bd6092ba0ca5fe5b9b2bc2ea 100644 --- a/doc/html/doxygen.css +++ b/doc/html/doxygen.css @@ -1,4 +1,4 @@ -/* The standard CSS for doxygen 1.8.20 */ +/* The standard CSS for doxygen 1.9.1 */ body, table, div, p, dl { font: 400 14px/22px Roboto,sans-serif; @@ -103,30 +103,96 @@ caption { } span.legend { - font-size: 70%; - text-align: center; + font-size: 70%; + text-align: center; } h3.version { - font-size: 90%; - text-align: center; + font-size: 90%; + text-align: center; } -div.qindex, div.navtab{ - background-color: #EBEFF6; - border: 1px solid #A3B4D7; - text-align: center; +div.navtab { + border-right: 1px solid #A3B4D7; + padding-right: 15px; + text-align: right; + line-height: 110%; +} + +div.navtab table { + border-spacing: 0; +} + +td.navtab { + padding-right: 6px; + padding-left: 6px; +} +td.navtabHL { + background-image: url('tab_a.png'); + background-repeat:repeat-x; + padding-right: 6px; + padding-left: 6px; +} + +td.navtabHL a, td.navtabHL a:visited { + color: #fff; + text-shadow: 0px 1px 1px rgba(0, 0, 0, 1.0); +} + +a.navtab { + font-weight: bold; } -div.qindex, div.navpath { +div.qindex{ + text-align: center; width: 100%; line-height: 140%; + font-size: 130%; + color: #A0A0A0; } -div.navtab { - margin-right: 15px; +dt.alphachar{ + font-size: 180%; + font-weight: bold; +} + +.alphachar a{ + color: black; +} + +.alphachar a:hover, .alphachar a:visited{ + text-decoration: none; } +.classindex dl { + padding: 25px; + column-count:1 +} + +.classindex dd { + display:inline-block; + margin-left: 50px; + width: 90%; + line-height: 1.15em; +} + +.classindex dl.odd { + background-color: #F8F9FC; +} + +@media(min-width: 1120px) { + .classindex dl { + column-count:2 + } +} + +@media(min-width: 1320px) { + .classindex dl { + column-count:3 + } +} + + /* @group Link Styling */ a { @@ -143,17 +209,6 @@ a:hover { text-decoration: underline; } -a.qindex { - font-weight: bold; -} - -a.qindexHL { - font-weight: bold; - background-color: #9CAFD4; - color: #FFFFFF; - border: 1px double #869DCA; -} - .contents a.qindexHL:visited { color: #FFFFFF; } @@ -1426,6 +1481,12 @@ div.toc li.level4 { margin-left: 45px; } +span.emoji { + /* font family used at the site: https://unicode.org/emoji/charts/full-emoji-list.html + * font-family: "Noto Color Emoji", "Apple Color Emoji", "Segoe UI Emoji", Times, Symbola, Aegyptus, Code2000, Code2001, Code2002, Musica, serif, LastResort; + */ +} + .PageDocRTL-title div.toc li.level1 { margin-left: 0 !important; margin-right: 0; diff --git a/doc/html/files.html b/doc/html/files.html index 71f5c68568850ff96539be9341f3cc5764b8df50..2af5d7cf3789280f394cad9187c87d7f0cb4779c 100644 --- a/doc/html/files.html +++ b/doc/html/files.html @@ -6,7 +6,7 @@ - + libevdev: File List @@ -25,7 +25,7 @@ @@ -36,10 +36,10 @@
- + @@ -90,7 +90,7 @@ $(function() { diff --git a/doc/html/globals.html b/doc/html/globals.html index a7cf8e35fa0cf3bbb7b509bca593049e1a6fa482..121f8a9625c68ea67e0aeb7510d4e70d087fc445 100644 --- a/doc/html/globals.html +++ b/doc/html/globals.html @@ -6,7 +6,7 @@ - + libevdev: Globals @@ -25,7 +25,7 @@ @@ -36,10 +36,10 @@
- + @@ -416,7 +416,7 @@ $(function() { diff --git a/doc/html/globals_defs.html b/doc/html/globals_defs.html index 577c9550a9664f1af69c5651e1e6de8d15f52a3b..788df59f28a4ee404fc250cd9d93a1ca087e7bf9 100644 --- a/doc/html/globals_defs.html +++ b/doc/html/globals_defs.html @@ -6,7 +6,7 @@ - + libevdev: Globals @@ -25,7 +25,7 @@ @@ -36,10 +36,10 @@
- + @@ -87,7 +87,7 @@ $(function() { diff --git a/doc/html/globals_enum.html b/doc/html/globals_enum.html index eb39b4449fd3dbfbbf2640ea5b33ca44b2586849..cd2f2037595be47d0ee0d7f6b522d8bfa3e51127 100644 --- a/doc/html/globals_enum.html +++ b/doc/html/globals_enum.html @@ -6,7 +6,7 @@ - + libevdev: Globals @@ -25,7 +25,7 @@ @@ -36,10 +36,10 @@
- + @@ -99,7 +99,7 @@ $(function() { diff --git a/doc/html/globals_eval.html b/doc/html/globals_eval.html index debfb47273cdeca5bb90b3bd5e17ef6f0cf2df9d..22c569c01b098c206df4b235e4ae8ea79ca15c36 100644 --- a/doc/html/globals_eval.html +++ b/doc/html/globals_eval.html @@ -6,7 +6,7 @@ - + libevdev: Globals @@ -25,7 +25,7 @@ @@ -36,10 +36,10 @@
- + @@ -123,7 +123,7 @@ $(function() { diff --git a/doc/html/globals_func.html b/doc/html/globals_func.html index df40ed3a3fc25d2ae6f5201af9144a8618f19434..6603af68fe3723ea3ef1b0fa8fe5daf97d01b035 100644 --- a/doc/html/globals_func.html +++ b/doc/html/globals_func.html @@ -6,7 +6,7 @@ - + libevdev: Globals @@ -25,7 +25,7 @@ @@ -36,10 +36,10 @@
- + @@ -344,7 +344,7 @@ $(function() { diff --git a/doc/html/globals_type.html b/doc/html/globals_type.html index ad00e34b80891a1f599a541ecbcb73d200c30da7..edcd54eb92c8f10249a802694dc9a0e59624ab6e 100644 --- a/doc/html/globals_type.html +++ b/doc/html/globals_type.html @@ -6,7 +6,7 @@ - + libevdev: Globals @@ -25,7 +25,7 @@ @@ -36,10 +36,10 @@
- + @@ -87,7 +87,7 @@ $(function() { diff --git a/doc/html/group__bits.html b/doc/html/group__bits.html index f6a6ca78ce7e9baee9c29b3065409ae63f6971fc..d361540fe044eae43ec05904dc3d1d881f61b5a3 100644 --- a/doc/html/group__bits.html +++ b/doc/html/group__bits.html @@ -6,7 +6,7 @@ - + libevdev: Querying device capabilities @@ -25,7 +25,7 @@ @@ -36,10 +36,10 @@
- + @@ -179,6 +179,9 @@ Functions

This is a shortcut for

val = libevdev_get_event_value(dev, t, c);
+
int libevdev_has_event_type(const struct libevdev *dev, unsigned int type)
+
int libevdev_get_event_value(const struct libevdev *dev, unsigned int type, unsigned int code)
Behaviour of this function is undefined if the device does not provide the event.
+
int libevdev_has_event_code(const struct libevdev *dev, unsigned int type, unsigned int code)
Parameters
@@ -489,7 +492,7 @@ The value for ABS_MT_ events is undefined, use

Behaviour of this function is undefined if the device does not provide the event.

-

If the device supports ABS_MT_SLOT, the value returned for any ABS_MT_* event code is the value of the currently active slot. You should use libevdev_get_slot_value() instead.

+

If the device supports ABS_MT_SLOT, the value returned for any ABS_MT_* event code is undefined. Use libevdev_get_slot_value() instead.

Parameters
devThe evdev device, already initialized with libevdev_set_fd()
@@ -865,9 +868,6 @@ The value for ABS_MT_ events is undefined, use
int libevdev_has_event_code(const struct libevdev *dev, unsigned int type, unsigned int code)
-
int libevdev_get_event_value(const struct libevdev *dev, unsigned int type, unsigned int code)
Behaviour of this function is undefined if the device does not provide the event.
-
int libevdev_has_event_type(const struct libevdev *dev, unsigned int type)
@@ -878,7 +878,7 @@ The value for ABS_MT_ events is undefined, use diff --git a/doc/html/group__events.html b/doc/html/group__events.html index 22003ff154732f6d7ac458bfa40e1f7af0f9adf8..b2074f0e2cf2e2cd078c558c0f16b0001fee44ba 100644 --- a/doc/html/group__events.html +++ b/doc/html/group__events.html @@ -6,7 +6,7 @@ - + libevdev: Event handling @@ -25,7 +25,7 @@ @@ -36,10 +36,10 @@
- + @@ -81,14 +81,14 @@ $(function() {
devThe evdev device, already initialized with libevdev_set_fd()
- -

Enumerations

enum  libevdev_read_flag { LIBEVDEV_READ_FLAG_SYNC, -LIBEVDEV_READ_FLAG_NORMAL, -LIBEVDEV_READ_FLAG_FORCE_SYNC, -LIBEVDEV_READ_FLAG_BLOCKING +
enum  libevdev_read_flag { LIBEVDEV_READ_FLAG_SYNC +, LIBEVDEV_READ_FLAG_NORMAL +, LIBEVDEV_READ_FLAG_FORCE_SYNC +, LIBEVDEV_READ_FLAG_BLOCKING }
 
enum  libevdev_read_status { LIBEVDEV_READ_STATUS_SUCCESS, -LIBEVDEV_READ_STATUS_SYNC +
enum  libevdev_read_status { LIBEVDEV_READ_STATUS_SUCCESS +, LIBEVDEV_READ_STATUS_SYNC }
 
@@ -263,7 +263,7 @@ Functions diff --git a/doc/html/group__init.html b/doc/html/group__init.html index 97b9fc526476a38c9ed753d9a77279d5b3cc696a..935a73212be3283a94d1362ac1b6745a3c314b50 100644 --- a/doc/html/group__init.html +++ b/doc/html/group__init.html @@ -6,7 +6,7 @@ - + libevdev: Initialization and setup @@ -25,7 +25,7 @@ @@ -36,10 +36,10 @@
- + @@ -81,8 +81,8 @@ $(function() {
-

Enumerations

enum  libevdev_grab_mode { LIBEVDEV_GRAB, -LIBEVDEV_UNGRAB +
enum  libevdev_grab_mode { LIBEVDEV_GRAB +, LIBEVDEV_UNGRAB }
 
@@ -120,10 +120,13 @@ Functions
return ENOMEM;
err = libevdev_set_fd(dev, fd);
-
if (err < 0) {
+
if (err < 0)
printf("Failed (errno %d): %s\n", -err, strerror(-err));
+
struct libevdev * libevdev_new(void)
Initialize a new libevdev device.
+
int libevdev_set_fd(struct libevdev *dev, int fd)
Set the fd for this struct and initialize internal data.
+
void libevdev_free(struct libevdev *dev)
Clean up and free the libevdev struct.

libevdev_set_fd() is the central call and initializes the internal structs for the device at the given fd. libevdev functions will fail if called before libevdev_set_fd() unless documented otherwise.

Enumeration Type Documentation

@@ -181,6 +184,11 @@ Functions
; // noop
+
int libevdev_next_event(struct libevdev *dev, unsigned int flags, struct input_event *ev)
Get the next event from the device.
+
@ LIBEVDEV_READ_STATUS_SYNC
Depending on the libevdev_next_event() read flag:
Definition: libevdev.h:1090
+
@ LIBEVDEV_READ_FLAG_SYNC
Process data in sync mode.
Definition: libevdev.h:761
+
@ LIBEVDEV_READ_FLAG_FORCE_SYNC
Pretend the next event is a SYN_DROPPED and require the caller to sync.
Definition: libevdev.h:763
+
int libevdev_change_fd(struct libevdev *dev, int fd)
Change the fd for this device, without re-reading the actual device.

The fd may be open in O_RDONLY or O_RDWR.

After changing the fd, the device is assumed ungrabbed and a caller must call libevdev_grab() again.

It is an error to call this function before calling libevdev_set_fd().

@@ -409,14 +417,6 @@ Functions -
struct libevdev * libevdev_new(void)
Initialize a new libevdev device.
-
int libevdev_set_fd(struct libevdev *dev, int fd)
Set the fd for this struct and initialize internal data.
-
void libevdev_free(struct libevdev *dev)
Clean up and free the libevdev struct.
-
@ LIBEVDEV_READ_FLAG_FORCE_SYNC
Pretend the next event is a SYN_DROPPED and require the caller to sync.
Definition: libevdev.h:760
-
@ LIBEVDEV_READ_STATUS_SYNC
Depending on the libevdev_next_event() read flag:
Definition: libevdev.h:1087
-
int libevdev_next_event(struct libevdev *dev, unsigned int flags, struct input_event *ev)
Get the next event from the device.
-
int libevdev_change_fd(struct libevdev *dev, int fd)
Change the fd for this device, without re-reading the actual device.
-
@ LIBEVDEV_READ_FLAG_SYNC
Process data in sync mode.
Definition: libevdev.h:758
@@ -427,7 +427,7 @@ Functions diff --git a/doc/html/group__kernel.html b/doc/html/group__kernel.html index 7e488821e134b3900708f8361ad315dc918c7fd7..72ef3cf8d586263f3d970c4d1115c8c5beec8563 100644 --- a/doc/html/group__kernel.html +++ b/doc/html/group__kernel.html @@ -6,7 +6,7 @@ - + libevdev: Modifying the appearance or capabilities of the device @@ -25,7 +25,7 @@ @@ -36,10 +36,10 @@
- + @@ -81,8 +81,8 @@ $(function() {
-

Enumerations

enum  libevdev_led_value { LIBEVDEV_LED_ON, -LIBEVDEV_LED_OFF +
enum  libevdev_led_value { LIBEVDEV_LED_ON +, LIBEVDEV_LED_OFF }
 
@@ -583,6 +583,9 @@ Functions
LED_CAPSL, LIBEVDEV_LED_OFF,
-1);
+
int libevdev_kernel_set_led_values(struct libevdev *dev,...)
Turn multiple LEDs on or off simultaneously.
+
@ LIBEVDEV_LED_OFF
Turn the LED off.
Definition: libevdev.h:1921
+
@ LIBEVDEV_LED_ON
Turn the LED on.
Definition: libevdev.h:1920

If any LED code or value is invalid, this function returns -EINVAL and no LEDs are modified.

Note
enabling an LED requires write permissions on the device's file descriptor.
Parameters
@@ -1309,9 +1312,6 @@ Functions -
@ LIBEVDEV_LED_OFF
Turn the LED off.
Definition: libevdev.h:1919
-
int libevdev_kernel_set_led_values(struct libevdev *dev,...)
Turn multiple LEDs on or off simultaneously.
-
@ LIBEVDEV_LED_ON
Turn the LED on.
Definition: libevdev.h:1918
@@ -1322,7 +1322,7 @@ Functions diff --git a/doc/html/group__logging.html b/doc/html/group__logging.html index 000a1f3f7e3e2e967c0e0303d6dc7f34c406ff01..85df567f9dc4328f87fd6fa00e48c6cd99f07623 100644 --- a/doc/html/group__logging.html +++ b/doc/html/group__logging.html @@ -6,7 +6,7 @@ - + libevdev: Library logging facilities @@ -25,7 +25,7 @@ @@ -36,10 +36,10 @@
- + @@ -91,9 +91,9 @@ Typedefs
-

Enumerations

enum  libevdev_log_priority { LIBEVDEV_LOG_ERROR, -LIBEVDEV_LOG_INFO, -LIBEVDEV_LOG_DEBUG +
enum  libevdev_log_priority { LIBEVDEV_LOG_ERROR +, LIBEVDEV_LOG_INFO +, LIBEVDEV_LOG_DEBUG }
 
@@ -364,7 +364,7 @@ A context-specific handler cannot be used for libevdev's uinput devices. diff --git a/doc/html/group__misc.html b/doc/html/group__misc.html index d5ec6eae976aca3ba5379e41d17efb90425c9bf1..a98641718b1d67505b4fa39e3a8115562ab35d64 100644 --- a/doc/html/group__misc.html +++ b/doc/html/group__misc.html @@ -6,7 +6,7 @@ - + libevdev: Miscellaneous helper functions @@ -25,7 +25,7 @@ @@ -36,10 +36,10 @@
- + @@ -365,7 +365,7 @@ Functions

Helper function to check if an event is of a specific type and code.

This is virtually the same as:

 ev->type == type && ev->code == code
-

with the exception that some sanity checks are performed to ensure type and code are valid.

+

with the exception that some sanity checks are performed to ensure type and code are valid.

Note
The ranges for types and codes are compiled into libevdev. If the kernel changes the max value, libevdev will not automatically pick these up.
Parameters
@@ -407,7 +407,7 @@ Functions

Helper function to check if an event is of a specific type.

This is virtually the same as:

 ev->type == type
-

with the exception that some sanity checks are performed to ensure type is valid.

+

with the exception that some sanity checks are performed to ensure type is valid.

Note
The ranges for types are compiled into libevdev. If the kernel changes the max value, libevdev will not automatically pick these up.
Parameters
@@ -866,7 +866,7 @@ On older kernels input properties may not be defined and diff --git a/doc/html/group__mt.html b/doc/html/group__mt.html index b01485551a0df3703137aaa079490eac676b140f..db95b404f1c64d2364ed6af1992d178388908ea2 100644 --- a/doc/html/group__mt.html +++ b/doc/html/group__mt.html @@ -6,7 +6,7 @@ - + libevdev: Multi-touch related functions @@ -25,7 +25,7 @@ @@ -36,10 +36,10 @@
- + @@ -144,6 +144,9 @@ Functions
libevdev_has_event_code(dev, EV_ABS, c) &&
slot < device->number_of_slots)
val = libevdev_get_slot_value(dev, slot, c);
+
int libevdev_has_event_type(const struct libevdev *dev, unsigned int type)
+
int libevdev_has_event_code(const struct libevdev *dev, unsigned int type, unsigned int code)
+
int libevdev_get_slot_value(const struct libevdev *dev, unsigned int slot, unsigned int code)
Return the current value of the code for the given slot.
Parameters
@@ -265,9 +268,6 @@ The value for events other than ABS_MT_ is undefined, use libevdev_fetch_value() -
int libevdev_has_event_code(const struct libevdev *dev, unsigned int type, unsigned int code)
-
int libevdev_get_slot_value(const struct libevdev *dev, unsigned int slot, unsigned int code)
Return the current value of the code for the given slot.
-
int libevdev_has_event_type(const struct libevdev *dev, unsigned int type)
@@ -278,7 +278,7 @@ The value for events other than ABS_MT_ is undefined, use libevdev_fetch_value() diff --git a/doc/html/group__uinput.html b/doc/html/group__uinput.html index 4deeaf076ee69c0bd2701b25d7952d27a616089e..1324a406a552a3d5700438937d52daa2afce85ae 100644 --- a/doc/html/group__uinput.html +++ b/doc/html/group__uinput.html @@ -6,7 +6,7 @@ - + libevdev: uinput device creation @@ -25,7 +25,7 @@ @@ -36,10 +36,10 @@
- + @@ -103,14 +103,13 @@ Functions

Creation of uinput devices based on existing libevdev devices.

These functions help to create uinput devices that emulate libevdev devices. In the simplest form it serves to duplicate an existing device:

int err;
-
int fd, new_fd, uifd;
+
int fd, uifd;
struct libevdev *dev;
struct libevdev_uinput *uidev;
-
struct input_event ev[2];
fd = open("/dev/input/event0", O_RDONLY);
if (fd < 0)
-
return err;
+
return -errno;
err = libevdev_new_from_fd(fd, &dev);
if (err != 0)
@@ -128,7 +127,7 @@ Functions
err = libevdev_uinput_write_event(uidev, EV_REL, REL_X, -1);
if (err != 0)
return err;
-
libevdev_uinput_write_event(uidev, EV_SYN, SYN_REPORT, 0);
+
err = libevdev_uinput_write_event(uidev, EV_SYN, SYN_REPORT, 0);
if (err != 0)
return err;
@@ -136,6 +135,11 @@ Functions
close(uifd);
close(fd);
+
int libevdev_new_from_fd(int fd, struct libevdev **dev)
Initialize a new libevdev device from the given fd.
+
void libevdev_free(struct libevdev *dev)
Clean up and free the libevdev struct.
+
int libevdev_uinput_write_event(const struct libevdev_uinput *uinput_dev, unsigned int type, unsigned int code, int value)
Post an event through the uinput device.
+
void libevdev_uinput_destroy(struct libevdev_uinput *uinput_dev)
Destroy a previously created uinput device and free associated memory.
+
int libevdev_uinput_create_from_device(const struct libevdev *dev, int uinput_fd, struct libevdev_uinput **uinput_dev)
Create a uinput device based on the given libevdev device.

Alternatively, a device can be constructed from scratch:

int err;
struct libevdev *dev;
@@ -160,6 +164,11 @@ Functions
// ... do something ...
+
struct libevdev * libevdev_new(void)
Initialize a new libevdev device.
+
int libevdev_enable_event_code(struct libevdev *dev, unsigned int type, unsigned int code, const void *data)
Forcibly enable an event code on this device, even if the underlying device does not support it.
+
int libevdev_enable_event_type(struct libevdev *dev, unsigned int type)
Forcibly enable an event type on this device, even if the underlying device does not support it.
+
void libevdev_set_name(struct libevdev *dev, const char *name)
Change the device's name as returned by libevdev_get_name().
+
@ LIBEVDEV_UINPUT_OPEN_MANAGED
let libevdev open and close /dev/uinput
Definition: libevdev-uinput.h:114

Function Documentation

◆ libevdev_uinput_create_from_device()

@@ -318,9 +327,9 @@ On FreeBSD, this function can not return NULL. libudev uses the UI_GET_SYSNAME i

Return the syspath representing this uinput device.

-

If the UI_GET_SYSNAME ioctl not available, libevdev makes an educated guess. The UI_GET_SYSNAME ioctl is available since Linux 3.15.

+

If the UI_GET_SYSNAME ioctl is not available, libevdev makes an educated guess. The UI_GET_SYSNAME ioctl is available since Linux 3.15.

The syspath returned is the one of the input node itself (e.g. /sys/devices/virtual/input/input123), not the syspath of the device node returned with libevdev_uinput_get_devnode().

-
Note
This function may return NULL if UI_GET_SYSNAME is not available. In that case, libevdev uses ctime and the device name to guess devices. To avoid false positives, wait at least wait at least 1.5s between creating devices that have the same name.
+
Note
This function may return NULL if UI_GET_SYSNAME is not available. In that case, libevdev uses ctime and the device name to guess devices. To avoid false positives, wait at least 1.5s between creating devices that have the same name.
FreeBSD does not have sysfs, on FreeBSD this function always returns NULL.
Parameters
@@ -388,16 +397,6 @@ FreeBSD does not have sysfs, on FreeBSD this function always returns NULL.
<
-
int libevdev_uinput_create_from_device(const struct libevdev *dev, int uinput_fd, struct libevdev_uinput **uinput_dev)
Create a uinput device based on the given libevdev device.
-
int libevdev_enable_event_type(struct libevdev *dev, unsigned int type)
Forcibly enable an event type on this device, even if the underlying device does not support it.
-
@ LIBEVDEV_UINPUT_OPEN_MANAGED
let libevdev open and close /dev/uinput
Definition: libevdev-uinput.h:113
-
struct libevdev * libevdev_new(void)
Initialize a new libevdev device.
-
void libevdev_uinput_destroy(struct libevdev_uinput *uinput_dev)
Destroy a previously created uinput device and free associated memory.
-
void libevdev_free(struct libevdev *dev)
Clean up and free the libevdev struct.
-
void libevdev_set_name(struct libevdev *dev, const char *name)
Change the device's name as returned by libevdev_get_name().
-
int libevdev_uinput_write_event(const struct libevdev_uinput *uinput_dev, unsigned int type, unsigned int code, int value)
Post an event through the uinput device.
-
int libevdev_enable_event_code(struct libevdev *dev, unsigned int type, unsigned int code, const void *data)
Forcibly enable an event code on this device, even if the underlying device does not support it.
-
int libevdev_new_from_fd(int fd, struct libevdev **dev)
Initialize a new libevdev device from the given fd.
@@ -408,7 +407,7 @@ FreeBSD does not have sysfs, on FreeBSD this function always returns NULL.< diff --git a/doc/html/index.html b/doc/html/index.html index a230475d0c9498141247326bc990c98a2cea5b97..7ec100b6c1d55b109b0959105ca9d53510a7c680 100644 --- a/doc/html/index.html +++ b/doc/html/index.html @@ -6,7 +6,7 @@ - + libevdev: Main Page @@ -25,7 +25,7 @@ @@ -36,10 +36,10 @@
- + @@ -94,9 +94,9 @@ Device handling

Where does libevdev sit?

libevdev is essentially a read(2) on steroids for /dev/input/eventX devices. It sits below the process that handles input events, in between the kernel and that process. In the simplest case, e.g. an evtest-like tool the stack would look like this:

 kernel → libevdev → evtest
-

For X.Org input modules, the stack would look like this:

 kernel → libevdev → xf86-input-evdev → X server → X client
-

For anything using libinput (e.g. most Wayland compositors), the stack the stack would look like this:

 kernel → libevdev → libinput → Compositor → Wayland client
-

libevdev does not have knowledge of X clients or Wayland clients, it is too low in the stack.

+

For X.Org input modules, the stack would look like this:

 kernel → libevdev → xf86-input-evdev → X server → X client
+

For anything using libinput (e.g. most Wayland compositors), the stack the stack would look like this:

 kernel → libevdev → libinput → Compositor → Wayland client
+

libevdev does not have knowledge of X clients or Wayland clients, it is too low in the stack.

Example

Below is a simple example that shows how libevdev could be used. This example opens a device, checks for relative axes and a left mouse button and if it finds them monitors the device to print the event.

@@ -130,6 +130,17 @@ Example
libevdev_event_code_get_name(ev.type, ev.code),
ev.value);
} while (rc == 1 || rc == 0 || rc == -EAGAIN);
+
int libevdev_get_id_vendor(const struct libevdev *dev)
+
int libevdev_get_id_product(const struct libevdev *dev)
+
int libevdev_has_event_type(const struct libevdev *dev, unsigned int type)
+
int libevdev_get_id_bustype(const struct libevdev *dev)
+
int libevdev_has_event_code(const struct libevdev *dev, unsigned int type, unsigned int code)
+
const char * libevdev_get_name(const struct libevdev *dev)
Retrieve the device's name, either as set by the caller or as read from the kernel.
+
int libevdev_next_event(struct libevdev *dev, unsigned int flags, struct input_event *ev)
Get the next event from the device.
+
@ LIBEVDEV_READ_FLAG_NORMAL
Process data in normal mode.
Definition: libevdev.h:762
+
int libevdev_new_from_fd(int fd, struct libevdev **dev)
Initialize a new libevdev device from the given fd.
+
const char * libevdev_event_code_get_name(unsigned int type, unsigned int code)
+
const char * libevdev_event_type_get_name(unsigned int type)

A more complete example is available with the libevdev-events tool here: https://gitlab.freedesktop.org/libevdev/libevdev/blob/master/tools/libevdev-events.c

Backwards compatibility with older kernel

@@ -149,17 +160,6 @@ Reporting bugs

Please report bugs in the freedesktop.org GitLab instance: https://gitlab.freedesktop.org/libevdev/libevdev/issues/

-
int libevdev_has_event_code(const struct libevdev *dev, unsigned int type, unsigned int code)
-
const char * libevdev_event_code_get_name(unsigned int type, unsigned int code)
-
int libevdev_has_event_type(const struct libevdev *dev, unsigned int type)
-
int libevdev_get_id_bustype(const struct libevdev *dev)
-
int libevdev_get_id_product(const struct libevdev *dev)
-
int libevdev_get_id_vendor(const struct libevdev *dev)
-
int libevdev_next_event(struct libevdev *dev, unsigned int flags, struct input_event *ev)
Get the next event from the device.
-
const char * libevdev_event_type_get_name(unsigned int type)
-
const char * libevdev_get_name(const struct libevdev *dev)
Retrieve the device's name, either as set by the caller or as read from the kernel.
-
@ LIBEVDEV_READ_FLAG_NORMAL
Process data in normal mode.
Definition: libevdev.h:759
-
int libevdev_new_from_fd(int fd, struct libevdev **dev)
Initialize a new libevdev device from the given fd.
@@ -170,7 +170,7 @@ Reporting bugs diff --git a/doc/html/ioctls.html b/doc/html/ioctls.html index 7baabf641322a8507ae5e3b3df9255940537b03c..806f5c7f9db4e01e4d14c6901bd4c2b620a688c1 100644 --- a/doc/html/ioctls.html +++ b/doc/html/ioctls.html @@ -6,7 +6,7 @@ - + libevdev: evdev ioctls @@ -25,7 +25,7 @@ @@ -36,10 +36,10 @@
- + @@ -139,7 +139,7 @@ $(function() { diff --git a/doc/html/kernel_header.html b/doc/html/kernel_header.html index 8917e4c86e2dab75fd821cf60576409213b902ec..09a19983920b70aa6e34ab7c2e9f615af5e6212c 100644 --- a/doc/html/kernel_header.html +++ b/doc/html/kernel_header.html @@ -6,7 +6,7 @@ - + libevdev: Kernel header @@ -25,7 +25,7 @@ @@ -36,10 +36,10 @@
- + @@ -90,7 +90,7 @@ $(function() { diff --git a/doc/html/libevdev-uinput_8h.html b/doc/html/libevdev-uinput_8h.html index e7f423670e20f18ae7eaa447a1afdc607787d900..ec43100cfeee0e587b9c84dc00a11a44d889cbb8 100644 --- a/doc/html/libevdev-uinput_8h.html +++ b/doc/html/libevdev-uinput_8h.html @@ -6,9 +6,9 @@ - + - libevdev: /home/whot/code/libevdev/release/libevdev/build.uQTRHZxVc0/libevdev/libevdev-uinput.h File Reference + libevdev: /home/whot/code/libevdev/release/libevdev/build.eXgVwUduJp/libevdev/libevdev-uinput.h File Reference @@ -25,7 +25,7 @@ @@ -36,10 +36,10 @@
- + @@ -140,7 +140,7 @@ Functions diff --git a/doc/html/libevdev-uinput_8h_source.html b/doc/html/libevdev-uinput_8h_source.html index 2b97ed76055530cff04d2bb28e55fecbc37fee05..4c4d818a2789af28fe00a0659cb955eb58e8bf4d 100644 --- a/doc/html/libevdev-uinput_8h_source.html +++ b/doc/html/libevdev-uinput_8h_source.html @@ -6,9 +6,9 @@ - + - libevdev: /home/whot/code/libevdev/release/libevdev/build.uQTRHZxVc0/libevdev/libevdev-uinput.h Source File + libevdev: /home/whot/code/libevdev/release/libevdev/build.eXgVwUduJp/libevdev/libevdev-uinput.h Source File @@ -25,7 +25,7 @@ @@ -36,10 +36,10 @@
- + @@ -76,77 +76,79 @@ $(function() {
libevdev-uinput.h
-Go to the documentation of this file.
1 /*
-
2  * Copyright © 2013 Red Hat, Inc.
-
3  *
-
4  * Permission to use, copy, modify, distribute, and sell this software and its
-
5  * documentation for any purpose is hereby granted without fee, provided that
-
6  * the above copyright notice appear in all copies and that both that copyright
-
7  * notice and this permission notice appear in supporting documentation, and
-
8  * that the name of the copyright holders not be used in advertising or
-
9  * publicity pertaining to distribution of the software without specific,
-
10  * written prior permission. The copyright holders make no representations
-
11  * about the suitability of this software for any purpose. It is provided "as
-
12  * is" without express or implied warranty.
-
13  *
-
14  * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
-
15  * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
-
16  * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
-
17  * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
-
18  * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
-
19  * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
-
20  * OF THIS SOFTWARE.
-
21  */
-
22 
-
23 #ifndef LIBEVDEV_UINPUT_H
-
24 #define LIBEVDEV_UINPUT_H
-
25 
-
26 #ifdef __cplusplus
-
27 extern "C" {
-
28 #endif
-
29 
-
30 #include <libevdev/libevdev.h>
+Go to the documentation of this file.
1 /* SPDX-License-Identifier: MIT */
+
2 /*
+
3  * Copyright © 2013 Red Hat, Inc.
+
4  *
+
5  * Permission is hereby granted, free of charge, to any person obtaining a copy
+
6  * of this software and associated documentation files (the "Software"), to
+
7  * deal in the Software without restriction, including without limitation the
+
8  * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+
9  * sell copies of the Software, and to permit persons to whom the Software is
+
10  * furnished to do so, subject to the following conditions:
+
11  *
+
12  * The above copyright notice and this permission notice (including the next
+
13  * paragraph) shall be included in all copies or substantial portions of the
+
14  * Software.
+
15  *
+
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+
17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+
18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+
19  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+
20  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+
21  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+
22  * IN THE SOFTWARE.
+
23  */
+
24 
+
25 #ifndef LIBEVDEV_UINPUT_H
+
26 #define LIBEVDEV_UINPUT_H
+
27 
+
28 #ifdef __cplusplus
+
29 extern "C" {
+
30 #endif
31 
-
32 struct libevdev_uinput;
+
32 #include <libevdev/libevdev.h>
33 
- -
110  /* intentionally -2 to avoid to avoid code like the below from accidentally working:
-
111  fd = open("/dev/uinput", O_RDWR); // fails, fd is -1
-
112  libevdev_uinput_create_from_device(dev, fd, &uidev); // may hide the error */
- -
114 };
-
115 
-
153 int libevdev_uinput_create_from_device(const struct libevdev *dev,
-
154  int uinput_fd,
-
155  struct libevdev_uinput **uinput_dev);
-
156 
-
168 void libevdev_uinput_destroy(struct libevdev_uinput *uinput_dev);
-
169 
-
183 int libevdev_uinput_get_fd(const struct libevdev_uinput *uinput_dev);
-
184 
-
209 const char* libevdev_uinput_get_syspath(struct libevdev_uinput *uinput_dev);
-
210 
-
231 const char* libevdev_uinput_get_devnode(struct libevdev_uinput *uinput_dev);
-
232 
-
247 int libevdev_uinput_write_event(const struct libevdev_uinput *uinput_dev,
-
248  unsigned int type,
-
249  unsigned int code,
-
250  int value);
-
251 #ifdef __cplusplus
-
252 }
-
253 #endif
-
254 
-
255 #endif /* LIBEVDEV_UINPUT_H */
-
- +
34 struct libevdev_uinput;
+
35 
+ +
111  /* intentionally -2 to avoid code like below from accidentally working:
+
112  fd = open("/dev/uinput", O_RDWR); // fails, fd is -1
+
113  libevdev_uinput_create_from_device(dev, fd, &uidev); // may hide the error */
+ +
115 };
+
116 
+
154 int libevdev_uinput_create_from_device(const struct libevdev *dev,
+
155  int uinput_fd,
+
156  struct libevdev_uinput **uinput_dev);
+
157 
+
169 void libevdev_uinput_destroy(struct libevdev_uinput *uinput_dev);
+
170 
+
184 int libevdev_uinput_get_fd(const struct libevdev_uinput *uinput_dev);
+
185 
+
210 const char* libevdev_uinput_get_syspath(struct libevdev_uinput *uinput_dev);
+
211 
+
232 const char* libevdev_uinput_get_devnode(struct libevdev_uinput *uinput_dev);
+
233 
+
248 int libevdev_uinput_write_event(const struct libevdev_uinput *uinput_dev,
+
249  unsigned int type,
+
250  unsigned int code,
+
251  int value);
+
252 #ifdef __cplusplus
+
253 }
+
254 #endif
+
255 
+
256 #endif /* LIBEVDEV_UINPUT_H */
+
int libevdev_uinput_write_event(const struct libevdev_uinput *uinput_dev, unsigned int type, unsigned int code, int value)
Post an event through the uinput device.
const char * libevdev_uinput_get_devnode(struct libevdev_uinput *uinput_dev)
Return the device node representing this uinput device.
-
int libevdev_uinput_create_from_device(const struct libevdev *dev, int uinput_fd, struct libevdev_uinput **uinput_dev)
Create a uinput device based on the given libevdev device.
-
@ LIBEVDEV_UINPUT_OPEN_MANAGED
let libevdev open and close /dev/uinput
Definition: libevdev-uinput.h:113
-
const char * libevdev_uinput_get_syspath(struct libevdev_uinput *uinput_dev)
Return the syspath representing this uinput device.
-
void libevdev_uinput_destroy(struct libevdev_uinput *uinput_dev)
Destroy a previously created uinput device and free associated memory.
-
libevdev_uinput_open_mode
Definition: libevdev-uinput.h:109
int libevdev_uinput_get_fd(const struct libevdev_uinput *uinput_dev)
Return the file descriptor used to create this uinput device.
-
int libevdev_uinput_write_event(const struct libevdev_uinput *uinput_dev, unsigned int type, unsigned int code, int value)
Post an event through the uinput device.
+
void libevdev_uinput_destroy(struct libevdev_uinput *uinput_dev)
Destroy a previously created uinput device and free associated memory.
+
const char * libevdev_uinput_get_syspath(struct libevdev_uinput *uinput_dev)
Return the syspath representing this uinput device.
+
int libevdev_uinput_create_from_device(const struct libevdev *dev, int uinput_fd, struct libevdev_uinput **uinput_dev)
Create a uinput device based on the given libevdev device.
+
libevdev_uinput_open_mode
Definition: libevdev-uinput.h:110
+
@ LIBEVDEV_UINPUT_OPEN_MANAGED
let libevdev open and close /dev/uinput
Definition: libevdev-uinput.h:114
+ +
@@ -157,7 +159,7 @@ $(function() { diff --git a/doc/html/libevdev_8h.html b/doc/html/libevdev_8h.html index bd7e80fc8ea6fea504b8da014a7aafbf3f576c9a..cfcada512835e9f2621daca302bb314f5e4d49ab 100644 --- a/doc/html/libevdev_8h.html +++ b/doc/html/libevdev_8h.html @@ -6,9 +6,9 @@ - + - libevdev: /home/whot/code/libevdev/release/libevdev/build.uQTRHZxVc0/libevdev/libevdev.h File Reference + libevdev: /home/whot/code/libevdev/release/libevdev/build.eXgVwUduJp/libevdev/libevdev.h File Reference @@ -25,7 +25,7 @@ @@ -36,10 +36,10 @@
- + @@ -104,27 +104,27 @@ Typedefs
devThe evdev device, already initialized with libevdev_set_fd()
- - - - -

Enumerations

enum  libevdev_read_flag { LIBEVDEV_READ_FLAG_SYNC, -LIBEVDEV_READ_FLAG_NORMAL, -LIBEVDEV_READ_FLAG_FORCE_SYNC, -LIBEVDEV_READ_FLAG_BLOCKING +
enum  libevdev_read_flag { LIBEVDEV_READ_FLAG_SYNC +, LIBEVDEV_READ_FLAG_NORMAL +, LIBEVDEV_READ_FLAG_FORCE_SYNC +, LIBEVDEV_READ_FLAG_BLOCKING }
 
enum  libevdev_log_priority { LIBEVDEV_LOG_ERROR, -LIBEVDEV_LOG_INFO, -LIBEVDEV_LOG_DEBUG +
enum  libevdev_log_priority { LIBEVDEV_LOG_ERROR +, LIBEVDEV_LOG_INFO +, LIBEVDEV_LOG_DEBUG }
 
enum  libevdev_grab_mode { LIBEVDEV_GRAB, -LIBEVDEV_UNGRAB +
enum  libevdev_grab_mode { LIBEVDEV_GRAB +, LIBEVDEV_UNGRAB }
 
enum  libevdev_read_status { LIBEVDEV_READ_STATUS_SUCCESS, -LIBEVDEV_READ_STATUS_SYNC +
enum  libevdev_read_status { LIBEVDEV_READ_STATUS_SUCCESS +, LIBEVDEV_READ_STATUS_SYNC }
 
enum  libevdev_led_value { LIBEVDEV_LED_ON, -LIBEVDEV_LED_OFF +
enum  libevdev_led_value { LIBEVDEV_LED_ON +, LIBEVDEV_LED_OFF }
 
@@ -409,7 +409,7 @@ Functions diff --git a/doc/html/libevdev_8h_source.html b/doc/html/libevdev_8h_source.html index 8a565ef305ecbcfb0d8456aacafcb7d69f6a790b..a4649962a22562b4a268f261a5cf0e45c1e64aa5 100644 --- a/doc/html/libevdev_8h_source.html +++ b/doc/html/libevdev_8h_source.html @@ -6,9 +6,9 @@ - + - libevdev: /home/whot/code/libevdev/release/libevdev/build.uQTRHZxVc0/libevdev/libevdev.h Source File + libevdev: /home/whot/code/libevdev/release/libevdev/build.eXgVwUduJp/libevdev/libevdev.h Source File @@ -25,7 +25,7 @@ @@ -36,10 +36,10 @@
- + @@ -76,372 +76,375 @@ $(function() {
libevdev.h
-Go to the documentation of this file.
1 /*
-
2  * Copyright © 2013 Red Hat, Inc.
-
3  *
-
4  * Permission to use, copy, modify, distribute, and sell this software and its
-
5  * documentation for any purpose is hereby granted without fee, provided that
-
6  * the above copyright notice appear in all copies and that both that copyright
-
7  * notice and this permission notice appear in supporting documentation, and
-
8  * that the name of the copyright holders not be used in advertising or
-
9  * publicity pertaining to distribution of the software without specific,
-
10  * written prior permission. The copyright holders make no representations
-
11  * about the suitability of this software for any purpose. It is provided "as
-
12  * is" without express or implied warranty.
-
13  *
-
14  * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
-
15  * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
-
16  * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
-
17  * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
-
18  * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
-
19  * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
-
20  * OF THIS SOFTWARE.
-
21  */
-
22 
-
23 #ifndef LIBEVDEV_H
-
24 #define LIBEVDEV_H
+Go to the documentation of this file.
1 /* SPDX-License-Identifier: MIT */
+
2 /*
+
3  * Copyright © 2013 Red Hat, Inc.
+
4  *
+
5  * Permission is hereby granted, free of charge, to any person obtaining a copy
+
6  * of this software and associated documentation files (the "Software"), to
+
7  * deal in the Software without restriction, including without limitation the
+
8  * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+
9  * sell copies of the Software, and to permit persons to whom the Software is
+
10  * furnished to do so, subject to the following conditions:
+
11  *
+
12  * The above copyright notice and this permission notice (including the next
+
13  * paragraph) shall be included in all copies or substantial portions of the
+
14  * Software.
+
15  *
+
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+
17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+
18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+
19  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+
20  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+
21  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+
22  * IN THE SOFTWARE.
+
23  *
+
24  */
25 
-
26 #ifdef __cplusplus
-
27 extern "C" {
-
28 #endif
-
29 
-
30 #include <linux/input.h>
-
31 #include <stdarg.h>
+
26 #ifndef LIBEVDEV_H
+
27 #define LIBEVDEV_H
+
28 
+
29 #ifdef __cplusplus
+
30 extern "C" {
+
31 #endif
32 
-
33 #define LIBEVDEV_ATTRIBUTE_PRINTF(_format, _args) __attribute__ ((format (printf, _format, _args)))
-
34 
-
752 struct libevdev;
-
753 
- - - - - -
763 };
-
764 
-
779 struct libevdev* libevdev_new(void);
-
780 
-
803 int libevdev_new_from_fd(int fd, struct libevdev **dev);
-
804 
-
818 void libevdev_free(struct libevdev *dev);
-
819 
- - - -
826  LIBEVDEV_LOG_DEBUG = 30
-
827 };
-
828 
-
845 typedef void (*libevdev_log_func_t)(enum libevdev_log_priority priority,
-
846  void *data,
-
847  const char *file, int line,
-
848  const char *func,
-
849  const char *format, va_list args)
- -
851 
- -
871 
- -
885 
- -
898 
-
918 typedef void (*libevdev_device_log_func_t)(const struct libevdev *dev,
-
919  enum libevdev_log_priority priority,
-
920  void *data,
-
921  const char *file, int line,
-
922  const char *func,
-
923  const char *format, va_list args)
- -
925 
-
947 void libevdev_set_device_log_function(struct libevdev *dev,
- -
949  enum libevdev_log_priority priority,
-
950  void *data);
-
951 
- - -
957  LIBEVDEV_UNGRAB = 4
-
958 };
-
959 
-
982 int libevdev_grab(struct libevdev *dev, enum libevdev_grab_mode grab);
-
983 
-
1016 int libevdev_set_fd(struct libevdev* dev, int fd);
-
1017 
-
1056 int libevdev_change_fd(struct libevdev* dev, int fd);
-
1057 
-
1066 int libevdev_get_fd(const struct libevdev* dev);
-
1067 
- - - -
1088 };
-
1089 
-
1140 int libevdev_next_event(struct libevdev *dev, unsigned int flags, struct input_event *ev);
-
1141 
-
1164 int libevdev_has_event_pending(struct libevdev *dev);
-
1165 
-
1180 const char* libevdev_get_name(const struct libevdev *dev);
-
1181 
-
1195 void libevdev_set_name(struct libevdev *dev, const char *name);
-
1196 
-
1212 const char * libevdev_get_phys(const struct libevdev *dev);
-
1213 
-
1227 void libevdev_set_phys(struct libevdev *dev, const char *phys);
-
1228 
-
1242 const char * libevdev_get_uniq(const struct libevdev *dev);
-
1243 
-
1257 void libevdev_set_uniq(struct libevdev *dev, const char *uniq);
-
1258 
-
1268 int libevdev_get_id_product(const struct libevdev *dev);
-
1269 
-
1281 void libevdev_set_id_product(struct libevdev *dev, int product_id);
-
1282 
-
1292 int libevdev_get_id_vendor(const struct libevdev *dev);
-
1293 
-
1305 void libevdev_set_id_vendor(struct libevdev *dev, int vendor_id);
-
1306 
-
1316 int libevdev_get_id_bustype(const struct libevdev *dev);
-
1317 
-
1329 void libevdev_set_id_bustype(struct libevdev *dev, int bustype);
-
1330 
-
1340 int libevdev_get_id_version(const struct libevdev *dev);
-
1341 
-
1353 void libevdev_set_id_version(struct libevdev *dev, int version);
-
1354 
-
1364 int libevdev_get_driver_version(const struct libevdev *dev);
-
1365 
-
1376 int libevdev_has_property(const struct libevdev *dev, unsigned int prop);
-
1377 
-
1389 int libevdev_enable_property(struct libevdev *dev, unsigned int prop);
-
1390 
-
1399 int libevdev_disable_property(struct libevdev *dev, unsigned int prop);
-
1400 
-
1411 int libevdev_has_event_type(const struct libevdev *dev, unsigned int type);
-
1412 
-
1424 int libevdev_has_event_code(const struct libevdev *dev, unsigned int type, unsigned int code);
-
1425 
-
1438 int libevdev_get_abs_minimum(const struct libevdev *dev, unsigned int code);
-
1439 
-
1452 int libevdev_get_abs_maximum(const struct libevdev *dev, unsigned int code);
-
1453 
-
1466 int libevdev_get_abs_fuzz(const struct libevdev *dev, unsigned int code);
-
1467 
-
1480 int libevdev_get_abs_flat(const struct libevdev *dev, unsigned int code);
-
1481 
-
1494 int libevdev_get_abs_resolution(const struct libevdev *dev, unsigned int code);
-
1495 
-
1509 const struct input_absinfo* libevdev_get_abs_info(const struct libevdev *dev, unsigned int code);
-
1510 
-
1533 int libevdev_get_event_value(const struct libevdev *dev, unsigned int type, unsigned int code);
-
1534 
-
1569 int libevdev_set_event_value(struct libevdev *dev, unsigned int type, unsigned int code, int value);
-
1570 
-
1596 int libevdev_fetch_event_value(const struct libevdev *dev, unsigned int type, unsigned int code, int *value);
-
1597 
-
1618 int libevdev_get_slot_value(const struct libevdev *dev, unsigned int slot, unsigned int code);
-
1619 
-
1648 int libevdev_set_slot_value(struct libevdev *dev, unsigned int slot, unsigned int code, int value);
-
1649 
-
1675 int libevdev_fetch_slot_value(const struct libevdev *dev, unsigned int slot, unsigned int code, int *value);
-
1676 
-
1690 int libevdev_get_num_slots(const struct libevdev *dev);
-
1691 
-
1707 int libevdev_get_current_slot(const struct libevdev *dev);
-
1708 
-
1720 void libevdev_set_abs_minimum(struct libevdev *dev, unsigned int code, int val);
-
1721 
-
1733 void libevdev_set_abs_maximum(struct libevdev *dev, unsigned int code, int val);
-
1734 
-
1746 void libevdev_set_abs_fuzz(struct libevdev *dev, unsigned int code, int val);
-
1747 
-
1759 void libevdev_set_abs_flat(struct libevdev *dev, unsigned int code, int val);
-
1760 
-
1772 void libevdev_set_abs_resolution(struct libevdev *dev, unsigned int code, int val);
-
1773 
-
1785 void libevdev_set_abs_info(struct libevdev *dev, unsigned int code, const struct input_absinfo *abs);
-
1786 
-
1804 int libevdev_enable_event_type(struct libevdev *dev, unsigned int type);
-
1805 
-
1832 int libevdev_disable_event_type(struct libevdev *dev, unsigned int type);
-
1833 
-
1867 int libevdev_enable_event_code(struct libevdev *dev, unsigned int type, unsigned int code, const void *data);
-
1868 
-
1896 int libevdev_disable_event_code(struct libevdev *dev, unsigned int type, unsigned int code);
-
1897 
-
1912 int libevdev_kernel_set_abs_info(struct libevdev *dev, unsigned int code, const struct input_absinfo *abs);
-
1913 
- - -
1919  LIBEVDEV_LED_OFF = 4
-
1920 };
-
1921 
-
1935 int libevdev_kernel_set_led_value(struct libevdev *dev, unsigned int code, enum libevdev_led_value value);
-
1936 
-
1960 int libevdev_kernel_set_led_values(struct libevdev *dev, ...);
-
1961 
-
1976 int libevdev_set_clock_id(struct libevdev *dev, int clockid);
-
1977 
-
1999 int libevdev_event_is_type(const struct input_event *ev, unsigned int type);
-
2000 
-
2024 int libevdev_event_is_code(const struct input_event *ev, unsigned int type, unsigned int code);
-
2025 
-
2037 const char * libevdev_event_type_get_name(unsigned int type);
-
2050 const char * libevdev_event_code_get_name(unsigned int type, unsigned int code);
-
2051 
-
2072 const char * libevdev_event_value_get_name(unsigned int type,
-
2073  unsigned int code,
-
2074  int value);
-
2088 const char* libevdev_property_get_name(unsigned int prop);
-
2089 
-
2102 int libevdev_event_type_get_max(unsigned int type);
-
2103 
-
2118 int libevdev_event_type_from_name(const char *name);
-
2119 
-
2136 int libevdev_event_type_from_name_n(const char *name, size_t len);
-
2137 
-
2157 int libevdev_event_code_from_name(unsigned int type, const char *name);
-
2158 
-
2180 int libevdev_event_code_from_name_n(unsigned int type, const char *name,
-
2181  size_t len);
-
2182 
-
2204 int libevdev_event_value_from_name(unsigned int type, unsigned int code,
-
2205  const char *name);
-
2206 
-
2223 int
- -
2225 
-
2244 int
-
2245 libevdev_event_type_from_code_name_n(const char *name, size_t len);
-
2246 
-
2263 int
- -
2265 
-
2284 int
-
2285 libevdev_event_code_from_code_name_n(const char *name, size_t len);
-
2286 
-
2310 int libevdev_event_value_from_name_n(unsigned int type, unsigned int code,
-
2311  const char *name, size_t len);
-
2312 
-
2325 int libevdev_property_from_name(const char *name);
-
2326 
-
2341 int libevdev_property_from_name_n(const char *name, size_t len);
-
2342 
-
2360 int libevdev_get_repeat(const struct libevdev *dev, int *delay, int *period);
-
2361 
-
2362 /********* DEPRECATED SECTION *********/
-
2363 #if defined(__GNUC__) && __GNUC__ >= 4
-
2364 #define LIBEVDEV_DEPRECATED __attribute__ ((deprecated))
-
2365 #else
-
2366 #define LIBEVDEV_DEPRECATED
-
2367 #endif
-
2368 
-
2369 #ifdef __cplusplus
-
2370 }
-
2371 #endif
-
2372 
-
2373 #endif /* LIBEVDEV_H */
-
-
void libevdev_set_abs_resolution(struct libevdev *dev, unsigned int code, int val)
Change the resolution for the given EV_ABS event code, if the code exists.
-
@ LIBEVDEV_UNGRAB
Ungrab the device if currently grabbed.
Definition: libevdev.h:957
-
int libevdev_event_type_get_max(unsigned int type)
-
int libevdev_has_event_code(const struct libevdev *dev, unsigned int type, unsigned int code)
-
int libevdev_event_value_from_name_n(unsigned int type, unsigned int code, const char *name, size_t len)
Look up an event value by its type, code and name.
-
const struct input_absinfo * libevdev_get_abs_info(const struct libevdev *dev, unsigned int code)
Get the axis info for the given axis, as advertised by the kernel.
-
void libevdev_set_id_version(struct libevdev *dev, int version)
-
int libevdev_event_type_from_name(const char *name)
Look up an event-type by its name.
-
int libevdev_kernel_set_led_value(struct libevdev *dev, unsigned int code, enum libevdev_led_value value)
Turn an LED on or off.
+
33 #include <linux/input.h>
+
34 #include <stdarg.h>
+
35 
+
36 #define LIBEVDEV_ATTRIBUTE_PRINTF(_format, _args) __attribute__ ((format (printf, _format, _args)))
+
37 
+
755 struct libevdev;
+
756 
+ + + + + +
766 };
+
767 
+
782 struct libevdev* libevdev_new(void);
+
783 
+
806 int libevdev_new_from_fd(int fd, struct libevdev **dev);
+
807 
+
821 void libevdev_free(struct libevdev *dev);
+
822 
+ + + +
829  LIBEVDEV_LOG_DEBUG = 30
+
830 };
+
831 
+
848 typedef void (*libevdev_log_func_t)(enum libevdev_log_priority priority,
+
849  void *data,
+
850  const char *file, int line,
+
851  const char *func,
+
852  const char *format, va_list args)
+ +
854 
+ +
874 
+ +
888 
+ +
901 
+
921 typedef void (*libevdev_device_log_func_t)(const struct libevdev *dev,
+
922  enum libevdev_log_priority priority,
+
923  void *data,
+
924  const char *file, int line,
+
925  const char *func,
+
926  const char *format, va_list args)
+ +
928 
+
950 void libevdev_set_device_log_function(struct libevdev *dev,
+ +
952  enum libevdev_log_priority priority,
+
953  void *data);
+
954 
+ + +
960  LIBEVDEV_UNGRAB = 4
+
961 };
+
962 
+
985 int libevdev_grab(struct libevdev *dev, enum libevdev_grab_mode grab);
+
986 
+
1019 int libevdev_set_fd(struct libevdev* dev, int fd);
+
1020 
+
1059 int libevdev_change_fd(struct libevdev* dev, int fd);
+
1060 
+
1069 int libevdev_get_fd(const struct libevdev* dev);
+
1070 
+ + + +
1091 };
+
1092 
+
1143 int libevdev_next_event(struct libevdev *dev, unsigned int flags, struct input_event *ev);
+
1144 
+
1167 int libevdev_has_event_pending(struct libevdev *dev);
+
1168 
+
1183 const char* libevdev_get_name(const struct libevdev *dev);
+
1184 
+
1198 void libevdev_set_name(struct libevdev *dev, const char *name);
+
1199 
+
1215 const char * libevdev_get_phys(const struct libevdev *dev);
+
1216 
+
1230 void libevdev_set_phys(struct libevdev *dev, const char *phys);
+
1231 
+
1245 const char * libevdev_get_uniq(const struct libevdev *dev);
+
1246 
+
1260 void libevdev_set_uniq(struct libevdev *dev, const char *uniq);
+
1261 
+
1271 int libevdev_get_id_product(const struct libevdev *dev);
+
1272 
+
1284 void libevdev_set_id_product(struct libevdev *dev, int product_id);
+
1285 
+
1295 int libevdev_get_id_vendor(const struct libevdev *dev);
+
1296 
+
1308 void libevdev_set_id_vendor(struct libevdev *dev, int vendor_id);
+
1309 
+
1319 int libevdev_get_id_bustype(const struct libevdev *dev);
+
1320 
+
1332 void libevdev_set_id_bustype(struct libevdev *dev, int bustype);
+
1333 
+
1343 int libevdev_get_id_version(const struct libevdev *dev);
+
1344 
+
1356 void libevdev_set_id_version(struct libevdev *dev, int version);
+
1357 
+
1367 int libevdev_get_driver_version(const struct libevdev *dev);
+
1368 
+
1379 int libevdev_has_property(const struct libevdev *dev, unsigned int prop);
+
1380 
+
1392 int libevdev_enable_property(struct libevdev *dev, unsigned int prop);
+
1393 
+
1402 int libevdev_disable_property(struct libevdev *dev, unsigned int prop);
+
1403 
+
1414 int libevdev_has_event_type(const struct libevdev *dev, unsigned int type);
+
1415 
+
1427 int libevdev_has_event_code(const struct libevdev *dev, unsigned int type, unsigned int code);
+
1428 
+
1441 int libevdev_get_abs_minimum(const struct libevdev *dev, unsigned int code);
+
1442 
+
1455 int libevdev_get_abs_maximum(const struct libevdev *dev, unsigned int code);
+
1456 
+
1469 int libevdev_get_abs_fuzz(const struct libevdev *dev, unsigned int code);
+
1470 
+
1483 int libevdev_get_abs_flat(const struct libevdev *dev, unsigned int code);
+
1484 
+
1497 int libevdev_get_abs_resolution(const struct libevdev *dev, unsigned int code);
+
1498 
+
1512 const struct input_absinfo* libevdev_get_abs_info(const struct libevdev *dev, unsigned int code);
+
1513 
+
1535 int libevdev_get_event_value(const struct libevdev *dev, unsigned int type, unsigned int code);
+
1536 
+
1571 int libevdev_set_event_value(struct libevdev *dev, unsigned int type, unsigned int code, int value);
+
1572 
+
1598 int libevdev_fetch_event_value(const struct libevdev *dev, unsigned int type, unsigned int code, int *value);
+
1599 
+
1620 int libevdev_get_slot_value(const struct libevdev *dev, unsigned int slot, unsigned int code);
+
1621 
+
1650 int libevdev_set_slot_value(struct libevdev *dev, unsigned int slot, unsigned int code, int value);
+
1651 
+
1677 int libevdev_fetch_slot_value(const struct libevdev *dev, unsigned int slot, unsigned int code, int *value);
+
1678 
+
1692 int libevdev_get_num_slots(const struct libevdev *dev);
+
1693 
+
1709 int libevdev_get_current_slot(const struct libevdev *dev);
+
1710 
+
1722 void libevdev_set_abs_minimum(struct libevdev *dev, unsigned int code, int val);
+
1723 
+
1735 void libevdev_set_abs_maximum(struct libevdev *dev, unsigned int code, int val);
+
1736 
+
1748 void libevdev_set_abs_fuzz(struct libevdev *dev, unsigned int code, int val);
+
1749 
+
1761 void libevdev_set_abs_flat(struct libevdev *dev, unsigned int code, int val);
+
1762 
+
1774 void libevdev_set_abs_resolution(struct libevdev *dev, unsigned int code, int val);
+
1775 
+
1787 void libevdev_set_abs_info(struct libevdev *dev, unsigned int code, const struct input_absinfo *abs);
+
1788 
+
1806 int libevdev_enable_event_type(struct libevdev *dev, unsigned int type);
+
1807 
+
1834 int libevdev_disable_event_type(struct libevdev *dev, unsigned int type);
+
1835 
+
1869 int libevdev_enable_event_code(struct libevdev *dev, unsigned int type, unsigned int code, const void *data);
+
1870 
+
1898 int libevdev_disable_event_code(struct libevdev *dev, unsigned int type, unsigned int code);
+
1899 
+
1914 int libevdev_kernel_set_abs_info(struct libevdev *dev, unsigned int code, const struct input_absinfo *abs);
+
1915 
+ + +
1921  LIBEVDEV_LED_OFF = 4
+
1922 };
+
1923 
+
1937 int libevdev_kernel_set_led_value(struct libevdev *dev, unsigned int code, enum libevdev_led_value value);
+
1938 
+
1962 int libevdev_kernel_set_led_values(struct libevdev *dev, ...);
+
1963 
+
1978 int libevdev_set_clock_id(struct libevdev *dev, int clockid);
+
1979 
+
2001 int libevdev_event_is_type(const struct input_event *ev, unsigned int type);
+
2002 
+
2026 int libevdev_event_is_code(const struct input_event *ev, unsigned int type, unsigned int code);
+
2027 
+
2039 const char * libevdev_event_type_get_name(unsigned int type);
+
2052 const char * libevdev_event_code_get_name(unsigned int type, unsigned int code);
+
2053 
+
2074 const char * libevdev_event_value_get_name(unsigned int type,
+
2075  unsigned int code,
+
2076  int value);
+
2090 const char* libevdev_property_get_name(unsigned int prop);
+
2091 
+
2104 int libevdev_event_type_get_max(unsigned int type);
+
2105 
+
2120 int libevdev_event_type_from_name(const char *name);
+
2121 
+
2138 int libevdev_event_type_from_name_n(const char *name, size_t len);
+
2139 
+
2159 int libevdev_event_code_from_name(unsigned int type, const char *name);
+
2160 
+
2182 int libevdev_event_code_from_name_n(unsigned int type, const char *name,
+
2183  size_t len);
+
2184 
+
2206 int libevdev_event_value_from_name(unsigned int type, unsigned int code,
+
2207  const char *name);
+
2208 
+
2225 int
+ +
2227 
+
2246 int
+
2247 libevdev_event_type_from_code_name_n(const char *name, size_t len);
+
2248 
+
2265 int
+ +
2267 
+
2286 int
+
2287 libevdev_event_code_from_code_name_n(const char *name, size_t len);
+
2288 
+
2312 int libevdev_event_value_from_name_n(unsigned int type, unsigned int code,
+
2313  const char *name, size_t len);
+
2314 
+
2327 int libevdev_property_from_name(const char *name);
+
2328 
+
2343 int libevdev_property_from_name_n(const char *name, size_t len);
+
2344 
+
2362 int libevdev_get_repeat(const struct libevdev *dev, int *delay, int *period);
+
2363 
+
2364 /********* DEPRECATED SECTION *********/
+
2365 #if defined(__GNUC__) && __GNUC__ >= 4
+
2366 #define LIBEVDEV_DEPRECATED __attribute__ ((deprecated))
+
2367 #else
+
2368 #define LIBEVDEV_DEPRECATED
+
2369 #endif
+
2370 
+
2371 #ifdef __cplusplus
+
2372 }
+
2373 #endif
+
2374 
+
2375 #endif /* LIBEVDEV_H */
+
int libevdev_get_id_vendor(const struct libevdev *dev)
+
int libevdev_fetch_event_value(const struct libevdev *dev, unsigned int type, unsigned int code, int *value)
Fetch the current value of the event type.
+
int libevdev_get_abs_fuzz(const struct libevdev *dev, unsigned int code)
Get the axis fuzz for the given axis, as advertised by the kernel.
+
int libevdev_get_id_product(const struct libevdev *dev)
+
int libevdev_get_driver_version(const struct libevdev *dev)
int libevdev_has_property(const struct libevdev *dev, unsigned int prop)
-
int libevdev_event_type_from_code_name_n(const char *name, size_t len)
Look up an event type for a event code name.
-
@ LIBEVDEV_GRAB
Grab the device if not currently grabbed.
Definition: libevdev.h:956
-
int libevdev_event_value_from_name(unsigned int type, unsigned int code, const char *name)
Look up an event value by its type, code and name.
-
@ LIBEVDEV_READ_FLAG_BLOCKING
The fd is not in O_NONBLOCK and a read may block.
Definition: libevdev.h:762
-
int libevdev_property_from_name_n(const char *name, size_t len)
Look up an input property by its name.
-
@ LIBEVDEV_LED_OFF
Turn the LED off.
Definition: libevdev.h:1919
+
int libevdev_has_event_type(const struct libevdev *dev, unsigned int type)
+
int libevdev_get_abs_minimum(const struct libevdev *dev, unsigned int code)
Get the minimum axis value for the given axis, as advertised by the kernel.
+
const char * libevdev_get_phys(const struct libevdev *dev)
Retrieve the device's physical location, either as set by the caller or as read from the kernel.
+
int libevdev_get_event_value(const struct libevdev *dev, unsigned int type, unsigned int code)
Behaviour of this function is undefined if the device does not provide the event.
+
int libevdev_get_abs_flat(const struct libevdev *dev, unsigned int code)
Get the axis flat for the given axis, as advertised by the kernel.
+
const struct input_absinfo * libevdev_get_abs_info(const struct libevdev *dev, unsigned int code)
Get the axis info for the given axis, as advertised by the kernel.
+
const char * libevdev_get_uniq(const struct libevdev *dev)
Retrieve the device's unique identifier, either as set by the caller or as read from the kernel.
int libevdev_get_abs_resolution(const struct libevdev *dev, unsigned int code)
Get the axis resolution for the given axis, as advertised by the kernel.
-
int libevdev_event_type_from_name_n(const char *name, size_t len)
Look up an event-type by its name.
-
libevdev_read_status
Definition: libevdev.h:1071
-
int libevdev_enable_event_type(struct libevdev *dev, unsigned int type)
Forcibly enable an event type on this device, even if the underlying device does not support it.
-
int libevdev_property_from_name(const char *name)
Look up an input property by its name.
-
int libevdev_enable_property(struct libevdev *dev, unsigned int prop)
-
int libevdev_kernel_set_led_values(struct libevdev *dev,...)
Turn multiple LEDs on or off simultaneously.
-
int libevdev_fetch_event_value(const struct libevdev *dev, unsigned int type, unsigned int code, int *value)
Fetch the current value of the event type.
-
void libevdev_set_log_function(libevdev_log_func_t logfunc, void *data)
Set a printf-style logging handler for library-internal logging.
-
struct libevdev * libevdev_new(void)
Initialize a new libevdev device.
-
int libevdev_get_slot_value(const struct libevdev *dev, unsigned int slot, unsigned int code)
Return the current value of the code for the given slot.
-
libevdev_log_priority
Definition: libevdev.h:823
int libevdev_get_id_version(const struct libevdev *dev)
-
#define LIBEVDEV_ATTRIBUTE_PRINTF(_format, _args)
Definition: libevdev.h:33
-
void(* libevdev_log_func_t)(enum libevdev_log_priority priority, void *data, const char *file, int line, const char *func, const char *format, va_list args)
Logging function called by library-internal logging.
Definition: libevdev.h:845
-
const char * libevdev_event_code_get_name(unsigned int type, unsigned int code)
-
int libevdev_kernel_set_abs_info(struct libevdev *dev, unsigned int code, const struct input_absinfo *abs)
Set the device's EV_ABS axis to the value defined in the abs parameter.
-
int libevdev_get_event_value(const struct libevdev *dev, unsigned int type, unsigned int code)
Behaviour of this function is undefined if the device does not provide the event.
-
int libevdev_event_code_from_name_n(unsigned int type, const char *name, size_t len)
Look up an event code by its type and name.
-
int libevdev_event_code_from_code_name_n(const char *name, size_t len)
Look up an event code by its name.
-
int libevdev_set_slot_value(struct libevdev *dev, unsigned int slot, unsigned int code, int value)
Set the value for a given code for the given slot.
+
int libevdev_get_abs_maximum(const struct libevdev *dev, unsigned int code)
Get the maximum axis value for the given axis, as advertised by the kernel.
+
int libevdev_get_id_bustype(const struct libevdev *dev)
+
int libevdev_has_event_code(const struct libevdev *dev, unsigned int type, unsigned int code)
+
const char * libevdev_get_name(const struct libevdev *dev)
Retrieve the device's name, either as set by the caller or as read from the kernel.
+
int libevdev_get_repeat(const struct libevdev *dev, int *delay, int *period)
Get the repeat delay and repeat period values for this device.
+
libevdev_read_status
Definition: libevdev.h:1074
+
libevdev_read_flag
Definition: libevdev.h:760
+
int libevdev_next_event(struct libevdev *dev, unsigned int flags, struct input_event *ev)
Get the next event from the device.
+
int libevdev_has_event_pending(struct libevdev *dev)
Check if there are events waiting for us.
+
@ LIBEVDEV_READ_STATUS_SYNC
Depending on the libevdev_next_event() read flag:
Definition: libevdev.h:1090
+
@ LIBEVDEV_READ_STATUS_SUCCESS
libevdev_next_event() has finished without an error and an event is available for processing.
Definition: libevdev.h:1081
+
@ LIBEVDEV_READ_FLAG_BLOCKING
The fd is not in O_NONBLOCK and a read may block.
Definition: libevdev.h:765
+
@ LIBEVDEV_READ_FLAG_SYNC
Process data in sync mode.
Definition: libevdev.h:761
+
@ LIBEVDEV_READ_FLAG_FORCE_SYNC
Pretend the next event is a SYN_DROPPED and require the caller to sync.
Definition: libevdev.h:763
+
@ LIBEVDEV_READ_FLAG_NORMAL
Process data in normal mode.
Definition: libevdev.h:762
+
struct libevdev * libevdev_new(void)
Initialize a new libevdev device.
+
int libevdev_grab(struct libevdev *dev, enum libevdev_grab_mode grab)
Grab or ungrab the device through a kernel EVIOCGRAB.
int libevdev_set_fd(struct libevdev *dev, int fd)
Set the fd for this struct and initialize internal data.
-
void libevdev_set_id_vendor(struct libevdev *dev, int vendor_id)
-
void libevdev_set_abs_flat(struct libevdev *dev, unsigned int code, int val)
Change the flat for the given EV_ABS event code, if the code exists.
+
int libevdev_new_from_fd(int fd, struct libevdev **dev)
Initialize a new libevdev device from the given fd.
+
libevdev_grab_mode
Definition: libevdev.h:958
+
int libevdev_get_fd(const struct libevdev *dev)
+
int libevdev_change_fd(struct libevdev *dev, int fd)
Change the fd for this device, without re-reading the actual device.
void libevdev_free(struct libevdev *dev)
Clean up and free the libevdev struct.
-
enum libevdev_log_priority libevdev_get_log_priority(void)
Return the current log priority level.
-
int libevdev_get_repeat(const struct libevdev *dev, int *delay, int *period)
Get the repeat delay and repeat period values for this device.
-
int libevdev_fetch_slot_value(const struct libevdev *dev, unsigned int slot, unsigned int code, int *value)
Fetch the current value of the code for the given slot.
+
@ LIBEVDEV_UNGRAB
Ungrab the device if currently grabbed.
Definition: libevdev.h:960
+
@ LIBEVDEV_GRAB
Grab the device if not currently grabbed.
Definition: libevdev.h:959
+
int libevdev_set_slot_value(struct libevdev *dev, unsigned int slot, unsigned int code, int value)
Set the value for a given code for the given slot.
+
void libevdev_set_abs_resolution(struct libevdev *dev, unsigned int code, int val)
Change the resolution for the given EV_ABS event code, if the code exists.
+
void libevdev_set_abs_maximum(struct libevdev *dev, unsigned int code, int val)
Change the maximum for the given EV_ABS event code, if the code exists.
+
int libevdev_set_clock_id(struct libevdev *dev, int clockid)
Set the clock ID to be used for timestamps.
+
int libevdev_kernel_set_abs_info(struct libevdev *dev, unsigned int code, const struct input_absinfo *abs)
Set the device's EV_ABS axis to the value defined in the abs parameter.
+
void libevdev_set_uniq(struct libevdev *dev, const char *uniq)
Change the device's unique identifier as returned by libevdev_get_uniq().
+
int libevdev_enable_event_code(struct libevdev *dev, unsigned int type, unsigned int code, const void *data)
Forcibly enable an event code on this device, even if the underlying device does not support it.
+
int libevdev_enable_event_type(struct libevdev *dev, unsigned int type)
Forcibly enable an event type on this device, even if the underlying device does not support it.
+
int libevdev_disable_event_code(struct libevdev *dev, unsigned int type, unsigned int code)
Forcibly disable an event code on this device, even if the underlying device provides it.
void libevdev_set_id_product(struct libevdev *dev, int product_id)
-
@ LIBEVDEV_READ_FLAG_FORCE_SYNC
Pretend the next event is a SYN_DROPPED and require the caller to sync.
Definition: libevdev.h:760
-
int libevdev_has_event_type(const struct libevdev *dev, unsigned int type)
+
int libevdev_set_event_value(struct libevdev *dev, unsigned int type, unsigned int code, int value)
Set the value for a given event type and code.
+
libevdev_led_value
Definition: libevdev.h:1919
+
void libevdev_set_id_vendor(struct libevdev *dev, int vendor_id)
+
int libevdev_disable_property(struct libevdev *dev, unsigned int prop)
+
int libevdev_kernel_set_led_values(struct libevdev *dev,...)
Turn multiple LEDs on or off simultaneously.
+
void libevdev_set_abs_fuzz(struct libevdev *dev, unsigned int code, int val)
Change the fuzz for the given EV_ABS event code, if the code exists.
+
int libevdev_kernel_set_led_value(struct libevdev *dev, unsigned int code, enum libevdev_led_value value)
Turn an LED on or off.
+
int libevdev_disable_event_type(struct libevdev *dev, unsigned int type)
Forcibly disable an event type on this device, even if the underlying device provides it.
+
void libevdev_set_abs_flat(struct libevdev *dev, unsigned int code, int val)
Change the flat for the given EV_ABS event code, if the code exists.
void libevdev_set_abs_minimum(struct libevdev *dev, unsigned int code, int val)
Change the minimum for the given EV_ABS event code, if the code exists.
-
@ LIBEVDEV_LOG_INFO
informational messages
Definition: libevdev.h:825
-
int libevdev_has_event_pending(struct libevdev *dev)
Check if there are events waiting for us.
-
void libevdev_set_abs_info(struct libevdev *dev, unsigned int code, const struct input_absinfo *abs)
Change the abs info for the given EV_ABS event code, if the code exists.
-
int libevdev_get_id_bustype(const struct libevdev *dev)
+
void libevdev_set_phys(struct libevdev *dev, const char *phys)
Change the device's physical location as returned by libevdev_get_phys().
void libevdev_set_name(struct libevdev *dev, const char *name)
Change the device's name as returned by libevdev_get_name().
-
const char * libevdev_get_uniq(const struct libevdev *dev)
Retrieve the device's unique identifier, either as set by the caller or as read from the kernel.
+
void libevdev_set_id_version(struct libevdev *dev, int version)
void libevdev_set_id_bustype(struct libevdev *dev, int bustype)
-
libevdev_read_flag
Definition: libevdev.h:757
-
int libevdev_get_id_product(const struct libevdev *dev)
+
int libevdev_enable_property(struct libevdev *dev, unsigned int prop)
+
void libevdev_set_abs_info(struct libevdev *dev, unsigned int code, const struct input_absinfo *abs)
Change the abs info for the given EV_ABS event code, if the code exists.
+
@ LIBEVDEV_LED_OFF
Turn the LED off.
Definition: libevdev.h:1921
+
@ LIBEVDEV_LED_ON
Turn the LED on.
Definition: libevdev.h:1920
+
libevdev_log_priority
Definition: libevdev.h:826
+
enum libevdev_log_priority libevdev_get_log_priority(void)
Return the current log priority level.
void libevdev_set_device_log_function(struct libevdev *dev, libevdev_device_log_func_t logfunc, enum libevdev_log_priority priority, void *data)
Set a printf-style logging handler for library-internal logging for this device context.
-
libevdev_led_value
Definition: libevdev.h:1917
-
int libevdev_get_id_vendor(const struct libevdev *dev)
-
void libevdev_set_uniq(struct libevdev *dev, const char *uniq)
Change the device's unique identifier as returned by libevdev_get_uniq().
-
@ LIBEVDEV_LOG_ERROR
critical errors and application bugs
Definition: libevdev.h:824
-
int libevdev_get_abs_flat(const struct libevdev *dev, unsigned int code)
Get the axis flat for the given axis, as advertised by the kernel.
-
int libevdev_get_num_slots(const struct libevdev *dev)
Get the number of slots supported by this device.
-
@ LIBEVDEV_READ_STATUS_SYNC
Depending on the libevdev_next_event() read flag:
Definition: libevdev.h:1087
-
@ LIBEVDEV_LOG_DEBUG
debug information
Definition: libevdev.h:826
-
int libevdev_next_event(struct libevdev *dev, unsigned int flags, struct input_event *ev)
Get the next event from the device.
-
int libevdev_get_abs_minimum(const struct libevdev *dev, unsigned int code)
Get the minimum axis value for the given axis, as advertised by the kernel.
-
int libevdev_disable_property(struct libevdev *dev, unsigned int prop)
-
@ LIBEVDEV_READ_STATUS_SUCCESS
libevdev_next_event() has finished without an error and an event is available for processing.
Definition: libevdev.h:1078
-
int libevdev_get_current_slot(const struct libevdev *dev)
Get the currently active slot.
+
void libevdev_set_log_function(libevdev_log_func_t logfunc, void *data)
Set a printf-style logging handler for library-internal logging.
+
void(* libevdev_device_log_func_t)(const struct libevdev *dev, enum libevdev_log_priority priority, void *data, const char *file, int line, const char *func, const char *format, va_list args)
Logging function called by library-internal logging for a specific libevdev context.
Definition: libevdev.h:921
+
void(* libevdev_log_func_t)(enum libevdev_log_priority priority, void *data, const char *file, int line, const char *func, const char *format, va_list args)
Logging function called by library-internal logging.
Definition: libevdev.h:848
+
void libevdev_set_log_priority(enum libevdev_log_priority priority)
Define the minimum level to be printed to the log handler.
+
@ LIBEVDEV_LOG_ERROR
critical errors and application bugs
Definition: libevdev.h:827
+
@ LIBEVDEV_LOG_INFO
informational messages
Definition: libevdev.h:828
+
@ LIBEVDEV_LOG_DEBUG
debug information
Definition: libevdev.h:829
+
int libevdev_event_code_from_name_n(unsigned int type, const char *name, size_t len)
Look up an event code by its type and name.
+
int libevdev_event_value_from_name(unsigned int type, unsigned int code, const char *name)
Look up an event value by its type, code and name.
int libevdev_event_is_code(const struct input_event *ev, unsigned int type, unsigned int code)
Helper function to check if an event is of a specific type and code.
-
int libevdev_enable_event_code(struct libevdev *dev, unsigned int type, unsigned int code, const void *data)
Forcibly enable an event code on this device, even if the underlying device does not support it.
-
const char * libevdev_property_get_name(unsigned int prop)
-
const char * libevdev_event_value_get_name(unsigned int type, unsigned int code, int value)
This function resolves the event value for a code.
-
int libevdev_get_driver_version(const struct libevdev *dev)
+
int libevdev_event_type_from_name_n(const char *name, size_t len)
Look up an event-type by its name.
+
int libevdev_event_code_from_code_name_n(const char *name, size_t len)
Look up an event code by its name.
+
int libevdev_event_type_from_name(const char *name)
Look up an event-type by its name.
int libevdev_event_code_from_name(unsigned int type, const char *name)
Look up an event code by its type and name.
-
int libevdev_set_clock_id(struct libevdev *dev, int clockid)
Set the clock ID to be used for timestamps.
-
int libevdev_get_abs_maximum(const struct libevdev *dev, unsigned int code)
Get the maximum axis value for the given axis, as advertised by the kernel.
-
void libevdev_set_phys(struct libevdev *dev, const char *phys)
Change the device's physical location as returned by libevdev_get_phys().
-
int libevdev_disable_event_code(struct libevdev *dev, unsigned int type, unsigned int code)
Forcibly disable an event code on this device, even if the underlying device provides it.
-
int libevdev_change_fd(struct libevdev *dev, int fd)
Change the fd for this device, without re-reading the actual device.
-
int libevdev_disable_event_type(struct libevdev *dev, unsigned int type)
Forcibly disable an event type on this device, even if the underlying device provides it.
-
const char * libevdev_get_phys(const struct libevdev *dev)
Retrieve the device's physical location, either as set by the caller or as read from the kernel.
-
int libevdev_get_fd(const struct libevdev *dev)
-
int libevdev_get_abs_fuzz(const struct libevdev *dev, unsigned int code)
Get the axis fuzz for the given axis, as advertised by the kernel.
-
void libevdev_set_abs_fuzz(struct libevdev *dev, unsigned int code, int val)
Change the fuzz for the given EV_ABS event code, if the code exists.
-
const char * libevdev_event_type_get_name(unsigned int type)
-
void libevdev_set_log_priority(enum libevdev_log_priority priority)
Define the minimum level to be printed to the log handler.
-
int libevdev_event_code_from_code_name(const char *name)
Look up an event code by its name.
-
int libevdev_grab(struct libevdev *dev, enum libevdev_grab_mode grab)
Grab or ungrab the device through a kernel EVIOCGRAB.
+
int libevdev_property_from_name(const char *name)
Look up an input property by its name.
+
int libevdev_property_from_name_n(const char *name, size_t len)
Look up an input property by its name.
+
int libevdev_event_type_from_code_name_n(const char *name, size_t len)
Look up an event type for a event code name.
+
const char * libevdev_event_code_get_name(unsigned int type, unsigned int code)
int libevdev_event_is_type(const struct input_event *ev, unsigned int type)
Helper function to check if an event is of a specific type.
-
libevdev_grab_mode
Definition: libevdev.h:955
-
const char * libevdev_get_name(const struct libevdev *dev)
Retrieve the device's name, either as set by the caller or as read from the kernel.
-
@ LIBEVDEV_LED_ON
Turn the LED on.
Definition: libevdev.h:1918
-
void libevdev_set_abs_maximum(struct libevdev *dev, unsigned int code, int val)
Change the maximum for the given EV_ABS event code, if the code exists.
-
@ LIBEVDEV_READ_FLAG_NORMAL
Process data in normal mode.
Definition: libevdev.h:759
-
@ LIBEVDEV_READ_FLAG_SYNC
Process data in sync mode.
Definition: libevdev.h:758
-
void(* libevdev_device_log_func_t)(const struct libevdev *dev, enum libevdev_log_priority priority, void *data, const char *file, int line, const char *func, const char *format, va_list args)
Logging function called by library-internal logging for a specific libevdev context.
Definition: libevdev.h:918
-
int libevdev_set_event_value(struct libevdev *dev, unsigned int type, unsigned int code, int value)
Set the value for a given event type and code.
+
int libevdev_event_code_from_code_name(const char *name)
Look up an event code by its name.
+
const char * libevdev_event_value_get_name(unsigned int type, unsigned int code, int value)
This function resolves the event value for a code.
+
int libevdev_event_type_get_max(unsigned int type)
+
const char * libevdev_event_type_get_name(unsigned int type)
+
const char * libevdev_property_get_name(unsigned int prop)
int libevdev_event_type_from_code_name(const char *name)
Look up an event type for a event code name.
-
int libevdev_new_from_fd(int fd, struct libevdev **dev)
Initialize a new libevdev device from the given fd.
+
int libevdev_event_value_from_name_n(unsigned int type, unsigned int code, const char *name, size_t len)
Look up an event value by its type, code and name.
+
int libevdev_get_slot_value(const struct libevdev *dev, unsigned int slot, unsigned int code)
Return the current value of the code for the given slot.
+
int libevdev_fetch_slot_value(const struct libevdev *dev, unsigned int slot, unsigned int code, int *value)
Fetch the current value of the code for the given slot.
+
int libevdev_get_current_slot(const struct libevdev *dev)
Get the currently active slot.
+
int libevdev_get_num_slots(const struct libevdev *dev)
Get the number of slots supported by this device.
+
#define LIBEVDEV_ATTRIBUTE_PRINTF(_format, _args)
Definition: libevdev.h:36
+
@@ -452,7 +455,7 @@ $(function() { diff --git a/doc/html/modules.html b/doc/html/modules.html index 4a5195fed2a953f00bbc67aaa4629cd3d73cb09d..73feb343e4a1b2bd386c45151520c094f5612740 100644 --- a/doc/html/modules.html +++ b/doc/html/modules.html @@ -6,7 +6,7 @@ - + libevdev: Modules @@ -25,7 +25,7 @@ @@ -36,10 +36,10 @@
- + @@ -95,7 +95,7 @@ $(function() { diff --git a/doc/html/pages.html b/doc/html/pages.html index 66e2b4065bab5fd3ee6758642f98394c1cdec8c0..1266783e38ea795ed121d0dd8e23680f57ad3a4c 100644 --- a/doc/html/pages.html +++ b/doc/html/pages.html @@ -6,7 +6,7 @@ - + libevdev: Related Pages @@ -25,7 +25,7 @@ @@ -36,10 +36,10 @@
- + @@ -94,7 +94,7 @@ $(function() { diff --git a/doc/html/search/all_0.html b/doc/html/search/all_0.html index a34319f3095081cfc50008dc8dda02588cd44eb5..1ec5b2d597f21e1c7b676f7f3167ffc217622540 100644 --- a/doc/html/search/all_0.html +++ b/doc/html/search/all_0.html @@ -1,7 +1,8 @@ - + + - + @@ -10,14 +11,14 @@
Loading...
- +
Searching...
No Matches
- +
diff --git a/doc/html/search/all_1.html b/doc/html/search/all_1.html index 51aff6f69cae8c3b53c814e6022909de43eff7cb..9f80e90431b7c693060f893c643e63cdcf60f53c 100644 --- a/doc/html/search/all_1.html +++ b/doc/html/search/all_1.html @@ -1,7 +1,8 @@ - + + - + @@ -10,14 +11,14 @@
Loading...
- +
Searching...
No Matches
- +
diff --git a/doc/html/search/all_2.html b/doc/html/search/all_2.html index 1f81f6645eaa41cc0d6caf0b46512858b3b065f4..02cfffc2e13911f86c16e1489830d3ca5d06b033 100644 --- a/doc/html/search/all_2.html +++ b/doc/html/search/all_2.html @@ -1,7 +1,8 @@ - + + - + @@ -10,14 +11,14 @@
Loading...
- +
Searching...
No Matches
- +
diff --git a/doc/html/search/all_2.js b/doc/html/search/all_2.js index c8d2e23f67b5d97f7c4d3fe83834e916c5d7d357..65423be6fe3466c377986ea063603613be3cb8db 100644 --- a/doc/html/search/all_2.js +++ b/doc/html/search/all_2.js @@ -1,5 +1,5 @@ var searchData= [ - ['event_20handling_2',['Event handling',['../group__events.html',1,'']]], - ['evdev_20ioctls_3',['evdev ioctls',['../ioctls.html',1,'']]] + ['evdev_20ioctls_2',['evdev ioctls',['../ioctls.html',1,'']]], + ['event_20handling_3',['Event handling',['../group__events.html',1,'']]] ]; diff --git a/doc/html/search/all_3.html b/doc/html/search/all_3.html index 2e31ab9110e15dca1aa1211204b9de5d1435c57d..39767b85baa9ec68a42ce7bcd9d238277818898b 100644 --- a/doc/html/search/all_3.html +++ b/doc/html/search/all_3.html @@ -1,7 +1,8 @@ - + + - + @@ -10,14 +11,14 @@
Loading...
- +
Searching...
No Matches
- +
diff --git a/doc/html/search/all_4.html b/doc/html/search/all_4.html index 0540c1633667640a85c5293a40f55989a1d78781..fc40463c89f794281268400aff9c675c6c2e27f6 100644 --- a/doc/html/search/all_4.html +++ b/doc/html/search/all_4.html @@ -1,7 +1,8 @@ - + + - + @@ -10,14 +11,14 @@
Loading...
- +
Searching...
No Matches
- +
diff --git a/doc/html/search/all_5.html b/doc/html/search/all_5.html index ebec30bfa22fc621c1ce2eb27563587ed8af689f..9dd9344b0d0ac453424f37ee7feef56711d58ef8 100644 --- a/doc/html/search/all_5.html +++ b/doc/html/search/all_5.html @@ -1,7 +1,8 @@ - + + - + @@ -10,14 +11,14 @@
Loading...
- +
Searching...
No Matches
- +
diff --git a/doc/html/search/all_5.js b/doc/html/search/all_5.js index 8be650bb4be63685b971d99a022ddad2becc49a1..6d46f25af01ff9d51b7804932c35a4ce4271f29a 100644 --- a/doc/html/search/all_5.js +++ b/doc/html/search/all_5.js @@ -1,117 +1,118 @@ var searchData= [ - ['libevdev_2duinput_2eh_6',['libevdev-uinput.h',['../libevdev-uinput_8h.html',1,'']]], - ['libevdev_2eh_7',['libevdev.h',['../libevdev_8h.html',1,'']]], - ['libevdev_5fattribute_5fprintf_8',['LIBEVDEV_ATTRIBUTE_PRINTF',['../libevdev_8h.html#a64a0f325e88e1be50eb806e1ff75aec8',1,'libevdev.h']]], - ['libevdev_5fchange_5ffd_9',['libevdev_change_fd',['../group__init.html#gac71c9cca4c572ed1b1a8c233be70a17c',1,'libevdev.h']]], - ['libevdev_5fdeprecated_10',['LIBEVDEV_DEPRECATED',['../libevdev_8h.html#aa136bf4638abda28de7cd9f48af534ae',1,'libevdev.h']]], - ['libevdev_5fdevice_5flog_5ffunc_5ft_11',['libevdev_device_log_func_t',['../group__logging.html#gab7eb997be2b701cc6f42e7b4c3478269',1,'libevdev.h']]], - ['libevdev_5fdisable_5fevent_5fcode_12',['libevdev_disable_event_code',['../group__kernel.html#ga6199a7c8144f54e092e913c2d2df16de',1,'libevdev.h']]], - ['libevdev_5fdisable_5fevent_5ftype_13',['libevdev_disable_event_type',['../group__kernel.html#gabbacb53b66882b5335055c0fd1f40d9a',1,'libevdev.h']]], - ['libevdev_5fdisable_5fproperty_14',['libevdev_disable_property',['../group__kernel.html#ga8f6367c36331c803ad69b2591e210019',1,'libevdev.h']]], - ['libevdev_5fenable_5fevent_5fcode_15',['libevdev_enable_event_code',['../group__kernel.html#ga51cfda33fd526549046399aadd764fca',1,'libevdev.h']]], - ['libevdev_5fenable_5fevent_5ftype_16',['libevdev_enable_event_type',['../group__kernel.html#ga59ef78b1557f9543d0060ab25b0167ca',1,'libevdev.h']]], - ['libevdev_5fenable_5fproperty_17',['libevdev_enable_property',['../group__kernel.html#gafc552080520c9d886452b05f3a1d75b6',1,'libevdev.h']]], - ['libevdev_5fevent_5fcode_5ffrom_5fcode_5fname_18',['libevdev_event_code_from_code_name',['../group__misc.html#gabad00f68481d83747a134c0a37aca003',1,'libevdev.h']]], - ['libevdev_5fevent_5fcode_5ffrom_5fcode_5fname_5fn_19',['libevdev_event_code_from_code_name_n',['../group__misc.html#ga5bf9af4b8c372d87793e8a3c2dbeb466',1,'libevdev.h']]], - ['libevdev_5fevent_5fcode_5ffrom_5fname_20',['libevdev_event_code_from_name',['../group__misc.html#ga6620301a67f467489e4a7f93afe81621',1,'libevdev.h']]], - ['libevdev_5fevent_5fcode_5ffrom_5fname_5fn_21',['libevdev_event_code_from_name_n',['../group__misc.html#ga17a760a9eea9dc25011f39e1d5c282a0',1,'libevdev.h']]], - ['libevdev_5fevent_5fcode_5fget_5fname_22',['libevdev_event_code_get_name',['../group__misc.html#gab407b3c2caaae502859c28460cad17bb',1,'libevdev.h']]], - ['libevdev_5fevent_5fis_5fcode_23',['libevdev_event_is_code',['../group__misc.html#ga37766a6a498fef3294d589abcce688bb',1,'libevdev.h']]], - ['libevdev_5fevent_5fis_5ftype_24',['libevdev_event_is_type',['../group__misc.html#gab8b6b80740e028261300b8952b61a596',1,'libevdev.h']]], - ['libevdev_5fevent_5ftype_5ffrom_5fcode_5fname_25',['libevdev_event_type_from_code_name',['../group__misc.html#gadd41b7514cca16c8b8920f16e562e08a',1,'libevdev.h']]], - ['libevdev_5fevent_5ftype_5ffrom_5fcode_5fname_5fn_26',['libevdev_event_type_from_code_name_n',['../group__misc.html#gab214498fca7a328f8a712ce15bf21982',1,'libevdev.h']]], - ['libevdev_5fevent_5ftype_5ffrom_5fname_27',['libevdev_event_type_from_name',['../group__misc.html#ga61ce3bf1e66bd172e583b86a11fc41f1',1,'libevdev.h']]], - ['libevdev_5fevent_5ftype_5ffrom_5fname_5fn_28',['libevdev_event_type_from_name_n',['../group__misc.html#ga4ee03d650200bb04a23233570667fa84',1,'libevdev.h']]], - ['libevdev_5fevent_5ftype_5fget_5fmax_29',['libevdev_event_type_get_max',['../group__misc.html#gabfad87ea78d034631cf3e5322ac383a1',1,'libevdev.h']]], - ['libevdev_5fevent_5ftype_5fget_5fname_30',['libevdev_event_type_get_name',['../group__misc.html#gac99720fd926bf288764f9a81bf37ed09',1,'libevdev.h']]], - ['libevdev_5fevent_5fvalue_5ffrom_5fname_31',['libevdev_event_value_from_name',['../group__misc.html#ga314903beeafedabe45f879637e7254b0',1,'libevdev.h']]], - ['libevdev_5fevent_5fvalue_5ffrom_5fname_5fn_32',['libevdev_event_value_from_name_n',['../group__misc.html#gaebfc6b0ebb70169c9fec61620f1ea85f',1,'libevdev.h']]], - ['libevdev_5fevent_5fvalue_5fget_5fname_33',['libevdev_event_value_get_name',['../group__misc.html#gabcd45c5e963cba245e944ea66e72fcc3',1,'libevdev.h']]], - ['libevdev_5ffetch_5fevent_5fvalue_34',['libevdev_fetch_event_value',['../group__bits.html#ga0a7be80d769294bf9758adf79c3c7147',1,'libevdev.h']]], - ['libevdev_5ffetch_5fslot_5fvalue_35',['libevdev_fetch_slot_value',['../group__mt.html#gaca19dca5aa8f0ea3b210f3fc670384ec',1,'libevdev.h']]], - ['libevdev_5ffree_36',['libevdev_free',['../group__init.html#gacd9fe760d15be25fc99ce469034bd78c',1,'libevdev.h']]], - ['libevdev_5fget_5fabs_5fflat_37',['libevdev_get_abs_flat',['../group__bits.html#ga6b3f7ebae2324524dc41384acd724b92',1,'libevdev.h']]], - ['libevdev_5fget_5fabs_5ffuzz_38',['libevdev_get_abs_fuzz',['../group__bits.html#ga1a3dfeb3bb2db0b4323c836c7ab10f1a',1,'libevdev.h']]], - ['libevdev_5fget_5fabs_5finfo_39',['libevdev_get_abs_info',['../group__bits.html#ga6d8e2caf87fa536fad979346671838d7',1,'libevdev.h']]], - ['libevdev_5fget_5fabs_5fmaximum_40',['libevdev_get_abs_maximum',['../group__bits.html#ga97a3411ae85f1f3b5c5eb1d5351b11ca',1,'libevdev.h']]], - ['libevdev_5fget_5fabs_5fminimum_41',['libevdev_get_abs_minimum',['../group__bits.html#ga482ce989a3f62f7e67e4ea7ad534189e',1,'libevdev.h']]], - ['libevdev_5fget_5fabs_5fresolution_42',['libevdev_get_abs_resolution',['../group__bits.html#ga75751e637a845201b6d1c419ecfa6ba4',1,'libevdev.h']]], - ['libevdev_5fget_5fcurrent_5fslot_43',['libevdev_get_current_slot',['../group__mt.html#gad22e2420be668b56ef486cde2e98c5dd',1,'libevdev.h']]], - ['libevdev_5fget_5fdriver_5fversion_44',['libevdev_get_driver_version',['../group__bits.html#ga31e9e7a99215a03bcdc339b53e1be2fa',1,'libevdev.h']]], - ['libevdev_5fget_5fevent_5fvalue_45',['libevdev_get_event_value',['../group__bits.html#ga6259f4c6bdba950329ff9cd48c2ef8a3',1,'libevdev.h']]], - ['libevdev_5fget_5ffd_46',['libevdev_get_fd',['../group__init.html#gab9bfc800859ac3aa63f41d58ec4b616c',1,'libevdev.h']]], - ['libevdev_5fget_5fid_5fbustype_47',['libevdev_get_id_bustype',['../group__bits.html#ga9bf55d416401642bad0c435735682308',1,'libevdev.h']]], - ['libevdev_5fget_5fid_5fproduct_48',['libevdev_get_id_product',['../group__bits.html#ga1dc66cfef646878d58be72f8902a6bac',1,'libevdev.h']]], - ['libevdev_5fget_5fid_5fvendor_49',['libevdev_get_id_vendor',['../group__bits.html#ga08891c3285da5b8d26769c9a34f063f3',1,'libevdev.h']]], - ['libevdev_5fget_5fid_5fversion_50',['libevdev_get_id_version',['../group__bits.html#ga75a07d0c96dfe09d2194c104c429d0ae',1,'libevdev.h']]], - ['libevdev_5fget_5flog_5fpriority_51',['libevdev_get_log_priority',['../group__logging.html#ga1da07493a798595cf85c127490b98ee8',1,'libevdev.h']]], - ['libevdev_5fget_5fname_52',['libevdev_get_name',['../group__bits.html#gaed0328c67b7a78422636d9fe09a73f12',1,'libevdev.h']]], - ['libevdev_5fget_5fnum_5fslots_53',['libevdev_get_num_slots',['../group__mt.html#gaf272526f0a59d2f61ef7389046cd4088',1,'libevdev.h']]], - ['libevdev_5fget_5fphys_54',['libevdev_get_phys',['../group__bits.html#ga5df483b0b24d7b96ea1181808fab851d',1,'libevdev.h']]], - ['libevdev_5fget_5frepeat_55',['libevdev_get_repeat',['../group__bits.html#gaf12fa199bb9497b38358d72e7505d770',1,'libevdev.h']]], - ['libevdev_5fget_5fslot_5fvalue_56',['libevdev_get_slot_value',['../group__mt.html#ga8c6303391cb4f90b2d46763cf4eb8bc8',1,'libevdev.h']]], - ['libevdev_5fget_5funiq_57',['libevdev_get_uniq',['../group__bits.html#ga6d9f7d44bff8828ead3d251177035ca4',1,'libevdev.h']]], - ['libevdev_5fgrab_58',['LIBEVDEV_GRAB',['../group__init.html#ggaa282ec9badaa6bc11b1dc5bb124dbd5bad3ac6f5f3ebf7d38a6aad74a88396c88',1,'LIBEVDEV_GRAB(): libevdev.h'],['../group__init.html#ga5d434af74fee20f273db568e2cbbd13f',1,'libevdev_grab(struct libevdev *dev, enum libevdev_grab_mode grab): libevdev.h']]], - ['libevdev_5fgrab_5fmode_59',['libevdev_grab_mode',['../group__init.html#gaa282ec9badaa6bc11b1dc5bb124dbd5b',1,'libevdev.h']]], - ['libevdev_5fhas_5fevent_5fcode_60',['libevdev_has_event_code',['../group__bits.html#gab2ab9dad417f33daa79fa0c3d682df0b',1,'libevdev.h']]], - ['libevdev_5fhas_5fevent_5fpending_61',['libevdev_has_event_pending',['../group__events.html#gae18fbfb59064c9c4b9d5db2d8cb23784',1,'libevdev.h']]], - ['libevdev_5fhas_5fevent_5ftype_62',['libevdev_has_event_type',['../group__bits.html#ga398bef155fa4a0cfb832de30723ebd14',1,'libevdev.h']]], - ['libevdev_5fhas_5fproperty_63',['libevdev_has_property',['../group__bits.html#ga36d529ea53f4522004bc7d16c051464b',1,'libevdev.h']]], - ['libevdev_5fkernel_5fset_5fabs_5finfo_64',['libevdev_kernel_set_abs_info',['../group__kernel.html#ga41c0321b93349d0ddd1f1c007ccf7de9',1,'libevdev.h']]], - ['libevdev_5fkernel_5fset_5fled_5fvalue_65',['libevdev_kernel_set_led_value',['../group__kernel.html#gaa7d13aeac3c40e16f296467780e67c01',1,'libevdev.h']]], - ['libevdev_5fkernel_5fset_5fled_5fvalues_66',['libevdev_kernel_set_led_values',['../group__kernel.html#ga93a19fa6e5be57903aff7c4a60af2a00',1,'libevdev.h']]], - ['libevdev_5fled_5foff_67',['LIBEVDEV_LED_OFF',['../group__kernel.html#gga8cddf7779debef0067665671e911ec41a23e508440306c387ddf89acd2db9e065',1,'libevdev.h']]], - ['libevdev_5fled_5fon_68',['LIBEVDEV_LED_ON',['../group__kernel.html#gga8cddf7779debef0067665671e911ec41a69d5a4cdf2a9357915fff0251a61d2ab',1,'libevdev.h']]], - ['libevdev_5fled_5fvalue_69',['libevdev_led_value',['../group__kernel.html#ga8cddf7779debef0067665671e911ec41',1,'libevdev.h']]], - ['libevdev_5flog_5fdebug_70',['LIBEVDEV_LOG_DEBUG',['../group__logging.html#gga0b798d0864f2b1b10e4603f9431b3364a760d66d422ffcf89b0f1ddb529b95793',1,'libevdev.h']]], - ['libevdev_5flog_5ferror_71',['LIBEVDEV_LOG_ERROR',['../group__logging.html#gga0b798d0864f2b1b10e4603f9431b3364a21fd1083f2ebd0a25f09ee982e365d5f',1,'libevdev.h']]], - ['libevdev_5flog_5ffunc_5ft_72',['libevdev_log_func_t',['../group__logging.html#gaf36c721d273c0794251eb7dacea2f0a4',1,'libevdev.h']]], - ['libevdev_5flog_5finfo_73',['LIBEVDEV_LOG_INFO',['../group__logging.html#gga0b798d0864f2b1b10e4603f9431b3364a4d13a031b112292ca3e7bab8c6d76abc',1,'libevdev.h']]], - ['libevdev_5flog_5fpriority_74',['libevdev_log_priority',['../group__logging.html#ga0b798d0864f2b1b10e4603f9431b3364',1,'libevdev.h']]], - ['libevdev_5fnew_75',['libevdev_new',['../group__init.html#ga332c8ee260b4ef864345abe5d04e820c',1,'libevdev.h']]], - ['libevdev_5fnew_5ffrom_5ffd_76',['libevdev_new_from_fd',['../group__init.html#ga89bb5bce1c23e293293484b05b12aaf4',1,'libevdev.h']]], - ['libevdev_5fnext_5fevent_77',['libevdev_next_event',['../group__events.html#gabb96c864e836c0b98788f4ab771c3a76',1,'libevdev.h']]], - ['libevdev_5fproperty_5ffrom_5fname_78',['libevdev_property_from_name',['../group__misc.html#ga6f4418c98aa475a2fc34d58a197f7edd',1,'libevdev.h']]], - ['libevdev_5fproperty_5ffrom_5fname_5fn_79',['libevdev_property_from_name_n',['../group__misc.html#gaaa0bc4c7d0d2aedc84c7dcffee9ce29b',1,'libevdev.h']]], - ['libevdev_5fproperty_5fget_5fname_80',['libevdev_property_get_name',['../group__misc.html#gacc12bdb7b912070ac9c375428f2c9892',1,'libevdev.h']]], - ['libevdev_5fread_5fflag_81',['libevdev_read_flag',['../group__events.html#ga56c288d9f2e4c1632986c4e218c494e9',1,'libevdev.h']]], - ['libevdev_5fread_5fflag_5fblocking_82',['LIBEVDEV_READ_FLAG_BLOCKING',['../group__events.html#gga56c288d9f2e4c1632986c4e218c494e9a0a348d44362a7e515b40a4ed4d528e19',1,'libevdev.h']]], - ['libevdev_5fread_5fflag_5fforce_5fsync_83',['LIBEVDEV_READ_FLAG_FORCE_SYNC',['../group__events.html#gga56c288d9f2e4c1632986c4e218c494e9a5198e5c9cc98b75f73f61b104d6a674c',1,'libevdev.h']]], - ['libevdev_5fread_5fflag_5fnormal_84',['LIBEVDEV_READ_FLAG_NORMAL',['../group__events.html#gga56c288d9f2e4c1632986c4e218c494e9ac0d6ee19551eecf76f1ede4f36252418',1,'libevdev.h']]], - ['libevdev_5fread_5fflag_5fsync_85',['LIBEVDEV_READ_FLAG_SYNC',['../group__events.html#gga56c288d9f2e4c1632986c4e218c494e9a1f13a19641d6dafcf01a86a6389800f8',1,'libevdev.h']]], - ['libevdev_5fread_5fstatus_86',['libevdev_read_status',['../group__events.html#ga4a96221b3c7f54dfb86035d952154e3a',1,'libevdev.h']]], - ['libevdev_5fread_5fstatus_5fsuccess_87',['LIBEVDEV_READ_STATUS_SUCCESS',['../group__events.html#gga4a96221b3c7f54dfb86035d952154e3aab053221fc1c9630eee7111b75aa0aec7',1,'libevdev.h']]], - ['libevdev_5fread_5fstatus_5fsync_88',['LIBEVDEV_READ_STATUS_SYNC',['../group__events.html#gga4a96221b3c7f54dfb86035d952154e3aa8d70b14a38204fde4ad433023baa545a',1,'libevdev.h']]], - ['libevdev_5fset_5fabs_5fflat_89',['libevdev_set_abs_flat',['../group__kernel.html#gabd309f30744a49e9391250b00ba2d67a',1,'libevdev.h']]], - ['libevdev_5fset_5fabs_5ffuzz_90',['libevdev_set_abs_fuzz',['../group__kernel.html#gaa192bf0c68620be819337da6ec361c21',1,'libevdev.h']]], - ['libevdev_5fset_5fabs_5finfo_91',['libevdev_set_abs_info',['../group__kernel.html#gafc7a4f5308e2dbf55f875630b8dca049',1,'libevdev.h']]], - ['libevdev_5fset_5fabs_5fmaximum_92',['libevdev_set_abs_maximum',['../group__kernel.html#ga2302fd9a491d8e27280157d67a703af6',1,'libevdev.h']]], - ['libevdev_5fset_5fabs_5fminimum_93',['libevdev_set_abs_minimum',['../group__kernel.html#gaca62172c2a823cd02eacf0d2292d917a',1,'libevdev.h']]], - ['libevdev_5fset_5fabs_5fresolution_94',['libevdev_set_abs_resolution',['../group__kernel.html#ga2266b59711cdaa4fc12fa56c9313a038',1,'libevdev.h']]], - ['libevdev_5fset_5fclock_5fid_95',['libevdev_set_clock_id',['../group__kernel.html#ga2925b6fbf8c7991ff2164424b840b82d',1,'libevdev.h']]], - ['libevdev_5fset_5fdevice_5flog_5ffunction_96',['libevdev_set_device_log_function',['../group__logging.html#ga2830ff0aa391d8d1111682d3e762091b',1,'libevdev.h']]], - ['libevdev_5fset_5fevent_5fvalue_97',['libevdev_set_event_value',['../group__kernel.html#ga79e82ee2a95cb08adb4172aabe0c7184',1,'libevdev.h']]], - ['libevdev_5fset_5ffd_98',['libevdev_set_fd',['../group__init.html#ga6658ac490d68c307ff8b8d1536c12b44',1,'libevdev.h']]], - ['libevdev_5fset_5fid_5fbustype_99',['libevdev_set_id_bustype',['../group__kernel.html#gaf99139c728ba1bd4b37ede612780b6b0',1,'libevdev.h']]], - ['libevdev_5fset_5fid_5fproduct_100',['libevdev_set_id_product',['../group__kernel.html#ga62fbdaac056ab5c3db154a9eeaf33799',1,'libevdev.h']]], - ['libevdev_5fset_5fid_5fvendor_101',['libevdev_set_id_vendor',['../group__kernel.html#ga8ce28051ebbb73de1d04d782f4d0d6fe',1,'libevdev.h']]], - ['libevdev_5fset_5fid_5fversion_102',['libevdev_set_id_version',['../group__kernel.html#gaee1d2db88b191ec21d5bf22dd4fe3055',1,'libevdev.h']]], - ['libevdev_5fset_5flog_5ffunction_103',['libevdev_set_log_function',['../group__logging.html#gaa60be86b83b3a6c82d8e536ba89ff955',1,'libevdev.h']]], - ['libevdev_5fset_5flog_5fpriority_104',['libevdev_set_log_priority',['../group__logging.html#gaf6b6842a9ed98b61d0abb421e853fd89',1,'libevdev.h']]], - ['libevdev_5fset_5fname_105',['libevdev_set_name',['../group__kernel.html#gae5dcdb7678cdc9be4ab1989725b4ed32',1,'libevdev.h']]], - ['libevdev_5fset_5fphys_106',['libevdev_set_phys',['../group__kernel.html#gacd57c8d6ace8e0b1417809a9c1c67af3',1,'libevdev.h']]], - ['libevdev_5fset_5fslot_5fvalue_107',['libevdev_set_slot_value',['../group__kernel.html#ga0c61f4919b03b0850529a50c37a20333',1,'libevdev.h']]], - ['libevdev_5fset_5funiq_108',['libevdev_set_uniq',['../group__kernel.html#ga4e4fd2627744fd5811c50c7403f27ad7',1,'libevdev.h']]], - ['libevdev_5fuinput_5fcreate_5ffrom_5fdevice_109',['libevdev_uinput_create_from_device',['../group__uinput.html#gaf14b21301bac9d79c20e890172873b96',1,'libevdev-uinput.h']]], - ['libevdev_5fuinput_5fdestroy_110',['libevdev_uinput_destroy',['../group__uinput.html#ga9dfa58a84eb4c6b97107dcf3fa621329',1,'libevdev-uinput.h']]], - ['libevdev_5fuinput_5fget_5fdevnode_111',['libevdev_uinput_get_devnode',['../group__uinput.html#ga4c595bcda748b08561e2819fe9b7c2d2',1,'libevdev-uinput.h']]], - ['libevdev_5fuinput_5fget_5ffd_112',['libevdev_uinput_get_fd',['../group__uinput.html#ga9cd7fb14a96d4cc14d3dffdcead84c5d',1,'libevdev-uinput.h']]], - ['libevdev_5fuinput_5fget_5fsyspath_113',['libevdev_uinput_get_syspath',['../group__uinput.html#gaacca93061fce57cec0ce3c52e443a427',1,'libevdev-uinput.h']]], - ['libevdev_5fuinput_5fopen_5fmanaged_114',['LIBEVDEV_UINPUT_OPEN_MANAGED',['../libevdev-uinput_8h.html#a6546acd3e4fe75a74d91eebf9bbd3d03adcf2d4de38844ee3a8c830bc3285afad',1,'libevdev-uinput.h']]], - ['libevdev_5fuinput_5fopen_5fmode_115',['libevdev_uinput_open_mode',['../libevdev-uinput_8h.html#a6546acd3e4fe75a74d91eebf9bbd3d03',1,'libevdev-uinput.h']]], - ['libevdev_5fuinput_5fwrite_5fevent_116',['libevdev_uinput_write_event',['../group__uinput.html#ga4c3c2f5fcd315a28a067f53b9f855fe7',1,'libevdev-uinput.h']]], - ['libevdev_5fungrab_117',['LIBEVDEV_UNGRAB',['../group__init.html#ggaa282ec9badaa6bc11b1dc5bb124dbd5ba6c0930d0c280753504cd05ebdcda09eb',1,'libevdev.h']]], - ['library_20logging_20facilities_118',['Library logging facilities',['../group__logging.html',1,'']]], - ['libevdev_2dinternal_20test_20suite_119',['libevdev-internal test suite',['../testing.html',1,'']]] + ['libevdev_2dinternal_20test_20suite_6',['libevdev-internal test suite',['../testing.html',1,'']]], + ['libevdev_2duinput_2eh_7',['libevdev-uinput.h',['../libevdev-uinput_8h.html',1,'']]], + ['libevdev_2eh_8',['libevdev.h',['../libevdev_8h.html',1,'']]], + ['libevdev_5fattribute_5fprintf_9',['LIBEVDEV_ATTRIBUTE_PRINTF',['../libevdev_8h.html#a64a0f325e88e1be50eb806e1ff75aec8',1,'libevdev.h']]], + ['libevdev_5fchange_5ffd_10',['libevdev_change_fd',['../group__init.html#gac71c9cca4c572ed1b1a8c233be70a17c',1,'libevdev.h']]], + ['libevdev_5fdeprecated_11',['LIBEVDEV_DEPRECATED',['../libevdev_8h.html#aa136bf4638abda28de7cd9f48af534ae',1,'libevdev.h']]], + ['libevdev_5fdevice_5flog_5ffunc_5ft_12',['libevdev_device_log_func_t',['../group__logging.html#gab7eb997be2b701cc6f42e7b4c3478269',1,'libevdev.h']]], + ['libevdev_5fdisable_5fevent_5fcode_13',['libevdev_disable_event_code',['../group__kernel.html#ga6199a7c8144f54e092e913c2d2df16de',1,'libevdev.h']]], + ['libevdev_5fdisable_5fevent_5ftype_14',['libevdev_disable_event_type',['../group__kernel.html#gabbacb53b66882b5335055c0fd1f40d9a',1,'libevdev.h']]], + ['libevdev_5fdisable_5fproperty_15',['libevdev_disable_property',['../group__kernel.html#ga8f6367c36331c803ad69b2591e210019',1,'libevdev.h']]], + ['libevdev_5fenable_5fevent_5fcode_16',['libevdev_enable_event_code',['../group__kernel.html#ga51cfda33fd526549046399aadd764fca',1,'libevdev.h']]], + ['libevdev_5fenable_5fevent_5ftype_17',['libevdev_enable_event_type',['../group__kernel.html#ga59ef78b1557f9543d0060ab25b0167ca',1,'libevdev.h']]], + ['libevdev_5fenable_5fproperty_18',['libevdev_enable_property',['../group__kernel.html#gafc552080520c9d886452b05f3a1d75b6',1,'libevdev.h']]], + ['libevdev_5fevent_5fcode_5ffrom_5fcode_5fname_19',['libevdev_event_code_from_code_name',['../group__misc.html#gabad00f68481d83747a134c0a37aca003',1,'libevdev.h']]], + ['libevdev_5fevent_5fcode_5ffrom_5fcode_5fname_5fn_20',['libevdev_event_code_from_code_name_n',['../group__misc.html#ga5bf9af4b8c372d87793e8a3c2dbeb466',1,'libevdev.h']]], + ['libevdev_5fevent_5fcode_5ffrom_5fname_21',['libevdev_event_code_from_name',['../group__misc.html#ga6620301a67f467489e4a7f93afe81621',1,'libevdev.h']]], + ['libevdev_5fevent_5fcode_5ffrom_5fname_5fn_22',['libevdev_event_code_from_name_n',['../group__misc.html#ga17a760a9eea9dc25011f39e1d5c282a0',1,'libevdev.h']]], + ['libevdev_5fevent_5fcode_5fget_5fname_23',['libevdev_event_code_get_name',['../group__misc.html#gab407b3c2caaae502859c28460cad17bb',1,'libevdev.h']]], + ['libevdev_5fevent_5fis_5fcode_24',['libevdev_event_is_code',['../group__misc.html#ga37766a6a498fef3294d589abcce688bb',1,'libevdev.h']]], + ['libevdev_5fevent_5fis_5ftype_25',['libevdev_event_is_type',['../group__misc.html#gab8b6b80740e028261300b8952b61a596',1,'libevdev.h']]], + ['libevdev_5fevent_5ftype_5ffrom_5fcode_5fname_26',['libevdev_event_type_from_code_name',['../group__misc.html#gadd41b7514cca16c8b8920f16e562e08a',1,'libevdev.h']]], + ['libevdev_5fevent_5ftype_5ffrom_5fcode_5fname_5fn_27',['libevdev_event_type_from_code_name_n',['../group__misc.html#gab214498fca7a328f8a712ce15bf21982',1,'libevdev.h']]], + ['libevdev_5fevent_5ftype_5ffrom_5fname_28',['libevdev_event_type_from_name',['../group__misc.html#ga61ce3bf1e66bd172e583b86a11fc41f1',1,'libevdev.h']]], + ['libevdev_5fevent_5ftype_5ffrom_5fname_5fn_29',['libevdev_event_type_from_name_n',['../group__misc.html#ga4ee03d650200bb04a23233570667fa84',1,'libevdev.h']]], + ['libevdev_5fevent_5ftype_5fget_5fmax_30',['libevdev_event_type_get_max',['../group__misc.html#gabfad87ea78d034631cf3e5322ac383a1',1,'libevdev.h']]], + ['libevdev_5fevent_5ftype_5fget_5fname_31',['libevdev_event_type_get_name',['../group__misc.html#gac99720fd926bf288764f9a81bf37ed09',1,'libevdev.h']]], + ['libevdev_5fevent_5fvalue_5ffrom_5fname_32',['libevdev_event_value_from_name',['../group__misc.html#ga314903beeafedabe45f879637e7254b0',1,'libevdev.h']]], + ['libevdev_5fevent_5fvalue_5ffrom_5fname_5fn_33',['libevdev_event_value_from_name_n',['../group__misc.html#gaebfc6b0ebb70169c9fec61620f1ea85f',1,'libevdev.h']]], + ['libevdev_5fevent_5fvalue_5fget_5fname_34',['libevdev_event_value_get_name',['../group__misc.html#gabcd45c5e963cba245e944ea66e72fcc3',1,'libevdev.h']]], + ['libevdev_5ffetch_5fevent_5fvalue_35',['libevdev_fetch_event_value',['../group__bits.html#ga0a7be80d769294bf9758adf79c3c7147',1,'libevdev.h']]], + ['libevdev_5ffetch_5fslot_5fvalue_36',['libevdev_fetch_slot_value',['../group__mt.html#gaca19dca5aa8f0ea3b210f3fc670384ec',1,'libevdev.h']]], + ['libevdev_5ffree_37',['libevdev_free',['../group__init.html#gacd9fe760d15be25fc99ce469034bd78c',1,'libevdev.h']]], + ['libevdev_5fget_5fabs_5fflat_38',['libevdev_get_abs_flat',['../group__bits.html#ga6b3f7ebae2324524dc41384acd724b92',1,'libevdev.h']]], + ['libevdev_5fget_5fabs_5ffuzz_39',['libevdev_get_abs_fuzz',['../group__bits.html#ga1a3dfeb3bb2db0b4323c836c7ab10f1a',1,'libevdev.h']]], + ['libevdev_5fget_5fabs_5finfo_40',['libevdev_get_abs_info',['../group__bits.html#ga6d8e2caf87fa536fad979346671838d7',1,'libevdev.h']]], + ['libevdev_5fget_5fabs_5fmaximum_41',['libevdev_get_abs_maximum',['../group__bits.html#ga97a3411ae85f1f3b5c5eb1d5351b11ca',1,'libevdev.h']]], + ['libevdev_5fget_5fabs_5fminimum_42',['libevdev_get_abs_minimum',['../group__bits.html#ga482ce989a3f62f7e67e4ea7ad534189e',1,'libevdev.h']]], + ['libevdev_5fget_5fabs_5fresolution_43',['libevdev_get_abs_resolution',['../group__bits.html#ga75751e637a845201b6d1c419ecfa6ba4',1,'libevdev.h']]], + ['libevdev_5fget_5fcurrent_5fslot_44',['libevdev_get_current_slot',['../group__mt.html#gad22e2420be668b56ef486cde2e98c5dd',1,'libevdev.h']]], + ['libevdev_5fget_5fdriver_5fversion_45',['libevdev_get_driver_version',['../group__bits.html#ga31e9e7a99215a03bcdc339b53e1be2fa',1,'libevdev.h']]], + ['libevdev_5fget_5fevent_5fvalue_46',['libevdev_get_event_value',['../group__bits.html#ga6259f4c6bdba950329ff9cd48c2ef8a3',1,'libevdev.h']]], + ['libevdev_5fget_5ffd_47',['libevdev_get_fd',['../group__init.html#gab9bfc800859ac3aa63f41d58ec4b616c',1,'libevdev.h']]], + ['libevdev_5fget_5fid_5fbustype_48',['libevdev_get_id_bustype',['../group__bits.html#ga9bf55d416401642bad0c435735682308',1,'libevdev.h']]], + ['libevdev_5fget_5fid_5fproduct_49',['libevdev_get_id_product',['../group__bits.html#ga1dc66cfef646878d58be72f8902a6bac',1,'libevdev.h']]], + ['libevdev_5fget_5fid_5fvendor_50',['libevdev_get_id_vendor',['../group__bits.html#ga08891c3285da5b8d26769c9a34f063f3',1,'libevdev.h']]], + ['libevdev_5fget_5fid_5fversion_51',['libevdev_get_id_version',['../group__bits.html#ga75a07d0c96dfe09d2194c104c429d0ae',1,'libevdev.h']]], + ['libevdev_5fget_5flog_5fpriority_52',['libevdev_get_log_priority',['../group__logging.html#ga1da07493a798595cf85c127490b98ee8',1,'libevdev.h']]], + ['libevdev_5fget_5fname_53',['libevdev_get_name',['../group__bits.html#gaed0328c67b7a78422636d9fe09a73f12',1,'libevdev.h']]], + ['libevdev_5fget_5fnum_5fslots_54',['libevdev_get_num_slots',['../group__mt.html#gaf272526f0a59d2f61ef7389046cd4088',1,'libevdev.h']]], + ['libevdev_5fget_5fphys_55',['libevdev_get_phys',['../group__bits.html#ga5df483b0b24d7b96ea1181808fab851d',1,'libevdev.h']]], + ['libevdev_5fget_5frepeat_56',['libevdev_get_repeat',['../group__bits.html#gaf12fa199bb9497b38358d72e7505d770',1,'libevdev.h']]], + ['libevdev_5fget_5fslot_5fvalue_57',['libevdev_get_slot_value',['../group__mt.html#ga8c6303391cb4f90b2d46763cf4eb8bc8',1,'libevdev.h']]], + ['libevdev_5fget_5funiq_58',['libevdev_get_uniq',['../group__bits.html#ga6d9f7d44bff8828ead3d251177035ca4',1,'libevdev.h']]], + ['libevdev_5fgrab_59',['LIBEVDEV_GRAB',['../group__init.html#ggaa282ec9badaa6bc11b1dc5bb124dbd5bad3ac6f5f3ebf7d38a6aad74a88396c88',1,'libevdev.h']]], + ['libevdev_5fgrab_60',['libevdev_grab',['../group__init.html#ga5d434af74fee20f273db568e2cbbd13f',1,'libevdev.h']]], + ['libevdev_5fgrab_5fmode_61',['libevdev_grab_mode',['../group__init.html#gaa282ec9badaa6bc11b1dc5bb124dbd5b',1,'libevdev.h']]], + ['libevdev_5fhas_5fevent_5fcode_62',['libevdev_has_event_code',['../group__bits.html#gab2ab9dad417f33daa79fa0c3d682df0b',1,'libevdev.h']]], + ['libevdev_5fhas_5fevent_5fpending_63',['libevdev_has_event_pending',['../group__events.html#gae18fbfb59064c9c4b9d5db2d8cb23784',1,'libevdev.h']]], + ['libevdev_5fhas_5fevent_5ftype_64',['libevdev_has_event_type',['../group__bits.html#ga398bef155fa4a0cfb832de30723ebd14',1,'libevdev.h']]], + ['libevdev_5fhas_5fproperty_65',['libevdev_has_property',['../group__bits.html#ga36d529ea53f4522004bc7d16c051464b',1,'libevdev.h']]], + ['libevdev_5fkernel_5fset_5fabs_5finfo_66',['libevdev_kernel_set_abs_info',['../group__kernel.html#ga41c0321b93349d0ddd1f1c007ccf7de9',1,'libevdev.h']]], + ['libevdev_5fkernel_5fset_5fled_5fvalue_67',['libevdev_kernel_set_led_value',['../group__kernel.html#gaa7d13aeac3c40e16f296467780e67c01',1,'libevdev.h']]], + ['libevdev_5fkernel_5fset_5fled_5fvalues_68',['libevdev_kernel_set_led_values',['../group__kernel.html#ga93a19fa6e5be57903aff7c4a60af2a00',1,'libevdev.h']]], + ['libevdev_5fled_5foff_69',['LIBEVDEV_LED_OFF',['../group__kernel.html#gga8cddf7779debef0067665671e911ec41a23e508440306c387ddf89acd2db9e065',1,'libevdev.h']]], + ['libevdev_5fled_5fon_70',['LIBEVDEV_LED_ON',['../group__kernel.html#gga8cddf7779debef0067665671e911ec41a69d5a4cdf2a9357915fff0251a61d2ab',1,'libevdev.h']]], + ['libevdev_5fled_5fvalue_71',['libevdev_led_value',['../group__kernel.html#ga8cddf7779debef0067665671e911ec41',1,'libevdev.h']]], + ['libevdev_5flog_5fdebug_72',['LIBEVDEV_LOG_DEBUG',['../group__logging.html#gga0b798d0864f2b1b10e4603f9431b3364a760d66d422ffcf89b0f1ddb529b95793',1,'libevdev.h']]], + ['libevdev_5flog_5ferror_73',['LIBEVDEV_LOG_ERROR',['../group__logging.html#gga0b798d0864f2b1b10e4603f9431b3364a21fd1083f2ebd0a25f09ee982e365d5f',1,'libevdev.h']]], + ['libevdev_5flog_5ffunc_5ft_74',['libevdev_log_func_t',['../group__logging.html#gaf36c721d273c0794251eb7dacea2f0a4',1,'libevdev.h']]], + ['libevdev_5flog_5finfo_75',['LIBEVDEV_LOG_INFO',['../group__logging.html#gga0b798d0864f2b1b10e4603f9431b3364a4d13a031b112292ca3e7bab8c6d76abc',1,'libevdev.h']]], + ['libevdev_5flog_5fpriority_76',['libevdev_log_priority',['../group__logging.html#ga0b798d0864f2b1b10e4603f9431b3364',1,'libevdev.h']]], + ['libevdev_5fnew_77',['libevdev_new',['../group__init.html#ga332c8ee260b4ef864345abe5d04e820c',1,'libevdev.h']]], + ['libevdev_5fnew_5ffrom_5ffd_78',['libevdev_new_from_fd',['../group__init.html#ga89bb5bce1c23e293293484b05b12aaf4',1,'libevdev.h']]], + ['libevdev_5fnext_5fevent_79',['libevdev_next_event',['../group__events.html#gabb96c864e836c0b98788f4ab771c3a76',1,'libevdev.h']]], + ['libevdev_5fproperty_5ffrom_5fname_80',['libevdev_property_from_name',['../group__misc.html#ga6f4418c98aa475a2fc34d58a197f7edd',1,'libevdev.h']]], + ['libevdev_5fproperty_5ffrom_5fname_5fn_81',['libevdev_property_from_name_n',['../group__misc.html#gaaa0bc4c7d0d2aedc84c7dcffee9ce29b',1,'libevdev.h']]], + ['libevdev_5fproperty_5fget_5fname_82',['libevdev_property_get_name',['../group__misc.html#gacc12bdb7b912070ac9c375428f2c9892',1,'libevdev.h']]], + ['libevdev_5fread_5fflag_83',['libevdev_read_flag',['../group__events.html#ga56c288d9f2e4c1632986c4e218c494e9',1,'libevdev.h']]], + ['libevdev_5fread_5fflag_5fblocking_84',['LIBEVDEV_READ_FLAG_BLOCKING',['../group__events.html#gga56c288d9f2e4c1632986c4e218c494e9a0a348d44362a7e515b40a4ed4d528e19',1,'libevdev.h']]], + ['libevdev_5fread_5fflag_5fforce_5fsync_85',['LIBEVDEV_READ_FLAG_FORCE_SYNC',['../group__events.html#gga56c288d9f2e4c1632986c4e218c494e9a5198e5c9cc98b75f73f61b104d6a674c',1,'libevdev.h']]], + ['libevdev_5fread_5fflag_5fnormal_86',['LIBEVDEV_READ_FLAG_NORMAL',['../group__events.html#gga56c288d9f2e4c1632986c4e218c494e9ac0d6ee19551eecf76f1ede4f36252418',1,'libevdev.h']]], + ['libevdev_5fread_5fflag_5fsync_87',['LIBEVDEV_READ_FLAG_SYNC',['../group__events.html#gga56c288d9f2e4c1632986c4e218c494e9a1f13a19641d6dafcf01a86a6389800f8',1,'libevdev.h']]], + ['libevdev_5fread_5fstatus_88',['libevdev_read_status',['../group__events.html#ga4a96221b3c7f54dfb86035d952154e3a',1,'libevdev.h']]], + ['libevdev_5fread_5fstatus_5fsuccess_89',['LIBEVDEV_READ_STATUS_SUCCESS',['../group__events.html#gga4a96221b3c7f54dfb86035d952154e3aab053221fc1c9630eee7111b75aa0aec7',1,'libevdev.h']]], + ['libevdev_5fread_5fstatus_5fsync_90',['LIBEVDEV_READ_STATUS_SYNC',['../group__events.html#gga4a96221b3c7f54dfb86035d952154e3aa8d70b14a38204fde4ad433023baa545a',1,'libevdev.h']]], + ['libevdev_5fset_5fabs_5fflat_91',['libevdev_set_abs_flat',['../group__kernel.html#gabd309f30744a49e9391250b00ba2d67a',1,'libevdev.h']]], + ['libevdev_5fset_5fabs_5ffuzz_92',['libevdev_set_abs_fuzz',['../group__kernel.html#gaa192bf0c68620be819337da6ec361c21',1,'libevdev.h']]], + ['libevdev_5fset_5fabs_5finfo_93',['libevdev_set_abs_info',['../group__kernel.html#gafc7a4f5308e2dbf55f875630b8dca049',1,'libevdev.h']]], + ['libevdev_5fset_5fabs_5fmaximum_94',['libevdev_set_abs_maximum',['../group__kernel.html#ga2302fd9a491d8e27280157d67a703af6',1,'libevdev.h']]], + ['libevdev_5fset_5fabs_5fminimum_95',['libevdev_set_abs_minimum',['../group__kernel.html#gaca62172c2a823cd02eacf0d2292d917a',1,'libevdev.h']]], + ['libevdev_5fset_5fabs_5fresolution_96',['libevdev_set_abs_resolution',['../group__kernel.html#ga2266b59711cdaa4fc12fa56c9313a038',1,'libevdev.h']]], + ['libevdev_5fset_5fclock_5fid_97',['libevdev_set_clock_id',['../group__kernel.html#ga2925b6fbf8c7991ff2164424b840b82d',1,'libevdev.h']]], + ['libevdev_5fset_5fdevice_5flog_5ffunction_98',['libevdev_set_device_log_function',['../group__logging.html#ga2830ff0aa391d8d1111682d3e762091b',1,'libevdev.h']]], + ['libevdev_5fset_5fevent_5fvalue_99',['libevdev_set_event_value',['../group__kernel.html#ga79e82ee2a95cb08adb4172aabe0c7184',1,'libevdev.h']]], + ['libevdev_5fset_5ffd_100',['libevdev_set_fd',['../group__init.html#ga6658ac490d68c307ff8b8d1536c12b44',1,'libevdev.h']]], + ['libevdev_5fset_5fid_5fbustype_101',['libevdev_set_id_bustype',['../group__kernel.html#gaf99139c728ba1bd4b37ede612780b6b0',1,'libevdev.h']]], + ['libevdev_5fset_5fid_5fproduct_102',['libevdev_set_id_product',['../group__kernel.html#ga62fbdaac056ab5c3db154a9eeaf33799',1,'libevdev.h']]], + ['libevdev_5fset_5fid_5fvendor_103',['libevdev_set_id_vendor',['../group__kernel.html#ga8ce28051ebbb73de1d04d782f4d0d6fe',1,'libevdev.h']]], + ['libevdev_5fset_5fid_5fversion_104',['libevdev_set_id_version',['../group__kernel.html#gaee1d2db88b191ec21d5bf22dd4fe3055',1,'libevdev.h']]], + ['libevdev_5fset_5flog_5ffunction_105',['libevdev_set_log_function',['../group__logging.html#gaa60be86b83b3a6c82d8e536ba89ff955',1,'libevdev.h']]], + ['libevdev_5fset_5flog_5fpriority_106',['libevdev_set_log_priority',['../group__logging.html#gaf6b6842a9ed98b61d0abb421e853fd89',1,'libevdev.h']]], + ['libevdev_5fset_5fname_107',['libevdev_set_name',['../group__kernel.html#gae5dcdb7678cdc9be4ab1989725b4ed32',1,'libevdev.h']]], + ['libevdev_5fset_5fphys_108',['libevdev_set_phys',['../group__kernel.html#gacd57c8d6ace8e0b1417809a9c1c67af3',1,'libevdev.h']]], + ['libevdev_5fset_5fslot_5fvalue_109',['libevdev_set_slot_value',['../group__kernel.html#ga0c61f4919b03b0850529a50c37a20333',1,'libevdev.h']]], + ['libevdev_5fset_5funiq_110',['libevdev_set_uniq',['../group__kernel.html#ga4e4fd2627744fd5811c50c7403f27ad7',1,'libevdev.h']]], + ['libevdev_5fuinput_5fcreate_5ffrom_5fdevice_111',['libevdev_uinput_create_from_device',['../group__uinput.html#gaf14b21301bac9d79c20e890172873b96',1,'libevdev-uinput.h']]], + ['libevdev_5fuinput_5fdestroy_112',['libevdev_uinput_destroy',['../group__uinput.html#ga9dfa58a84eb4c6b97107dcf3fa621329',1,'libevdev-uinput.h']]], + ['libevdev_5fuinput_5fget_5fdevnode_113',['libevdev_uinput_get_devnode',['../group__uinput.html#ga4c595bcda748b08561e2819fe9b7c2d2',1,'libevdev-uinput.h']]], + ['libevdev_5fuinput_5fget_5ffd_114',['libevdev_uinput_get_fd',['../group__uinput.html#ga9cd7fb14a96d4cc14d3dffdcead84c5d',1,'libevdev-uinput.h']]], + ['libevdev_5fuinput_5fget_5fsyspath_115',['libevdev_uinput_get_syspath',['../group__uinput.html#gaacca93061fce57cec0ce3c52e443a427',1,'libevdev-uinput.h']]], + ['libevdev_5fuinput_5fopen_5fmanaged_116',['LIBEVDEV_UINPUT_OPEN_MANAGED',['../libevdev-uinput_8h.html#a6546acd3e4fe75a74d91eebf9bbd3d03adcf2d4de38844ee3a8c830bc3285afad',1,'libevdev-uinput.h']]], + ['libevdev_5fuinput_5fopen_5fmode_117',['libevdev_uinput_open_mode',['../libevdev-uinput_8h.html#a6546acd3e4fe75a74d91eebf9bbd3d03',1,'libevdev-uinput.h']]], + ['libevdev_5fuinput_5fwrite_5fevent_118',['libevdev_uinput_write_event',['../group__uinput.html#ga4c3c2f5fcd315a28a067f53b9f855fe7',1,'libevdev-uinput.h']]], + ['libevdev_5fungrab_119',['LIBEVDEV_UNGRAB',['../group__init.html#ggaa282ec9badaa6bc11b1dc5bb124dbd5ba6c0930d0c280753504cd05ebdcda09eb',1,'libevdev.h']]], + ['library_20logging_20facilities_120',['Library logging facilities',['../group__logging.html',1,'']]] ]; diff --git a/doc/html/search/all_6.html b/doc/html/search/all_6.html index 31cbd052ed6a57125164ff3f3bc6270e9b8af261..f1e516d75abf29bc81d9b238432e0eff2192ea1d 100644 --- a/doc/html/search/all_6.html +++ b/doc/html/search/all_6.html @@ -1,7 +1,8 @@ - + + - + @@ -10,14 +11,14 @@
Loading...
- +
Searching...
No Matches
- +
diff --git a/doc/html/search/all_6.js b/doc/html/search/all_6.js index ca6ceafd35237d1bc99d5ee3cd3cfd9c057fb488..3cea197b668dac2f5ea84c984fa7d0409769c77f 100644 --- a/doc/html/search/all_6.js +++ b/doc/html/search/all_6.js @@ -1,6 +1,6 @@ var searchData= [ - ['modifying_20the_20appearance_20or_20capabilities_20of_20the_20device_120',['Modifying the appearance or capabilities of the device',['../group__kernel.html',1,'']]], ['miscellaneous_20helper_20functions_121',['Miscellaneous helper functions',['../group__misc.html',1,'']]], - ['multi_2dtouch_20related_20functions_122',['Multi-touch related functions',['../group__mt.html',1,'']]] + ['modifying_20the_20appearance_20or_20capabilities_20of_20the_20device_122',['Modifying the appearance or capabilities of the device',['../group__kernel.html',1,'']]], + ['multi_2dtouch_20related_20functions_123',['Multi-touch related functions',['../group__mt.html',1,'']]] ]; diff --git a/doc/html/search/all_7.html b/doc/html/search/all_7.html index 18c555de264a7eaab630641f00b2f666e2d8e641..8ddbf6c8e51e6232275b56dfb49b7a6bd143388a 100644 --- a/doc/html/search/all_7.html +++ b/doc/html/search/all_7.html @@ -1,7 +1,8 @@ - + + - + @@ -10,14 +11,14 @@
Loading...
- +
Searching...
No Matches
- +
diff --git a/doc/html/search/all_7.js b/doc/html/search/all_7.js index 89e1a001fa5e0999df3a87e5a77ac95b84da1f68..055cb205e31928b7fbc2b301337c138124ba928d 100644 --- a/doc/html/search/all_7.js +++ b/doc/html/search/all_7.js @@ -1,4 +1,4 @@ var searchData= [ - ['querying_20device_20capabilities_123',['Querying device capabilities',['../group__bits.html',1,'']]] + ['querying_20device_20capabilities_124',['Querying device capabilities',['../group__bits.html',1,'']]] ]; diff --git a/doc/html/search/all_8.html b/doc/html/search/all_8.html index 0f9eb416d3d4fd623c0d60b4a99b4851ded23a93..83c55ae222936f83e88b307baefeb74673007077 100644 --- a/doc/html/search/all_8.html +++ b/doc/html/search/all_8.html @@ -1,7 +1,8 @@ - + + - + @@ -10,14 +11,14 @@
Loading...
- +
Searching...
No Matches
- +
diff --git a/doc/html/search/all_8.js b/doc/html/search/all_8.js index b143ea6e1417227505bb2e2e793f319561ba3ed4..94ce2e19c36a4b027895082e1b550a2eb69a89d1 100644 --- a/doc/html/search/all_8.js +++ b/doc/html/search/all_8.js @@ -1,5 +1,5 @@ var searchData= [ - ['statically_20linking_20libevdev_124',['Statically linking libevdev',['../static_linking.html',1,'']]], - ['syn_5fdropped_20handling_125',['SYN_DROPPED handling',['../syn_dropped.html',1,'']]] + ['statically_20linking_20libevdev_125',['Statically linking libevdev',['../static_linking.html',1,'']]], + ['syn_5fdropped_20handling_126',['SYN_DROPPED handling',['../syn_dropped.html',1,'']]] ]; diff --git a/doc/html/search/all_9.html b/doc/html/search/all_9.html index d27c0f7c2dc2358a4b17b16aa2591020e9acdd9b..1e263c134c45cf4590dd10068a31052e44e3bb64 100644 --- a/doc/html/search/all_9.html +++ b/doc/html/search/all_9.html @@ -1,7 +1,8 @@ - + + - + @@ -10,14 +11,14 @@
Loading...
- +
Searching...
No Matches
- +
diff --git a/doc/html/search/all_9.js b/doc/html/search/all_9.js index 7d2bbfbccd10acaddff74df5757e8c2bce664523..04ddd4b423c8f930d2e158896b2ec34d94e94be6 100644 --- a/doc/html/search/all_9.js +++ b/doc/html/search/all_9.js @@ -1,4 +1,4 @@ var searchData= [ - ['uinput_20device_20creation_126',['uinput device creation',['../group__uinput.html',1,'']]] + ['uinput_20device_20creation_127',['uinput device creation',['../group__uinput.html',1,'']]] ]; diff --git a/doc/html/search/defines_0.html b/doc/html/search/defines_0.html index 0ede6c4b3eaafe22acf32736a66d15864066fbe0..15cc3de38d3d743bf47034017377623757dd10fe 100644 --- a/doc/html/search/defines_0.html +++ b/doc/html/search/defines_0.html @@ -1,7 +1,8 @@ - + + - + @@ -10,14 +11,14 @@
Loading...
- +
Searching...
No Matches
- +
diff --git a/doc/html/search/defines_0.js b/doc/html/search/defines_0.js index 9b9ada4313ee17b5e5fc04dfc33a689da14c4df8..aeccf3bad18de52fe4998ee55f5feea84064f1dc 100644 --- a/doc/html/search/defines_0.js +++ b/doc/html/search/defines_0.js @@ -1,5 +1,5 @@ var searchData= [ - ['libevdev_5fattribute_5fprintf_238',['LIBEVDEV_ATTRIBUTE_PRINTF',['../libevdev_8h.html#a64a0f325e88e1be50eb806e1ff75aec8',1,'libevdev.h']]], - ['libevdev_5fdeprecated_239',['LIBEVDEV_DEPRECATED',['../libevdev_8h.html#aa136bf4638abda28de7cd9f48af534ae',1,'libevdev.h']]] + ['libevdev_5fattribute_5fprintf_239',['LIBEVDEV_ATTRIBUTE_PRINTF',['../libevdev_8h.html#a64a0f325e88e1be50eb806e1ff75aec8',1,'libevdev.h']]], + ['libevdev_5fdeprecated_240',['LIBEVDEV_DEPRECATED',['../libevdev_8h.html#aa136bf4638abda28de7cd9f48af534ae',1,'libevdev.h']]] ]; diff --git a/doc/html/search/enums_0.html b/doc/html/search/enums_0.html index 9035e6aa12120a30f95607d9ce87aa3c4f99607d..141fff57be08342bbba65a3d54140e6ae9f2256e 100644 --- a/doc/html/search/enums_0.html +++ b/doc/html/search/enums_0.html @@ -1,7 +1,8 @@ - + + - + @@ -10,14 +11,14 @@
Loading...
- +
Searching...
No Matches
- +
diff --git a/doc/html/search/enums_0.js b/doc/html/search/enums_0.js index ac679d4e30b6d6569dc0902e3ba4dd79c6db9903..20fa8f87f1d8d5e078f26639d9d5ae7db092fd42 100644 --- a/doc/html/search/enums_0.js +++ b/doc/html/search/enums_0.js @@ -1,9 +1,9 @@ var searchData= [ - ['libevdev_5fgrab_5fmode_218',['libevdev_grab_mode',['../group__init.html#gaa282ec9badaa6bc11b1dc5bb124dbd5b',1,'libevdev.h']]], - ['libevdev_5fled_5fvalue_219',['libevdev_led_value',['../group__kernel.html#ga8cddf7779debef0067665671e911ec41',1,'libevdev.h']]], - ['libevdev_5flog_5fpriority_220',['libevdev_log_priority',['../group__logging.html#ga0b798d0864f2b1b10e4603f9431b3364',1,'libevdev.h']]], - ['libevdev_5fread_5fflag_221',['libevdev_read_flag',['../group__events.html#ga56c288d9f2e4c1632986c4e218c494e9',1,'libevdev.h']]], - ['libevdev_5fread_5fstatus_222',['libevdev_read_status',['../group__events.html#ga4a96221b3c7f54dfb86035d952154e3a',1,'libevdev.h']]], - ['libevdev_5fuinput_5fopen_5fmode_223',['libevdev_uinput_open_mode',['../libevdev-uinput_8h.html#a6546acd3e4fe75a74d91eebf9bbd3d03',1,'libevdev-uinput.h']]] + ['libevdev_5fgrab_5fmode_219',['libevdev_grab_mode',['../group__init.html#gaa282ec9badaa6bc11b1dc5bb124dbd5b',1,'libevdev.h']]], + ['libevdev_5fled_5fvalue_220',['libevdev_led_value',['../group__kernel.html#ga8cddf7779debef0067665671e911ec41',1,'libevdev.h']]], + ['libevdev_5flog_5fpriority_221',['libevdev_log_priority',['../group__logging.html#ga0b798d0864f2b1b10e4603f9431b3364',1,'libevdev.h']]], + ['libevdev_5fread_5fflag_222',['libevdev_read_flag',['../group__events.html#ga56c288d9f2e4c1632986c4e218c494e9',1,'libevdev.h']]], + ['libevdev_5fread_5fstatus_223',['libevdev_read_status',['../group__events.html#ga4a96221b3c7f54dfb86035d952154e3a',1,'libevdev.h']]], + ['libevdev_5fuinput_5fopen_5fmode_224',['libevdev_uinput_open_mode',['../libevdev-uinput_8h.html#a6546acd3e4fe75a74d91eebf9bbd3d03',1,'libevdev-uinput.h']]] ]; diff --git a/doc/html/search/enumvalues_0.html b/doc/html/search/enumvalues_0.html index c2cd472acd31260a65ec7a97c007a704b5cace24..0d131d95b8b1c3e3811a94a6ea3bb9bf5bdad9e6 100644 --- a/doc/html/search/enumvalues_0.html +++ b/doc/html/search/enumvalues_0.html @@ -1,7 +1,8 @@ - + + - + @@ -10,14 +11,14 @@
Loading...
- +
Searching...
No Matches
- +
diff --git a/doc/html/search/enumvalues_0.js b/doc/html/search/enumvalues_0.js index de986a5ee5f2eec87f39965f3df58b723b317b36..918c5b489f5f2af8befe479ef50550104ac30640 100644 --- a/doc/html/search/enumvalues_0.js +++ b/doc/html/search/enumvalues_0.js @@ -1,17 +1,17 @@ var searchData= [ - ['libevdev_5fgrab_224',['LIBEVDEV_GRAB',['../group__init.html#ggaa282ec9badaa6bc11b1dc5bb124dbd5bad3ac6f5f3ebf7d38a6aad74a88396c88',1,'libevdev.h']]], - ['libevdev_5fled_5foff_225',['LIBEVDEV_LED_OFF',['../group__kernel.html#gga8cddf7779debef0067665671e911ec41a23e508440306c387ddf89acd2db9e065',1,'libevdev.h']]], - ['libevdev_5fled_5fon_226',['LIBEVDEV_LED_ON',['../group__kernel.html#gga8cddf7779debef0067665671e911ec41a69d5a4cdf2a9357915fff0251a61d2ab',1,'libevdev.h']]], - ['libevdev_5flog_5fdebug_227',['LIBEVDEV_LOG_DEBUG',['../group__logging.html#gga0b798d0864f2b1b10e4603f9431b3364a760d66d422ffcf89b0f1ddb529b95793',1,'libevdev.h']]], - ['libevdev_5flog_5ferror_228',['LIBEVDEV_LOG_ERROR',['../group__logging.html#gga0b798d0864f2b1b10e4603f9431b3364a21fd1083f2ebd0a25f09ee982e365d5f',1,'libevdev.h']]], - ['libevdev_5flog_5finfo_229',['LIBEVDEV_LOG_INFO',['../group__logging.html#gga0b798d0864f2b1b10e4603f9431b3364a4d13a031b112292ca3e7bab8c6d76abc',1,'libevdev.h']]], - ['libevdev_5fread_5fflag_5fblocking_230',['LIBEVDEV_READ_FLAG_BLOCKING',['../group__events.html#gga56c288d9f2e4c1632986c4e218c494e9a0a348d44362a7e515b40a4ed4d528e19',1,'libevdev.h']]], - ['libevdev_5fread_5fflag_5fforce_5fsync_231',['LIBEVDEV_READ_FLAG_FORCE_SYNC',['../group__events.html#gga56c288d9f2e4c1632986c4e218c494e9a5198e5c9cc98b75f73f61b104d6a674c',1,'libevdev.h']]], - ['libevdev_5fread_5fflag_5fnormal_232',['LIBEVDEV_READ_FLAG_NORMAL',['../group__events.html#gga56c288d9f2e4c1632986c4e218c494e9ac0d6ee19551eecf76f1ede4f36252418',1,'libevdev.h']]], - ['libevdev_5fread_5fflag_5fsync_233',['LIBEVDEV_READ_FLAG_SYNC',['../group__events.html#gga56c288d9f2e4c1632986c4e218c494e9a1f13a19641d6dafcf01a86a6389800f8',1,'libevdev.h']]], - ['libevdev_5fread_5fstatus_5fsuccess_234',['LIBEVDEV_READ_STATUS_SUCCESS',['../group__events.html#gga4a96221b3c7f54dfb86035d952154e3aab053221fc1c9630eee7111b75aa0aec7',1,'libevdev.h']]], - ['libevdev_5fread_5fstatus_5fsync_235',['LIBEVDEV_READ_STATUS_SYNC',['../group__events.html#gga4a96221b3c7f54dfb86035d952154e3aa8d70b14a38204fde4ad433023baa545a',1,'libevdev.h']]], - ['libevdev_5fuinput_5fopen_5fmanaged_236',['LIBEVDEV_UINPUT_OPEN_MANAGED',['../libevdev-uinput_8h.html#a6546acd3e4fe75a74d91eebf9bbd3d03adcf2d4de38844ee3a8c830bc3285afad',1,'libevdev-uinput.h']]], - ['libevdev_5fungrab_237',['LIBEVDEV_UNGRAB',['../group__init.html#ggaa282ec9badaa6bc11b1dc5bb124dbd5ba6c0930d0c280753504cd05ebdcda09eb',1,'libevdev.h']]] + ['libevdev_5fgrab_225',['LIBEVDEV_GRAB',['../group__init.html#ggaa282ec9badaa6bc11b1dc5bb124dbd5bad3ac6f5f3ebf7d38a6aad74a88396c88',1,'libevdev.h']]], + ['libevdev_5fled_5foff_226',['LIBEVDEV_LED_OFF',['../group__kernel.html#gga8cddf7779debef0067665671e911ec41a23e508440306c387ddf89acd2db9e065',1,'libevdev.h']]], + ['libevdev_5fled_5fon_227',['LIBEVDEV_LED_ON',['../group__kernel.html#gga8cddf7779debef0067665671e911ec41a69d5a4cdf2a9357915fff0251a61d2ab',1,'libevdev.h']]], + ['libevdev_5flog_5fdebug_228',['LIBEVDEV_LOG_DEBUG',['../group__logging.html#gga0b798d0864f2b1b10e4603f9431b3364a760d66d422ffcf89b0f1ddb529b95793',1,'libevdev.h']]], + ['libevdev_5flog_5ferror_229',['LIBEVDEV_LOG_ERROR',['../group__logging.html#gga0b798d0864f2b1b10e4603f9431b3364a21fd1083f2ebd0a25f09ee982e365d5f',1,'libevdev.h']]], + ['libevdev_5flog_5finfo_230',['LIBEVDEV_LOG_INFO',['../group__logging.html#gga0b798d0864f2b1b10e4603f9431b3364a4d13a031b112292ca3e7bab8c6d76abc',1,'libevdev.h']]], + ['libevdev_5fread_5fflag_5fblocking_231',['LIBEVDEV_READ_FLAG_BLOCKING',['../group__events.html#gga56c288d9f2e4c1632986c4e218c494e9a0a348d44362a7e515b40a4ed4d528e19',1,'libevdev.h']]], + ['libevdev_5fread_5fflag_5fforce_5fsync_232',['LIBEVDEV_READ_FLAG_FORCE_SYNC',['../group__events.html#gga56c288d9f2e4c1632986c4e218c494e9a5198e5c9cc98b75f73f61b104d6a674c',1,'libevdev.h']]], + ['libevdev_5fread_5fflag_5fnormal_233',['LIBEVDEV_READ_FLAG_NORMAL',['../group__events.html#gga56c288d9f2e4c1632986c4e218c494e9ac0d6ee19551eecf76f1ede4f36252418',1,'libevdev.h']]], + ['libevdev_5fread_5fflag_5fsync_234',['LIBEVDEV_READ_FLAG_SYNC',['../group__events.html#gga56c288d9f2e4c1632986c4e218c494e9a1f13a19641d6dafcf01a86a6389800f8',1,'libevdev.h']]], + ['libevdev_5fread_5fstatus_5fsuccess_235',['LIBEVDEV_READ_STATUS_SUCCESS',['../group__events.html#gga4a96221b3c7f54dfb86035d952154e3aab053221fc1c9630eee7111b75aa0aec7',1,'libevdev.h']]], + ['libevdev_5fread_5fstatus_5fsync_236',['LIBEVDEV_READ_STATUS_SYNC',['../group__events.html#gga4a96221b3c7f54dfb86035d952154e3aa8d70b14a38204fde4ad433023baa545a',1,'libevdev.h']]], + ['libevdev_5fuinput_5fopen_5fmanaged_237',['LIBEVDEV_UINPUT_OPEN_MANAGED',['../libevdev-uinput_8h.html#a6546acd3e4fe75a74d91eebf9bbd3d03adcf2d4de38844ee3a8c830bc3285afad',1,'libevdev-uinput.h']]], + ['libevdev_5fungrab_238',['LIBEVDEV_UNGRAB',['../group__init.html#ggaa282ec9badaa6bc11b1dc5bb124dbd5ba6c0930d0c280753504cd05ebdcda09eb',1,'libevdev.h']]] ]; diff --git a/doc/html/search/files_0.html b/doc/html/search/files_0.html index 76b64f5bb4603ad2fb3f78c4f962dc8b58f0351a..9498842a62658a696497b75d13f38e46e8d06776 100644 --- a/doc/html/search/files_0.html +++ b/doc/html/search/files_0.html @@ -1,7 +1,8 @@ - + + - + @@ -10,14 +11,14 @@
Loading...
- +
Searching...
No Matches
- +
diff --git a/doc/html/search/files_0.js b/doc/html/search/files_0.js index f57911f8bded3f20ccf2f689c0475283abc451c9..3cea379b87921fca0b8bca14ca2707f4e1489000 100644 --- a/doc/html/search/files_0.js +++ b/doc/html/search/files_0.js @@ -1,5 +1,5 @@ var searchData= [ - ['libevdev_2duinput_2eh_127',['libevdev-uinput.h',['../libevdev-uinput_8h.html',1,'']]], - ['libevdev_2eh_128',['libevdev.h',['../libevdev_8h.html',1,'']]] + ['libevdev_2duinput_2eh_128',['libevdev-uinput.h',['../libevdev-uinput_8h.html',1,'']]], + ['libevdev_2eh_129',['libevdev.h',['../libevdev_8h.html',1,'']]] ]; diff --git a/doc/html/search/functions_0.html b/doc/html/search/functions_0.html index f04535ae67847d65edeaf03627670fa47e4daf36..eb4c5014c401e4d277434803bd0322e70ca31cd8 100644 --- a/doc/html/search/functions_0.html +++ b/doc/html/search/functions_0.html @@ -1,7 +1,8 @@ - + + - + @@ -10,14 +11,14 @@
Loading...
- +
Searching...
No Matches
- +
diff --git a/doc/html/search/functions_0.js b/doc/html/search/functions_0.js index 124ebfb911e1e0ce15cf46e6ea1b77847323475c..530d50dac503854e43c660904d13c6b8dd35819c 100644 --- a/doc/html/search/functions_0.js +++ b/doc/html/search/functions_0.js @@ -1,90 +1,90 @@ var searchData= [ - ['libevdev_5fchange_5ffd_129',['libevdev_change_fd',['../group__init.html#gac71c9cca4c572ed1b1a8c233be70a17c',1,'libevdev.h']]], - ['libevdev_5fdisable_5fevent_5fcode_130',['libevdev_disable_event_code',['../group__kernel.html#ga6199a7c8144f54e092e913c2d2df16de',1,'libevdev.h']]], - ['libevdev_5fdisable_5fevent_5ftype_131',['libevdev_disable_event_type',['../group__kernel.html#gabbacb53b66882b5335055c0fd1f40d9a',1,'libevdev.h']]], - ['libevdev_5fdisable_5fproperty_132',['libevdev_disable_property',['../group__kernel.html#ga8f6367c36331c803ad69b2591e210019',1,'libevdev.h']]], - ['libevdev_5fenable_5fevent_5fcode_133',['libevdev_enable_event_code',['../group__kernel.html#ga51cfda33fd526549046399aadd764fca',1,'libevdev.h']]], - ['libevdev_5fenable_5fevent_5ftype_134',['libevdev_enable_event_type',['../group__kernel.html#ga59ef78b1557f9543d0060ab25b0167ca',1,'libevdev.h']]], - ['libevdev_5fenable_5fproperty_135',['libevdev_enable_property',['../group__kernel.html#gafc552080520c9d886452b05f3a1d75b6',1,'libevdev.h']]], - ['libevdev_5fevent_5fcode_5ffrom_5fcode_5fname_136',['libevdev_event_code_from_code_name',['../group__misc.html#gabad00f68481d83747a134c0a37aca003',1,'libevdev.h']]], - ['libevdev_5fevent_5fcode_5ffrom_5fcode_5fname_5fn_137',['libevdev_event_code_from_code_name_n',['../group__misc.html#ga5bf9af4b8c372d87793e8a3c2dbeb466',1,'libevdev.h']]], - ['libevdev_5fevent_5fcode_5ffrom_5fname_138',['libevdev_event_code_from_name',['../group__misc.html#ga6620301a67f467489e4a7f93afe81621',1,'libevdev.h']]], - ['libevdev_5fevent_5fcode_5ffrom_5fname_5fn_139',['libevdev_event_code_from_name_n',['../group__misc.html#ga17a760a9eea9dc25011f39e1d5c282a0',1,'libevdev.h']]], - ['libevdev_5fevent_5fcode_5fget_5fname_140',['libevdev_event_code_get_name',['../group__misc.html#gab407b3c2caaae502859c28460cad17bb',1,'libevdev.h']]], - ['libevdev_5fevent_5fis_5fcode_141',['libevdev_event_is_code',['../group__misc.html#ga37766a6a498fef3294d589abcce688bb',1,'libevdev.h']]], - ['libevdev_5fevent_5fis_5ftype_142',['libevdev_event_is_type',['../group__misc.html#gab8b6b80740e028261300b8952b61a596',1,'libevdev.h']]], - ['libevdev_5fevent_5ftype_5ffrom_5fcode_5fname_143',['libevdev_event_type_from_code_name',['../group__misc.html#gadd41b7514cca16c8b8920f16e562e08a',1,'libevdev.h']]], - ['libevdev_5fevent_5ftype_5ffrom_5fcode_5fname_5fn_144',['libevdev_event_type_from_code_name_n',['../group__misc.html#gab214498fca7a328f8a712ce15bf21982',1,'libevdev.h']]], - ['libevdev_5fevent_5ftype_5ffrom_5fname_145',['libevdev_event_type_from_name',['../group__misc.html#ga61ce3bf1e66bd172e583b86a11fc41f1',1,'libevdev.h']]], - ['libevdev_5fevent_5ftype_5ffrom_5fname_5fn_146',['libevdev_event_type_from_name_n',['../group__misc.html#ga4ee03d650200bb04a23233570667fa84',1,'libevdev.h']]], - ['libevdev_5fevent_5ftype_5fget_5fmax_147',['libevdev_event_type_get_max',['../group__misc.html#gabfad87ea78d034631cf3e5322ac383a1',1,'libevdev.h']]], - ['libevdev_5fevent_5ftype_5fget_5fname_148',['libevdev_event_type_get_name',['../group__misc.html#gac99720fd926bf288764f9a81bf37ed09',1,'libevdev.h']]], - ['libevdev_5fevent_5fvalue_5ffrom_5fname_149',['libevdev_event_value_from_name',['../group__misc.html#ga314903beeafedabe45f879637e7254b0',1,'libevdev.h']]], - ['libevdev_5fevent_5fvalue_5ffrom_5fname_5fn_150',['libevdev_event_value_from_name_n',['../group__misc.html#gaebfc6b0ebb70169c9fec61620f1ea85f',1,'libevdev.h']]], - ['libevdev_5fevent_5fvalue_5fget_5fname_151',['libevdev_event_value_get_name',['../group__misc.html#gabcd45c5e963cba245e944ea66e72fcc3',1,'libevdev.h']]], - ['libevdev_5ffetch_5fevent_5fvalue_152',['libevdev_fetch_event_value',['../group__bits.html#ga0a7be80d769294bf9758adf79c3c7147',1,'libevdev.h']]], - ['libevdev_5ffetch_5fslot_5fvalue_153',['libevdev_fetch_slot_value',['../group__mt.html#gaca19dca5aa8f0ea3b210f3fc670384ec',1,'libevdev.h']]], - ['libevdev_5ffree_154',['libevdev_free',['../group__init.html#gacd9fe760d15be25fc99ce469034bd78c',1,'libevdev.h']]], - ['libevdev_5fget_5fabs_5fflat_155',['libevdev_get_abs_flat',['../group__bits.html#ga6b3f7ebae2324524dc41384acd724b92',1,'libevdev.h']]], - ['libevdev_5fget_5fabs_5ffuzz_156',['libevdev_get_abs_fuzz',['../group__bits.html#ga1a3dfeb3bb2db0b4323c836c7ab10f1a',1,'libevdev.h']]], - ['libevdev_5fget_5fabs_5finfo_157',['libevdev_get_abs_info',['../group__bits.html#ga6d8e2caf87fa536fad979346671838d7',1,'libevdev.h']]], - ['libevdev_5fget_5fabs_5fmaximum_158',['libevdev_get_abs_maximum',['../group__bits.html#ga97a3411ae85f1f3b5c5eb1d5351b11ca',1,'libevdev.h']]], - ['libevdev_5fget_5fabs_5fminimum_159',['libevdev_get_abs_minimum',['../group__bits.html#ga482ce989a3f62f7e67e4ea7ad534189e',1,'libevdev.h']]], - ['libevdev_5fget_5fabs_5fresolution_160',['libevdev_get_abs_resolution',['../group__bits.html#ga75751e637a845201b6d1c419ecfa6ba4',1,'libevdev.h']]], - ['libevdev_5fget_5fcurrent_5fslot_161',['libevdev_get_current_slot',['../group__mt.html#gad22e2420be668b56ef486cde2e98c5dd',1,'libevdev.h']]], - ['libevdev_5fget_5fdriver_5fversion_162',['libevdev_get_driver_version',['../group__bits.html#ga31e9e7a99215a03bcdc339b53e1be2fa',1,'libevdev.h']]], - ['libevdev_5fget_5fevent_5fvalue_163',['libevdev_get_event_value',['../group__bits.html#ga6259f4c6bdba950329ff9cd48c2ef8a3',1,'libevdev.h']]], - ['libevdev_5fget_5ffd_164',['libevdev_get_fd',['../group__init.html#gab9bfc800859ac3aa63f41d58ec4b616c',1,'libevdev.h']]], - ['libevdev_5fget_5fid_5fbustype_165',['libevdev_get_id_bustype',['../group__bits.html#ga9bf55d416401642bad0c435735682308',1,'libevdev.h']]], - ['libevdev_5fget_5fid_5fproduct_166',['libevdev_get_id_product',['../group__bits.html#ga1dc66cfef646878d58be72f8902a6bac',1,'libevdev.h']]], - ['libevdev_5fget_5fid_5fvendor_167',['libevdev_get_id_vendor',['../group__bits.html#ga08891c3285da5b8d26769c9a34f063f3',1,'libevdev.h']]], - ['libevdev_5fget_5fid_5fversion_168',['libevdev_get_id_version',['../group__bits.html#ga75a07d0c96dfe09d2194c104c429d0ae',1,'libevdev.h']]], - ['libevdev_5fget_5flog_5fpriority_169',['libevdev_get_log_priority',['../group__logging.html#ga1da07493a798595cf85c127490b98ee8',1,'libevdev.h']]], - ['libevdev_5fget_5fname_170',['libevdev_get_name',['../group__bits.html#gaed0328c67b7a78422636d9fe09a73f12',1,'libevdev.h']]], - ['libevdev_5fget_5fnum_5fslots_171',['libevdev_get_num_slots',['../group__mt.html#gaf272526f0a59d2f61ef7389046cd4088',1,'libevdev.h']]], - ['libevdev_5fget_5fphys_172',['libevdev_get_phys',['../group__bits.html#ga5df483b0b24d7b96ea1181808fab851d',1,'libevdev.h']]], - ['libevdev_5fget_5frepeat_173',['libevdev_get_repeat',['../group__bits.html#gaf12fa199bb9497b38358d72e7505d770',1,'libevdev.h']]], - ['libevdev_5fget_5fslot_5fvalue_174',['libevdev_get_slot_value',['../group__mt.html#ga8c6303391cb4f90b2d46763cf4eb8bc8',1,'libevdev.h']]], - ['libevdev_5fget_5funiq_175',['libevdev_get_uniq',['../group__bits.html#ga6d9f7d44bff8828ead3d251177035ca4',1,'libevdev.h']]], - ['libevdev_5fgrab_176',['libevdev_grab',['../group__init.html#ga5d434af74fee20f273db568e2cbbd13f',1,'libevdev.h']]], - ['libevdev_5fhas_5fevent_5fcode_177',['libevdev_has_event_code',['../group__bits.html#gab2ab9dad417f33daa79fa0c3d682df0b',1,'libevdev.h']]], - ['libevdev_5fhas_5fevent_5fpending_178',['libevdev_has_event_pending',['../group__events.html#gae18fbfb59064c9c4b9d5db2d8cb23784',1,'libevdev.h']]], - ['libevdev_5fhas_5fevent_5ftype_179',['libevdev_has_event_type',['../group__bits.html#ga398bef155fa4a0cfb832de30723ebd14',1,'libevdev.h']]], - ['libevdev_5fhas_5fproperty_180',['libevdev_has_property',['../group__bits.html#ga36d529ea53f4522004bc7d16c051464b',1,'libevdev.h']]], - ['libevdev_5fkernel_5fset_5fabs_5finfo_181',['libevdev_kernel_set_abs_info',['../group__kernel.html#ga41c0321b93349d0ddd1f1c007ccf7de9',1,'libevdev.h']]], - ['libevdev_5fkernel_5fset_5fled_5fvalue_182',['libevdev_kernel_set_led_value',['../group__kernel.html#gaa7d13aeac3c40e16f296467780e67c01',1,'libevdev.h']]], - ['libevdev_5fkernel_5fset_5fled_5fvalues_183',['libevdev_kernel_set_led_values',['../group__kernel.html#ga93a19fa6e5be57903aff7c4a60af2a00',1,'libevdev.h']]], - ['libevdev_5fnew_184',['libevdev_new',['../group__init.html#ga332c8ee260b4ef864345abe5d04e820c',1,'libevdev.h']]], - ['libevdev_5fnew_5ffrom_5ffd_185',['libevdev_new_from_fd',['../group__init.html#ga89bb5bce1c23e293293484b05b12aaf4',1,'libevdev.h']]], - ['libevdev_5fnext_5fevent_186',['libevdev_next_event',['../group__events.html#gabb96c864e836c0b98788f4ab771c3a76',1,'libevdev.h']]], - ['libevdev_5fproperty_5ffrom_5fname_187',['libevdev_property_from_name',['../group__misc.html#ga6f4418c98aa475a2fc34d58a197f7edd',1,'libevdev.h']]], - ['libevdev_5fproperty_5ffrom_5fname_5fn_188',['libevdev_property_from_name_n',['../group__misc.html#gaaa0bc4c7d0d2aedc84c7dcffee9ce29b',1,'libevdev.h']]], - ['libevdev_5fproperty_5fget_5fname_189',['libevdev_property_get_name',['../group__misc.html#gacc12bdb7b912070ac9c375428f2c9892',1,'libevdev.h']]], - ['libevdev_5fset_5fabs_5fflat_190',['libevdev_set_abs_flat',['../group__kernel.html#gabd309f30744a49e9391250b00ba2d67a',1,'libevdev.h']]], - ['libevdev_5fset_5fabs_5ffuzz_191',['libevdev_set_abs_fuzz',['../group__kernel.html#gaa192bf0c68620be819337da6ec361c21',1,'libevdev.h']]], - ['libevdev_5fset_5fabs_5finfo_192',['libevdev_set_abs_info',['../group__kernel.html#gafc7a4f5308e2dbf55f875630b8dca049',1,'libevdev.h']]], - ['libevdev_5fset_5fabs_5fmaximum_193',['libevdev_set_abs_maximum',['../group__kernel.html#ga2302fd9a491d8e27280157d67a703af6',1,'libevdev.h']]], - ['libevdev_5fset_5fabs_5fminimum_194',['libevdev_set_abs_minimum',['../group__kernel.html#gaca62172c2a823cd02eacf0d2292d917a',1,'libevdev.h']]], - ['libevdev_5fset_5fabs_5fresolution_195',['libevdev_set_abs_resolution',['../group__kernel.html#ga2266b59711cdaa4fc12fa56c9313a038',1,'libevdev.h']]], - ['libevdev_5fset_5fclock_5fid_196',['libevdev_set_clock_id',['../group__kernel.html#ga2925b6fbf8c7991ff2164424b840b82d',1,'libevdev.h']]], - ['libevdev_5fset_5fdevice_5flog_5ffunction_197',['libevdev_set_device_log_function',['../group__logging.html#ga2830ff0aa391d8d1111682d3e762091b',1,'libevdev.h']]], - ['libevdev_5fset_5fevent_5fvalue_198',['libevdev_set_event_value',['../group__kernel.html#ga79e82ee2a95cb08adb4172aabe0c7184',1,'libevdev.h']]], - ['libevdev_5fset_5ffd_199',['libevdev_set_fd',['../group__init.html#ga6658ac490d68c307ff8b8d1536c12b44',1,'libevdev.h']]], - ['libevdev_5fset_5fid_5fbustype_200',['libevdev_set_id_bustype',['../group__kernel.html#gaf99139c728ba1bd4b37ede612780b6b0',1,'libevdev.h']]], - ['libevdev_5fset_5fid_5fproduct_201',['libevdev_set_id_product',['../group__kernel.html#ga62fbdaac056ab5c3db154a9eeaf33799',1,'libevdev.h']]], - ['libevdev_5fset_5fid_5fvendor_202',['libevdev_set_id_vendor',['../group__kernel.html#ga8ce28051ebbb73de1d04d782f4d0d6fe',1,'libevdev.h']]], - ['libevdev_5fset_5fid_5fversion_203',['libevdev_set_id_version',['../group__kernel.html#gaee1d2db88b191ec21d5bf22dd4fe3055',1,'libevdev.h']]], - ['libevdev_5fset_5flog_5ffunction_204',['libevdev_set_log_function',['../group__logging.html#gaa60be86b83b3a6c82d8e536ba89ff955',1,'libevdev.h']]], - ['libevdev_5fset_5flog_5fpriority_205',['libevdev_set_log_priority',['../group__logging.html#gaf6b6842a9ed98b61d0abb421e853fd89',1,'libevdev.h']]], - ['libevdev_5fset_5fname_206',['libevdev_set_name',['../group__kernel.html#gae5dcdb7678cdc9be4ab1989725b4ed32',1,'libevdev.h']]], - ['libevdev_5fset_5fphys_207',['libevdev_set_phys',['../group__kernel.html#gacd57c8d6ace8e0b1417809a9c1c67af3',1,'libevdev.h']]], - ['libevdev_5fset_5fslot_5fvalue_208',['libevdev_set_slot_value',['../group__kernel.html#ga0c61f4919b03b0850529a50c37a20333',1,'libevdev.h']]], - ['libevdev_5fset_5funiq_209',['libevdev_set_uniq',['../group__kernel.html#ga4e4fd2627744fd5811c50c7403f27ad7',1,'libevdev.h']]], - ['libevdev_5fuinput_5fcreate_5ffrom_5fdevice_210',['libevdev_uinput_create_from_device',['../group__uinput.html#gaf14b21301bac9d79c20e890172873b96',1,'libevdev-uinput.h']]], - ['libevdev_5fuinput_5fdestroy_211',['libevdev_uinput_destroy',['../group__uinput.html#ga9dfa58a84eb4c6b97107dcf3fa621329',1,'libevdev-uinput.h']]], - ['libevdev_5fuinput_5fget_5fdevnode_212',['libevdev_uinput_get_devnode',['../group__uinput.html#ga4c595bcda748b08561e2819fe9b7c2d2',1,'libevdev-uinput.h']]], - ['libevdev_5fuinput_5fget_5ffd_213',['libevdev_uinput_get_fd',['../group__uinput.html#ga9cd7fb14a96d4cc14d3dffdcead84c5d',1,'libevdev-uinput.h']]], - ['libevdev_5fuinput_5fget_5fsyspath_214',['libevdev_uinput_get_syspath',['../group__uinput.html#gaacca93061fce57cec0ce3c52e443a427',1,'libevdev-uinput.h']]], - ['libevdev_5fuinput_5fwrite_5fevent_215',['libevdev_uinput_write_event',['../group__uinput.html#ga4c3c2f5fcd315a28a067f53b9f855fe7',1,'libevdev-uinput.h']]] + ['libevdev_5fchange_5ffd_130',['libevdev_change_fd',['../group__init.html#gac71c9cca4c572ed1b1a8c233be70a17c',1,'libevdev.h']]], + ['libevdev_5fdisable_5fevent_5fcode_131',['libevdev_disable_event_code',['../group__kernel.html#ga6199a7c8144f54e092e913c2d2df16de',1,'libevdev.h']]], + ['libevdev_5fdisable_5fevent_5ftype_132',['libevdev_disable_event_type',['../group__kernel.html#gabbacb53b66882b5335055c0fd1f40d9a',1,'libevdev.h']]], + ['libevdev_5fdisable_5fproperty_133',['libevdev_disable_property',['../group__kernel.html#ga8f6367c36331c803ad69b2591e210019',1,'libevdev.h']]], + ['libevdev_5fenable_5fevent_5fcode_134',['libevdev_enable_event_code',['../group__kernel.html#ga51cfda33fd526549046399aadd764fca',1,'libevdev.h']]], + ['libevdev_5fenable_5fevent_5ftype_135',['libevdev_enable_event_type',['../group__kernel.html#ga59ef78b1557f9543d0060ab25b0167ca',1,'libevdev.h']]], + ['libevdev_5fenable_5fproperty_136',['libevdev_enable_property',['../group__kernel.html#gafc552080520c9d886452b05f3a1d75b6',1,'libevdev.h']]], + ['libevdev_5fevent_5fcode_5ffrom_5fcode_5fname_137',['libevdev_event_code_from_code_name',['../group__misc.html#gabad00f68481d83747a134c0a37aca003',1,'libevdev.h']]], + ['libevdev_5fevent_5fcode_5ffrom_5fcode_5fname_5fn_138',['libevdev_event_code_from_code_name_n',['../group__misc.html#ga5bf9af4b8c372d87793e8a3c2dbeb466',1,'libevdev.h']]], + ['libevdev_5fevent_5fcode_5ffrom_5fname_139',['libevdev_event_code_from_name',['../group__misc.html#ga6620301a67f467489e4a7f93afe81621',1,'libevdev.h']]], + ['libevdev_5fevent_5fcode_5ffrom_5fname_5fn_140',['libevdev_event_code_from_name_n',['../group__misc.html#ga17a760a9eea9dc25011f39e1d5c282a0',1,'libevdev.h']]], + ['libevdev_5fevent_5fcode_5fget_5fname_141',['libevdev_event_code_get_name',['../group__misc.html#gab407b3c2caaae502859c28460cad17bb',1,'libevdev.h']]], + ['libevdev_5fevent_5fis_5fcode_142',['libevdev_event_is_code',['../group__misc.html#ga37766a6a498fef3294d589abcce688bb',1,'libevdev.h']]], + ['libevdev_5fevent_5fis_5ftype_143',['libevdev_event_is_type',['../group__misc.html#gab8b6b80740e028261300b8952b61a596',1,'libevdev.h']]], + ['libevdev_5fevent_5ftype_5ffrom_5fcode_5fname_144',['libevdev_event_type_from_code_name',['../group__misc.html#gadd41b7514cca16c8b8920f16e562e08a',1,'libevdev.h']]], + ['libevdev_5fevent_5ftype_5ffrom_5fcode_5fname_5fn_145',['libevdev_event_type_from_code_name_n',['../group__misc.html#gab214498fca7a328f8a712ce15bf21982',1,'libevdev.h']]], + ['libevdev_5fevent_5ftype_5ffrom_5fname_146',['libevdev_event_type_from_name',['../group__misc.html#ga61ce3bf1e66bd172e583b86a11fc41f1',1,'libevdev.h']]], + ['libevdev_5fevent_5ftype_5ffrom_5fname_5fn_147',['libevdev_event_type_from_name_n',['../group__misc.html#ga4ee03d650200bb04a23233570667fa84',1,'libevdev.h']]], + ['libevdev_5fevent_5ftype_5fget_5fmax_148',['libevdev_event_type_get_max',['../group__misc.html#gabfad87ea78d034631cf3e5322ac383a1',1,'libevdev.h']]], + ['libevdev_5fevent_5ftype_5fget_5fname_149',['libevdev_event_type_get_name',['../group__misc.html#gac99720fd926bf288764f9a81bf37ed09',1,'libevdev.h']]], + ['libevdev_5fevent_5fvalue_5ffrom_5fname_150',['libevdev_event_value_from_name',['../group__misc.html#ga314903beeafedabe45f879637e7254b0',1,'libevdev.h']]], + ['libevdev_5fevent_5fvalue_5ffrom_5fname_5fn_151',['libevdev_event_value_from_name_n',['../group__misc.html#gaebfc6b0ebb70169c9fec61620f1ea85f',1,'libevdev.h']]], + ['libevdev_5fevent_5fvalue_5fget_5fname_152',['libevdev_event_value_get_name',['../group__misc.html#gabcd45c5e963cba245e944ea66e72fcc3',1,'libevdev.h']]], + ['libevdev_5ffetch_5fevent_5fvalue_153',['libevdev_fetch_event_value',['../group__bits.html#ga0a7be80d769294bf9758adf79c3c7147',1,'libevdev.h']]], + ['libevdev_5ffetch_5fslot_5fvalue_154',['libevdev_fetch_slot_value',['../group__mt.html#gaca19dca5aa8f0ea3b210f3fc670384ec',1,'libevdev.h']]], + ['libevdev_5ffree_155',['libevdev_free',['../group__init.html#gacd9fe760d15be25fc99ce469034bd78c',1,'libevdev.h']]], + ['libevdev_5fget_5fabs_5fflat_156',['libevdev_get_abs_flat',['../group__bits.html#ga6b3f7ebae2324524dc41384acd724b92',1,'libevdev.h']]], + ['libevdev_5fget_5fabs_5ffuzz_157',['libevdev_get_abs_fuzz',['../group__bits.html#ga1a3dfeb3bb2db0b4323c836c7ab10f1a',1,'libevdev.h']]], + ['libevdev_5fget_5fabs_5finfo_158',['libevdev_get_abs_info',['../group__bits.html#ga6d8e2caf87fa536fad979346671838d7',1,'libevdev.h']]], + ['libevdev_5fget_5fabs_5fmaximum_159',['libevdev_get_abs_maximum',['../group__bits.html#ga97a3411ae85f1f3b5c5eb1d5351b11ca',1,'libevdev.h']]], + ['libevdev_5fget_5fabs_5fminimum_160',['libevdev_get_abs_minimum',['../group__bits.html#ga482ce989a3f62f7e67e4ea7ad534189e',1,'libevdev.h']]], + ['libevdev_5fget_5fabs_5fresolution_161',['libevdev_get_abs_resolution',['../group__bits.html#ga75751e637a845201b6d1c419ecfa6ba4',1,'libevdev.h']]], + ['libevdev_5fget_5fcurrent_5fslot_162',['libevdev_get_current_slot',['../group__mt.html#gad22e2420be668b56ef486cde2e98c5dd',1,'libevdev.h']]], + ['libevdev_5fget_5fdriver_5fversion_163',['libevdev_get_driver_version',['../group__bits.html#ga31e9e7a99215a03bcdc339b53e1be2fa',1,'libevdev.h']]], + ['libevdev_5fget_5fevent_5fvalue_164',['libevdev_get_event_value',['../group__bits.html#ga6259f4c6bdba950329ff9cd48c2ef8a3',1,'libevdev.h']]], + ['libevdev_5fget_5ffd_165',['libevdev_get_fd',['../group__init.html#gab9bfc800859ac3aa63f41d58ec4b616c',1,'libevdev.h']]], + ['libevdev_5fget_5fid_5fbustype_166',['libevdev_get_id_bustype',['../group__bits.html#ga9bf55d416401642bad0c435735682308',1,'libevdev.h']]], + ['libevdev_5fget_5fid_5fproduct_167',['libevdev_get_id_product',['../group__bits.html#ga1dc66cfef646878d58be72f8902a6bac',1,'libevdev.h']]], + ['libevdev_5fget_5fid_5fvendor_168',['libevdev_get_id_vendor',['../group__bits.html#ga08891c3285da5b8d26769c9a34f063f3',1,'libevdev.h']]], + ['libevdev_5fget_5fid_5fversion_169',['libevdev_get_id_version',['../group__bits.html#ga75a07d0c96dfe09d2194c104c429d0ae',1,'libevdev.h']]], + ['libevdev_5fget_5flog_5fpriority_170',['libevdev_get_log_priority',['../group__logging.html#ga1da07493a798595cf85c127490b98ee8',1,'libevdev.h']]], + ['libevdev_5fget_5fname_171',['libevdev_get_name',['../group__bits.html#gaed0328c67b7a78422636d9fe09a73f12',1,'libevdev.h']]], + ['libevdev_5fget_5fnum_5fslots_172',['libevdev_get_num_slots',['../group__mt.html#gaf272526f0a59d2f61ef7389046cd4088',1,'libevdev.h']]], + ['libevdev_5fget_5fphys_173',['libevdev_get_phys',['../group__bits.html#ga5df483b0b24d7b96ea1181808fab851d',1,'libevdev.h']]], + ['libevdev_5fget_5frepeat_174',['libevdev_get_repeat',['../group__bits.html#gaf12fa199bb9497b38358d72e7505d770',1,'libevdev.h']]], + ['libevdev_5fget_5fslot_5fvalue_175',['libevdev_get_slot_value',['../group__mt.html#ga8c6303391cb4f90b2d46763cf4eb8bc8',1,'libevdev.h']]], + ['libevdev_5fget_5funiq_176',['libevdev_get_uniq',['../group__bits.html#ga6d9f7d44bff8828ead3d251177035ca4',1,'libevdev.h']]], + ['libevdev_5fgrab_177',['libevdev_grab',['../group__init.html#ga5d434af74fee20f273db568e2cbbd13f',1,'libevdev.h']]], + ['libevdev_5fhas_5fevent_5fcode_178',['libevdev_has_event_code',['../group__bits.html#gab2ab9dad417f33daa79fa0c3d682df0b',1,'libevdev.h']]], + ['libevdev_5fhas_5fevent_5fpending_179',['libevdev_has_event_pending',['../group__events.html#gae18fbfb59064c9c4b9d5db2d8cb23784',1,'libevdev.h']]], + ['libevdev_5fhas_5fevent_5ftype_180',['libevdev_has_event_type',['../group__bits.html#ga398bef155fa4a0cfb832de30723ebd14',1,'libevdev.h']]], + ['libevdev_5fhas_5fproperty_181',['libevdev_has_property',['../group__bits.html#ga36d529ea53f4522004bc7d16c051464b',1,'libevdev.h']]], + ['libevdev_5fkernel_5fset_5fabs_5finfo_182',['libevdev_kernel_set_abs_info',['../group__kernel.html#ga41c0321b93349d0ddd1f1c007ccf7de9',1,'libevdev.h']]], + ['libevdev_5fkernel_5fset_5fled_5fvalue_183',['libevdev_kernel_set_led_value',['../group__kernel.html#gaa7d13aeac3c40e16f296467780e67c01',1,'libevdev.h']]], + ['libevdev_5fkernel_5fset_5fled_5fvalues_184',['libevdev_kernel_set_led_values',['../group__kernel.html#ga93a19fa6e5be57903aff7c4a60af2a00',1,'libevdev.h']]], + ['libevdev_5fnew_185',['libevdev_new',['../group__init.html#ga332c8ee260b4ef864345abe5d04e820c',1,'libevdev.h']]], + ['libevdev_5fnew_5ffrom_5ffd_186',['libevdev_new_from_fd',['../group__init.html#ga89bb5bce1c23e293293484b05b12aaf4',1,'libevdev.h']]], + ['libevdev_5fnext_5fevent_187',['libevdev_next_event',['../group__events.html#gabb96c864e836c0b98788f4ab771c3a76',1,'libevdev.h']]], + ['libevdev_5fproperty_5ffrom_5fname_188',['libevdev_property_from_name',['../group__misc.html#ga6f4418c98aa475a2fc34d58a197f7edd',1,'libevdev.h']]], + ['libevdev_5fproperty_5ffrom_5fname_5fn_189',['libevdev_property_from_name_n',['../group__misc.html#gaaa0bc4c7d0d2aedc84c7dcffee9ce29b',1,'libevdev.h']]], + ['libevdev_5fproperty_5fget_5fname_190',['libevdev_property_get_name',['../group__misc.html#gacc12bdb7b912070ac9c375428f2c9892',1,'libevdev.h']]], + ['libevdev_5fset_5fabs_5fflat_191',['libevdev_set_abs_flat',['../group__kernel.html#gabd309f30744a49e9391250b00ba2d67a',1,'libevdev.h']]], + ['libevdev_5fset_5fabs_5ffuzz_192',['libevdev_set_abs_fuzz',['../group__kernel.html#gaa192bf0c68620be819337da6ec361c21',1,'libevdev.h']]], + ['libevdev_5fset_5fabs_5finfo_193',['libevdev_set_abs_info',['../group__kernel.html#gafc7a4f5308e2dbf55f875630b8dca049',1,'libevdev.h']]], + ['libevdev_5fset_5fabs_5fmaximum_194',['libevdev_set_abs_maximum',['../group__kernel.html#ga2302fd9a491d8e27280157d67a703af6',1,'libevdev.h']]], + ['libevdev_5fset_5fabs_5fminimum_195',['libevdev_set_abs_minimum',['../group__kernel.html#gaca62172c2a823cd02eacf0d2292d917a',1,'libevdev.h']]], + ['libevdev_5fset_5fabs_5fresolution_196',['libevdev_set_abs_resolution',['../group__kernel.html#ga2266b59711cdaa4fc12fa56c9313a038',1,'libevdev.h']]], + ['libevdev_5fset_5fclock_5fid_197',['libevdev_set_clock_id',['../group__kernel.html#ga2925b6fbf8c7991ff2164424b840b82d',1,'libevdev.h']]], + ['libevdev_5fset_5fdevice_5flog_5ffunction_198',['libevdev_set_device_log_function',['../group__logging.html#ga2830ff0aa391d8d1111682d3e762091b',1,'libevdev.h']]], + ['libevdev_5fset_5fevent_5fvalue_199',['libevdev_set_event_value',['../group__kernel.html#ga79e82ee2a95cb08adb4172aabe0c7184',1,'libevdev.h']]], + ['libevdev_5fset_5ffd_200',['libevdev_set_fd',['../group__init.html#ga6658ac490d68c307ff8b8d1536c12b44',1,'libevdev.h']]], + ['libevdev_5fset_5fid_5fbustype_201',['libevdev_set_id_bustype',['../group__kernel.html#gaf99139c728ba1bd4b37ede612780b6b0',1,'libevdev.h']]], + ['libevdev_5fset_5fid_5fproduct_202',['libevdev_set_id_product',['../group__kernel.html#ga62fbdaac056ab5c3db154a9eeaf33799',1,'libevdev.h']]], + ['libevdev_5fset_5fid_5fvendor_203',['libevdev_set_id_vendor',['../group__kernel.html#ga8ce28051ebbb73de1d04d782f4d0d6fe',1,'libevdev.h']]], + ['libevdev_5fset_5fid_5fversion_204',['libevdev_set_id_version',['../group__kernel.html#gaee1d2db88b191ec21d5bf22dd4fe3055',1,'libevdev.h']]], + ['libevdev_5fset_5flog_5ffunction_205',['libevdev_set_log_function',['../group__logging.html#gaa60be86b83b3a6c82d8e536ba89ff955',1,'libevdev.h']]], + ['libevdev_5fset_5flog_5fpriority_206',['libevdev_set_log_priority',['../group__logging.html#gaf6b6842a9ed98b61d0abb421e853fd89',1,'libevdev.h']]], + ['libevdev_5fset_5fname_207',['libevdev_set_name',['../group__kernel.html#gae5dcdb7678cdc9be4ab1989725b4ed32',1,'libevdev.h']]], + ['libevdev_5fset_5fphys_208',['libevdev_set_phys',['../group__kernel.html#gacd57c8d6ace8e0b1417809a9c1c67af3',1,'libevdev.h']]], + ['libevdev_5fset_5fslot_5fvalue_209',['libevdev_set_slot_value',['../group__kernel.html#ga0c61f4919b03b0850529a50c37a20333',1,'libevdev.h']]], + ['libevdev_5fset_5funiq_210',['libevdev_set_uniq',['../group__kernel.html#ga4e4fd2627744fd5811c50c7403f27ad7',1,'libevdev.h']]], + ['libevdev_5fuinput_5fcreate_5ffrom_5fdevice_211',['libevdev_uinput_create_from_device',['../group__uinput.html#gaf14b21301bac9d79c20e890172873b96',1,'libevdev-uinput.h']]], + ['libevdev_5fuinput_5fdestroy_212',['libevdev_uinput_destroy',['../group__uinput.html#ga9dfa58a84eb4c6b97107dcf3fa621329',1,'libevdev-uinput.h']]], + ['libevdev_5fuinput_5fget_5fdevnode_213',['libevdev_uinput_get_devnode',['../group__uinput.html#ga4c595bcda748b08561e2819fe9b7c2d2',1,'libevdev-uinput.h']]], + ['libevdev_5fuinput_5fget_5ffd_214',['libevdev_uinput_get_fd',['../group__uinput.html#ga9cd7fb14a96d4cc14d3dffdcead84c5d',1,'libevdev-uinput.h']]], + ['libevdev_5fuinput_5fget_5fsyspath_215',['libevdev_uinput_get_syspath',['../group__uinput.html#gaacca93061fce57cec0ce3c52e443a427',1,'libevdev-uinput.h']]], + ['libevdev_5fuinput_5fwrite_5fevent_216',['libevdev_uinput_write_event',['../group__uinput.html#ga4c3c2f5fcd315a28a067f53b9f855fe7',1,'libevdev-uinput.h']]] ]; diff --git a/doc/html/search/groups_0.html b/doc/html/search/groups_0.html index 5c10318cac1654a434bacbe767906aedad49de94..c600b4970a8363761f11ede4a43c183ad55f0a8b 100644 --- a/doc/html/search/groups_0.html +++ b/doc/html/search/groups_0.html @@ -1,7 +1,8 @@ - + + - + @@ -10,14 +11,14 @@
Loading...
- +
Searching...
No Matches
- +
diff --git a/doc/html/search/groups_0.js b/doc/html/search/groups_0.js index 8892e0708184ba234ff0c4044fef2551a4396fad..c72fa47c6220faa58bbac5a8782d7ce2e4a571c8 100644 --- a/doc/html/search/groups_0.js +++ b/doc/html/search/groups_0.js @@ -1,4 +1,4 @@ var searchData= [ - ['event_20handling_240',['Event handling',['../group__events.html',1,'']]] + ['event_20handling_241',['Event handling',['../group__events.html',1,'']]] ]; diff --git a/doc/html/search/groups_1.html b/doc/html/search/groups_1.html index c3b5b264dd9068e5917aa9716a919164afe5af67..2eb3550dc8eccc20ac618262a80dc53c4587ea96 100644 --- a/doc/html/search/groups_1.html +++ b/doc/html/search/groups_1.html @@ -1,7 +1,8 @@ - + + - + @@ -10,14 +11,14 @@
Loading...
- +
Searching...
No Matches
- +
diff --git a/doc/html/search/groups_1.js b/doc/html/search/groups_1.js index 5ebdefe14b23e130d8099e667a359c8ab3836e43..3dda67ad306514c3687055d86b545a8e48d2a58e 100644 --- a/doc/html/search/groups_1.js +++ b/doc/html/search/groups_1.js @@ -1,4 +1,4 @@ var searchData= [ - ['initialization_20and_20setup_241',['Initialization and setup',['../group__init.html',1,'']]] + ['initialization_20and_20setup_242',['Initialization and setup',['../group__init.html',1,'']]] ]; diff --git a/doc/html/search/groups_2.html b/doc/html/search/groups_2.html index 9d0942100af7d41b9a0d049fbb9929cabdfb6fda..12f4af7a0bac3edd2a3be2c49b1569af79ef7385 100644 --- a/doc/html/search/groups_2.html +++ b/doc/html/search/groups_2.html @@ -1,7 +1,8 @@ - + + - + @@ -10,14 +11,14 @@
Loading...
- +
Searching...
No Matches
- +
diff --git a/doc/html/search/groups_2.js b/doc/html/search/groups_2.js index e27988afc326fd7c8faa374b8ad69b8549fee29f..134c20c97d2f839342af2b0342b8d9cd96328eac 100644 --- a/doc/html/search/groups_2.js +++ b/doc/html/search/groups_2.js @@ -1,4 +1,4 @@ var searchData= [ - ['library_20logging_20facilities_242',['Library logging facilities',['../group__logging.html',1,'']]] + ['library_20logging_20facilities_243',['Library logging facilities',['../group__logging.html',1,'']]] ]; diff --git a/doc/html/search/groups_3.html b/doc/html/search/groups_3.html index e5d6c03e9668579243376d498d353ba29c6476b4..5e235b53ca4c9ab52f364648e6711c9121b0ccf9 100644 --- a/doc/html/search/groups_3.html +++ b/doc/html/search/groups_3.html @@ -1,7 +1,8 @@ - + + - + @@ -10,14 +11,14 @@
Loading...
- +
Searching...
No Matches
- +
diff --git a/doc/html/search/groups_3.js b/doc/html/search/groups_3.js index dc0b3451a70c71ccbf3b1e8deea3241cb9da59d7..22178a7e3ad2d0650960bbb3c8d24cf9cdcc0f10 100644 --- a/doc/html/search/groups_3.js +++ b/doc/html/search/groups_3.js @@ -1,6 +1,6 @@ var searchData= [ - ['modifying_20the_20appearance_20or_20capabilities_20of_20the_20device_243',['Modifying the appearance or capabilities of the device',['../group__kernel.html',1,'']]], ['miscellaneous_20helper_20functions_244',['Miscellaneous helper functions',['../group__misc.html',1,'']]], - ['multi_2dtouch_20related_20functions_245',['Multi-touch related functions',['../group__mt.html',1,'']]] + ['modifying_20the_20appearance_20or_20capabilities_20of_20the_20device_245',['Modifying the appearance or capabilities of the device',['../group__kernel.html',1,'']]], + ['multi_2dtouch_20related_20functions_246',['Multi-touch related functions',['../group__mt.html',1,'']]] ]; diff --git a/doc/html/search/groups_4.html b/doc/html/search/groups_4.html index d7f3b238d8ef44fff21163e3353ccd51da76d56c..99405e159cc77c2e9d7a8237d8818136f9392bc6 100644 --- a/doc/html/search/groups_4.html +++ b/doc/html/search/groups_4.html @@ -1,7 +1,8 @@ - + + - + @@ -10,14 +11,14 @@
Loading...
- +
Searching...
No Matches
- +
diff --git a/doc/html/search/groups_4.js b/doc/html/search/groups_4.js index a640e834aa5c3eb656a08410a70db9ce755a5bb0..421013846cbf462ad45ac55d7889ccb73c25ad38 100644 --- a/doc/html/search/groups_4.js +++ b/doc/html/search/groups_4.js @@ -1,4 +1,4 @@ var searchData= [ - ['querying_20device_20capabilities_246',['Querying device capabilities',['../group__bits.html',1,'']]] + ['querying_20device_20capabilities_247',['Querying device capabilities',['../group__bits.html',1,'']]] ]; diff --git a/doc/html/search/groups_5.html b/doc/html/search/groups_5.html index 4729b27c758288822d48b811c22cad852d622a42..583f5f58a4c2a3cedaff99c659dbaba3841ca12d 100644 --- a/doc/html/search/groups_5.html +++ b/doc/html/search/groups_5.html @@ -1,7 +1,8 @@ - + + - + @@ -10,14 +11,14 @@
Loading...
- +
Searching...
No Matches
- +
diff --git a/doc/html/search/groups_5.js b/doc/html/search/groups_5.js index 9c7f6938f84e8e21f72131fca7c56dc7e8ebcbc5..2b170ac69e87ff7cc137fe0b167205ced7c8ec0d 100644 --- a/doc/html/search/groups_5.js +++ b/doc/html/search/groups_5.js @@ -1,4 +1,4 @@ var searchData= [ - ['uinput_20device_20creation_247',['uinput device creation',['../group__uinput.html',1,'']]] + ['uinput_20device_20creation_248',['uinput device creation',['../group__uinput.html',1,'']]] ]; diff --git a/doc/html/search/nomatches.html b/doc/html/search/nomatches.html index 4377320895b9a5b98e140ebf2f76ec09158d1156..2b9360b6bd700092477e10cf056de3f8967dd808 100644 --- a/doc/html/search/nomatches.html +++ b/doc/html/search/nomatches.html @@ -1,5 +1,6 @@ - + + diff --git a/doc/html/search/pages_0.html b/doc/html/search/pages_0.html index a281c4b03c33991728df2aa86dda72b08aaf0473..8517b48f05dc324c03ca98dfc7fa660d0c13c8dd 100644 --- a/doc/html/search/pages_0.html +++ b/doc/html/search/pages_0.html @@ -1,7 +1,8 @@ - + + - + @@ -10,14 +11,14 @@
Loading...
- +
Searching...
No Matches
- +
diff --git a/doc/html/search/pages_0.js b/doc/html/search/pages_0.js index 8a8d4ff832e876c736e49b0da35823fe32816641..e6858affae82205197bcdb8396a6b433971e92f7 100644 --- a/doc/html/search/pages_0.js +++ b/doc/html/search/pages_0.js @@ -1,4 +1,4 @@ var searchData= [ - ['compatibility_20and_20behavior_20across_20kernel_20versions_248',['Compatibility and Behavior across kernel versions',['../backwardscompatibility.html',1,'']]] + ['compatibility_20and_20behavior_20across_20kernel_20versions_249',['Compatibility and Behavior across kernel versions',['../backwardscompatibility.html',1,'']]] ]; diff --git a/doc/html/search/pages_1.html b/doc/html/search/pages_1.html index 0e1cf6b9e4f232f6a1fc83a2746686536de1c17c..a0fb679631b1c26641bb0e608af27e6fba421ed2 100644 --- a/doc/html/search/pages_1.html +++ b/doc/html/search/pages_1.html @@ -1,7 +1,8 @@ - + + - + @@ -10,14 +11,14 @@
Loading...
- +
Searching...
No Matches
- +
diff --git a/doc/html/search/pages_1.js b/doc/html/search/pages_1.js index 73a30f0067d2c4e860ae6de5396ee57ddc59827a..d6b874b868096af0a51a976336f83cbcef660803 100644 --- a/doc/html/search/pages_1.js +++ b/doc/html/search/pages_1.js @@ -1,4 +1,4 @@ var searchData= [ - ['deprecated_20list_249',['Deprecated List',['../deprecated.html',1,'']]] + ['deprecated_20list_250',['Deprecated List',['../deprecated.html',1,'']]] ]; diff --git a/doc/html/search/pages_2.html b/doc/html/search/pages_2.html index e11214cb57033fea53cb99f79daf6f21ec958586..084edfd03f7f3dbf8beb198eb006dd66f58e4fca 100644 --- a/doc/html/search/pages_2.html +++ b/doc/html/search/pages_2.html @@ -1,7 +1,8 @@ - + + - + @@ -10,14 +11,14 @@
Loading...
- +
Searching...
No Matches
- +
diff --git a/doc/html/search/pages_2.js b/doc/html/search/pages_2.js index b8c85fd91e19747d5dd952045c9030dbdab0f8e0..740b4ef8873c7e0d7e390b91db9ad575135a4051 100644 --- a/doc/html/search/pages_2.js +++ b/doc/html/search/pages_2.js @@ -1,4 +1,4 @@ var searchData= [ - ['evdev_20ioctls_250',['evdev ioctls',['../ioctls.html',1,'']]] + ['evdev_20ioctls_251',['evdev ioctls',['../ioctls.html',1,'']]] ]; diff --git a/doc/html/search/pages_3.html b/doc/html/search/pages_3.html index c509f1194378ebd13f0fcff36c95c46523fb927e..c0b45b0fc9327d817d10c7893ea4c81067a2516a 100644 --- a/doc/html/search/pages_3.html +++ b/doc/html/search/pages_3.html @@ -1,7 +1,8 @@ - + + - + @@ -10,14 +11,14 @@
Loading...
- +
Searching...
No Matches
- +
diff --git a/doc/html/search/pages_3.js b/doc/html/search/pages_3.js index 7c2eeec151cf698230206fb56a10c5b342509198..2ca4e5a07b9639f82eae44a6533160acda4d2a4d 100644 --- a/doc/html/search/pages_3.js +++ b/doc/html/search/pages_3.js @@ -1,4 +1,4 @@ var searchData= [ - ['kernel_20header_251',['Kernel header',['../kernel_header.html',1,'']]] + ['kernel_20header_252',['Kernel header',['../kernel_header.html',1,'']]] ]; diff --git a/doc/html/search/pages_4.html b/doc/html/search/pages_4.html index 7053756ef59f7af0828e88a2ab9ee92d149d4bb6..0f05c2e73c0fb9dc427d39c01c138885816839fd 100644 --- a/doc/html/search/pages_4.html +++ b/doc/html/search/pages_4.html @@ -1,7 +1,8 @@ - + + - + @@ -10,14 +11,14 @@
Loading...
- +
Searching...
No Matches
- +
diff --git a/doc/html/search/pages_4.js b/doc/html/search/pages_4.js index bb75481b6b8510564c15ea7803d7f87ff4402b1d..bf72ecd0cab6c87b2ccb0787027c627206760590 100644 --- a/doc/html/search/pages_4.js +++ b/doc/html/search/pages_4.js @@ -1,4 +1,4 @@ var searchData= [ - ['libevdev_2dinternal_20test_20suite_252',['libevdev-internal test suite',['../testing.html',1,'']]] + ['libevdev_2dinternal_20test_20suite_253',['libevdev-internal test suite',['../testing.html',1,'']]] ]; diff --git a/doc/html/search/pages_5.html b/doc/html/search/pages_5.html index 937d0df3a417780d69c06b24be9275d079c21797..27e2b6c7832156d2909bc289332737e87b84fffd 100644 --- a/doc/html/search/pages_5.html +++ b/doc/html/search/pages_5.html @@ -1,7 +1,8 @@ - + + - + @@ -10,14 +11,14 @@
Loading...
- +
Searching...
No Matches
- +
diff --git a/doc/html/search/pages_5.js b/doc/html/search/pages_5.js index c68f385c7bee9c80b4a6fb108b15435c62addb32..be09cca8b3e2bdefb3ca1ca0b8337e769ed89bd5 100644 --- a/doc/html/search/pages_5.js +++ b/doc/html/search/pages_5.js @@ -1,5 +1,5 @@ var searchData= [ - ['statically_20linking_20libevdev_253',['Statically linking libevdev',['../static_linking.html',1,'']]], - ['syn_5fdropped_20handling_254',['SYN_DROPPED handling',['../syn_dropped.html',1,'']]] + ['statically_20linking_20libevdev_254',['Statically linking libevdev',['../static_linking.html',1,'']]], + ['syn_5fdropped_20handling_255',['SYN_DROPPED handling',['../syn_dropped.html',1,'']]] ]; diff --git a/doc/html/search/search.css b/doc/html/search/search.css index 933cf0880822844d43d990898f29ea2784606e19..9074198f81f13dedf965db7bf9ba591fe194eae3 100644 --- a/doc/html/search/search.css +++ b/doc/html/search/search.css @@ -204,19 +204,21 @@ a.SRScope:focus, a.SRScope:active { span.SRScope { padding-left: 4px; + font-family: Arial, Verdana, sans-serif; } .SRPage .SRStatus { padding: 2px 5px; font-size: 8pt; font-style: italic; + font-family: Arial, Verdana, sans-serif; } .SRResult { display: none; } -DIV.searchresults { +div.searchresults { margin-left: 10px; margin-right: 10px; } diff --git a/doc/html/search/search.js b/doc/html/search/search.js index 92b609464afbf6a4fb3eb1a005600f607ef3fe2b..fb226f734e6daca1cfb5a63012d8563e26677549 100644 --- a/doc/html/search/search.js +++ b/doc/html/search/search.js @@ -80,9 +80,10 @@ function getYPos(item) storing this instance. Is needed to be able to set timeouts. resultPath - path to use for external files */ -function SearchBox(name, resultsPath, inFrame, label) +function SearchBox(name, resultsPath, inFrame, label, extension) { if (!name || !resultsPath) { alert("Missing parameters to SearchBox."); } + if (!extension || extension == "") { extension = ".html"; } // ---------- Instance variables this.name = name; @@ -97,6 +98,7 @@ function SearchBox(name, resultsPath, inFrame, label) this.searchActive = false; this.insideFrame = inFrame; this.searchLabel = label; + this.extension = extension; // ----------- DOM Elements @@ -347,13 +349,13 @@ function SearchBox(name, resultsPath, inFrame, label) if (idx!=-1) { var hexCode=idx.toString(16); - resultsPage = this.resultsPath + '/' + indexSectionNames[this.searchIndex] + '_' + hexCode + '.html'; + resultsPage = this.resultsPath + '/' + indexSectionNames[this.searchIndex] + '_' + hexCode + this.extension; resultsPageWithSearch = resultsPage+'?'+escape(searchValue); hasResultsPage = true; } else // nothing available for this search term { - resultsPage = this.resultsPath + '/nomatches.html'; + resultsPage = this.resultsPath + '/nomatches' + this.extension; resultsPageWithSearch = resultsPage; hasResultsPage = false; } @@ -439,12 +441,12 @@ function SearchResults(name) while (element && element!=parentElement) { - if (element.nodeName == 'DIV' && element.className == 'SRChildren') + if (element.nodeName.toLowerCase() == 'div' && element.className == 'SRChildren') { return element; } - if (element.nodeName == 'DIV' && element.hasChildNodes()) + if (element.nodeName.toLowerCase() == 'div' && element.hasChildNodes()) { element = element.firstChild; } diff --git a/doc/html/search/typedefs_0.html b/doc/html/search/typedefs_0.html index b66f0a7b911dfcf60b99e47cff62c6df5b9387b1..a4684c4ad28bb88e3cd581697596b2faea2b5caa 100644 --- a/doc/html/search/typedefs_0.html +++ b/doc/html/search/typedefs_0.html @@ -1,7 +1,8 @@ - + + - + @@ -10,14 +11,14 @@
Loading...
- +
Searching...
No Matches
- +
diff --git a/doc/html/search/typedefs_0.js b/doc/html/search/typedefs_0.js index 4fc664284985307813b138b6cdeadfa2db4fd9a2..5395044f36804b8977791e1cadcfb87e86d7ffd2 100644 --- a/doc/html/search/typedefs_0.js +++ b/doc/html/search/typedefs_0.js @@ -1,5 +1,5 @@ var searchData= [ - ['libevdev_5fdevice_5flog_5ffunc_5ft_216',['libevdev_device_log_func_t',['../group__logging.html#gab7eb997be2b701cc6f42e7b4c3478269',1,'libevdev.h']]], - ['libevdev_5flog_5ffunc_5ft_217',['libevdev_log_func_t',['../group__logging.html#gaf36c721d273c0794251eb7dacea2f0a4',1,'libevdev.h']]] + ['libevdev_5fdevice_5flog_5ffunc_5ft_217',['libevdev_device_log_func_t',['../group__logging.html#gab7eb997be2b701cc6f42e7b4c3478269',1,'libevdev.h']]], + ['libevdev_5flog_5ffunc_5ft_218',['libevdev_log_func_t',['../group__logging.html#gaf36c721d273c0794251eb7dacea2f0a4',1,'libevdev.h']]] ]; diff --git a/doc/html/static_linking.html b/doc/html/static_linking.html index 871294aca521bc538b40f3f90415bbcca3c336bb..71e682e0b50b03da05bede481cc426235edb0bea 100644 --- a/doc/html/static_linking.html +++ b/doc/html/static_linking.html @@ -6,7 +6,7 @@ - + libevdev: Statically linking libevdev @@ -25,7 +25,7 @@ @@ -36,10 +36,10 @@
- + @@ -87,7 +87,7 @@ $(function() { diff --git a/doc/html/syn_dropped.html b/doc/html/syn_dropped.html index c3e6a9b6181dcb14704d64049580ce0477714b8e..723dd593d92bd5f16e61717ae2850bddaa807c41 100644 --- a/doc/html/syn_dropped.html +++ b/doc/html/syn_dropped.html @@ -6,7 +6,7 @@ - + libevdev: SYN_DROPPED handling @@ -25,7 +25,7 @@ @@ -36,10 +36,10 @@
- + @@ -185,6 +185,9 @@ Synchronizing ABS_MT_TRACKING_ID
EV_ABS ABS_MT_POSITION_Y 10
EV_SYN SYN_REPORT 0
-------------------
+
@ LIBEVDEV_READ_STATUS_SYNC
Depending on the libevdev_next_event() read flag:
Definition: libevdev.h:1090
+
@ LIBEVDEV_READ_FLAG_SYNC
Process data in sync mode.
Definition: libevdev.h:761
+
@ LIBEVDEV_READ_FLAG_NORMAL
Process data in normal mode.
Definition: libevdev.h:762

The axis events do not reflect the position of a current touch point, a client must take care not to generate a new touch point based on those updates.

Discarding events before synchronizing

@@ -209,9 +212,6 @@ Discarding events before synchronizing
EV_SYN SYN_REPORT 0
-
@ LIBEVDEV_READ_STATUS_SYNC
Depending on the libevdev_next_event() read flag:
Definition: libevdev.h:1087
-
@ LIBEVDEV_READ_FLAG_NORMAL
Process data in normal mode.
Definition: libevdev.h:759
-
@ LIBEVDEV_READ_FLAG_SYNC
Process data in sync mode.
Definition: libevdev.h:758
@@ -222,7 +222,7 @@ Discarding events before synchronizing diff --git a/doc/html/testing.html b/doc/html/testing.html index 00f118fcadfca3927f4857f66e72608b6510308f..49ad449885c7cff55f3304dc5182b3deebd8a811 100644 --- a/doc/html/testing.html +++ b/doc/html/testing.html @@ -6,7 +6,7 @@ - + libevdev: libevdev-internal test suite @@ -25,7 +25,7 @@ @@ -36,10 +36,10 @@
- + @@ -75,11 +75,11 @@ $(function() {

libevdev's internal test suite uses the Check unit testing framework.

Tests are divided into test suites and test cases. Most tests create a uinput device, so you'll need to run as root, and your kernel must have CONFIG_INPUT_UINPUT enabled.

To run a specific suite only:

export CK_RUN_SUITE="suite name"
-

To run a specific test case only:

export CK_RUN_TEST="test case name"
-

To get a list of all suites or tests:

git grep "suite_create"
+

To run a specific test case only:

export CK_RUN_TEST="test case name"
+

To get a list of all suites or tests:

git grep "suite_create"
 git grep "tcase_create"
-

By default, Check forks, making debugging harder. The test suite tries to detect if it is running inside gdb and disable forking. If that doesn't work for some reason, run gdb as below to avoid forking.

sudo CK_FORK=no CK_RUN_TEST="test case name" gdb ./test/test-libevdev
-

A special target make gcov-report.txt exists that runs gcov and leaves a libevdev.c.gcov file. Check that for test coverage.

+

By default, Check forks, making debugging harder. The test suite tries to detect if it is running inside gdb and disable forking. If that doesn't work for some reason, run gdb as below to avoid forking.

sudo CK_FORK=no CK_RUN_TEST="test case name" gdb ./test/test-libevdev
+

A special target make gcov-report.txt exists that runs gcov and leaves a libevdev.c.gcov file. Check that for test coverage.

make check is hooked up to run the test and gcov (again, needs root).

The test suite creates a lot of devices, very quickly. Add the following xorg.conf.d snippet to avoid the devices being added as X devices (at the time of writing, mutter can't handle these devices and exits after getting a BadDevice error).

$ cat /etc/X11/xorg.conf.d/99-ignore-libevdev-devices.conf
 Section "InputClass"
@@ -99,7 +99,7 @@ EndSection
 
 
 
diff --git a/export_include/libevdev/libevdev.h b/export_include/libevdev/libevdev.h
index 6ffcda73128abd173d9b0dac6f9b6ecdf5121c92..30e4d6f88a44c86e4c41682fc3b2fb444a428b11 100644
--- a/export_include/libevdev/libevdev.h
+++ b/export_include/libevdev/libevdev.h
@@ -1,23 +1,26 @@
+/* SPDX-License-Identifier: MIT */
 /*
  * Copyright © 2013 Red Hat, Inc.
  *
- * Permission to use, copy, modify, distribute, and sell this software and its
- * documentation for any purpose is hereby granted without fee, provided that
- * the above copyright notice appear in all copies and that both that copyright
- * notice and this permission notice appear in supporting documentation, and
- * that the name of the copyright holders not be used in advertising or
- * publicity pertaining to distribution of the software without specific,
- * written prior permission.  The copyright holders make no representations
- * about the suitability of this software for any purpose.  It is provided "as
- * is" without express or implied warranty.
- *
- * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
- * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
- * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
- * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
- * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
- * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
- * OF THIS SOFTWARE.
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
  */
 
 #ifndef LIBEVDEV_H
@@ -631,7 +634,7 @@ extern "C" {
  *         return ENOMEM;
  *
  * err = libevdev_set_fd(dev, fd);
- * if (err < 0) {
+ * if (err < 0)
  *         printf("Failed (errno %d): %s\n", -err, strerror(-err));
  *
  * libevdev_free(dev);
@@ -1515,8 +1518,7 @@ const struct input_absinfo* libevdev_get_abs_info(const struct libevdev *dev, un
  * the event.
  *
  * If the device supports ABS_MT_SLOT, the value returned for any ABS_MT_*
- * event code is the value of the currently active slot. You should use
- * libevdev_get_slot_value() instead.
+ * event code is undefined. Use libevdev_get_slot_value() instead.
  *
  * @param dev The evdev device, already initialized with libevdev_set_fd()
  * @param type The event type for the code to query (EV_SYN, EV_REL, etc.)
diff --git a/include/config.h b/include/config.h
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..bd31307ec6eb6cce929cfe16cd484a1d7c60d7eb 100644
--- a/include/config.h
+++ b/include/config.h
@@ -0,0 +1,9 @@
+/*
+ * Autogenerated by the Meson build system.
+ * Do not edit, your changes will be lost.
+ */
+
+#pragma once
+
+#define _GNU_SOURCE 1
+
diff --git a/include/event-names.h b/include/event-names.h
index 4d4545dceab1c416a99a134916d31065e732b662..02f6f0bbba1887367e5df5a6ca04f7ae5b933ae9 100644
--- a/include/event-names.h
+++ b/include/event-names.h
@@ -281,7 +281,7 @@ static const char * const key_map[KEY_MAX + 1] = {
     [KEY_PAUSECD] = "KEY_PAUSECD",
     [KEY_PROG3] = "KEY_PROG3",
     [KEY_PROG4] = "KEY_PROG4",
-    [KEY_DASHBOARD] = "KEY_DASHBOARD",
+    [KEY_ALL_APPLICATIONS] = "KEY_ALL_APPLICATIONS",
     [KEY_SUSPEND] = "KEY_SUSPEND",
     [KEY_CLOSE] = "KEY_CLOSE",
     [KEY_PLAY] = "KEY_PLAY",
@@ -417,6 +417,9 @@ static const char * const key_map[KEY_MAX + 1] = {
     [KEY_10CHANNELSUP] = "KEY_10CHANNELSUP",
     [KEY_10CHANNELSDOWN] = "KEY_10CHANNELSDOWN",
     [KEY_IMAGES] = "KEY_IMAGES",
+    [KEY_NOTIFICATION_CENTER] = "KEY_NOTIFICATION_CENTER",
+    [KEY_PICKUP_PHONE] = "KEY_PICKUP_PHONE",
+    [KEY_HANGUP_PHONE] = "KEY_HANGUP_PHONE",
     [KEY_DEL_EOL] = "KEY_DEL_EOL",
     [KEY_DEL_EOS] = "KEY_DEL_EOS",
     [KEY_INS_LINE] = "KEY_INS_LINE",
@@ -442,6 +445,7 @@ static const char * const key_map[KEY_MAX + 1] = {
     [KEY_FN_F] = "KEY_FN_F",
     [KEY_FN_S] = "KEY_FN_S",
     [KEY_FN_B] = "KEY_FN_B",
+    [KEY_FN_RIGHT_SHIFT] = "KEY_FN_RIGHT_SHIFT",
     [KEY_BRL_DOT1] = "KEY_BRL_DOT1",
     [KEY_BRL_DOT2] = "KEY_BRL_DOT2",
     [KEY_BRL_DOT3] = "KEY_BRL_DOT3",
@@ -494,6 +498,8 @@ static const char * const key_map[KEY_MAX + 1] = {
     [KEY_VOICECOMMAND] = "KEY_VOICECOMMAND",
     [KEY_ASSISTANT] = "KEY_ASSISTANT",
     [KEY_KBD_LAYOUT_NEXT] = "KEY_KBD_LAYOUT_NEXT",
+    [KEY_EMOJI_PICKER] = "KEY_EMOJI_PICKER",
+    [KEY_DICTATE] = "KEY_DICTATE",
     [KEY_BRIGHTNESS_MIN] = "KEY_BRIGHTNESS_MIN",
     [KEY_BRIGHTNESS_MAX] = "KEY_BRIGHTNESS_MAX",
     [KEY_KBDINPUTASSIST_PREV] = "KEY_KBDINPUTASSIST_PREV",
@@ -1063,6 +1069,7 @@ static const struct name_entry code_names[] = {
     { .name = "KEY_AB", .value = KEY_AB },
     { .name = "KEY_ADDRESSBOOK", .value = KEY_ADDRESSBOOK },
     { .name = "KEY_AGAIN", .value = KEY_AGAIN },
+    { .name = "KEY_ALL_APPLICATIONS", .value = KEY_ALL_APPLICATIONS },
     { .name = "KEY_ALS_TOGGLE", .value = KEY_ALS_TOGGLE },
     { .name = "KEY_ALTERASE", .value = KEY_ALTERASE },
     { .name = "KEY_ANGLE", .value = KEY_ANGLE },
@@ -1137,7 +1144,6 @@ static const struct name_entry code_names[] = {
     { .name = "KEY_CUT", .value = KEY_CUT },
     { .name = "KEY_CYCLEWINDOWS", .value = KEY_CYCLEWINDOWS },
     { .name = "KEY_D", .value = KEY_D },
-    { .name = "KEY_DASHBOARD", .value = KEY_DASHBOARD },
     { .name = "KEY_DATA", .value = KEY_DATA },
     { .name = "KEY_DATABASE", .value = KEY_DATABASE },
     { .name = "KEY_DELETE", .value = KEY_DELETE },
@@ -1145,6 +1151,7 @@ static const struct name_entry code_names[] = {
     { .name = "KEY_DEL_EOL", .value = KEY_DEL_EOL },
     { .name = "KEY_DEL_EOS", .value = KEY_DEL_EOS },
     { .name = "KEY_DEL_LINE", .value = KEY_DEL_LINE },
+    { .name = "KEY_DICTATE", .value = KEY_DICTATE },
     { .name = "KEY_DIGITS", .value = KEY_DIGITS },
     { .name = "KEY_DIRECTORY", .value = KEY_DIRECTORY },
     { .name = "KEY_DISPLAYTOGGLE", .value = KEY_DISPLAYTOGGLE },
@@ -1160,6 +1167,7 @@ static const struct name_entry code_names[] = {
     { .name = "KEY_EJECTCD", .value = KEY_EJECTCD },
     { .name = "KEY_EJECTCLOSECD", .value = KEY_EJECTCLOSECD },
     { .name = "KEY_EMAIL", .value = KEY_EMAIL },
+    { .name = "KEY_EMOJI_PICKER", .value = KEY_EMOJI_PICKER },
     { .name = "KEY_END", .value = KEY_END },
     { .name = "KEY_ENTER", .value = KEY_ENTER },
     { .name = "KEY_EPG", .value = KEY_EPG },
@@ -1219,6 +1227,7 @@ static const struct name_entry code_names[] = {
     { .name = "KEY_FN_F7", .value = KEY_FN_F7 },
     { .name = "KEY_FN_F8", .value = KEY_FN_F8 },
     { .name = "KEY_FN_F9", .value = KEY_FN_F9 },
+    { .name = "KEY_FN_RIGHT_SHIFT", .value = KEY_FN_RIGHT_SHIFT },
     { .name = "KEY_FN_S", .value = KEY_FN_S },
     { .name = "KEY_FORWARD", .value = KEY_FORWARD },
     { .name = "KEY_FORWARDMAIL", .value = KEY_FORWARDMAIL },
@@ -1234,6 +1243,7 @@ static const struct name_entry code_names[] = {
     { .name = "KEY_GREEN", .value = KEY_GREEN },
     { .name = "KEY_H", .value = KEY_H },
     { .name = "KEY_HANGEUL", .value = KEY_HANGEUL },
+    { .name = "KEY_HANGUP_PHONE", .value = KEY_HANGUP_PHONE },
     { .name = "KEY_HANJA", .value = KEY_HANJA },
     { .name = "KEY_HELP", .value = KEY_HELP },
     { .name = "KEY_HENKAN", .value = KEY_HENKAN },
@@ -1366,6 +1376,7 @@ static const struct name_entry code_names[] = {
     { .name = "KEY_NEXT", .value = KEY_NEXT },
     { .name = "KEY_NEXTSONG", .value = KEY_NEXTSONG },
     { .name = "KEY_NEXT_FAVORITE", .value = KEY_NEXT_FAVORITE },
+    { .name = "KEY_NOTIFICATION_CENTER", .value = KEY_NOTIFICATION_CENTER },
     { .name = "KEY_NUMERIC_0", .value = KEY_NUMERIC_0 },
     { .name = "KEY_NUMERIC_1", .value = KEY_NUMERIC_1 },
     { .name = "KEY_NUMERIC_11", .value = KEY_NUMERIC_11 },
@@ -1399,6 +1410,7 @@ static const struct name_entry code_names[] = {
     { .name = "KEY_PAUSE_RECORD", .value = KEY_PAUSE_RECORD },
     { .name = "KEY_PC", .value = KEY_PC },
     { .name = "KEY_PHONE", .value = KEY_PHONE },
+    { .name = "KEY_PICKUP_PHONE", .value = KEY_PICKUP_PHONE },
     { .name = "KEY_PLAY", .value = KEY_PLAY },
     { .name = "KEY_PLAYCD", .value = KEY_PLAYCD },
     { .name = "KEY_PLAYER", .value = KEY_PLAYER },
diff --git a/include/linux/input.h b/include/linux/input.h
index 624af0d8fcbda1f13e48c33fa6504da95a45cc7a..03c512efb0c21da6b61d345520bc481b7fc950c5 100644
--- a/include/linux/input.h
+++ b/include/linux/input.h
@@ -1,5 +1,5 @@
-//#ifdef __linux__
+#ifdef __linux__
 #include "linux/input.h"
-//#elif __FreeBSD__
-//#include "freebsd/input.h"
-//#endif
+#elif __FreeBSD__
+#include "freebsd/input.h"
+#endif
diff --git a/include/linux/linux/input-event-codes.h b/include/linux/linux/input-event-codes.h
index 0c2e27d28e0acdf825bab42cbffb452275f065ed..7989d9483ea75e2bbaaf78c1fd3d3bca741678ff 100644
--- a/include/linux/linux/input-event-codes.h
+++ b/include/linux/linux/input-event-codes.h
@@ -278,7 +278,8 @@
 #define KEY_PAUSECD		201
 #define KEY_PROG3		202
 #define KEY_PROG4		203
-#define KEY_DASHBOARD		204	/* AL Dashboard */
+#define KEY_ALL_APPLICATIONS	204	/* AC Desktop Show All Applications */
+#define KEY_DASHBOARD		KEY_ALL_APPLICATIONS
 #define KEY_SUSPEND		205
 #define KEY_CLOSE		206	/* AC Close */
 #define KEY_PLAY		207
@@ -515,6 +516,9 @@
 #define KEY_10CHANNELSUP	0x1b8	/* 10 channels up (10+) */
 #define KEY_10CHANNELSDOWN	0x1b9	/* 10 channels down (10-) */
 #define KEY_IMAGES		0x1ba	/* AL Image Browser */
+#define KEY_NOTIFICATION_CENTER	0x1bc	/* Show/hide the notification center */
+#define KEY_PICKUP_PHONE	0x1bd	/* Answer incoming call */
+#define KEY_HANGUP_PHONE	0x1be	/* Decline incoming call */
 
 #define KEY_DEL_EOL		0x1c0
 #define KEY_DEL_EOS		0x1c1
@@ -542,6 +546,7 @@
 #define KEY_FN_F		0x1e2
 #define KEY_FN_S		0x1e3
 #define KEY_FN_B		0x1e4
+#define KEY_FN_RIGHT_SHIFT	0x1e5
 
 #define KEY_BRL_DOT1		0x1f1
 #define KEY_BRL_DOT2		0x1f2
@@ -607,6 +612,8 @@
 #define KEY_VOICECOMMAND		0x246	/* Listening Voice Command */
 #define KEY_ASSISTANT		0x247	/* AL Context-aware desktop assistant */
 #define KEY_KBD_LAYOUT_NEXT	0x248	/* AC Next Keyboard Layout Select */
+#define KEY_EMOJI_PICKER	0x249	/* Show/hide emoji picker (HUTRR101) */
+#define KEY_DICTATE		0x24a	/* Start or Stop Voice Dictation Session (HUTRR99) */
 
 #define KEY_BRIGHTNESS_MIN		0x250	/* Set Brightness to Minimum */
 #define KEY_BRIGHTNESS_MAX		0x251	/* Set Brightness to Maximum */
diff --git a/include/linux/linux/input.h b/include/linux/linux/input.h
index 537d23ea0007b08330e3d01b2b2fa8837878e55b..9826a58b856bb46758d5fa7f9a8bb68ab63beaa7 100644
--- a/include/linux/linux/input.h
+++ b/include/linux/linux/input.h
@@ -82,7 +82,7 @@ struct input_id {
  * in units per radian.
  * When INPUT_PROP_ACCELEROMETER is set the resolution changes.
  * The main axes (ABS_X, ABS_Y, ABS_Z) are then reported in
- * in units per g (units/g) and in units per degree per second
+ * units per g (units/g) and in units per degree per second
  * (units/deg/s) for rotational axes (ABS_RX, ABS_RY, ABS_RZ).
  */
 struct input_absinfo {
diff --git a/libevdev/Makefile.in b/libevdev/Makefile.in
new file mode 100644
index 0000000000000000000000000000000000000000..92da062cc760ef35c664b581e72ae50303a3c45e
--- /dev/null
+++ b/libevdev/Makefile.in
@@ -0,0 +1,750 @@
+# Makefile.in generated by automake 1.16.5 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994-2021 Free Software Foundation, Inc.
+
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+
+VPATH = @srcdir@
+am__is_gnu_make = { \
+  if test -z '$(MAKELEVEL)'; then \
+    false; \
+  elif test -n '$(MAKE_HOST)'; then \
+    true; \
+  elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
+    true; \
+  else \
+    false; \
+  fi; \
+}
+am__make_running_with_option = \
+  case $${target_option-} in \
+      ?) ;; \
+      *) echo "am__make_running_with_option: internal error: invalid" \
+              "target option '$${target_option-}' specified" >&2; \
+         exit 1;; \
+  esac; \
+  has_opt=no; \
+  sane_makeflags=$$MAKEFLAGS; \
+  if $(am__is_gnu_make); then \
+    sane_makeflags=$$MFLAGS; \
+  else \
+    case $$MAKEFLAGS in \
+      *\\[\ \	]*) \
+        bs=\\; \
+        sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+          | sed "s/$$bs$$bs[$$bs $$bs	]*//g"`;; \
+    esac; \
+  fi; \
+  skip_next=no; \
+  strip_trailopt () \
+  { \
+    flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+  }; \
+  for flg in $$sane_makeflags; do \
+    test $$skip_next = yes && { skip_next=no; continue; }; \
+    case $$flg in \
+      *=*|--*) continue;; \
+        -*I) strip_trailopt 'I'; skip_next=yes;; \
+      -*I?*) strip_trailopt 'I';; \
+        -*O) strip_trailopt 'O'; skip_next=yes;; \
+      -*O?*) strip_trailopt 'O';; \
+        -*l) strip_trailopt 'l'; skip_next=yes;; \
+      -*l?*) strip_trailopt 'l';; \
+      -[dEDm]) skip_next=yes;; \
+      -[JT]) skip_next=yes;; \
+    esac; \
+    case $$flg in \
+      *$$target_option*) has_opt=yes; break;; \
+    esac; \
+  done; \
+  test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+@GCOV_ENABLED_TRUE@am__append_1 = *.gcno
+subdir = libevdev
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/m4/attributes.m4 \
+	$(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \
+	$(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \
+	$(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+	$(ACLOCAL_M4)
+DIST_COMMON = $(srcdir)/Makefile.am $(libevdevinclude_HEADERS) \
+	$(am__DIST_COMMON)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+    $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+    *) f=$$p;; \
+  esac;
+am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
+am__install_max = 40
+am__nobase_strip_setup = \
+  srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
+am__nobase_strip = \
+  for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
+am__nobase_list = $(am__nobase_strip_setup); \
+  for p in $$list; do echo "$$p $$p"; done | \
+  sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
+  $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
+    if (++n[$$2] == $(am__install_max)) \
+      { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
+    END { for (dir in files) print dir, files[dir] }'
+am__base_list = \
+  sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
+  sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
+am__uninstall_files_from_dir = { \
+  test -z "$$files" \
+    || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
+    || { echo " ( cd '$$dir' && rm -f" $$files ")"; \
+         $(am__cd) "$$dir" && rm -f $$files; }; \
+  }
+am__installdirs = "$(DESTDIR)$(libdir)" \
+	"$(DESTDIR)$(libevdevincludedir)"
+LTLIBRARIES = $(lib_LTLIBRARIES)
+libevdev_la_LIBADD =
+am_libevdev_la_OBJECTS = libevdev-uinput.lo libevdev.lo \
+	libevdev-names.lo
+libevdev_la_OBJECTS = $(am_libevdev_la_OBJECTS)
+AM_V_lt = $(am__v_lt_@AM_V@)
+am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
+am__v_lt_0 = --silent
+am__v_lt_1 = 
+libevdev_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+	$(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+	$(libevdev_la_LDFLAGS) $(LDFLAGS) -o $@
+AM_V_P = $(am__v_P_@AM_V@)
+am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_@AM_V@)
+am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
+am__v_GEN_0 = @echo "  GEN     " $@;
+am__v_GEN_1 = 
+AM_V_at = $(am__v_at_@AM_V@)
+am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 = 
+DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
+depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp
+am__maybe_remake_depfiles = depfiles
+am__depfiles_remade = ./$(DEPDIR)/libevdev-names.Plo \
+	./$(DEPDIR)/libevdev-uinput.Plo ./$(DEPDIR)/libevdev.Plo
+am__mv = mv -f
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+	$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+	$(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \
+	$(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
+	$(AM_CFLAGS) $(CFLAGS)
+AM_V_CC = $(am__v_CC_@AM_V@)
+am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@)
+am__v_CC_0 = @echo "  CC      " $@;
+am__v_CC_1 = 
+CCLD = $(CC)
+LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+	$(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+	$(AM_LDFLAGS) $(LDFLAGS) -o $@
+AM_V_CCLD = $(am__v_CCLD_@AM_V@)
+am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@)
+am__v_CCLD_0 = @echo "  CCLD    " $@;
+am__v_CCLD_1 = 
+SOURCES = $(libevdev_la_SOURCES)
+DIST_SOURCES = $(libevdev_la_SOURCES)
+am__can_run_installinfo = \
+  case $$AM_UPDATE_INFO_DIR in \
+    n|no|NO) false;; \
+    *) (install-info --version) >/dev/null 2>&1;; \
+  esac
+HEADERS = $(libevdevinclude_HEADERS)
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
+# Read a list of newline-separated strings from the standard input,
+# and print each of them once, without duplicates.  Input order is
+# *not* preserved.
+am__uniquify_input = $(AWK) '\
+  BEGIN { nonempty = 0; } \
+  { items[$$0] = 1; nonempty = 1; } \
+  END { if (nonempty) { for (i in items) print i; }; } \
+'
+# Make sure the list of sources is unique.  This is necessary because,
+# e.g., the same source file might be shared among _SOURCES variables
+# for different programs/libraries.
+am__define_uniq_tagged_files = \
+  list='$(am__tagged_files)'; \
+  unique=`for i in $$list; do \
+    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+  done | $(am__uniquify_input)`
+am__DIST_COMMON = $(srcdir)/Makefile.in \
+	$(top_srcdir)/build-aux/depcomp
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CHECK_CFLAGS = @CHECK_CFLAGS@
+CHECK_LIBS = @CHECK_LIBS@
+CPPFLAGS = @CPPFLAGS@
+CSCOPE = @CSCOPE@
+CTAGS = @CTAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLTOOL = @DLLTOOL@
+DOXYGEN = @DOXYGEN@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+ETAGS = @ETAGS@
+EXEEXT = @EXEEXT@
+FGREP = @FGREP@
+GCC_CFLAGS = @GCC_CFLAGS@
+GCOV_CFLAGS = @GCOV_CFLAGS@
+GCOV_LDFLAGS = @GCOV_LDFLAGS@
+GNU_LD_FLAGS = @GNU_LD_FLAGS@
+GREP = @GREP@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LIBEVDEV_LT_VERSION = @LIBEVDEV_LT_VERSION@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
+MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MKDIR_P = @MKDIR_P@
+NM = @NM@
+NMEDIT = @NMEDIT@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OS = @OS@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PKG_CONFIG = @PKG_CONFIG@
+PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
+PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
+PYTHON = @PYTHON@
+PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
+PYTHON_PLATFORM = @PYTHON_PLATFORM@
+PYTHON_PREFIX = @PYTHON_PREFIX@
+PYTHON_VERSION = @PYTHON_VERSION@
+RANLIB = @RANLIB@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+VALGRIND = @VALGRIND@
+VERSION = @VERSION@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+pkgpyexecdir = @pkgpyexecdir@
+pkgpythondir = @pkgpythondir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+pyexecdir = @pyexecdir@
+pythondir = @pythondir@
+runstatedir = @runstatedir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+lib_LTLIBRARIES = libevdev.la
+AM_CPPFLAGS = $(GCC_CFLAGS) $(GCOV_CFLAGS) -I$(top_srcdir)/include -I$(top_srcdir)
+AM_LDFLAGS = $(GCOV_LDFLAGS)
+libevdev_la_SOURCES = \
+                   libevdev.h \
+                   libevdev-int.h \
+                   libevdev-util.h \
+                   libevdev-uinput.c \
+                   libevdev-uinput.h \
+                   libevdev-uinput-int.h \
+                   libevdev.c \
+                   libevdev-names.c \
+		   ../include/linux/input.h \
+		   ../include/linux/uinput.h \
+		   ../include/linux/@OS@/input-event-codes.h \
+		   ../include/linux/@OS@/input.h \
+		   ../include/linux/@OS@/uinput.h
+
+libevdev_la_LDFLAGS = \
+        $(AM_LDFLAGS) \
+	-version-info $(LIBEVDEV_LT_VERSION) \
+	-Wl,--version-script="$(srcdir)/libevdev.sym" \
+	$(GNU_LD_FLAGS)
+
+EXTRA_libevdev_la_DEPENDENCIES = $(srcdir)/libevdev.sym
+libevdevincludedir = $(includedir)/libevdev-1.0/libevdev
+libevdevinclude_HEADERS = libevdev.h libevdev-uinput.h
+EXTRA_DIST = make-event-names.py libevdev.sym
+CLEANFILES = event-names.h $(am__append_1)
+BUILT_SOURCES = event-names.h
+all: $(BUILT_SOURCES)
+	$(MAKE) $(AM_MAKEFLAGS) all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .lo .o .obj
+$(srcdir)/Makefile.in:  $(srcdir)/Makefile.am  $(am__configure_deps)
+	@for dep in $?; do \
+	  case '$(am__configure_deps)' in \
+	    *$$dep*) \
+	      ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+	        && { if test -f $@; then exit 0; else break; fi; }; \
+	      exit 1;; \
+	  esac; \
+	done; \
+	echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign libevdev/Makefile'; \
+	$(am__cd) $(top_srcdir) && \
+	  $(AUTOMAKE) --foreign libevdev/Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+	@case '$?' in \
+	  *config.status*) \
+	    cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+	  *) \
+	    echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \
+	    cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \
+	esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure:  $(am__configure_deps)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4):  $(am__aclocal_m4_deps)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+
+install-libLTLIBRARIES: $(lib_LTLIBRARIES)
+	@$(NORMAL_INSTALL)
+	@list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \
+	list2=; for p in $$list; do \
+	  if test -f $$p; then \
+	    list2="$$list2 $$p"; \
+	  else :; fi; \
+	done; \
+	test -z "$$list2" || { \
+	  echo " $(MKDIR_P) '$(DESTDIR)$(libdir)'"; \
+	  $(MKDIR_P) "$(DESTDIR)$(libdir)" || exit 1; \
+	  echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(libdir)'"; \
+	  $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(libdir)"; \
+	}
+
+uninstall-libLTLIBRARIES:
+	@$(NORMAL_UNINSTALL)
+	@list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \
+	for p in $$list; do \
+	  $(am__strip_dir) \
+	  echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$f'"; \
+	  $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$f"; \
+	done
+
+clean-libLTLIBRARIES:
+	-test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES)
+	@list='$(lib_LTLIBRARIES)'; \
+	locs=`for p in $$list; do echo $$p; done | \
+	      sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \
+	      sort -u`; \
+	test -z "$$locs" || { \
+	  echo rm -f $${locs}; \
+	  rm -f $${locs}; \
+	}
+
+libevdev.la: $(libevdev_la_OBJECTS) $(libevdev_la_DEPENDENCIES) $(EXTRA_libevdev_la_DEPENDENCIES) 
+	$(AM_V_CCLD)$(libevdev_la_LINK) -rpath $(libdir) $(libevdev_la_OBJECTS) $(libevdev_la_LIBADD) $(LIBS)
+
+mostlyclean-compile:
+	-rm -f *.$(OBJEXT)
+
+distclean-compile:
+	-rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libevdev-names.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libevdev-uinput.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libevdev.Plo@am__quote@ # am--include-marker
+
+$(am__depfiles_remade):
+	@$(MKDIR_P) $(@D)
+	@echo '# dummy' >$@-t && $(am__mv) $@-t $@
+
+am--depfiles: $(am__depfiles_remade)
+
+.c.o:
+@am__fastdepCC_TRUE@	$(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\
+@am__fastdepCC_TRUE@	$(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
+@am__fastdepCC_TRUE@	$(am__mv) $$depbase.Tpo $$depbase.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $<
+
+.c.obj:
+@am__fastdepCC_TRUE@	$(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\
+@am__fastdepCC_TRUE@	$(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\
+@am__fastdepCC_TRUE@	$(am__mv) $$depbase.Tpo $$depbase.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
+
+.c.lo:
+@am__fastdepCC_TRUE@	$(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\
+@am__fastdepCC_TRUE@	$(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
+@am__fastdepCC_TRUE@	$(am__mv) $$depbase.Tpo $$depbase.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $<
+
+mostlyclean-libtool:
+	-rm -f *.lo
+
+clean-libtool:
+	-rm -rf .libs _libs
+install-libevdevincludeHEADERS: $(libevdevinclude_HEADERS)
+	@$(NORMAL_INSTALL)
+	@list='$(libevdevinclude_HEADERS)'; test -n "$(libevdevincludedir)" || list=; \
+	if test -n "$$list"; then \
+	  echo " $(MKDIR_P) '$(DESTDIR)$(libevdevincludedir)'"; \
+	  $(MKDIR_P) "$(DESTDIR)$(libevdevincludedir)" || exit 1; \
+	fi; \
+	for p in $$list; do \
+	  if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+	  echo "$$d$$p"; \
+	done | $(am__base_list) | \
+	while read files; do \
+	  echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(libevdevincludedir)'"; \
+	  $(INSTALL_HEADER) $$files "$(DESTDIR)$(libevdevincludedir)" || exit $$?; \
+	done
+
+uninstall-libevdevincludeHEADERS:
+	@$(NORMAL_UNINSTALL)
+	@list='$(libevdevinclude_HEADERS)'; test -n "$(libevdevincludedir)" || list=; \
+	files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
+	dir='$(DESTDIR)$(libevdevincludedir)'; $(am__uninstall_files_from_dir)
+
+ID: $(am__tagged_files)
+	$(am__define_uniq_tagged_files); mkid -fID $$unique
+tags: tags-am
+TAGS: tags
+
+tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+	set x; \
+	here=`pwd`; \
+	$(am__define_uniq_tagged_files); \
+	shift; \
+	if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+	  test -n "$$unique" || unique=$$empty_fix; \
+	  if test $$# -gt 0; then \
+	    $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+	      "$$@" $$unique; \
+	  else \
+	    $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+	      $$unique; \
+	  fi; \
+	fi
+ctags: ctags-am
+
+CTAGS: ctags
+ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+	$(am__define_uniq_tagged_files); \
+	test -z "$(CTAGS_ARGS)$$unique" \
+	  || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+	     $$unique
+
+GTAGS:
+	here=`$(am__cd) $(top_builddir) && pwd` \
+	  && $(am__cd) $(top_srcdir) \
+	  && gtags -i $(GTAGS_ARGS) "$$here"
+cscopelist: cscopelist-am
+
+cscopelist-am: $(am__tagged_files)
+	list='$(am__tagged_files)'; \
+	case "$(srcdir)" in \
+	  [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
+	  *) sdir=$(subdir)/$(srcdir) ;; \
+	esac; \
+	for i in $$list; do \
+	  if test -f "$$i"; then \
+	    echo "$(subdir)/$$i"; \
+	  else \
+	    echo "$$sdir/$$i"; \
+	  fi; \
+	done >> $(top_builddir)/cscope.files
+
+distclean-tags:
+	-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+distdir: $(BUILT_SOURCES)
+	$(MAKE) $(AM_MAKEFLAGS) distdir-am
+
+distdir-am: $(DISTFILES)
+	@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+	topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+	list='$(DISTFILES)'; \
+	  dist_files=`for file in $$list; do echo $$file; done | \
+	  sed -e "s|^$$srcdirstrip/||;t" \
+	      -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+	case $$dist_files in \
+	  */*) $(MKDIR_P) `echo "$$dist_files" | \
+			   sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+			   sort -u` ;; \
+	esac; \
+	for file in $$dist_files; do \
+	  if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+	  if test -d $$d/$$file; then \
+	    dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+	    if test -d "$(distdir)/$$file"; then \
+	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+	    fi; \
+	    if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+	      cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+	    fi; \
+	    cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+	  else \
+	    test -f "$(distdir)/$$file" \
+	    || cp -p $$d/$$file "$(distdir)/$$file" \
+	    || exit 1; \
+	  fi; \
+	done
+check-am: all-am
+check: $(BUILT_SOURCES)
+	$(MAKE) $(AM_MAKEFLAGS) check-am
+all-am: Makefile $(LTLIBRARIES) $(HEADERS)
+installdirs:
+	for dir in "$(DESTDIR)$(libdir)" "$(DESTDIR)$(libevdevincludedir)"; do \
+	  test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+	done
+install: $(BUILT_SOURCES)
+	$(MAKE) $(AM_MAKEFLAGS) install-am
+install-exec: $(BUILT_SOURCES)
+	$(MAKE) $(AM_MAKEFLAGS) install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+	@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+	if test -z '$(STRIP)'; then \
+	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	      install; \
+	else \
+	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	    "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+	fi
+mostlyclean-generic:
+
+clean-generic:
+	-test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
+
+distclean-generic:
+	-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+	-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+	@echo "This command is intended for maintainers to use"
+	@echo "it deletes files that may require special tools to rebuild."
+	-test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES)
+clean: clean-am
+
+clean-am: clean-generic clean-libLTLIBRARIES clean-libtool \
+	mostlyclean-am
+
+distclean: distclean-am
+		-rm -f ./$(DEPDIR)/libevdev-names.Plo
+	-rm -f ./$(DEPDIR)/libevdev-uinput.Plo
+	-rm -f ./$(DEPDIR)/libevdev.Plo
+	-rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+	distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am: install-libevdevincludeHEADERS
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am: install-libLTLIBRARIES
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+		-rm -f ./$(DEPDIR)/libevdev-names.Plo
+	-rm -f ./$(DEPDIR)/libevdev-uinput.Plo
+	-rm -f ./$(DEPDIR)/libevdev.Plo
+	-rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+	mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-libLTLIBRARIES \
+	uninstall-libevdevincludeHEADERS
+
+.MAKE: all check install install-am install-exec install-strip
+
+.PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \
+	clean-generic clean-libLTLIBRARIES clean-libtool cscopelist-am \
+	ctags ctags-am distclean distclean-compile distclean-generic \
+	distclean-libtool distclean-tags distdir dvi dvi-am html \
+	html-am info info-am install install-am install-data \
+	install-data-am install-dvi install-dvi-am install-exec \
+	install-exec-am install-html install-html-am install-info \
+	install-info-am install-libLTLIBRARIES \
+	install-libevdevincludeHEADERS install-man install-pdf \
+	install-pdf-am install-ps install-ps-am install-strip \
+	installcheck installcheck-am installdirs maintainer-clean \
+	maintainer-clean-generic mostlyclean mostlyclean-compile \
+	mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+	tags tags-am uninstall uninstall-am uninstall-libLTLIBRARIES \
+	uninstall-libevdevincludeHEADERS
+
+.PRECIOUS: Makefile
+
+
+event-names.h: Makefile make-event-names.py
+	$(PYTHON) $(srcdir)/make-event-names.py $(top_srcdir)/include/linux/@OS@/input.h $(top_srcdir)/include/linux/@OS@/input-event-codes.h  > $@
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/libevdev/libevdev-int.h b/libevdev/libevdev-int.h
index 7da5cf02c20b4df747e9f1358ffd2aec1d14834e..8e2518e6c5602a4e7bcb651b0af636c87439bef1 100644
--- a/libevdev/libevdev-int.h
+++ b/libevdev/libevdev-int.h
@@ -1,23 +1,6 @@
+// SPDX-License-Identifier: MIT
 /*
  * Copyright © 2013 Red Hat, Inc.
- *
- * Permission to use, copy, modify, distribute, and sell this software and its
- * documentation for any purpose is hereby granted without fee, provided that
- * the above copyright notice appear in all copies and that both that copyright
- * notice and this permission notice appear in supporting documentation, and
- * that the name of the copyright holders not be used in advertising or
- * publicity pertaining to distribution of the software without specific,
- * written prior permission.  The copyright holders make no representations
- * about the suitability of this software for any purpose.  It is provided "as
- * is" without express or implied warranty.
- *
- * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
- * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
- * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
- * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
- * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
- * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
- * OF THIS SOFTWARE.
  */
 
 #ifndef LIBEVDEV_INT_H
diff --git a/libevdev/libevdev-names.c b/libevdev/libevdev-names.c
index ef4cfb47bed79261beaeb4cfae5d79e22107bee1..82329c394ca8d4f922a47b085aaf3248cac5c253 100644
--- a/libevdev/libevdev-names.c
+++ b/libevdev/libevdev-names.c
@@ -1,23 +1,6 @@
+// SPDX-License-Identifier: MIT
 /*
  * Copyright © 2013 David Herrmann 
- *
- * Permission to use, copy, modify, distribute, and sell this software and its
- * documentation for any purpose is hereby granted without fee, provided that
- * the above copyright notice appear in all copies and that both that copyright
- * notice and this permission notice appear in supporting documentation, and
- * that the name of the copyright holders not be used in advertising or
- * publicity pertaining to distribution of the software without specific,
- * written prior permission.  The copyright holders make no representations
- * about the suitability of this software for any purpose.  It is provided "as
- * is" without express or implied warranty.
- *
- * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
- * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
- * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
- * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
- * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
- * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
- * OF THIS SOFTWARE.
  */
 
 #include "config.h"
diff --git a/libevdev/libevdev-uinput-int.h b/libevdev/libevdev-uinput-int.h
index 22d1684ba691c8d6d02f19333b9783499f06f566..d7e674a93d1533172a037b93d02f5bab75186ee4 100644
--- a/libevdev/libevdev-uinput-int.h
+++ b/libevdev/libevdev-uinput-int.h
@@ -1,23 +1,6 @@
+// SPDX-License-Identifier: MIT
 /*
  * Copyright © 2013 Red Hat, Inc.
- *
- * Permission to use, copy, modify, distribute, and sell this software and its
- * documentation for any purpose is hereby granted without fee, provided that
- * the above copyright notice appear in all copies and that both that copyright
- * notice and this permission notice appear in supporting documentation, and
- * that the name of the copyright holders not be used in advertising or
- * publicity pertaining to distribution of the software without specific,
- * written prior permission.  The copyright holders make no representations
- * about the suitability of this software for any purpose.  It is provided "as
- * is" without express or implied warranty.
- *
- * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
- * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
- * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
- * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
- * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
- * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
- * OF THIS SOFTWARE.
  */
 
 struct libevdev_uinput {
diff --git a/libevdev/libevdev-uinput.c b/libevdev/libevdev-uinput.c
index 6d2e43ff53fc66c063c61cf1767384d3ccb6c805..6773e91189a461c2045a9022bdcd37482cc74969 100644
--- a/libevdev/libevdev-uinput.c
+++ b/libevdev/libevdev-uinput.c
@@ -1,23 +1,6 @@
+// SPDX-License-Identifier: MIT
 /*
  * Copyright © 2013 Red Hat, Inc.
- *
- * Permission to use, copy, modify, distribute, and sell this software and its
- * documentation for any purpose is hereby granted without fee, provided that
- * the above copyright notice appear in all copies and that both that copyright
- * notice and this permission notice appear in supporting documentation, and
- * that the name of the copyright holders not be used in advertising or
- * publicity pertaining to distribution of the software without specific,
- * written prior permission.  The copyright holders make no representations
- * about the suitability of this software for any purpose.  It is provided "as
- * is" without express or implied warranty.
- *
- * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
- * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
- * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
- * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
- * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
- * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
- * OF THIS SOFTWARE.
  */
 
 #include "config.h"
@@ -185,7 +168,7 @@ libevdev_uinput_get_fd(const struct libevdev_uinput *uinput_dev)
  * FreeBSD does not have anything similar to sysfs.
  * Set libevdev_uinput->syspath to NULL unconditionally.
  * Look up the device nodes directly instead of via sysfs, as this matches what
- * is returned by the UI_GET_SYSNAME ioctl() on FreeBSD.  
+ * is returned by the UI_GET_SYSNAME ioctl() on FreeBSD.
  */
 static int
 fetch_syspath_and_devnode(struct libevdev_uinput *uinput_dev)
@@ -485,11 +468,7 @@ libevdev_uinput_write_event(const struct libevdev_uinput *uinput_dev,
 			    unsigned int code,
 			    int value)
 {
-#ifndef __MUSL__
 	struct input_event ev = { {0,0}, type, code, value };
-#else
-	struct input_event ev = { type, code, value };
-#endif
 	int fd = libevdev_uinput_get_fd(uinput_dev);
 	int rc, max;
 
diff --git a/libevdev/libevdev-uinput.h b/libevdev/libevdev-uinput.h
index 41f40fa66ec8d09ff06c5d81c594a91cfbfc6c08..b54ec026eba791f76b7d87fa51ca56ec769e2336 100644
--- a/libevdev/libevdev-uinput.h
+++ b/libevdev/libevdev-uinput.h
@@ -1,23 +1,25 @@
+/* SPDX-License-Identifier: MIT */
 /*
  * Copyright © 2013 Red Hat, Inc.
  *
- * Permission to use, copy, modify, distribute, and sell this software and its
- * documentation for any purpose is hereby granted without fee, provided that
- * the above copyright notice appear in all copies and that both that copyright
- * notice and this permission notice appear in supporting documentation, and
- * that the name of the copyright holders not be used in advertising or
- * publicity pertaining to distribution of the software without specific,
- * written prior permission.  The copyright holders make no representations
- * about the suitability of this software for any purpose.  It is provided "as
- * is" without express or implied warranty.
- *
- * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
- * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
- * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
- * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
- * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
- * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
- * OF THIS SOFTWARE.
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
  */
 
 #ifndef LIBEVDEV_UINPUT_H
@@ -40,14 +42,13 @@ struct libevdev_uinput;
  *
  * @code
  * int err;
- * int fd, new_fd, uifd;
+ * int fd, uifd;
  * struct libevdev *dev;
  * struct libevdev_uinput *uidev;
- * struct input_event ev[2];
  *
  * fd = open("/dev/input/event0", O_RDONLY);
  * if (fd < 0)
- *     return err;
+ *     return -errno;
  *
  * err = libevdev_new_from_fd(fd, &dev);
  * if (err != 0)
@@ -65,7 +66,7 @@ struct libevdev_uinput;
  * err = libevdev_uinput_write_event(uidev, EV_REL, REL_X, -1);
  * if (err != 0)
  *     return err;
- * libevdev_uinput_write_event(uidev, EV_SYN, SYN_REPORT, 0);
+ * err = libevdev_uinput_write_event(uidev, EV_SYN, SYN_REPORT, 0);
  * if (err != 0)
  *     return err;
  *
@@ -107,7 +108,7 @@ struct libevdev_uinput;
  */
 
 enum libevdev_uinput_open_mode {
-	/* intentionally -2 to avoid to avoid code like the below from accidentally working:
+	/* intentionally -2 to avoid code like below from accidentally working:
 		fd = open("/dev/uinput", O_RDWR); // fails, fd is -1
 		libevdev_uinput_create_from_device(dev, fd, &uidev); // may hide the error */
 	LIBEVDEV_UINPUT_OPEN_MANAGED = -2  /**< let libevdev open and close @c /dev/uinput */
@@ -186,7 +187,7 @@ int libevdev_uinput_get_fd(const struct libevdev_uinput *uinput_dev);
  * @ingroup uinput
  *
  * Return the syspath representing this uinput device. If the UI_GET_SYSNAME
- * ioctl not available, libevdev makes an educated guess.
+ * ioctl is not available, libevdev makes an educated guess.
  * The UI_GET_SYSNAME ioctl is available since Linux 3.15.
  *
  * The syspath returned is the one of the input node itself
@@ -195,8 +196,8 @@ int libevdev_uinput_get_fd(const struct libevdev_uinput *uinput_dev);
  *
  * @note This function may return NULL if UI_GET_SYSNAME is not available.
  * In that case, libevdev uses ctime and the device name to guess devices.
- * To avoid false positives, wait at least wait at least 1.5s between
- * creating devices that have the same name.
+ * To avoid false positives, wait at least 1.5s between creating devices that
+ * have the same name.
  *
  * @note FreeBSD does not have sysfs, on FreeBSD this function always returns
  * NULL.
@@ -219,7 +220,7 @@ const char* libevdev_uinput_get_syspath(struct libevdev_uinput *uinput_dev);
  * @note This function may return NULL. libevdev may have to guess the
  * syspath and the device node. See libevdev_uinput_get_syspath() for details.
  *
- * @note On FreeBSD, this function can not return NULL.  libudev uses the
+ * @note On FreeBSD, this function can not return NULL. libudev uses the
  * UI_GET_SYSNAME ioctl to get the device node on this platform and if that
  * fails, the call to libevdev_uinput_create_from_device() fails.
  *
diff --git a/libevdev/libevdev-util.h b/libevdev/libevdev-util.h
index 972f9dfb7be35330ab686959b88e42b5db579313..ed85c959617e1f1801f8e899dbabc225bd4bd514 100644
--- a/libevdev/libevdev-util.h
+++ b/libevdev/libevdev-util.h
@@ -1,23 +1,6 @@
+// SPDX-License-Identifier: MIT
 /*
  * Copyright © 2013 Red Hat, Inc.
- *
- * Permission to use, copy, modify, distribute, and sell this software and its
- * documentation for any purpose is hereby granted without fee, provided that
- * the above copyright notice appear in all copies and that both that copyright
- * notice and this permission notice appear in supporting documentation, and
- * that the name of the copyright holders not be used in advertising or
- * publicity pertaining to distribution of the software without specific,
- * written prior permission.  The copyright holders make no representations
- * about the suitability of this software for any purpose.  It is provided "as
- * is" without express or implied warranty.
- *
- * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
- * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
- * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
- * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
- * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
- * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
- * OF THIS SOFTWARE.
  */
 
 #ifndef _UTIL_H_
diff --git a/libevdev/libevdev.c b/libevdev/libevdev.c
index 2b90a6c51d7802cba81d602bb72c4672a0a720f9..b941cfb1e73d1a0ccd1c950d41d49de5e5f7fe45 100644
--- a/libevdev/libevdev.c
+++ b/libevdev/libevdev.c
@@ -1,23 +1,6 @@
+// SPDX-License-Identifier: MIT
 /*
  * Copyright © 2013 Red Hat, Inc.
- *
- * Permission to use, copy, modify, distribute, and sell this software and its
- * documentation for any purpose is hereby granted without fee, provided that
- * the above copyright notice appear in all copies and that both that copyright
- * notice and this permission notice appear in supporting documentation, and
- * that the name of the copyright holders not be used in advertising or
- * publicity pertaining to distribution of the software without specific,
- * written prior permission.  The copyright holders make no representations
- * about the suitability of this software for any purpose.  It is provided "as
- * is" without express or implied warranty.
- *
- * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
- * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
- * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
- * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
- * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
- * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
- * OF THIS SOFTWARE.
  */
 
 #include "config.h"
diff --git a/libevdev/libevdev.h b/libevdev/libevdev.h
index 6ffcda73128abd173d9b0dac6f9b6ecdf5121c92..30e4d6f88a44c86e4c41682fc3b2fb444a428b11 100644
--- a/libevdev/libevdev.h
+++ b/libevdev/libevdev.h
@@ -1,23 +1,26 @@
+/* SPDX-License-Identifier: MIT */
 /*
  * Copyright © 2013 Red Hat, Inc.
  *
- * Permission to use, copy, modify, distribute, and sell this software and its
- * documentation for any purpose is hereby granted without fee, provided that
- * the above copyright notice appear in all copies and that both that copyright
- * notice and this permission notice appear in supporting documentation, and
- * that the name of the copyright holders not be used in advertising or
- * publicity pertaining to distribution of the software without specific,
- * written prior permission.  The copyright holders make no representations
- * about the suitability of this software for any purpose.  It is provided "as
- * is" without express or implied warranty.
- *
- * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
- * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
- * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
- * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
- * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
- * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
- * OF THIS SOFTWARE.
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
  */
 
 #ifndef LIBEVDEV_H
@@ -631,7 +634,7 @@ extern "C" {
  *         return ENOMEM;
  *
  * err = libevdev_set_fd(dev, fd);
- * if (err < 0) {
+ * if (err < 0)
  *         printf("Failed (errno %d): %s\n", -err, strerror(-err));
  *
  * libevdev_free(dev);
@@ -1515,8 +1518,7 @@ const struct input_absinfo* libevdev_get_abs_info(const struct libevdev *dev, un
  * the event.
  *
  * If the device supports ABS_MT_SLOT, the value returned for any ABS_MT_*
- * event code is the value of the currently active slot. You should use
- * libevdev_get_slot_value() instead.
+ * event code is undefined. Use libevdev_get_slot_value() instead.
  *
  * @param dev The evdev device, already initialized with libevdev_set_fd()
  * @param type The event type for the code to query (EV_SYN, EV_REL, etc.)
diff --git a/libevdev/libevdev.sym b/libevdev/libevdev.sym
index 30af65de74ffba9a5cc699fbb026c1656176aa0f..4161962dc8bb2fdf8bca647ffc87e3f1f71215e6 100644
--- a/libevdev/libevdev.sym
+++ b/libevdev/libevdev.sym
@@ -1,23 +1,6 @@
+/* SPDX-License-Identifier: MIT */
 /*
  * Copyright (c) 2013 David Herrmann 
- *
- * Permission to use, copy, modify, distribute, and sell this software and its
- * documentation for any purpose is hereby granted without fee, provided that
- * the above copyright notice appear in all copies and that both that copyright
- * notice and this permission notice appear in supporting documentation, and
- * that the name of the copyright holders not be used in advertising or
- * publicity pertaining to distribution of the software without specific,
- * written prior permission.  The copyright holders make no representations
- * about the suitability of this software for any purpose.  It is provided "as
- * is" without express or implied warranty.
- *
- * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
- * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
- * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
- * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
- * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
- * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
- * OF THIS SOFTWARE.
  */
 
 LIBEVDEV_1 {
diff --git a/libevdev/make-event-names.py b/libevdev/make-event-names.py
index 88addd77e3583e06a9f2c3772dde778c2ef83c19..743b4b58b170f6da0c09e57dcc908ec0a879bf96 100755
--- a/libevdev/make-event-names.py
+++ b/libevdev/make-event-names.py
@@ -70,10 +70,10 @@ def print_bits(bits, prefix):
     if not hasattr(bits, prefix):
         return
     print("static const char * const %s_map[%s_MAX + 1] = {" % (prefix, prefix.upper()))
-    for val, name in list(getattr(bits, prefix).items()):
+    for val, name in sorted(list(getattr(bits, prefix).items())):
         print("    [%s] = \"%s\"," % (name, name))
     if prefix == "key":
-        for val, name in list(getattr(bits, "btn").items()):
+        for val, name in sorted(list(getattr(bits, "btn").items())):
             print("    [%s] = \"%s\"," % (name, name))
     print("};")
     print("")
@@ -118,7 +118,7 @@ def print_lookup(bits, prefix):
     if not hasattr(bits, prefix):
         return
 
-    names = list(getattr(bits, prefix).items())
+    names = sorted(list(getattr(bits, prefix).items()))
     if prefix == "btn":
         names = names + btn_additional
 
diff --git a/meson.build b/meson.build
index d38fd913fa6908f8e064f4c0fedb5c45300d077c..63504acd2781fcec22cfa6bd564c0c724c61e41d 100644
--- a/meson.build
+++ b/meson.build
@@ -1,5 +1,5 @@
 project('libevdev', 'c',
-	version: '1.10.0', # change autotools version too
+	version: '1.12.1', # change autotools version too
 	license: 'MIT/Expat',
 	default_options: [ 'c_std=gnu99', 'warning_level=2' ],
 	meson_version: '>= 0.47.0')
@@ -37,6 +37,7 @@ config_h.set('_GNU_SOURCE', '1')
 # Dependencies
 pkgconfig = import('pkgconfig')
 dep_lm = cc.find_library('m')
+dep_rt = cc.find_library('rt')
 
 input_h = join_paths(meson.source_root(), 'include', 'linux', host_machine.system(), 'input.h')
 uinput_h = join_paths(meson.source_root(), 'include', 'linux', host_machine.system(), 'uinput.h')
@@ -76,7 +77,7 @@ version_flag = '-Wl,--version-script,@0@'.format(mapfile)
 lib_libevdev = library('evdev',
 	src_libevdev,
 	include_directories: [includes_include],
-	dependencies: [],
+	dependencies: [dep_rt],
 	version: libevdev_so_version,
 	link_args: version_flag,
 	link_depends: mapfile,
@@ -108,6 +109,11 @@ executable('libevdev-events',
 	   include_directories: [includes_include],
 	   dependencies: dep_libevdev,
 	   install: false)
+executable('libevdev-list-codes',
+	   sources: ['tools/libevdev-list-codes.c'],
+	   include_directories: [includes_include],
+	   dependencies: dep_libevdev,
+	   install: false)
 executable('touchpad-edge-detector',
 	   sources: ['tools/touchpad-edge-detector.c'],
 	   include_directories: [includes_include],
diff --git a/test/Makefile.am b/test/Makefile.am
new file mode 100644
index 0000000000000000000000000000000000000000..5f0c008d9b899ae7a2806437838e8bf163095078
--- /dev/null
+++ b/test/Makefile.am
@@ -0,0 +1,143 @@
+build_tests = test-compile-pedantic test-link
+
+if ENABLE_STATIC_LINK_TEST
+build_tests += test-static-link
+endif
+
+noinst_PROGRAMS = $(build_tests)
+
+AM_CPPFLAGS = -I$(top_srcdir) -I$(top_srcdir)/include -I$(top_builddir)/libevdev
+AM_LDFLAGS =
+
+test_compile_pedantic_SOURCES = test-compile-pedantic.c
+test_compile_pedantic_CFLAGS = $(AM_CPPFLAGS) -pedantic -Werror -std=c89
+
+test_link_SOURCES = test-link.c
+test_link_CFLAGS = -I$(top_srcdir)
+test_link_LDADD = $(top_builddir)/libevdev/libevdev.la
+
+test_static_link_SOURCES = test-link.c
+test_static_link_CFLAGS = -I$(top_srcdir)
+test_static_link_LDADD = $(top_builddir)/libevdev/libevdev.la
+test_static_link_LDFLAGS = $(AM_LDFLAGS) -static
+
+check_local_deps =
+
+if ENABLE_RUNTIME_TESTS
+run_tests = \
+	    test-libevdev \
+	    test-kernel \
+	    test-uinput \
+	    test-event-codes \
+	    test-libevdev-internals \
+	    $(NULL)
+
+.NOTPARALLEL:
+
+noinst_PROGRAMS += $(run_tests)
+
+TESTS = $(run_tests)
+
+common_sources = \
+		 test-common-uinput.c \
+		 test-common-uinput.h \
+		 test-common.c \
+		 test-common.h
+
+# include builddir for event-names.h
+AM_CPPFLAGS += $(CHECK_CFLAGS) $(GCOV_CFLAGS)
+AM_LDFLAGS += $(GCOV_LDFLAGS)
+
+test_event_codes_SOURCES = \
+			test-main.c \
+			test-event-codes.c \
+			test-event-names.c \
+			test-context.c \
+			$(common_sources)
+test_event_codes_LDADD = $(CHECK_LIBS) $(top_builddir)/libevdev/libevdev.la
+test_event_codes_LDFLAGS = -no-install
+
+test_libevdev_internals_SOURCES = \
+			test-main.c \
+			test-int-queue.c \
+			$(common_sources)
+test_libevdev_internals_LDADD = $(CHECK_LIBS) $(top_builddir)/libevdev/libevdev.la
+test_libevdev_internals_LDFLAGS = -no-install
+
+test_uinput_SOURCES = \
+			test-main.c \
+			test-uinput.c \
+			$(common_sources)
+test_uinput_LDADD = $(CHECK_LIBS) $(top_builddir)/libevdev/libevdev.la
+test_uinput_LDFLAGS = -no-install
+
+test_libevdev_SOURCES = \
+			test-main.c \
+			test-libevdev-init.c \
+			test-libevdev-has-event.c \
+			test-libevdev-events.c \
+			$(common_sources)
+
+test_libevdev_LDADD = $(CHECK_LIBS) $(top_builddir)/libevdev/libevdev.la
+test_libevdev_LDFLAGS = -no-install
+
+test_kernel_SOURCES = \
+		      test-main.c \
+		      test-kernel.c \
+		      $(common_sources)
+
+test_kernel_CFLAGS = -I$(top_srcdir)
+test_kernel_LDADD = $(CHECK_LIBS) $(top_builddir)/libevdev/libevdev.la
+
+if HAVE_VALGRIND
+VALGRIND_FLAGS=--leak-check=full \
+		--quiet \
+		--error-exitcode=3 \
+		--suppressions=$(srcdir)/valgrind.suppressions
+
+valgrind:
+	        $(MAKE) check-TESTS CK_TIMEOUT_MULTIPLIER=10 LOG_COMPILER="$(VALGRIND)" LOG_FLAGS="$(VALGRIND_FLAGS)"
+
+check_local_deps += valgrind
+
+endif
+
+if GCOV_ENABLED
+
+CLEANFILES = gcov-reports/*.gcov gcov-reports/summary.txt *.gcno *.gcda
+
+gcov-report: generate-gcov-report.sh check-TESTS
+	$(AM_V_GEN)$(srcdir)/generate-gcov-report.sh gcov-reports $(top_builddir)/libevdev $(builddir)
+
+gcov: gcov-report
+	@cat gcov-reports/summary.txt
+
+check_local_deps += gcov
+
+else
+
+gcov-report.txt:
+	@true
+
+gcov:
+	@true
+
+
+endif # GCOV_ENABLED
+
+.PHONY: gcov gcov-clean gcov-report
+
+endif # ENABLE_RUNTIME_TESTS
+
+if ENABLE_STATIC_SYMBOL_LEAKS_TEST
+static-symbol-leaks: test-static-link test-static-symbols-leak.sh
+	$(AM_V_GEN) $(srcdir)/test-static-symbols-leak.sh $(builddir)
+
+check_local_deps += static-symbol-leaks
+
+endif # HAVE_NM
+
+EXTRA_DIST = valgrind.suppressions  generate-gcov-report.sh test-static-symbols-leak.sh
+
+check-local: $(check_local_deps)
+
diff --git a/test/Makefile.in b/test/Makefile.in
new file mode 100644
index 0000000000000000000000000000000000000000..0cc74e3eed3e8e19c1b5276a278834d8e07e9b35
--- /dev/null
+++ b/test/Makefile.in
@@ -0,0 +1,1439 @@
+# Makefile.in generated by automake 1.16.5 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994-2021 Free Software Foundation, Inc.
+
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+VPATH = @srcdir@
+am__is_gnu_make = { \
+  if test -z '$(MAKELEVEL)'; then \
+    false; \
+  elif test -n '$(MAKE_HOST)'; then \
+    true; \
+  elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
+    true; \
+  else \
+    false; \
+  fi; \
+}
+am__make_running_with_option = \
+  case $${target_option-} in \
+      ?) ;; \
+      *) echo "am__make_running_with_option: internal error: invalid" \
+              "target option '$${target_option-}' specified" >&2; \
+         exit 1;; \
+  esac; \
+  has_opt=no; \
+  sane_makeflags=$$MAKEFLAGS; \
+  if $(am__is_gnu_make); then \
+    sane_makeflags=$$MFLAGS; \
+  else \
+    case $$MAKEFLAGS in \
+      *\\[\ \	]*) \
+        bs=\\; \
+        sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+          | sed "s/$$bs$$bs[$$bs $$bs	]*//g"`;; \
+    esac; \
+  fi; \
+  skip_next=no; \
+  strip_trailopt () \
+  { \
+    flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+  }; \
+  for flg in $$sane_makeflags; do \
+    test $$skip_next = yes && { skip_next=no; continue; }; \
+    case $$flg in \
+      *=*|--*) continue;; \
+        -*I) strip_trailopt 'I'; skip_next=yes;; \
+      -*I?*) strip_trailopt 'I';; \
+        -*O) strip_trailopt 'O'; skip_next=yes;; \
+      -*O?*) strip_trailopt 'O';; \
+        -*l) strip_trailopt 'l'; skip_next=yes;; \
+      -*l?*) strip_trailopt 'l';; \
+      -[dEDm]) skip_next=yes;; \
+      -[JT]) skip_next=yes;; \
+    esac; \
+    case $$flg in \
+      *$$target_option*) has_opt=yes; break;; \
+    esac; \
+  done; \
+  test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+@ENABLE_STATIC_LINK_TEST_TRUE@am__append_1 = test-static-link
+noinst_PROGRAMS = $(am__EXEEXT_2) $(am__EXEEXT_4)
+@ENABLE_RUNTIME_TESTS_TRUE@am__append_2 = $(run_tests)
+@ENABLE_RUNTIME_TESTS_TRUE@TESTS = $(am__EXEEXT_3)
+
+# include builddir for event-names.h
+@ENABLE_RUNTIME_TESTS_TRUE@am__append_3 = $(CHECK_CFLAGS) $(GCOV_CFLAGS)
+@ENABLE_RUNTIME_TESTS_TRUE@am__append_4 = $(GCOV_LDFLAGS)
+@ENABLE_RUNTIME_TESTS_TRUE@@HAVE_VALGRIND_TRUE@am__append_5 = valgrind
+@ENABLE_RUNTIME_TESTS_TRUE@@GCOV_ENABLED_TRUE@am__append_6 = gcov
+@ENABLE_STATIC_SYMBOL_LEAKS_TEST_TRUE@am__append_7 = static-symbol-leaks
+subdir = test
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/m4/attributes.m4 \
+	$(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \
+	$(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \
+	$(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+	$(ACLOCAL_M4)
+DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+@ENABLE_STATIC_LINK_TEST_TRUE@am__EXEEXT_1 =  \
+@ENABLE_STATIC_LINK_TEST_TRUE@	test-static-link$(EXEEXT)
+am__EXEEXT_2 = test-compile-pedantic$(EXEEXT) test-link$(EXEEXT) \
+	$(am__EXEEXT_1)
+@ENABLE_RUNTIME_TESTS_TRUE@am__EXEEXT_3 = test-libevdev$(EXEEXT) \
+@ENABLE_RUNTIME_TESTS_TRUE@	test-kernel$(EXEEXT) \
+@ENABLE_RUNTIME_TESTS_TRUE@	test-uinput$(EXEEXT) \
+@ENABLE_RUNTIME_TESTS_TRUE@	test-event-codes$(EXEEXT) \
+@ENABLE_RUNTIME_TESTS_TRUE@	test-libevdev-internals$(EXEEXT)
+@ENABLE_RUNTIME_TESTS_TRUE@am__EXEEXT_4 = $(am__EXEEXT_3)
+PROGRAMS = $(noinst_PROGRAMS)
+am_test_compile_pedantic_OBJECTS =  \
+	test_compile_pedantic-test-compile-pedantic.$(OBJEXT)
+test_compile_pedantic_OBJECTS = $(am_test_compile_pedantic_OBJECTS)
+test_compile_pedantic_LDADD = $(LDADD)
+AM_V_lt = $(am__v_lt_@AM_V@)
+am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
+am__v_lt_0 = --silent
+am__v_lt_1 = 
+test_compile_pedantic_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \
+	$(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \
+	$(test_compile_pedantic_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
+	$(LDFLAGS) -o $@
+am__test_event_codes_SOURCES_DIST = test-main.c test-event-codes.c \
+	test-event-names.c test-context.c test-common-uinput.c \
+	test-common-uinput.h test-common.c test-common.h
+@ENABLE_RUNTIME_TESTS_TRUE@am__objects_1 =  \
+@ENABLE_RUNTIME_TESTS_TRUE@	test-common-uinput.$(OBJEXT) \
+@ENABLE_RUNTIME_TESTS_TRUE@	test-common.$(OBJEXT)
+@ENABLE_RUNTIME_TESTS_TRUE@am_test_event_codes_OBJECTS =  \
+@ENABLE_RUNTIME_TESTS_TRUE@	test-main.$(OBJEXT) \
+@ENABLE_RUNTIME_TESTS_TRUE@	test-event-codes.$(OBJEXT) \
+@ENABLE_RUNTIME_TESTS_TRUE@	test-event-names.$(OBJEXT) \
+@ENABLE_RUNTIME_TESTS_TRUE@	test-context.$(OBJEXT) \
+@ENABLE_RUNTIME_TESTS_TRUE@	$(am__objects_1)
+test_event_codes_OBJECTS = $(am_test_event_codes_OBJECTS)
+am__DEPENDENCIES_1 =
+@ENABLE_RUNTIME_TESTS_TRUE@test_event_codes_DEPENDENCIES =  \
+@ENABLE_RUNTIME_TESTS_TRUE@	$(am__DEPENDENCIES_1) \
+@ENABLE_RUNTIME_TESTS_TRUE@	$(top_builddir)/libevdev/libevdev.la
+test_event_codes_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \
+	$(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \
+	$(AM_CFLAGS) $(CFLAGS) $(test_event_codes_LDFLAGS) $(LDFLAGS) \
+	-o $@
+am__test_kernel_SOURCES_DIST = test-main.c test-kernel.c \
+	test-common-uinput.c test-common-uinput.h test-common.c \
+	test-common.h
+@ENABLE_RUNTIME_TESTS_TRUE@am__objects_2 = test_kernel-test-common-uinput.$(OBJEXT) \
+@ENABLE_RUNTIME_TESTS_TRUE@	test_kernel-test-common.$(OBJEXT)
+@ENABLE_RUNTIME_TESTS_TRUE@am_test_kernel_OBJECTS =  \
+@ENABLE_RUNTIME_TESTS_TRUE@	test_kernel-test-main.$(OBJEXT) \
+@ENABLE_RUNTIME_TESTS_TRUE@	test_kernel-test-kernel.$(OBJEXT) \
+@ENABLE_RUNTIME_TESTS_TRUE@	$(am__objects_2)
+test_kernel_OBJECTS = $(am_test_kernel_OBJECTS)
+@ENABLE_RUNTIME_TESTS_TRUE@test_kernel_DEPENDENCIES =  \
+@ENABLE_RUNTIME_TESTS_TRUE@	$(am__DEPENDENCIES_1) \
+@ENABLE_RUNTIME_TESTS_TRUE@	$(top_builddir)/libevdev/libevdev.la
+test_kernel_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+	$(LIBTOOLFLAGS) --mode=link $(CCLD) $(test_kernel_CFLAGS) \
+	$(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
+am__test_libevdev_SOURCES_DIST = test-main.c test-libevdev-init.c \
+	test-libevdev-has-event.c test-libevdev-events.c \
+	test-common-uinput.c test-common-uinput.h test-common.c \
+	test-common.h
+@ENABLE_RUNTIME_TESTS_TRUE@am_test_libevdev_OBJECTS =  \
+@ENABLE_RUNTIME_TESTS_TRUE@	test-main.$(OBJEXT) \
+@ENABLE_RUNTIME_TESTS_TRUE@	test-libevdev-init.$(OBJEXT) \
+@ENABLE_RUNTIME_TESTS_TRUE@	test-libevdev-has-event.$(OBJEXT) \
+@ENABLE_RUNTIME_TESTS_TRUE@	test-libevdev-events.$(OBJEXT) \
+@ENABLE_RUNTIME_TESTS_TRUE@	$(am__objects_1)
+test_libevdev_OBJECTS = $(am_test_libevdev_OBJECTS)
+@ENABLE_RUNTIME_TESTS_TRUE@test_libevdev_DEPENDENCIES =  \
+@ENABLE_RUNTIME_TESTS_TRUE@	$(am__DEPENDENCIES_1) \
+@ENABLE_RUNTIME_TESTS_TRUE@	$(top_builddir)/libevdev/libevdev.la
+test_libevdev_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+	$(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+	$(test_libevdev_LDFLAGS) $(LDFLAGS) -o $@
+am__test_libevdev_internals_SOURCES_DIST = test-main.c \
+	test-int-queue.c test-common-uinput.c test-common-uinput.h \
+	test-common.c test-common.h
+@ENABLE_RUNTIME_TESTS_TRUE@am_test_libevdev_internals_OBJECTS =  \
+@ENABLE_RUNTIME_TESTS_TRUE@	test-main.$(OBJEXT) \
+@ENABLE_RUNTIME_TESTS_TRUE@	test-int-queue.$(OBJEXT) \
+@ENABLE_RUNTIME_TESTS_TRUE@	$(am__objects_1)
+test_libevdev_internals_OBJECTS =  \
+	$(am_test_libevdev_internals_OBJECTS)
+@ENABLE_RUNTIME_TESTS_TRUE@test_libevdev_internals_DEPENDENCIES =  \
+@ENABLE_RUNTIME_TESTS_TRUE@	$(am__DEPENDENCIES_1) \
+@ENABLE_RUNTIME_TESTS_TRUE@	$(top_builddir)/libevdev/libevdev.la
+test_libevdev_internals_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \
+	$(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \
+	$(AM_CFLAGS) $(CFLAGS) $(test_libevdev_internals_LDFLAGS) \
+	$(LDFLAGS) -o $@
+am_test_link_OBJECTS = test_link-test-link.$(OBJEXT)
+test_link_OBJECTS = $(am_test_link_OBJECTS)
+test_link_DEPENDENCIES = $(top_builddir)/libevdev/libevdev.la
+test_link_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+	$(LIBTOOLFLAGS) --mode=link $(CCLD) $(test_link_CFLAGS) \
+	$(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
+am_test_static_link_OBJECTS = test_static_link-test-link.$(OBJEXT)
+test_static_link_OBJECTS = $(am_test_static_link_OBJECTS)
+test_static_link_DEPENDENCIES = $(top_builddir)/libevdev/libevdev.la
+test_static_link_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \
+	$(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \
+	$(test_static_link_CFLAGS) $(CFLAGS) \
+	$(test_static_link_LDFLAGS) $(LDFLAGS) -o $@
+am__test_uinput_SOURCES_DIST = test-main.c test-uinput.c \
+	test-common-uinput.c test-common-uinput.h test-common.c \
+	test-common.h
+@ENABLE_RUNTIME_TESTS_TRUE@am_test_uinput_OBJECTS =  \
+@ENABLE_RUNTIME_TESTS_TRUE@	test-main.$(OBJEXT) \
+@ENABLE_RUNTIME_TESTS_TRUE@	test-uinput.$(OBJEXT) \
+@ENABLE_RUNTIME_TESTS_TRUE@	$(am__objects_1)
+test_uinput_OBJECTS = $(am_test_uinput_OBJECTS)
+@ENABLE_RUNTIME_TESTS_TRUE@test_uinput_DEPENDENCIES =  \
+@ENABLE_RUNTIME_TESTS_TRUE@	$(am__DEPENDENCIES_1) \
+@ENABLE_RUNTIME_TESTS_TRUE@	$(top_builddir)/libevdev/libevdev.la
+test_uinput_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+	$(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+	$(test_uinput_LDFLAGS) $(LDFLAGS) -o $@
+AM_V_P = $(am__v_P_@AM_V@)
+am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_@AM_V@)
+am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
+am__v_GEN_0 = @echo "  GEN     " $@;
+am__v_GEN_1 = 
+AM_V_at = $(am__v_at_@AM_V@)
+am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 = 
+DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
+depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp
+am__maybe_remake_depfiles = depfiles
+am__depfiles_remade = ./$(DEPDIR)/test-common-uinput.Po \
+	./$(DEPDIR)/test-common.Po ./$(DEPDIR)/test-context.Po \
+	./$(DEPDIR)/test-event-codes.Po \
+	./$(DEPDIR)/test-event-names.Po ./$(DEPDIR)/test-int-queue.Po \
+	./$(DEPDIR)/test-libevdev-events.Po \
+	./$(DEPDIR)/test-libevdev-has-event.Po \
+	./$(DEPDIR)/test-libevdev-init.Po ./$(DEPDIR)/test-main.Po \
+	./$(DEPDIR)/test-uinput.Po \
+	./$(DEPDIR)/test_compile_pedantic-test-compile-pedantic.Po \
+	./$(DEPDIR)/test_kernel-test-common-uinput.Po \
+	./$(DEPDIR)/test_kernel-test-common.Po \
+	./$(DEPDIR)/test_kernel-test-kernel.Po \
+	./$(DEPDIR)/test_kernel-test-main.Po \
+	./$(DEPDIR)/test_link-test-link.Po \
+	./$(DEPDIR)/test_static_link-test-link.Po
+am__mv = mv -f
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+	$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+	$(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \
+	$(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
+	$(AM_CFLAGS) $(CFLAGS)
+AM_V_CC = $(am__v_CC_@AM_V@)
+am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@)
+am__v_CC_0 = @echo "  CC      " $@;
+am__v_CC_1 = 
+CCLD = $(CC)
+LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+	$(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+	$(AM_LDFLAGS) $(LDFLAGS) -o $@
+AM_V_CCLD = $(am__v_CCLD_@AM_V@)
+am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@)
+am__v_CCLD_0 = @echo "  CCLD    " $@;
+am__v_CCLD_1 = 
+SOURCES = $(test_compile_pedantic_SOURCES) $(test_event_codes_SOURCES) \
+	$(test_kernel_SOURCES) $(test_libevdev_SOURCES) \
+	$(test_libevdev_internals_SOURCES) $(test_link_SOURCES) \
+	$(test_static_link_SOURCES) $(test_uinput_SOURCES)
+DIST_SOURCES = $(test_compile_pedantic_SOURCES) \
+	$(am__test_event_codes_SOURCES_DIST) \
+	$(am__test_kernel_SOURCES_DIST) \
+	$(am__test_libevdev_SOURCES_DIST) \
+	$(am__test_libevdev_internals_SOURCES_DIST) \
+	$(test_link_SOURCES) $(test_static_link_SOURCES) \
+	$(am__test_uinput_SOURCES_DIST)
+am__can_run_installinfo = \
+  case $$AM_UPDATE_INFO_DIR in \
+    n|no|NO) false;; \
+    *) (install-info --version) >/dev/null 2>&1;; \
+  esac
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
+# Read a list of newline-separated strings from the standard input,
+# and print each of them once, without duplicates.  Input order is
+# *not* preserved.
+am__uniquify_input = $(AWK) '\
+  BEGIN { nonempty = 0; } \
+  { items[$$0] = 1; nonempty = 1; } \
+  END { if (nonempty) { for (i in items) print i; }; } \
+'
+# Make sure the list of sources is unique.  This is necessary because,
+# e.g., the same source file might be shared among _SOURCES variables
+# for different programs/libraries.
+am__define_uniq_tagged_files = \
+  list='$(am__tagged_files)'; \
+  unique=`for i in $$list; do \
+    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+  done | $(am__uniquify_input)`
+am__tty_colors_dummy = \
+  mgn= red= grn= lgn= blu= brg= std=; \
+  am__color_tests=no
+am__tty_colors = { \
+  $(am__tty_colors_dummy); \
+  if test "X$(AM_COLOR_TESTS)" = Xno; then \
+    am__color_tests=no; \
+  elif test "X$(AM_COLOR_TESTS)" = Xalways; then \
+    am__color_tests=yes; \
+  elif test "X$$TERM" != Xdumb && { test -t 1; } 2>/dev/null; then \
+    am__color_tests=yes; \
+  fi; \
+  if test $$am__color_tests = yes; then \
+    red=''; \
+    grn=''; \
+    lgn=''; \
+    blu=''; \
+    mgn=''; \
+    brg=''; \
+    std=''; \
+  fi; \
+}
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+    $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+    *) f=$$p;; \
+  esac;
+am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
+am__install_max = 40
+am__nobase_strip_setup = \
+  srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
+am__nobase_strip = \
+  for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
+am__nobase_list = $(am__nobase_strip_setup); \
+  for p in $$list; do echo "$$p $$p"; done | \
+  sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
+  $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
+    if (++n[$$2] == $(am__install_max)) \
+      { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
+    END { for (dir in files) print dir, files[dir] }'
+am__base_list = \
+  sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
+  sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
+am__uninstall_files_from_dir = { \
+  test -z "$$files" \
+    || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
+    || { echo " ( cd '$$dir' && rm -f" $$files ")"; \
+         $(am__cd) "$$dir" && rm -f $$files; }; \
+  }
+am__recheck_rx = ^[ 	]*:recheck:[ 	]*
+am__global_test_result_rx = ^[ 	]*:global-test-result:[ 	]*
+am__copy_in_global_log_rx = ^[ 	]*:copy-in-global-log:[ 	]*
+# A command that, given a newline-separated list of test names on the
+# standard input, print the name of the tests that are to be re-run
+# upon "make recheck".
+am__list_recheck_tests = $(AWK) '{ \
+  recheck = 1; \
+  while ((rc = (getline line < ($$0 ".trs"))) != 0) \
+    { \
+      if (rc < 0) \
+        { \
+          if ((getline line2 < ($$0 ".log")) < 0) \
+	    recheck = 0; \
+          break; \
+        } \
+      else if (line ~ /$(am__recheck_rx)[nN][Oo]/) \
+        { \
+          recheck = 0; \
+          break; \
+        } \
+      else if (line ~ /$(am__recheck_rx)[yY][eE][sS]/) \
+        { \
+          break; \
+        } \
+    }; \
+  if (recheck) \
+    print $$0; \
+  close ($$0 ".trs"); \
+  close ($$0 ".log"); \
+}'
+# A command that, given a newline-separated list of test names on the
+# standard input, create the global log from their .trs and .log files.
+am__create_global_log = $(AWK) ' \
+function fatal(msg) \
+{ \
+  print "fatal: making $@: " msg | "cat >&2"; \
+  exit 1; \
+} \
+function rst_section(header) \
+{ \
+  print header; \
+  len = length(header); \
+  for (i = 1; i <= len; i = i + 1) \
+    printf "="; \
+  printf "\n\n"; \
+} \
+{ \
+  copy_in_global_log = 1; \
+  global_test_result = "RUN"; \
+  while ((rc = (getline line < ($$0 ".trs"))) != 0) \
+    { \
+      if (rc < 0) \
+         fatal("failed to read from " $$0 ".trs"); \
+      if (line ~ /$(am__global_test_result_rx)/) \
+        { \
+          sub("$(am__global_test_result_rx)", "", line); \
+          sub("[ 	]*$$", "", line); \
+          global_test_result = line; \
+        } \
+      else if (line ~ /$(am__copy_in_global_log_rx)[nN][oO]/) \
+        copy_in_global_log = 0; \
+    }; \
+  if (copy_in_global_log) \
+    { \
+      rst_section(global_test_result ": " $$0); \
+      while ((rc = (getline line < ($$0 ".log"))) != 0) \
+      { \
+        if (rc < 0) \
+          fatal("failed to read from " $$0 ".log"); \
+        print line; \
+      }; \
+      printf "\n"; \
+    }; \
+  close ($$0 ".trs"); \
+  close ($$0 ".log"); \
+}'
+# Restructured Text title.
+am__rst_title = { sed 's/.*/   &   /;h;s/./=/g;p;x;s/ *$$//;p;g' && echo; }
+# Solaris 10 'make', and several other traditional 'make' implementations,
+# pass "-e" to $(SHELL), and POSIX 2008 even requires this.  Work around it
+# by disabling -e (using the XSI extension "set +e") if it's set.
+am__sh_e_setup = case $$- in *e*) set +e;; esac
+# Default flags passed to test drivers.
+am__common_driver_flags = \
+  --color-tests "$$am__color_tests" \
+  --enable-hard-errors "$$am__enable_hard_errors" \
+  --expect-failure "$$am__expect_failure"
+# To be inserted before the command running the test.  Creates the
+# directory for the log if needed.  Stores in $dir the directory
+# containing $f, in $tst the test, in $log the log.  Executes the
+# developer- defined test setup AM_TESTS_ENVIRONMENT (if any), and
+# passes TESTS_ENVIRONMENT.  Set up options for the wrapper that
+# will run the test scripts (or their associated LOG_COMPILER, if
+# thy have one).
+am__check_pre = \
+$(am__sh_e_setup);					\
+$(am__vpath_adj_setup) $(am__vpath_adj)			\
+$(am__tty_colors);					\
+srcdir=$(srcdir); export srcdir;			\
+case "$@" in						\
+  */*) am__odir=`echo "./$@" | sed 's|/[^/]*$$||'`;;	\
+    *) am__odir=.;; 					\
+esac;							\
+test "x$$am__odir" = x"." || test -d "$$am__odir" 	\
+  || $(MKDIR_P) "$$am__odir" || exit $$?;		\
+if test -f "./$$f"; then dir=./;			\
+elif test -f "$$f"; then dir=;				\
+else dir="$(srcdir)/"; fi;				\
+tst=$$dir$$f; log='$@'; 				\
+if test -n '$(DISABLE_HARD_ERRORS)'; then		\
+  am__enable_hard_errors=no; 				\
+else							\
+  am__enable_hard_errors=yes; 				\
+fi; 							\
+case " $(XFAIL_TESTS) " in				\
+  *[\ \	]$$f[\ \	]* | *[\ \	]$$dir$$f[\ \	]*) \
+    am__expect_failure=yes;;				\
+  *)							\
+    am__expect_failure=no;;				\
+esac; 							\
+$(AM_TESTS_ENVIRONMENT) $(TESTS_ENVIRONMENT)
+# A shell command to get the names of the tests scripts with any registered
+# extension removed (i.e., equivalently, the names of the test logs, with
+# the '.log' extension removed).  The result is saved in the shell variable
+# '$bases'.  This honors runtime overriding of TESTS and TEST_LOGS.  Sadly,
+# we cannot use something simpler, involving e.g., "$(TEST_LOGS:.log=)",
+# since that might cause problem with VPATH rewrites for suffix-less tests.
+# See also 'test-harness-vpath-rewrite.sh' and 'test-trs-basic.sh'.
+am__set_TESTS_bases = \
+  bases='$(TEST_LOGS)'; \
+  bases=`for i in $$bases; do echo $$i; done | sed 's/\.log$$//'`; \
+  bases=`echo $$bases`
+AM_TESTSUITE_SUMMARY_HEADER = ' for $(PACKAGE_STRING)'
+RECHECK_LOGS = $(TEST_LOGS)
+AM_RECURSIVE_TARGETS = check recheck
+TEST_SUITE_LOG = test-suite.log
+TEST_EXTENSIONS = @EXEEXT@ .test
+LOG_DRIVER = $(SHELL) $(top_srcdir)/build-aux/test-driver
+LOG_COMPILE = $(LOG_COMPILER) $(AM_LOG_FLAGS) $(LOG_FLAGS)
+am__set_b = \
+  case '$@' in \
+    */*) \
+      case '$*' in \
+        */*) b='$*';; \
+          *) b=`echo '$@' | sed 's/\.log$$//'`; \
+       esac;; \
+    *) \
+      b='$*';; \
+  esac
+am__test_logs1 = $(TESTS:=.log)
+am__test_logs2 = $(am__test_logs1:@EXEEXT@.log=.log)
+TEST_LOGS = $(am__test_logs2:.test.log=.log)
+TEST_LOG_DRIVER = $(SHELL) $(top_srcdir)/build-aux/test-driver
+TEST_LOG_COMPILE = $(TEST_LOG_COMPILER) $(AM_TEST_LOG_FLAGS) \
+	$(TEST_LOG_FLAGS)
+am__DIST_COMMON = $(srcdir)/Makefile.in \
+	$(top_srcdir)/build-aux/depcomp \
+	$(top_srcdir)/build-aux/test-driver
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CHECK_CFLAGS = @CHECK_CFLAGS@
+CHECK_LIBS = @CHECK_LIBS@
+CPPFLAGS = @CPPFLAGS@
+CSCOPE = @CSCOPE@
+CTAGS = @CTAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLTOOL = @DLLTOOL@
+DOXYGEN = @DOXYGEN@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+ETAGS = @ETAGS@
+EXEEXT = @EXEEXT@
+FGREP = @FGREP@
+GCC_CFLAGS = @GCC_CFLAGS@
+GCOV_CFLAGS = @GCOV_CFLAGS@
+GCOV_LDFLAGS = @GCOV_LDFLAGS@
+GNU_LD_FLAGS = @GNU_LD_FLAGS@
+GREP = @GREP@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LIBEVDEV_LT_VERSION = @LIBEVDEV_LT_VERSION@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
+MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MKDIR_P = @MKDIR_P@
+NM = @NM@
+NMEDIT = @NMEDIT@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OS = @OS@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PKG_CONFIG = @PKG_CONFIG@
+PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
+PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
+PYTHON = @PYTHON@
+PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
+PYTHON_PLATFORM = @PYTHON_PLATFORM@
+PYTHON_PREFIX = @PYTHON_PREFIX@
+PYTHON_VERSION = @PYTHON_VERSION@
+RANLIB = @RANLIB@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+VALGRIND = @VALGRIND@
+VERSION = @VERSION@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+pkgpyexecdir = @pkgpyexecdir@
+pkgpythondir = @pkgpythondir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+pyexecdir = @pyexecdir@
+pythondir = @pythondir@
+runstatedir = @runstatedir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+build_tests = test-compile-pedantic test-link $(am__append_1)
+AM_CPPFLAGS = -I$(top_srcdir) -I$(top_srcdir)/include \
+	-I$(top_builddir)/libevdev $(am__append_3)
+AM_LDFLAGS = $(am__append_4)
+test_compile_pedantic_SOURCES = test-compile-pedantic.c
+test_compile_pedantic_CFLAGS = $(AM_CPPFLAGS) -pedantic -Werror -std=c89
+test_link_SOURCES = test-link.c
+test_link_CFLAGS = -I$(top_srcdir)
+test_link_LDADD = $(top_builddir)/libevdev/libevdev.la
+test_static_link_SOURCES = test-link.c
+test_static_link_CFLAGS = -I$(top_srcdir)
+test_static_link_LDADD = $(top_builddir)/libevdev/libevdev.la
+test_static_link_LDFLAGS = $(AM_LDFLAGS) -static
+check_local_deps = $(am__append_5) $(am__append_6) $(am__append_7)
+@ENABLE_RUNTIME_TESTS_TRUE@run_tests = \
+@ENABLE_RUNTIME_TESTS_TRUE@	    test-libevdev \
+@ENABLE_RUNTIME_TESTS_TRUE@	    test-kernel \
+@ENABLE_RUNTIME_TESTS_TRUE@	    test-uinput \
+@ENABLE_RUNTIME_TESTS_TRUE@	    test-event-codes \
+@ENABLE_RUNTIME_TESTS_TRUE@	    test-libevdev-internals \
+@ENABLE_RUNTIME_TESTS_TRUE@	    $(NULL)
+
+@ENABLE_RUNTIME_TESTS_TRUE@common_sources = \
+@ENABLE_RUNTIME_TESTS_TRUE@		 test-common-uinput.c \
+@ENABLE_RUNTIME_TESTS_TRUE@		 test-common-uinput.h \
+@ENABLE_RUNTIME_TESTS_TRUE@		 test-common.c \
+@ENABLE_RUNTIME_TESTS_TRUE@		 test-common.h
+
+@ENABLE_RUNTIME_TESTS_TRUE@test_event_codes_SOURCES = \
+@ENABLE_RUNTIME_TESTS_TRUE@			test-main.c \
+@ENABLE_RUNTIME_TESTS_TRUE@			test-event-codes.c \
+@ENABLE_RUNTIME_TESTS_TRUE@			test-event-names.c \
+@ENABLE_RUNTIME_TESTS_TRUE@			test-context.c \
+@ENABLE_RUNTIME_TESTS_TRUE@			$(common_sources)
+
+@ENABLE_RUNTIME_TESTS_TRUE@test_event_codes_LDADD = $(CHECK_LIBS) $(top_builddir)/libevdev/libevdev.la
+@ENABLE_RUNTIME_TESTS_TRUE@test_event_codes_LDFLAGS = -no-install
+@ENABLE_RUNTIME_TESTS_TRUE@test_libevdev_internals_SOURCES = \
+@ENABLE_RUNTIME_TESTS_TRUE@			test-main.c \
+@ENABLE_RUNTIME_TESTS_TRUE@			test-int-queue.c \
+@ENABLE_RUNTIME_TESTS_TRUE@			$(common_sources)
+
+@ENABLE_RUNTIME_TESTS_TRUE@test_libevdev_internals_LDADD = $(CHECK_LIBS) $(top_builddir)/libevdev/libevdev.la
+@ENABLE_RUNTIME_TESTS_TRUE@test_libevdev_internals_LDFLAGS = -no-install
+@ENABLE_RUNTIME_TESTS_TRUE@test_uinput_SOURCES = \
+@ENABLE_RUNTIME_TESTS_TRUE@			test-main.c \
+@ENABLE_RUNTIME_TESTS_TRUE@			test-uinput.c \
+@ENABLE_RUNTIME_TESTS_TRUE@			$(common_sources)
+
+@ENABLE_RUNTIME_TESTS_TRUE@test_uinput_LDADD = $(CHECK_LIBS) $(top_builddir)/libevdev/libevdev.la
+@ENABLE_RUNTIME_TESTS_TRUE@test_uinput_LDFLAGS = -no-install
+@ENABLE_RUNTIME_TESTS_TRUE@test_libevdev_SOURCES = \
+@ENABLE_RUNTIME_TESTS_TRUE@			test-main.c \
+@ENABLE_RUNTIME_TESTS_TRUE@			test-libevdev-init.c \
+@ENABLE_RUNTIME_TESTS_TRUE@			test-libevdev-has-event.c \
+@ENABLE_RUNTIME_TESTS_TRUE@			test-libevdev-events.c \
+@ENABLE_RUNTIME_TESTS_TRUE@			$(common_sources)
+
+@ENABLE_RUNTIME_TESTS_TRUE@test_libevdev_LDADD = $(CHECK_LIBS) $(top_builddir)/libevdev/libevdev.la
+@ENABLE_RUNTIME_TESTS_TRUE@test_libevdev_LDFLAGS = -no-install
+@ENABLE_RUNTIME_TESTS_TRUE@test_kernel_SOURCES = \
+@ENABLE_RUNTIME_TESTS_TRUE@		      test-main.c \
+@ENABLE_RUNTIME_TESTS_TRUE@		      test-kernel.c \
+@ENABLE_RUNTIME_TESTS_TRUE@		      $(common_sources)
+
+@ENABLE_RUNTIME_TESTS_TRUE@test_kernel_CFLAGS = -I$(top_srcdir)
+@ENABLE_RUNTIME_TESTS_TRUE@test_kernel_LDADD = $(CHECK_LIBS) $(top_builddir)/libevdev/libevdev.la
+@ENABLE_RUNTIME_TESTS_TRUE@@HAVE_VALGRIND_TRUE@VALGRIND_FLAGS = --leak-check=full \
+@ENABLE_RUNTIME_TESTS_TRUE@@HAVE_VALGRIND_TRUE@		--quiet \
+@ENABLE_RUNTIME_TESTS_TRUE@@HAVE_VALGRIND_TRUE@		--error-exitcode=3 \
+@ENABLE_RUNTIME_TESTS_TRUE@@HAVE_VALGRIND_TRUE@		--suppressions=$(srcdir)/valgrind.suppressions
+
+@ENABLE_RUNTIME_TESTS_TRUE@@GCOV_ENABLED_TRUE@CLEANFILES = gcov-reports/*.gcov gcov-reports/summary.txt *.gcno *.gcda
+EXTRA_DIST = valgrind.suppressions  generate-gcov-report.sh test-static-symbols-leak.sh
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .lo .log .o .obj .test .test$(EXEEXT) .trs
+$(srcdir)/Makefile.in:  $(srcdir)/Makefile.am  $(am__configure_deps)
+	@for dep in $?; do \
+	  case '$(am__configure_deps)' in \
+	    *$$dep*) \
+	      ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+	        && { if test -f $@; then exit 0; else break; fi; }; \
+	      exit 1;; \
+	  esac; \
+	done; \
+	echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign test/Makefile'; \
+	$(am__cd) $(top_srcdir) && \
+	  $(AUTOMAKE) --foreign test/Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+	@case '$?' in \
+	  *config.status*) \
+	    cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+	  *) \
+	    echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \
+	    cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \
+	esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure:  $(am__configure_deps)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4):  $(am__aclocal_m4_deps)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+
+clean-noinstPROGRAMS:
+	@list='$(noinst_PROGRAMS)'; test -n "$$list" || exit 0; \
+	echo " rm -f" $$list; \
+	rm -f $$list || exit $$?; \
+	test -n "$(EXEEXT)" || exit 0; \
+	list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \
+	echo " rm -f" $$list; \
+	rm -f $$list
+
+test-compile-pedantic$(EXEEXT): $(test_compile_pedantic_OBJECTS) $(test_compile_pedantic_DEPENDENCIES) $(EXTRA_test_compile_pedantic_DEPENDENCIES) 
+	@rm -f test-compile-pedantic$(EXEEXT)
+	$(AM_V_CCLD)$(test_compile_pedantic_LINK) $(test_compile_pedantic_OBJECTS) $(test_compile_pedantic_LDADD) $(LIBS)
+
+test-event-codes$(EXEEXT): $(test_event_codes_OBJECTS) $(test_event_codes_DEPENDENCIES) $(EXTRA_test_event_codes_DEPENDENCIES) 
+	@rm -f test-event-codes$(EXEEXT)
+	$(AM_V_CCLD)$(test_event_codes_LINK) $(test_event_codes_OBJECTS) $(test_event_codes_LDADD) $(LIBS)
+
+test-kernel$(EXEEXT): $(test_kernel_OBJECTS) $(test_kernel_DEPENDENCIES) $(EXTRA_test_kernel_DEPENDENCIES) 
+	@rm -f test-kernel$(EXEEXT)
+	$(AM_V_CCLD)$(test_kernel_LINK) $(test_kernel_OBJECTS) $(test_kernel_LDADD) $(LIBS)
+
+test-libevdev$(EXEEXT): $(test_libevdev_OBJECTS) $(test_libevdev_DEPENDENCIES) $(EXTRA_test_libevdev_DEPENDENCIES) 
+	@rm -f test-libevdev$(EXEEXT)
+	$(AM_V_CCLD)$(test_libevdev_LINK) $(test_libevdev_OBJECTS) $(test_libevdev_LDADD) $(LIBS)
+
+test-libevdev-internals$(EXEEXT): $(test_libevdev_internals_OBJECTS) $(test_libevdev_internals_DEPENDENCIES) $(EXTRA_test_libevdev_internals_DEPENDENCIES) 
+	@rm -f test-libevdev-internals$(EXEEXT)
+	$(AM_V_CCLD)$(test_libevdev_internals_LINK) $(test_libevdev_internals_OBJECTS) $(test_libevdev_internals_LDADD) $(LIBS)
+
+test-link$(EXEEXT): $(test_link_OBJECTS) $(test_link_DEPENDENCIES) $(EXTRA_test_link_DEPENDENCIES) 
+	@rm -f test-link$(EXEEXT)
+	$(AM_V_CCLD)$(test_link_LINK) $(test_link_OBJECTS) $(test_link_LDADD) $(LIBS)
+
+test-static-link$(EXEEXT): $(test_static_link_OBJECTS) $(test_static_link_DEPENDENCIES) $(EXTRA_test_static_link_DEPENDENCIES) 
+	@rm -f test-static-link$(EXEEXT)
+	$(AM_V_CCLD)$(test_static_link_LINK) $(test_static_link_OBJECTS) $(test_static_link_LDADD) $(LIBS)
+
+test-uinput$(EXEEXT): $(test_uinput_OBJECTS) $(test_uinput_DEPENDENCIES) $(EXTRA_test_uinput_DEPENDENCIES) 
+	@rm -f test-uinput$(EXEEXT)
+	$(AM_V_CCLD)$(test_uinput_LINK) $(test_uinput_OBJECTS) $(test_uinput_LDADD) $(LIBS)
+
+mostlyclean-compile:
+	-rm -f *.$(OBJEXT)
+
+distclean-compile:
+	-rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-common-uinput.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-common.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-context.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-event-codes.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-event-names.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-int-queue.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-libevdev-events.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-libevdev-has-event.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-libevdev-init.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-main.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-uinput.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_compile_pedantic-test-compile-pedantic.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_kernel-test-common-uinput.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_kernel-test-common.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_kernel-test-kernel.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_kernel-test-main.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_link-test-link.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_static_link-test-link.Po@am__quote@ # am--include-marker
+
+$(am__depfiles_remade):
+	@$(MKDIR_P) $(@D)
+	@echo '# dummy' >$@-t && $(am__mv) $@-t $@
+
+am--depfiles: $(am__depfiles_remade)
+
+.c.o:
+@am__fastdepCC_TRUE@	$(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\
+@am__fastdepCC_TRUE@	$(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
+@am__fastdepCC_TRUE@	$(am__mv) $$depbase.Tpo $$depbase.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $<
+
+.c.obj:
+@am__fastdepCC_TRUE@	$(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\
+@am__fastdepCC_TRUE@	$(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\
+@am__fastdepCC_TRUE@	$(am__mv) $$depbase.Tpo $$depbase.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
+
+.c.lo:
+@am__fastdepCC_TRUE@	$(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\
+@am__fastdepCC_TRUE@	$(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
+@am__fastdepCC_TRUE@	$(am__mv) $$depbase.Tpo $$depbase.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $<
+
+test_compile_pedantic-test-compile-pedantic.o: test-compile-pedantic.c
+@am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_compile_pedantic_CFLAGS) $(CFLAGS) -MT test_compile_pedantic-test-compile-pedantic.o -MD -MP -MF $(DEPDIR)/test_compile_pedantic-test-compile-pedantic.Tpo -c -o test_compile_pedantic-test-compile-pedantic.o `test -f 'test-compile-pedantic.c' || echo '$(srcdir)/'`test-compile-pedantic.c
+@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/test_compile_pedantic-test-compile-pedantic.Tpo $(DEPDIR)/test_compile_pedantic-test-compile-pedantic.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='test-compile-pedantic.c' object='test_compile_pedantic-test-compile-pedantic.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_compile_pedantic_CFLAGS) $(CFLAGS) -c -o test_compile_pedantic-test-compile-pedantic.o `test -f 'test-compile-pedantic.c' || echo '$(srcdir)/'`test-compile-pedantic.c
+
+test_compile_pedantic-test-compile-pedantic.obj: test-compile-pedantic.c
+@am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_compile_pedantic_CFLAGS) $(CFLAGS) -MT test_compile_pedantic-test-compile-pedantic.obj -MD -MP -MF $(DEPDIR)/test_compile_pedantic-test-compile-pedantic.Tpo -c -o test_compile_pedantic-test-compile-pedantic.obj `if test -f 'test-compile-pedantic.c'; then $(CYGPATH_W) 'test-compile-pedantic.c'; else $(CYGPATH_W) '$(srcdir)/test-compile-pedantic.c'; fi`
+@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/test_compile_pedantic-test-compile-pedantic.Tpo $(DEPDIR)/test_compile_pedantic-test-compile-pedantic.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='test-compile-pedantic.c' object='test_compile_pedantic-test-compile-pedantic.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_compile_pedantic_CFLAGS) $(CFLAGS) -c -o test_compile_pedantic-test-compile-pedantic.obj `if test -f 'test-compile-pedantic.c'; then $(CYGPATH_W) 'test-compile-pedantic.c'; else $(CYGPATH_W) '$(srcdir)/test-compile-pedantic.c'; fi`
+
+test_kernel-test-main.o: test-main.c
+@am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_kernel_CFLAGS) $(CFLAGS) -MT test_kernel-test-main.o -MD -MP -MF $(DEPDIR)/test_kernel-test-main.Tpo -c -o test_kernel-test-main.o `test -f 'test-main.c' || echo '$(srcdir)/'`test-main.c
+@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/test_kernel-test-main.Tpo $(DEPDIR)/test_kernel-test-main.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='test-main.c' object='test_kernel-test-main.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_kernel_CFLAGS) $(CFLAGS) -c -o test_kernel-test-main.o `test -f 'test-main.c' || echo '$(srcdir)/'`test-main.c
+
+test_kernel-test-main.obj: test-main.c
+@am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_kernel_CFLAGS) $(CFLAGS) -MT test_kernel-test-main.obj -MD -MP -MF $(DEPDIR)/test_kernel-test-main.Tpo -c -o test_kernel-test-main.obj `if test -f 'test-main.c'; then $(CYGPATH_W) 'test-main.c'; else $(CYGPATH_W) '$(srcdir)/test-main.c'; fi`
+@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/test_kernel-test-main.Tpo $(DEPDIR)/test_kernel-test-main.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='test-main.c' object='test_kernel-test-main.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_kernel_CFLAGS) $(CFLAGS) -c -o test_kernel-test-main.obj `if test -f 'test-main.c'; then $(CYGPATH_W) 'test-main.c'; else $(CYGPATH_W) '$(srcdir)/test-main.c'; fi`
+
+test_kernel-test-kernel.o: test-kernel.c
+@am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_kernel_CFLAGS) $(CFLAGS) -MT test_kernel-test-kernel.o -MD -MP -MF $(DEPDIR)/test_kernel-test-kernel.Tpo -c -o test_kernel-test-kernel.o `test -f 'test-kernel.c' || echo '$(srcdir)/'`test-kernel.c
+@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/test_kernel-test-kernel.Tpo $(DEPDIR)/test_kernel-test-kernel.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='test-kernel.c' object='test_kernel-test-kernel.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_kernel_CFLAGS) $(CFLAGS) -c -o test_kernel-test-kernel.o `test -f 'test-kernel.c' || echo '$(srcdir)/'`test-kernel.c
+
+test_kernel-test-kernel.obj: test-kernel.c
+@am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_kernel_CFLAGS) $(CFLAGS) -MT test_kernel-test-kernel.obj -MD -MP -MF $(DEPDIR)/test_kernel-test-kernel.Tpo -c -o test_kernel-test-kernel.obj `if test -f 'test-kernel.c'; then $(CYGPATH_W) 'test-kernel.c'; else $(CYGPATH_W) '$(srcdir)/test-kernel.c'; fi`
+@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/test_kernel-test-kernel.Tpo $(DEPDIR)/test_kernel-test-kernel.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='test-kernel.c' object='test_kernel-test-kernel.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_kernel_CFLAGS) $(CFLAGS) -c -o test_kernel-test-kernel.obj `if test -f 'test-kernel.c'; then $(CYGPATH_W) 'test-kernel.c'; else $(CYGPATH_W) '$(srcdir)/test-kernel.c'; fi`
+
+test_kernel-test-common-uinput.o: test-common-uinput.c
+@am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_kernel_CFLAGS) $(CFLAGS) -MT test_kernel-test-common-uinput.o -MD -MP -MF $(DEPDIR)/test_kernel-test-common-uinput.Tpo -c -o test_kernel-test-common-uinput.o `test -f 'test-common-uinput.c' || echo '$(srcdir)/'`test-common-uinput.c
+@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/test_kernel-test-common-uinput.Tpo $(DEPDIR)/test_kernel-test-common-uinput.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='test-common-uinput.c' object='test_kernel-test-common-uinput.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_kernel_CFLAGS) $(CFLAGS) -c -o test_kernel-test-common-uinput.o `test -f 'test-common-uinput.c' || echo '$(srcdir)/'`test-common-uinput.c
+
+test_kernel-test-common-uinput.obj: test-common-uinput.c
+@am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_kernel_CFLAGS) $(CFLAGS) -MT test_kernel-test-common-uinput.obj -MD -MP -MF $(DEPDIR)/test_kernel-test-common-uinput.Tpo -c -o test_kernel-test-common-uinput.obj `if test -f 'test-common-uinput.c'; then $(CYGPATH_W) 'test-common-uinput.c'; else $(CYGPATH_W) '$(srcdir)/test-common-uinput.c'; fi`
+@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/test_kernel-test-common-uinput.Tpo $(DEPDIR)/test_kernel-test-common-uinput.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='test-common-uinput.c' object='test_kernel-test-common-uinput.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_kernel_CFLAGS) $(CFLAGS) -c -o test_kernel-test-common-uinput.obj `if test -f 'test-common-uinput.c'; then $(CYGPATH_W) 'test-common-uinput.c'; else $(CYGPATH_W) '$(srcdir)/test-common-uinput.c'; fi`
+
+test_kernel-test-common.o: test-common.c
+@am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_kernel_CFLAGS) $(CFLAGS) -MT test_kernel-test-common.o -MD -MP -MF $(DEPDIR)/test_kernel-test-common.Tpo -c -o test_kernel-test-common.o `test -f 'test-common.c' || echo '$(srcdir)/'`test-common.c
+@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/test_kernel-test-common.Tpo $(DEPDIR)/test_kernel-test-common.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='test-common.c' object='test_kernel-test-common.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_kernel_CFLAGS) $(CFLAGS) -c -o test_kernel-test-common.o `test -f 'test-common.c' || echo '$(srcdir)/'`test-common.c
+
+test_kernel-test-common.obj: test-common.c
+@am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_kernel_CFLAGS) $(CFLAGS) -MT test_kernel-test-common.obj -MD -MP -MF $(DEPDIR)/test_kernel-test-common.Tpo -c -o test_kernel-test-common.obj `if test -f 'test-common.c'; then $(CYGPATH_W) 'test-common.c'; else $(CYGPATH_W) '$(srcdir)/test-common.c'; fi`
+@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/test_kernel-test-common.Tpo $(DEPDIR)/test_kernel-test-common.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='test-common.c' object='test_kernel-test-common.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_kernel_CFLAGS) $(CFLAGS) -c -o test_kernel-test-common.obj `if test -f 'test-common.c'; then $(CYGPATH_W) 'test-common.c'; else $(CYGPATH_W) '$(srcdir)/test-common.c'; fi`
+
+test_link-test-link.o: test-link.c
+@am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_link_CFLAGS) $(CFLAGS) -MT test_link-test-link.o -MD -MP -MF $(DEPDIR)/test_link-test-link.Tpo -c -o test_link-test-link.o `test -f 'test-link.c' || echo '$(srcdir)/'`test-link.c
+@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/test_link-test-link.Tpo $(DEPDIR)/test_link-test-link.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='test-link.c' object='test_link-test-link.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_link_CFLAGS) $(CFLAGS) -c -o test_link-test-link.o `test -f 'test-link.c' || echo '$(srcdir)/'`test-link.c
+
+test_link-test-link.obj: test-link.c
+@am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_link_CFLAGS) $(CFLAGS) -MT test_link-test-link.obj -MD -MP -MF $(DEPDIR)/test_link-test-link.Tpo -c -o test_link-test-link.obj `if test -f 'test-link.c'; then $(CYGPATH_W) 'test-link.c'; else $(CYGPATH_W) '$(srcdir)/test-link.c'; fi`
+@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/test_link-test-link.Tpo $(DEPDIR)/test_link-test-link.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='test-link.c' object='test_link-test-link.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_link_CFLAGS) $(CFLAGS) -c -o test_link-test-link.obj `if test -f 'test-link.c'; then $(CYGPATH_W) 'test-link.c'; else $(CYGPATH_W) '$(srcdir)/test-link.c'; fi`
+
+test_static_link-test-link.o: test-link.c
+@am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_static_link_CFLAGS) $(CFLAGS) -MT test_static_link-test-link.o -MD -MP -MF $(DEPDIR)/test_static_link-test-link.Tpo -c -o test_static_link-test-link.o `test -f 'test-link.c' || echo '$(srcdir)/'`test-link.c
+@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/test_static_link-test-link.Tpo $(DEPDIR)/test_static_link-test-link.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='test-link.c' object='test_static_link-test-link.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_static_link_CFLAGS) $(CFLAGS) -c -o test_static_link-test-link.o `test -f 'test-link.c' || echo '$(srcdir)/'`test-link.c
+
+test_static_link-test-link.obj: test-link.c
+@am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_static_link_CFLAGS) $(CFLAGS) -MT test_static_link-test-link.obj -MD -MP -MF $(DEPDIR)/test_static_link-test-link.Tpo -c -o test_static_link-test-link.obj `if test -f 'test-link.c'; then $(CYGPATH_W) 'test-link.c'; else $(CYGPATH_W) '$(srcdir)/test-link.c'; fi`
+@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/test_static_link-test-link.Tpo $(DEPDIR)/test_static_link-test-link.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='test-link.c' object='test_static_link-test-link.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_static_link_CFLAGS) $(CFLAGS) -c -o test_static_link-test-link.obj `if test -f 'test-link.c'; then $(CYGPATH_W) 'test-link.c'; else $(CYGPATH_W) '$(srcdir)/test-link.c'; fi`
+
+mostlyclean-libtool:
+	-rm -f *.lo
+
+clean-libtool:
+	-rm -rf .libs _libs
+
+ID: $(am__tagged_files)
+	$(am__define_uniq_tagged_files); mkid -fID $$unique
+tags: tags-am
+TAGS: tags
+
+tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+	set x; \
+	here=`pwd`; \
+	$(am__define_uniq_tagged_files); \
+	shift; \
+	if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+	  test -n "$$unique" || unique=$$empty_fix; \
+	  if test $$# -gt 0; then \
+	    $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+	      "$$@" $$unique; \
+	  else \
+	    $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+	      $$unique; \
+	  fi; \
+	fi
+ctags: ctags-am
+
+CTAGS: ctags
+ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+	$(am__define_uniq_tagged_files); \
+	test -z "$(CTAGS_ARGS)$$unique" \
+	  || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+	     $$unique
+
+GTAGS:
+	here=`$(am__cd) $(top_builddir) && pwd` \
+	  && $(am__cd) $(top_srcdir) \
+	  && gtags -i $(GTAGS_ARGS) "$$here"
+cscopelist: cscopelist-am
+
+cscopelist-am: $(am__tagged_files)
+	list='$(am__tagged_files)'; \
+	case "$(srcdir)" in \
+	  [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
+	  *) sdir=$(subdir)/$(srcdir) ;; \
+	esac; \
+	for i in $$list; do \
+	  if test -f "$$i"; then \
+	    echo "$(subdir)/$$i"; \
+	  else \
+	    echo "$$sdir/$$i"; \
+	  fi; \
+	done >> $(top_builddir)/cscope.files
+
+distclean-tags:
+	-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+# Recover from deleted '.trs' file; this should ensure that
+# "rm -f foo.log; make foo.trs" re-run 'foo.test', and re-create
+# both 'foo.log' and 'foo.trs'.  Break the recipe in two subshells
+# to avoid problems with "make -n".
+.log.trs:
+	rm -f $< $@
+	$(MAKE) $(AM_MAKEFLAGS) $<
+
+# Leading 'am--fnord' is there to ensure the list of targets does not
+# expand to empty, as could happen e.g. with make check TESTS=''.
+am--fnord $(TEST_LOGS) $(TEST_LOGS:.log=.trs): $(am__force_recheck)
+am--force-recheck:
+	@:
+
+$(TEST_SUITE_LOG): $(TEST_LOGS)
+	@$(am__set_TESTS_bases); \
+	am__f_ok () { test -f "$$1" && test -r "$$1"; }; \
+	redo_bases=`for i in $$bases; do \
+	              am__f_ok $$i.trs && am__f_ok $$i.log || echo $$i; \
+	            done`; \
+	if test -n "$$redo_bases"; then \
+	  redo_logs=`for i in $$redo_bases; do echo $$i.log; done`; \
+	  redo_results=`for i in $$redo_bases; do echo $$i.trs; done`; \
+	  if $(am__make_dryrun); then :; else \
+	    rm -f $$redo_logs && rm -f $$redo_results || exit 1; \
+	  fi; \
+	fi; \
+	if test -n "$$am__remaking_logs"; then \
+	  echo "fatal: making $(TEST_SUITE_LOG): possible infinite" \
+	       "recursion detected" >&2; \
+	elif test -n "$$redo_logs"; then \
+	  am__remaking_logs=yes $(MAKE) $(AM_MAKEFLAGS) $$redo_logs; \
+	fi; \
+	if $(am__make_dryrun); then :; else \
+	  st=0;  \
+	  errmsg="fatal: making $(TEST_SUITE_LOG): failed to create"; \
+	  for i in $$redo_bases; do \
+	    test -f $$i.trs && test -r $$i.trs \
+	      || { echo "$$errmsg $$i.trs" >&2; st=1; }; \
+	    test -f $$i.log && test -r $$i.log \
+	      || { echo "$$errmsg $$i.log" >&2; st=1; }; \
+	  done; \
+	  test $$st -eq 0 || exit 1; \
+	fi
+	@$(am__sh_e_setup); $(am__tty_colors); $(am__set_TESTS_bases); \
+	ws='[ 	]'; \
+	results=`for b in $$bases; do echo $$b.trs; done`; \
+	test -n "$$results" || results=/dev/null; \
+	all=`  grep "^$$ws*:test-result:"           $$results | wc -l`; \
+	pass=` grep "^$$ws*:test-result:$$ws*PASS"  $$results | wc -l`; \
+	fail=` grep "^$$ws*:test-result:$$ws*FAIL"  $$results | wc -l`; \
+	skip=` grep "^$$ws*:test-result:$$ws*SKIP"  $$results | wc -l`; \
+	xfail=`grep "^$$ws*:test-result:$$ws*XFAIL" $$results | wc -l`; \
+	xpass=`grep "^$$ws*:test-result:$$ws*XPASS" $$results | wc -l`; \
+	error=`grep "^$$ws*:test-result:$$ws*ERROR" $$results | wc -l`; \
+	if test `expr $$fail + $$xpass + $$error` -eq 0; then \
+	  success=true; \
+	else \
+	  success=false; \
+	fi; \
+	br='==================='; br=$$br$$br$$br$$br; \
+	result_count () \
+	{ \
+	    if test x"$$1" = x"--maybe-color"; then \
+	      maybe_colorize=yes; \
+	    elif test x"$$1" = x"--no-color"; then \
+	      maybe_colorize=no; \
+	    else \
+	      echo "$@: invalid 'result_count' usage" >&2; exit 4; \
+	    fi; \
+	    shift; \
+	    desc=$$1 count=$$2; \
+	    if test $$maybe_colorize = yes && test $$count -gt 0; then \
+	      color_start=$$3 color_end=$$std; \
+	    else \
+	      color_start= color_end=; \
+	    fi; \
+	    echo "$${color_start}# $$desc $$count$${color_end}"; \
+	}; \
+	create_testsuite_report () \
+	{ \
+	  result_count $$1 "TOTAL:" $$all   "$$brg"; \
+	  result_count $$1 "PASS: " $$pass  "$$grn"; \
+	  result_count $$1 "SKIP: " $$skip  "$$blu"; \
+	  result_count $$1 "XFAIL:" $$xfail "$$lgn"; \
+	  result_count $$1 "FAIL: " $$fail  "$$red"; \
+	  result_count $$1 "XPASS:" $$xpass "$$red"; \
+	  result_count $$1 "ERROR:" $$error "$$mgn"; \
+	}; \
+	{								\
+	  echo "$(PACKAGE_STRING): $(subdir)/$(TEST_SUITE_LOG)" |	\
+	    $(am__rst_title);						\
+	  create_testsuite_report --no-color;				\
+	  echo;								\
+	  echo ".. contents:: :depth: 2";				\
+	  echo;								\
+	  for b in $$bases; do echo $$b; done				\
+	    | $(am__create_global_log);					\
+	} >$(TEST_SUITE_LOG).tmp || exit 1;				\
+	mv $(TEST_SUITE_LOG).tmp $(TEST_SUITE_LOG);			\
+	if $$success; then						\
+	  col="$$grn";							\
+	 else								\
+	  col="$$red";							\
+	  test x"$$VERBOSE" = x || cat $(TEST_SUITE_LOG);		\
+	fi;								\
+	echo "$${col}$$br$${std}"; 					\
+	echo "$${col}Testsuite summary"$(AM_TESTSUITE_SUMMARY_HEADER)"$${std}";	\
+	echo "$${col}$$br$${std}"; 					\
+	create_testsuite_report --maybe-color;				\
+	echo "$$col$$br$$std";						\
+	if $$success; then :; else					\
+	  echo "$${col}See $(subdir)/$(TEST_SUITE_LOG)$${std}";		\
+	  if test -n "$(PACKAGE_BUGREPORT)"; then			\
+	    echo "$${col}Please report to $(PACKAGE_BUGREPORT)$${std}";	\
+	  fi;								\
+	  echo "$$col$$br$$std";					\
+	fi;								\
+	$$success || exit 1
+
+check-TESTS: 
+	@list='$(RECHECK_LOGS)';           test -z "$$list" || rm -f $$list
+	@list='$(RECHECK_LOGS:.log=.trs)'; test -z "$$list" || rm -f $$list
+	@test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
+	@set +e; $(am__set_TESTS_bases); \
+	log_list=`for i in $$bases; do echo $$i.log; done`; \
+	trs_list=`for i in $$bases; do echo $$i.trs; done`; \
+	log_list=`echo $$log_list`; trs_list=`echo $$trs_list`; \
+	$(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) TEST_LOGS="$$log_list"; \
+	exit $$?;
+recheck: all 
+	@test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
+	@set +e; $(am__set_TESTS_bases); \
+	bases=`for i in $$bases; do echo $$i; done \
+	         | $(am__list_recheck_tests)` || exit 1; \
+	log_list=`for i in $$bases; do echo $$i.log; done`; \
+	log_list=`echo $$log_list`; \
+	$(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) \
+	        am__force_recheck=am--force-recheck \
+	        TEST_LOGS="$$log_list"; \
+	exit $$?
+test-libevdev.log: test-libevdev$(EXEEXT)
+	@p='test-libevdev$(EXEEXT)'; \
+	b='test-libevdev'; \
+	$(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+	--log-file $$b.log --trs-file $$b.trs \
+	$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+	"$$tst" $(AM_TESTS_FD_REDIRECT)
+test-kernel.log: test-kernel$(EXEEXT)
+	@p='test-kernel$(EXEEXT)'; \
+	b='test-kernel'; \
+	$(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+	--log-file $$b.log --trs-file $$b.trs \
+	$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+	"$$tst" $(AM_TESTS_FD_REDIRECT)
+test-uinput.log: test-uinput$(EXEEXT)
+	@p='test-uinput$(EXEEXT)'; \
+	b='test-uinput'; \
+	$(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+	--log-file $$b.log --trs-file $$b.trs \
+	$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+	"$$tst" $(AM_TESTS_FD_REDIRECT)
+test-event-codes.log: test-event-codes$(EXEEXT)
+	@p='test-event-codes$(EXEEXT)'; \
+	b='test-event-codes'; \
+	$(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+	--log-file $$b.log --trs-file $$b.trs \
+	$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+	"$$tst" $(AM_TESTS_FD_REDIRECT)
+test-libevdev-internals.log: test-libevdev-internals$(EXEEXT)
+	@p='test-libevdev-internals$(EXEEXT)'; \
+	b='test-libevdev-internals'; \
+	$(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+	--log-file $$b.log --trs-file $$b.trs \
+	$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+	"$$tst" $(AM_TESTS_FD_REDIRECT)
+.test.log:
+	@p='$<'; \
+	$(am__set_b); \
+	$(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \
+	--log-file $$b.log --trs-file $$b.trs \
+	$(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \
+	"$$tst" $(AM_TESTS_FD_REDIRECT)
+@am__EXEEXT_TRUE@.test$(EXEEXT).log:
+@am__EXEEXT_TRUE@	@p='$<'; \
+@am__EXEEXT_TRUE@	$(am__set_b); \
+@am__EXEEXT_TRUE@	$(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \
+@am__EXEEXT_TRUE@	--log-file $$b.log --trs-file $$b.trs \
+@am__EXEEXT_TRUE@	$(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \
+@am__EXEEXT_TRUE@	"$$tst" $(AM_TESTS_FD_REDIRECT)
+distdir: $(BUILT_SOURCES)
+	$(MAKE) $(AM_MAKEFLAGS) distdir-am
+
+distdir-am: $(DISTFILES)
+	@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+	topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+	list='$(DISTFILES)'; \
+	  dist_files=`for file in $$list; do echo $$file; done | \
+	  sed -e "s|^$$srcdirstrip/||;t" \
+	      -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+	case $$dist_files in \
+	  */*) $(MKDIR_P) `echo "$$dist_files" | \
+			   sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+			   sort -u` ;; \
+	esac; \
+	for file in $$dist_files; do \
+	  if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+	  if test -d $$d/$$file; then \
+	    dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+	    if test -d "$(distdir)/$$file"; then \
+	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+	    fi; \
+	    if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+	      cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+	    fi; \
+	    cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+	  else \
+	    test -f "$(distdir)/$$file" \
+	    || cp -p $$d/$$file "$(distdir)/$$file" \
+	    || exit 1; \
+	  fi; \
+	done
+check-am: all-am
+	$(MAKE) $(AM_MAKEFLAGS) check-TESTS check-local
+check: check-am
+all-am: Makefile $(PROGRAMS)
+installdirs:
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+	@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+	if test -z '$(STRIP)'; then \
+	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	      install; \
+	else \
+	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	    "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+	fi
+mostlyclean-generic:
+	-test -z "$(TEST_LOGS)" || rm -f $(TEST_LOGS)
+	-test -z "$(TEST_LOGS:.log=.trs)" || rm -f $(TEST_LOGS:.log=.trs)
+	-test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
+
+clean-generic:
+	-test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
+
+distclean-generic:
+	-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+	-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+	@echo "This command is intended for maintainers to use"
+	@echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-generic clean-libtool clean-noinstPROGRAMS \
+	mostlyclean-am
+
+distclean: distclean-am
+		-rm -f ./$(DEPDIR)/test-common-uinput.Po
+	-rm -f ./$(DEPDIR)/test-common.Po
+	-rm -f ./$(DEPDIR)/test-context.Po
+	-rm -f ./$(DEPDIR)/test-event-codes.Po
+	-rm -f ./$(DEPDIR)/test-event-names.Po
+	-rm -f ./$(DEPDIR)/test-int-queue.Po
+	-rm -f ./$(DEPDIR)/test-libevdev-events.Po
+	-rm -f ./$(DEPDIR)/test-libevdev-has-event.Po
+	-rm -f ./$(DEPDIR)/test-libevdev-init.Po
+	-rm -f ./$(DEPDIR)/test-main.Po
+	-rm -f ./$(DEPDIR)/test-uinput.Po
+	-rm -f ./$(DEPDIR)/test_compile_pedantic-test-compile-pedantic.Po
+	-rm -f ./$(DEPDIR)/test_kernel-test-common-uinput.Po
+	-rm -f ./$(DEPDIR)/test_kernel-test-common.Po
+	-rm -f ./$(DEPDIR)/test_kernel-test-kernel.Po
+	-rm -f ./$(DEPDIR)/test_kernel-test-main.Po
+	-rm -f ./$(DEPDIR)/test_link-test-link.Po
+	-rm -f ./$(DEPDIR)/test_static_link-test-link.Po
+	-rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+	distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am:
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+		-rm -f ./$(DEPDIR)/test-common-uinput.Po
+	-rm -f ./$(DEPDIR)/test-common.Po
+	-rm -f ./$(DEPDIR)/test-context.Po
+	-rm -f ./$(DEPDIR)/test-event-codes.Po
+	-rm -f ./$(DEPDIR)/test-event-names.Po
+	-rm -f ./$(DEPDIR)/test-int-queue.Po
+	-rm -f ./$(DEPDIR)/test-libevdev-events.Po
+	-rm -f ./$(DEPDIR)/test-libevdev-has-event.Po
+	-rm -f ./$(DEPDIR)/test-libevdev-init.Po
+	-rm -f ./$(DEPDIR)/test-main.Po
+	-rm -f ./$(DEPDIR)/test-uinput.Po
+	-rm -f ./$(DEPDIR)/test_compile_pedantic-test-compile-pedantic.Po
+	-rm -f ./$(DEPDIR)/test_kernel-test-common-uinput.Po
+	-rm -f ./$(DEPDIR)/test_kernel-test-common.Po
+	-rm -f ./$(DEPDIR)/test_kernel-test-kernel.Po
+	-rm -f ./$(DEPDIR)/test_kernel-test-main.Po
+	-rm -f ./$(DEPDIR)/test_link-test-link.Po
+	-rm -f ./$(DEPDIR)/test_static_link-test-link.Po
+	-rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+	mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am:
+
+.MAKE: check-am install-am install-strip
+
+.PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-TESTS \
+	check-am check-local clean clean-generic clean-libtool \
+	clean-noinstPROGRAMS cscopelist-am ctags ctags-am distclean \
+	distclean-compile distclean-generic distclean-libtool \
+	distclean-tags distdir dvi dvi-am html html-am info info-am \
+	install install-am install-data install-data-am install-dvi \
+	install-dvi-am install-exec install-exec-am install-html \
+	install-html-am install-info install-info-am install-man \
+	install-pdf install-pdf-am install-ps install-ps-am \
+	install-strip installcheck installcheck-am installdirs \
+	maintainer-clean maintainer-clean-generic mostlyclean \
+	mostlyclean-compile mostlyclean-generic mostlyclean-libtool \
+	pdf pdf-am ps ps-am recheck tags tags-am uninstall \
+	uninstall-am
+
+.PRECIOUS: Makefile
+
+
+@ENABLE_RUNTIME_TESTS_TRUE@.NOTPARALLEL:
+
+@ENABLE_RUNTIME_TESTS_TRUE@@HAVE_VALGRIND_TRUE@valgrind:
+@ENABLE_RUNTIME_TESTS_TRUE@@HAVE_VALGRIND_TRUE@	        $(MAKE) check-TESTS CK_TIMEOUT_MULTIPLIER=10 LOG_COMPILER="$(VALGRIND)" LOG_FLAGS="$(VALGRIND_FLAGS)"
+
+@ENABLE_RUNTIME_TESTS_TRUE@@GCOV_ENABLED_TRUE@gcov-report: generate-gcov-report.sh check-TESTS
+@ENABLE_RUNTIME_TESTS_TRUE@@GCOV_ENABLED_TRUE@	$(AM_V_GEN)$(srcdir)/generate-gcov-report.sh gcov-reports $(top_builddir)/libevdev $(builddir)
+
+@ENABLE_RUNTIME_TESTS_TRUE@@GCOV_ENABLED_TRUE@gcov: gcov-report
+@ENABLE_RUNTIME_TESTS_TRUE@@GCOV_ENABLED_TRUE@	@cat gcov-reports/summary.txt
+
+@ENABLE_RUNTIME_TESTS_TRUE@@GCOV_ENABLED_FALSE@gcov-report.txt:
+@ENABLE_RUNTIME_TESTS_TRUE@@GCOV_ENABLED_FALSE@	@true
+
+@ENABLE_RUNTIME_TESTS_TRUE@@GCOV_ENABLED_FALSE@gcov:
+@ENABLE_RUNTIME_TESTS_TRUE@@GCOV_ENABLED_FALSE@	@true
+
+@ENABLE_RUNTIME_TESTS_TRUE@.PHONY: gcov gcov-clean gcov-report
+
+@ENABLE_STATIC_SYMBOL_LEAKS_TEST_TRUE@static-symbol-leaks: test-static-link test-static-symbols-leak.sh
+@ENABLE_STATIC_SYMBOL_LEAKS_TEST_TRUE@	$(AM_V_GEN) $(srcdir)/test-static-symbols-leak.sh $(builddir)
+
+check-local: $(check_local_deps)
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/test/generate-gcov-report.sh b/test/generate-gcov-report.sh
new file mode 100644
index 0000000000000000000000000000000000000000..ff27845fbdb3c1b12b326fddf8b2137a19334a9e
--- /dev/null
+++ b/test/generate-gcov-report.sh
@@ -0,0 +1,40 @@
+#!/usr/bin/env bash
+
+set -e
+
+if [[ $# -lt 2 ]]; then
+    echo "Usage: ./generate-gcov-report.sh   [ ... ]"
+    exit 1
+fi
+
+target_dir=$1
+shift
+source_dirs=$*
+
+if [[ "${target_dir:0:1}" != '/' ]]; then
+    target_dir="$PWD/$target_dir"
+fi
+summary_file="$target_dir/summary.txt"
+
+mkdir -p "$target_dir"
+rm -f "$target_dir"/*.gcov
+
+for dir in $source_dirs; do
+	pushd "$dir" > /dev/null
+	for file in *.c; do
+		find ./ -name "*${file/\.c/.gcda}" -exec gcov {} \; > /dev/null
+	done
+	find ./ -name "*.gcov" \! -path "*/`basename "$target_dir"`/*" -exec mv {} "$target_dir" \;
+	popd > /dev/null
+done
+
+echo "========== coverage report ========" > "$summary_file"
+for file in "$target_dir"/*.gcov; do
+	total=`grep -v " -:" "$file" | wc -l`
+	missing=`grep "#####" "$file" | wc -l`
+	hit=$((total - missing));
+	percent=$((($hit * 100)/$total))
+	fname=`basename "$file"`
+	printf "%-32s total lines: %4s not tested: %4s (%3s%%)\n" "$fname" "$total" "$missing" "$percent">> "$summary_file"
+done
+echo "========== =============== ========" >> "$summary_file"
diff --git a/test/test-common-uinput.c b/test/test-common-uinput.c
new file mode 100644
index 0000000000000000000000000000000000000000..00b9e7e575dfd68790f0d759be54c9e49b9c3406
--- /dev/null
+++ b/test/test-common-uinput.c
@@ -0,0 +1,282 @@
+// SPDX-License-Identifier: MIT
+/*
+ * Copyright © 2013 Red Hat, Inc.
+ */
+
+#include "config.h"
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+#include 
+#include 
+#include 
+
+#include "test-common-uinput.h"
+
+#define SYS_INPUT_DIR "/sys/class/input"
+#define DEV_INPUT_DIR "/dev/input/"
+
+struct uinput_device
+{
+	struct libevdev *d; /* lazy, it has all the accessors */
+	struct libevdev_uinput *uidev;
+	int dev_fd; /* open fd to the devnode */
+	int uinput_fd;
+};
+
+struct uinput_device*
+uinput_device_new(const char *name)
+{
+	struct uinput_device *dev;
+
+	dev = calloc(1, sizeof(*dev));
+	if (!dev)
+		return NULL;
+
+	dev->d = libevdev_new();
+	dev->dev_fd = -1;
+	dev->uinput_fd = -1;
+
+	if (name)
+		libevdev_set_name(dev->d, name);
+
+	return dev;
+}
+
+int
+uinput_device_new_with_events_v(struct uinput_device **d, const char *name, const struct input_id *id, va_list args)
+{
+	int rc;
+	struct uinput_device *dev;
+
+	dev = uinput_device_new(name);
+	if (!dev)
+		return -ENOMEM;
+	if (id != DEFAULT_IDS)
+		uinput_device_set_ids(dev, id);
+
+	rc = uinput_device_set_event_bits_v(dev, args);
+
+	if (rc == 0)
+		rc = uinput_device_create(dev);
+
+	if (rc != 0) {
+		uinput_device_free(dev);
+		dev = NULL;
+	} else
+		*d = dev;
+
+	return rc;
+}
+
+int
+uinput_device_new_with_events(struct uinput_device **d, const char *name, const struct input_id *id, ...)
+{
+	int rc;
+	va_list args;
+
+	va_start(args, id);
+	rc = uinput_device_new_with_events_v(d, name, id, args);
+	va_end(args);
+
+	return rc;
+}
+
+void
+uinput_device_free(struct uinput_device *dev)
+{
+	if (!dev)
+		return;
+
+	if (dev->uinput_fd != -1) {
+		(void)ioctl(dev->uinput_fd, UI_DEV_DESTROY, NULL);
+		close(dev->uinput_fd);
+	}
+	if (dev->dev_fd != -1)
+		close(dev->dev_fd);
+	libevdev_free(dev->d);
+	libevdev_uinput_destroy(dev->uidev);
+	free(dev);
+}
+
+int
+uinput_device_get_fd(const struct uinput_device *dev)
+{
+	return dev->dev_fd;
+}
+
+const char*
+uinput_device_get_devnode(const struct uinput_device *dev)
+{
+	return libevdev_uinput_get_devnode(dev->uidev);
+}
+
+int
+uinput_device_create(struct uinput_device* d)
+{
+	int rc;
+	int fd;
+	const char *devnode;
+
+	fd = open("/dev/uinput", O_RDWR);
+	if (fd < 0)
+		goto error;
+
+	d->uinput_fd = fd;
+
+	rc = libevdev_uinput_create_from_device(d->d, fd, &d->uidev);
+	if (rc != 0)
+		goto error;
+
+	devnode = libevdev_uinput_get_devnode(d->uidev);
+	if (devnode == NULL)
+		goto error;
+
+	d->dev_fd = open(devnode, O_RDWR);
+	if (d->dev_fd == -1)
+		goto error;
+
+	/* write abs resolution now */
+	if (libevdev_has_event_type(d->d, EV_ABS)) {
+		int  code;
+		for (code = 0; code < ABS_CNT; code++) {
+			const struct input_absinfo *abs;
+
+			/* can't change slots */
+			if (code == ABS_MT_SLOT)
+				continue;
+
+			abs = libevdev_get_abs_info(d->d, code);
+			if (!abs)
+				continue;
+
+			rc = ioctl(d->dev_fd, EVIOCSABS(code), abs);
+			if (rc < 0) {
+				printf("error %s for code %d\n", strerror(-rc), code);
+				goto error;
+			}
+		}
+	}
+
+	return 0;
+
+error:
+	if (d->dev_fd != -1)
+		close(d->dev_fd);
+	if (d->uinput_fd != -1)
+		close(d->uinput_fd);
+	return -errno;
+
+}
+
+int uinput_device_set_name(struct uinput_device *dev, const char *name)
+{
+	libevdev_set_name(dev->d, name);
+	return 0;
+}
+
+int uinput_device_set_ids(struct uinput_device *dev, const struct input_id *ids)
+{
+	libevdev_set_id_product(dev->d, ids->product);
+	libevdev_set_id_vendor(dev->d, ids->vendor);
+	libevdev_set_id_bustype(dev->d, ids->bustype);
+	libevdev_set_id_version(dev->d, ids->version);
+	return 0;
+}
+
+int
+uinput_device_set_bit(struct uinput_device* dev, unsigned int bit)
+{
+	return libevdev_enable_event_type(dev->d, bit);
+}
+
+int
+uinput_device_set_prop(struct uinput_device *dev, unsigned int prop)
+{
+	return libevdev_enable_property(dev->d, prop);
+}
+
+int
+uinput_device_set_event_bit(struct uinput_device* dev, unsigned int type, unsigned int code)
+{
+	return libevdev_enable_event_code(dev->d, type, code, NULL);
+}
+
+int
+uinput_device_set_event_bits_v(struct uinput_device *dev, va_list args)
+{
+	int type, code;
+	int rc = 0;
+
+	do {
+		type = va_arg(args, int);
+		if (type == -1)
+			break;
+		code = va_arg(args, int);
+		if (code == -1)
+			break;
+		rc = libevdev_enable_event_code(dev->d, type, code, NULL);
+	} while (rc == 0);
+
+	return rc;
+}
+
+int
+uinput_device_set_event_bits(struct uinput_device *dev, ...)
+{
+	int rc;
+	va_list args;
+	va_start(args, dev);
+	rc = uinput_device_set_event_bits_v(dev, args);
+	va_end(args);
+
+	return rc;
+}
+
+int
+uinput_device_set_abs_bit(struct uinput_device* dev, unsigned int code, const struct input_absinfo *absinfo)
+{
+	return libevdev_enable_event_code(dev->d, EV_ABS, code, absinfo);
+}
+
+int
+uinput_device_event(const struct uinput_device *dev, unsigned int type, unsigned int code, int value)
+{
+	return libevdev_uinput_write_event(dev->uidev, type, code, value);
+}
+
+int uinput_device_event_multiple_v(const struct uinput_device* dev, va_list args)
+{
+	int type, code, value;
+	int rc = 0;
+
+	do {
+		type = va_arg(args, int);
+		if (type == -1)
+			break;
+		code = va_arg(args, int);
+		if (code == -1)
+			break;
+		value = va_arg(args, int);
+		rc = uinput_device_event(dev, type, code, value);
+	} while (rc == 0);
+
+	return rc;
+}
+
+int uinput_device_event_multiple(const struct uinput_device* dev, ...)
+{
+	int rc;
+	va_list args;
+	va_start(args, dev);
+	rc = uinput_device_event_multiple_v(dev, args);
+	va_end(args);
+	return rc;
+}
diff --git a/test/test-common-uinput.h b/test/test-common-uinput.h
new file mode 100644
index 0000000000000000000000000000000000000000..9c2f64ca9cd7e3696adafd615690076e3c3c5678
--- /dev/null
+++ b/test/test-common-uinput.h
@@ -0,0 +1,31 @@
+// SPDX-License-Identifier: MIT
+/*
+ * Copyright © 2013 Red Hat, Inc.
+ */
+
+#include "config.h"
+#include 
+
+#define DEFAULT_IDS NULL
+
+struct uinput_device* uinput_device_new(const char *name);
+int uinput_device_new_with_events(struct uinput_device **dev, const char *name, const struct input_id *ids, ...);
+int uinput_device_new_with_events_v(struct uinput_device **dev, const char *name, const struct input_id *ids, va_list args);
+void uinput_device_free(struct uinput_device *dev);
+
+int uinput_device_create(struct uinput_device* dev);
+int uinput_device_set_name(struct uinput_device* dev, const char *name);
+int uinput_device_set_ids(struct uinput_device* dev, const struct input_id *ids);
+int uinput_device_set_bit(struct uinput_device* dev, unsigned int bit);
+int uinput_device_set_prop(struct uinput_device *dev, unsigned int prop);
+int uinput_device_set_event_bit(struct uinput_device* dev, unsigned int type, unsigned int code);
+int uinput_device_set_event_bits(struct uinput_device* dev, ...);
+int uinput_device_set_event_bits_v(struct uinput_device* dev, va_list args);
+int uinput_device_set_abs_bit(struct uinput_device* dev, unsigned int code, const struct input_absinfo *absinfo);
+int uinput_device_event(const struct uinput_device* dev, unsigned int type, unsigned int code, int value);
+int uinput_device_event_multiple(const struct uinput_device* dev, ...);
+int uinput_device_event_multiple_v(const struct uinput_device* dev, va_list args);
+int uinput_device_get_fd(const struct uinput_device *dev);
+const char* uinput_device_get_devnode(const struct uinput_device *dev);
+
+char *uinput_devnode_from_syspath(const char *syspath);
diff --git a/test/test-common.c b/test/test-common.c
new file mode 100644
index 0000000000000000000000000000000000000000..31c126deb27e2572c94744e09127b0bbee6c3665
--- /dev/null
+++ b/test/test-common.c
@@ -0,0 +1,102 @@
+// SPDX-License-Identifier: MIT
+/*
+ * Copyright © 2013 Red Hat, Inc.
+ */
+
+#include "config.h"
+#include 
+#include 
+#include 
+#include 
+
+#include "test-common.h"
+
+void test_logfunc_abort_on_error(enum libevdev_log_priority priority,
+				 void *data,
+				 const char *file, int line,
+				 const char *func,
+				 const char *format, va_list args)
+{
+	vprintf(format, args);
+	ck_abort();
+}
+
+void test_logfunc_ignore_error(enum libevdev_log_priority priority,
+			       void *data,
+			       const char *file, int line,
+			       const char *func,
+			       const char *format, va_list args)
+{
+}
+
+void test_create_device(struct uinput_device **uidev_return,
+			struct libevdev **dev_return,
+			...)
+{
+	int rc, fd;
+	struct uinput_device *uidev;
+	struct libevdev *dev;
+	va_list args;
+
+	va_start(args, dev_return);
+
+	rc = uinput_device_new_with_events_v(&uidev, TEST_DEVICE_NAME, DEFAULT_IDS, args);
+	va_end(args);
+
+	ck_assert_msg(rc == 0, "Failed to create uinput device: %s", strerror(-rc));
+
+	fd = uinput_device_get_fd(uidev);
+
+	rc = libevdev_new_from_fd(fd, &dev);
+	ck_assert_msg(rc == 0, "Failed to init device device: %s", strerror(-rc));
+	rc = fcntl(fd, F_SETFL, O_NONBLOCK);
+	ck_assert_msg(rc == 0, "fcntl failed: %s", strerror(errno));
+
+	*uidev_return = uidev;
+	*dev_return = dev;
+}
+
+void test_create_abs_device(struct uinput_device **uidev_return,
+			    struct libevdev **dev_return,
+			    int nabs,
+			    const struct input_absinfo *abs,
+			    ...)
+{
+	int rc, fd;
+	struct uinput_device *uidev;
+	struct libevdev *dev;
+	va_list args;
+
+	uidev = uinput_device_new(TEST_DEVICE_NAME);
+	ck_assert(uidev != NULL);
+
+	va_start(args, abs);
+	rc = uinput_device_set_event_bits_v(uidev, args);
+	ck_assert_msg(rc == 0, "Failed to set uinput bits");
+	va_end(args);
+
+	while (--nabs >= 0) {
+		int code;
+		struct input_absinfo a;
+
+		code = abs[nabs].value;
+		a = abs[nabs];
+		a.value = 0;
+
+		rc = uinput_device_set_abs_bit(uidev, code, &a);
+		ck_assert_msg(rc == 0, "for abs field %d\n", nabs);
+	}
+
+	rc = uinput_device_create(uidev);
+	ck_assert_msg(rc == 0, "Failed to create uinput device: %s", strerror(-rc));
+
+	fd = uinput_device_get_fd(uidev);
+
+	rc = libevdev_new_from_fd(fd, &dev);
+	ck_assert_msg(rc == 0, "Failed to init device device: %s", strerror(-rc));
+	rc = fcntl(fd, F_SETFL, O_NONBLOCK);
+	ck_assert_msg(rc == 0, "fcntl failed: %s", strerror(errno));
+
+	*uidev_return = uidev;
+	*dev_return = dev;
+}
diff --git a/test/test-common.h b/test/test-common.h
new file mode 100644
index 0000000000000000000000000000000000000000..fd5a54984c19979616ab4d5e2b107468f0ae2596
--- /dev/null
+++ b/test/test-common.h
@@ -0,0 +1,93 @@
+// SPDX-License-Identifier: MIT
+/*
+ * Copyright © 2013 Red Hat, Inc.
+ */
+
+#include "config.h"
+#include 
+#include 
+#include 
+
+#include 
+
+#ifndef _TEST_COMMON_H_
+#define _TEST_COMMON_H_
+
+struct libevdev_test {
+	const char *name;
+	Suite* (*setup)(void);
+	bool needs_root_privileges;
+} __attribute__((aligned(16)));
+
+#define _TEST_SUITE(name, root_privs) \
+	static Suite* (name##_setup)(void); \
+	static const struct libevdev_test _test \
+	__attribute__((used)) \
+	__attribute__((section ("test_section"))) = { \
+		#name, name##_setup, root_privs \
+	}; \
+	static Suite* (name##_setup)(void)
+
+#define TEST_SUITE(name) \
+	_TEST_SUITE(name, false)
+
+#define TEST_SUITE_ROOT_PRIVILEGES(name) \
+	_TEST_SUITE(name, true)
+
+#define TEST_DEVICE_NAME "libevdev test device"
+
+#define add_test(suite, func) do { \
+	TCase *tc = tcase_create(#func); \
+	tcase_add_test(tc, func); \
+	suite_add_tcase(suite, tc); \
+} while(0)
+
+#include "test-common-uinput.h"
+
+#define assert_event(e_, t, c, v) \
+do { \
+	const struct input_event *e = (e_); \
+	ck_assert_int_eq(e->type, (t)); \
+	ck_assert_int_eq(e->code, (c)); \
+	ck_assert_int_eq(e->value, (v)); \
+} while(0)
+
+void test_create_device(struct uinput_device **uidev,
+			struct libevdev **dev,
+			...);
+void test_create_abs_device(struct uinput_device **uidev,
+			    struct libevdev **dev,
+			    int nabs,
+			    const struct input_absinfo *abs,
+			    ...);
+
+void test_logfunc_abort_on_error(enum libevdev_log_priority priority,
+				 void *data,
+				 const char *file, int line,
+				 const char *func,
+				 const char *format, va_list args);
+void test_logfunc_ignore_error(enum libevdev_log_priority priority,
+			       void *data,
+			       const char *file, int line,
+			       const char *func,
+			       const char *format, va_list args);
+
+static inline void
+print_event(const struct input_event *ev)
+{
+	if (ev->type == EV_SYN)
+		printf("Event: time %ld.%06ld, ++++++++++++++++++++ %s +++++++++++++++\n",
+			ev->input_event_sec,
+			ev->input_event_usec,
+			libevdev_event_type_get_name(ev->type));
+	else
+		printf("Event: time %ld.%06ld, type %d (%s), code %d (%s), value %d\n",
+			ev->input_event_sec,
+			ev->input_event_usec,
+			ev->type,
+			libevdev_event_type_get_name(ev->type),
+			ev->code,
+			libevdev_event_code_get_name(ev->type, ev->code),
+			ev->value);
+}
+#endif /* _TEST_COMMON_H_ */
diff --git a/test/test-compile-pedantic.c b/test/test-compile-pedantic.c
new file mode 100644
index 0000000000000000000000000000000000000000..6faea86b0cc798f20d5844a2e61cc3fff63382eb
--- /dev/null
+++ b/test/test-compile-pedantic.c
@@ -0,0 +1,6 @@
+#include 
+#include 
+
+int main(void) {
+	return 0;
+}
diff --git a/test/test-context.c b/test/test-context.c
new file mode 100644
index 0000000000000000000000000000000000000000..3fc25294a084acaccc6825e3806df9a4abb28439
--- /dev/null
+++ b/test/test-context.c
@@ -0,0 +1,161 @@
+// SPDX-License-Identifier: MIT
+/*
+ * Copyright © 2019 Red Hat, Inc.
+ */
+
+#include "config.h"
+#include "test-common.h"
+
+START_TEST(test_info)
+{
+	struct libevdev *d = libevdev_new();
+
+	libevdev_set_name(d, "some name");
+	ck_assert_str_eq(libevdev_get_name(d), "some name");
+	libevdev_set_phys(d, "physical");
+	ck_assert_str_eq(libevdev_get_phys(d), "physical");
+	libevdev_set_uniq(d, "very unique");
+	ck_assert_str_eq(libevdev_get_uniq(d), "very unique");
+
+	libevdev_set_id_bustype(d, 1);
+	libevdev_set_id_vendor(d, 2);
+	libevdev_set_id_product(d, 3);
+	libevdev_set_id_version(d, 4);
+	ck_assert_int_eq(libevdev_get_id_bustype(d), 1);
+	ck_assert_int_eq(libevdev_get_id_vendor(d), 2);
+	ck_assert_int_eq(libevdev_get_id_product(d), 3);
+	ck_assert_int_eq(libevdev_get_id_version(d), 4);
+
+	libevdev_free(d);
+}
+END_TEST
+
+START_TEST(test_properties)
+{
+	for (unsigned prop = 0; prop < INPUT_PROP_CNT; prop++) {
+		struct libevdev *d = libevdev_new();
+
+		ck_assert(!libevdev_has_property(d, prop));
+		libevdev_enable_property(d, prop);
+		ck_assert(libevdev_has_property(d, prop));
+		libevdev_free(d);
+	}
+}
+END_TEST
+
+START_TEST(test_bits)
+{
+	for (unsigned type = 1; type < EV_CNT; type++) {
+		unsigned max = libevdev_event_type_get_max(type);
+
+		if((int)max == -1)
+			continue;
+
+		for (unsigned code = 0; code <= max; code++) {
+			struct libevdev *d = libevdev_new();
+			const struct input_absinfo abs = {
+				.minimum = 10,
+				.maximum = 20,
+				.fuzz = 30,
+				.flat = 40,
+				.resolution = 50,
+			};
+			const void *data = NULL;
+
+			if (type == EV_ABS || type == EV_REP)
+				data = &abs;
+
+			ck_assert(!libevdev_has_event_code(d, type, code));
+			libevdev_enable_event_code(d, type, code, data);
+			ck_assert(libevdev_has_event_code(d, type, code));
+			libevdev_free(d);
+		}
+	}
+}
+END_TEST
+
+START_TEST(test_mt_slots_enable_disable)
+{
+	struct libevdev *d = libevdev_new();
+	struct input_absinfo abs = {0};
+
+	abs.maximum = 5;
+	libevdev_enable_event_code(d, EV_ABS, ABS_MT_SLOT, &abs);
+	ck_assert(libevdev_has_event_code(d, EV_ABS, ABS_MT_SLOT));
+	ck_assert_int_eq(libevdev_get_num_slots(d), 6);
+
+	libevdev_disable_event_code(d, EV_ABS, ABS_MT_SLOT);
+	ck_assert(!libevdev_has_event_code(d, EV_ABS, ABS_MT_SLOT));
+	ck_assert_int_eq(libevdev_get_num_slots(d), -1);
+
+	abs.maximum = 2;
+	libevdev_enable_event_code(d, EV_ABS, ABS_MT_SLOT, &abs);
+	ck_assert(libevdev_has_event_code(d, EV_ABS, ABS_MT_SLOT));
+	ck_assert_int_eq(libevdev_get_num_slots(d), 3);
+
+	libevdev_free(d);
+}
+END_TEST
+
+START_TEST(test_mt_slots_increase_decrease)
+{
+	struct libevdev *d = libevdev_new();
+	struct input_absinfo abs = {0};
+
+	abs.maximum = 5;
+	libevdev_enable_event_code(d, EV_ABS, ABS_MT_SLOT, &abs);
+	ck_assert(libevdev_has_event_code(d, EV_ABS, ABS_MT_SLOT));
+	ck_assert_int_eq(libevdev_get_num_slots(d), 6);
+
+	abs.maximum = 2;
+	libevdev_enable_event_code(d, EV_ABS, ABS_MT_SLOT, &abs);
+	ck_assert(libevdev_has_event_code(d, EV_ABS, ABS_MT_SLOT));
+	ck_assert_int_eq(libevdev_get_num_slots(d), 3);
+
+	abs.maximum = 6;
+	libevdev_enable_event_code(d, EV_ABS, ABS_MT_SLOT, &abs);
+	ck_assert(libevdev_has_event_code(d, EV_ABS, ABS_MT_SLOT));
+	ck_assert_int_eq(libevdev_get_num_slots(d), 7);
+
+	abs.maximum = 10;
+	libevdev_enable_event_code(d, EV_ABS, ABS_MT_SLOT, &abs);
+	ck_assert(libevdev_has_event_code(d, EV_ABS, ABS_MT_SLOT));
+	ck_assert_int_eq(libevdev_get_num_slots(d), 11);
+
+	libevdev_free(d);
+}
+END_TEST
+
+START_TEST(test_mt_tracking_id)
+{
+	struct libevdev *d = libevdev_new();
+	struct input_absinfo abs = { .maximum = 5 };
+
+	libevdev_enable_event_code(d, EV_ABS, ABS_MT_SLOT, &abs);
+
+	/* Not yet enabled, so 0. This is technically undefined */
+	for (int slot = 0; slot < 5; slot++)
+		ck_assert_int_eq(libevdev_get_slot_value(d, 0, ABS_MT_TRACKING_ID), 0);
+
+	libevdev_enable_event_code(d, EV_ABS, ABS_MT_TRACKING_ID, &abs);
+
+	for (int slot = 0; slot < 5; slot++)
+		ck_assert_int_eq(libevdev_get_slot_value(d, 0, ABS_MT_TRACKING_ID), -1);
+
+	libevdev_free(d);
+}
+END_TEST
+
+TEST_SUITE(event_name_suite)
+{
+	Suite *s = suite_create("Context manipulation");
+
+	add_test(s, test_info);
+	add_test(s, test_properties);
+	add_test(s, test_bits);
+	add_test(s, test_mt_slots_enable_disable);
+	add_test(s, test_mt_slots_increase_decrease);
+	add_test(s, test_mt_tracking_id);
+
+	return s;
+}
diff --git a/test/test-event-codes.c b/test/test-event-codes.c
new file mode 100644
index 0000000000000000000000000000000000000000..d26d41aaccba0144b12ba288a5c6615d9f7e72f0
--- /dev/null
+++ b/test/test-event-codes.c
@@ -0,0 +1,268 @@
+// SPDX-License-Identifier: MIT
+/*
+ * Copyright © 2013 David Herrmann 
+ */
+
+#include "config.h"
+#include "test-common.h"
+
+START_TEST(test_type_names)
+{
+	ck_assert_int_eq(libevdev_event_type_from_name("EV_SYN"), EV_SYN);
+	ck_assert_int_eq(libevdev_event_type_from_name("EV_KEY"), EV_KEY);
+	ck_assert_int_eq(libevdev_event_type_from_name("EV_REL"), EV_REL);
+	ck_assert_int_eq(libevdev_event_type_from_name("EV_ABS"), EV_ABS);
+	ck_assert_int_eq(libevdev_event_type_from_name("EV_MSC"), EV_MSC);
+	ck_assert_int_eq(libevdev_event_type_from_name("EV_SND"), EV_SND);
+	ck_assert_int_eq(libevdev_event_type_from_name("EV_SW"), EV_SW);
+	ck_assert_int_eq(libevdev_event_type_from_name("EV_LED"), EV_LED);
+	ck_assert_int_eq(libevdev_event_type_from_name("EV_REP"), EV_REP);
+	ck_assert_int_eq(libevdev_event_type_from_name("EV_FF"), EV_FF);
+	ck_assert_int_eq(libevdev_event_type_from_name("EV_FF_STATUS"), EV_FF_STATUS);
+	ck_assert_int_eq(libevdev_event_type_from_name("EV_MAX"), EV_MAX);
+
+	ck_assert_int_eq(libevdev_event_type_from_name_n("EV_SYNTAX", 6), EV_SYN);
+	ck_assert_int_eq(libevdev_event_type_from_name_n("EV_REPTILE", 6), EV_REP);
+}
+END_TEST
+
+START_TEST(test_type_names_invalid)
+{
+	ck_assert_int_eq(libevdev_event_type_from_name("EV_Syn"), -1);
+	ck_assert_int_eq(libevdev_event_type_from_name("ev_SYN"), -1);
+	ck_assert_int_eq(libevdev_event_type_from_name("SYN"), -1);
+	ck_assert_int_eq(libevdev_event_type_from_name("EV_SYNTAX"), -1);
+
+	ck_assert_int_eq(libevdev_event_type_from_name_n("EV_SYN", 5), -1);
+	ck_assert_int_eq(libevdev_event_type_from_name_n("EV_REPTILE", 7), -1);
+}
+END_TEST
+
+START_TEST(test_type_name_lookup)
+{
+	ck_assert_int_eq(libevdev_event_type_from_code_name("SYN_REPORT"), EV_SYN);
+	ck_assert_int_eq(libevdev_event_type_from_code_name("KEY_A"), EV_KEY);
+	ck_assert_int_eq(libevdev_event_type_from_code_name("REL_Z"), EV_REL);
+	ck_assert_int_eq(libevdev_event_type_from_code_name("ABS_Z"), EV_ABS);
+	ck_assert_int_eq(libevdev_event_type_from_code_name("MSC_SERIAL"), EV_MSC);
+	ck_assert_int_eq(libevdev_event_type_from_code_name("SND_TONE"), EV_SND);
+	ck_assert_int_eq(libevdev_event_type_from_code_name("SW_TABLET_MODE"), EV_SW);
+	ck_assert_int_eq(libevdev_event_type_from_code_name("LED_CHARGING"), EV_LED);
+	ck_assert_int_eq(libevdev_event_type_from_code_name("REP_PERIOD"), EV_REP);
+	ck_assert_int_eq(libevdev_event_type_from_code_name("FF_SPRING"), EV_FF);
+	ck_assert_int_eq(libevdev_event_type_from_code_name("FF_STATUS_STOPPED"), EV_FF_STATUS);
+
+	ck_assert_int_eq(libevdev_event_type_from_code_name_n("KEY_1zzzzz", 5), EV_KEY);
+	ck_assert_int_eq(libevdev_event_type_from_code_name_n("ABS_Zooom", 5), EV_ABS);
+
+	ck_assert_int_eq(libevdev_event_type_from_code_name("KEY_MAX"), EV_KEY);
+	ck_assert_int_eq(libevdev_event_type_from_code_name("REL_MAX"), EV_REL);
+	ck_assert_int_eq(libevdev_event_type_from_code_name("ABS_MAX"), EV_ABS);
+}
+END_TEST
+
+START_TEST(test_type_name_lookup_invalid)
+{
+	ck_assert_int_eq(libevdev_event_type_from_name("SYN_REPORTED"),  -1);
+	ck_assert_int_eq(libevdev_event_type_from_name("syn_blah"), -1);
+	ck_assert_int_eq(libevdev_event_type_from_name("SYN_"), -1);
+	ck_assert_int_eq(libevdev_event_type_from_name("KEY_BANANA"), -1);
+
+	ck_assert_int_eq(libevdev_event_type_from_name_n("KEY_BA", 6), -1);
+	ck_assert_int_eq(libevdev_event_type_from_name_n("KEY_BLAH", 8), -1);
+}
+END_TEST
+
+START_TEST(test_code_names)
+{
+	ck_assert_int_eq(libevdev_event_code_from_name(EV_SYN, "SYN_REPORT"), SYN_REPORT);
+	ck_assert_int_eq(libevdev_event_code_from_name(EV_ABS, "ABS_X"), ABS_X);
+	ck_assert_int_eq(libevdev_event_code_from_name(EV_KEY, "BTN_A"), BTN_A);
+	ck_assert_int_eq(libevdev_event_code_from_name(EV_KEY, "KEY_A"), KEY_A);
+	ck_assert_int_eq(libevdev_event_code_from_name(EV_REL, "REL_X"), REL_X);
+	ck_assert_int_eq(libevdev_event_code_from_name(EV_MSC, "MSC_RAW"), MSC_RAW);
+	ck_assert_int_eq(libevdev_event_code_from_name(EV_LED, "LED_KANA"), LED_KANA);
+	ck_assert_int_eq(libevdev_event_code_from_name(EV_SND, "SND_BELL"), SND_BELL);
+	ck_assert_int_eq(libevdev_event_code_from_name(EV_REP, "REP_DELAY"), REP_DELAY);
+	ck_assert_int_eq(libevdev_event_code_from_name(EV_SYN, "SYN_DROPPED"), SYN_DROPPED);
+	ck_assert_int_eq(libevdev_event_code_from_name(EV_KEY, "KEY_RESERVED"), KEY_RESERVED);
+	ck_assert_int_eq(libevdev_event_code_from_name(EV_KEY, "BTN_0"), BTN_0);
+	ck_assert_int_eq(libevdev_event_code_from_name(EV_KEY, "KEY_0"), KEY_0);
+	ck_assert_int_eq(libevdev_event_code_from_name(EV_FF, "FF_GAIN"), FF_GAIN);
+	ck_assert_int_eq(libevdev_event_code_from_name(EV_FF_STATUS, "FF_STATUS_MAX"), FF_STATUS_MAX);
+	ck_assert_int_eq(libevdev_event_code_from_name(EV_SW, "SW_PEN_INSERTED"), SW_PEN_INSERTED);
+
+	ck_assert_int_eq(libevdev_event_code_from_name_n(EV_ABS, "ABS_YXZ", 5), ABS_Y);
+}
+END_TEST
+
+START_TEST(test_code_name_lookup)
+{
+	/* Same as test_code_names() but without the type */
+	ck_assert_int_eq(libevdev_event_code_from_code_name("SYN_REPORT"), SYN_REPORT);
+	ck_assert_int_eq(libevdev_event_code_from_code_name("ABS_X"), ABS_X);
+	ck_assert_int_eq(libevdev_event_code_from_code_name("BTN_A"), BTN_A);
+	ck_assert_int_eq(libevdev_event_code_from_code_name("KEY_A"), KEY_A);
+	ck_assert_int_eq(libevdev_event_code_from_code_name("REL_X"), REL_X);
+	ck_assert_int_eq(libevdev_event_code_from_code_name("MSC_RAW"), MSC_RAW);
+	ck_assert_int_eq(libevdev_event_code_from_code_name("LED_KANA"), LED_KANA);
+	ck_assert_int_eq(libevdev_event_code_from_code_name("SND_BELL"), SND_BELL);
+	ck_assert_int_eq(libevdev_event_code_from_code_name("REP_DELAY"), REP_DELAY);
+	ck_assert_int_eq(libevdev_event_code_from_code_name("SYN_DROPPED"), SYN_DROPPED);
+	ck_assert_int_eq(libevdev_event_code_from_code_name("KEY_RESERVED"), KEY_RESERVED);
+	ck_assert_int_eq(libevdev_event_code_from_code_name("BTN_0"), BTN_0);
+	ck_assert_int_eq(libevdev_event_code_from_code_name("KEY_0"), KEY_0);
+	ck_assert_int_eq(libevdev_event_code_from_code_name("FF_GAIN"), FF_GAIN);
+	ck_assert_int_eq(libevdev_event_code_from_code_name("FF_STATUS_MAX"), FF_STATUS_MAX);
+	ck_assert_int_eq(libevdev_event_code_from_code_name("SW_PEN_INSERTED"), SW_PEN_INSERTED);
+
+	ck_assert_int_eq(libevdev_event_code_from_code_name_n("ABS_YXZ", 5), ABS_Y);
+}
+END_TEST
+
+START_TEST(test_code_names_invalid)
+{
+	ck_assert_int_eq(libevdev_event_code_from_name(EV_MAX, "MAX_FAKE"), -1);
+	ck_assert_int_eq(libevdev_event_code_from_name(EV_CNT, "CNT_FAKE"), -1);
+	ck_assert_int_eq(libevdev_event_code_from_name(EV_PWR, "PWR_SOMETHING"), -1);
+	ck_assert_int_eq(libevdev_event_code_from_name(EV_ABS, "EV_ABS"), -1);
+	ck_assert_int_eq(libevdev_event_code_from_name(EV_ABS, "ABS_XY"), -1);
+	ck_assert_int_eq(libevdev_event_code_from_name(EV_KEY, "BTN_GAMEPAD"), -1);
+	ck_assert_int_eq(libevdev_event_code_from_name(EV_KEY, "BUS_PCI"), -1);
+	ck_assert_int_eq(libevdev_event_code_from_name(EV_FF_STATUS, "FF_STATUS"), -1);
+	ck_assert_int_eq(libevdev_event_code_from_name(EV_FF_STATUS, "FF_STATUS_"), -1);
+	ck_assert_int_eq(libevdev_event_code_from_name(EV_FF, "FF_STATUS"), -1);
+	ck_assert_int_eq(libevdev_event_code_from_name(EV_FF, "FF_STATUS_"), -1);
+	ck_assert_int_eq(libevdev_event_code_from_name(EV_KEY, "ID_BUS"), -1);
+	ck_assert_int_eq(libevdev_event_code_from_name(EV_SND, "SND_CNT"), -1);
+	ck_assert_int_eq(libevdev_event_code_from_name(EV_SW, "SW_CNT"), -1);
+
+	ck_assert_int_eq(libevdev_event_code_from_name_n(EV_ABS, "ABS_X", 4), -1);
+}
+END_TEST
+
+START_TEST(test_code_name_lookup_invalid)
+{
+	/* Same as test_code_names_invalid() but without the type */
+	ck_assert_int_eq(libevdev_event_code_from_code_name("MAX_FAKE"), -1);
+	ck_assert_int_eq(libevdev_event_code_from_code_name("CNT_FAKE"), -1);
+	ck_assert_int_eq(libevdev_event_code_from_code_name("PWR_SOMETHING"), -1);
+	ck_assert_int_eq(libevdev_event_code_from_code_name("EV_ABS"), -1);
+	ck_assert_int_eq(libevdev_event_code_from_code_name("ABS_XY"), -1);
+	ck_assert_int_eq(libevdev_event_code_from_code_name("BTN_GAMEPAD"), -1);
+	ck_assert_int_eq(libevdev_event_code_from_code_name("BUS_PCI"), -1);
+	ck_assert_int_eq(libevdev_event_code_from_code_name("FF_STATUS"), -1);
+	ck_assert_int_eq(libevdev_event_code_from_code_name("FF_STATUS_"), -1);
+	ck_assert_int_eq(libevdev_event_code_from_code_name("FF_STATUS"), -1);
+	ck_assert_int_eq(libevdev_event_code_from_code_name("FF_STATUS_"), -1);
+	ck_assert_int_eq(libevdev_event_code_from_code_name("ID_BUS"), -1);
+	ck_assert_int_eq(libevdev_event_code_from_code_name("SND_CNT"), -1);
+	ck_assert_int_eq(libevdev_event_code_from_code_name("SW_CNT"), -1);
+
+	ck_assert_int_eq(libevdev_event_code_from_code_name_n("ABS_X", 4), -1);
+}
+END_TEST
+
+START_TEST(test_code_names_max)
+{
+	ck_assert_int_eq(libevdev_event_code_from_name(EV_SYN, "SYN_MAX"), SYN_MAX);
+	ck_assert_int_eq(libevdev_event_code_from_name(EV_KEY, "KEY_MAX"), KEY_MAX);
+	ck_assert_int_eq(libevdev_event_code_from_name(EV_REL, "REL_MAX"), REL_MAX);
+	ck_assert_int_eq(libevdev_event_code_from_name(EV_ABS, "ABS_MAX"), ABS_MAX);
+	ck_assert_int_eq(libevdev_event_code_from_name(EV_MSC, "MSC_MAX"), MSC_MAX);
+	ck_assert_int_eq(libevdev_event_code_from_name(EV_SW, "SW_MAX"), SW_MAX);
+	ck_assert_int_eq(libevdev_event_code_from_name(EV_LED, "LED_MAX"), LED_MAX);
+	ck_assert_int_eq(libevdev_event_code_from_name(EV_SND, "SND_MAX"), SND_MAX);
+	ck_assert_int_eq(libevdev_event_code_from_name(EV_REP, "REP_MAX"), REP_MAX);
+	ck_assert_int_eq(libevdev_event_code_from_name(EV_FF, "FF_MAX"), FF_MAX);
+
+	ck_assert_int_eq(libevdev_event_code_from_code_name("SYN_MAX"), SYN_MAX);
+	ck_assert_int_eq(libevdev_event_code_from_code_name("KEY_MAX"), KEY_MAX);
+	ck_assert_int_eq(libevdev_event_code_from_code_name("REL_MAX"), REL_MAX);
+	ck_assert_int_eq(libevdev_event_code_from_code_name("ABS_MAX"), ABS_MAX);
+	ck_assert_int_eq(libevdev_event_code_from_code_name("MSC_MAX"), MSC_MAX);
+	ck_assert_int_eq(libevdev_event_code_from_code_name("SW_MAX"), SW_MAX);
+	ck_assert_int_eq(libevdev_event_code_from_code_name("LED_MAX"), LED_MAX);
+	ck_assert_int_eq(libevdev_event_code_from_code_name("SND_MAX"), SND_MAX);
+	ck_assert_int_eq(libevdev_event_code_from_code_name("REP_MAX"), REP_MAX);
+	ck_assert_int_eq(libevdev_event_code_from_code_name("FF_MAX"), FF_MAX);
+}
+END_TEST
+
+START_TEST(test_value_names)
+{
+	ck_assert_int_eq(libevdev_event_value_from_name(EV_ABS, ABS_MT_TOOL_TYPE, "MT_TOOL_PALM"), MT_TOOL_PALM);
+	ck_assert_int_eq(libevdev_event_value_from_name(EV_ABS, ABS_MT_TOOL_TYPE, "MT_TOOL_FINGER"), MT_TOOL_FINGER);
+	ck_assert_int_eq(libevdev_event_value_from_name(EV_ABS, ABS_MT_TOOL_TYPE, "MT_TOOL_PEN"), MT_TOOL_PEN);
+	ck_assert_int_eq(libevdev_event_value_from_name(EV_ABS, ABS_MT_TOOL_TYPE, "MT_TOOL_MAX"), MT_TOOL_MAX);
+}
+END_TEST
+
+START_TEST(test_value_names_invalid)
+{
+	ck_assert_int_eq(libevdev_event_value_from_name(EV_SYN, REL_X, "MT_TOOL_PALM"), -1);
+	ck_assert_int_eq(libevdev_event_value_from_name(EV_REL, REL_X, "MT_TOOL_PALM"), -1);
+	ck_assert_int_eq(libevdev_event_value_from_name(EV_ABS, ABS_X, "MT_TOOL_PALM"), -1);
+	ck_assert_int_eq(libevdev_event_value_from_name(EV_ABS, ABS_MT_TOOL_TYPE, "MT_TOOL_"), -1);
+	ck_assert_int_eq(libevdev_event_value_from_name(EV_ABS, ABS_MT_TOOL_TYPE, "MT_TOOL_PALMA"), -1);
+	ck_assert_int_eq(libevdev_event_value_from_name(EV_ABS, ABS_MT_TOOL_TYPE, ""), -1);
+	ck_assert_int_eq(libevdev_event_value_from_name(EV_ABS, ABS_MT_TOOL_TYPE, "EV_ABS"), -1);
+	ck_assert_int_eq(libevdev_event_value_from_name(EV_ABS, ABS_MT_TOOL_TYPE, "ABS_X"), -1);
+}
+END_TEST
+
+START_TEST(test_properties)
+{
+	struct prop {
+		int val;
+		const char *name;
+	} lut[] = {
+		{ INPUT_PROP_DIRECT, "INPUT_PROP_DIRECT" },
+		{ INPUT_PROP_POINTER, "INPUT_PROP_POINTER" },
+		{ INPUT_PROP_MAX, "INPUT_PROP_MAX" },
+		{ -1, NULL}
+	};
+	struct prop *p = lut;
+	while (p->val != -1) {
+		ck_assert_int_eq(libevdev_property_from_name(p->name), p->val);
+		p++;
+	}
+}
+END_TEST
+
+START_TEST(test_properties_invalid)
+{
+	ck_assert_int_eq(libevdev_property_from_name("EV_ABS"), -1);
+	ck_assert_int_eq(libevdev_property_from_name("INPUT_PROP"), -1);
+	ck_assert_int_eq(libevdev_property_from_name("INPUT_PROP_"), -1);
+	ck_assert_int_eq(libevdev_property_from_name("INPUT_PROP_FOO"), -1);
+
+	ck_assert_int_eq(libevdev_property_from_name_n("INPUT_PROP_POINTER", 11), -1);
+	ck_assert_int_eq(libevdev_property_from_name_n("INPUT_PROP_POINTER",
+						strlen("INPUT_PROP_POINTER") - 1), -1);
+}
+END_TEST
+
+TEST_SUITE(event_code_suite)
+{
+	Suite *s = suite_create("Event codes");
+
+	add_test(s, test_type_names);
+	add_test(s, test_type_names_invalid);
+	add_test(s, test_type_name_lookup);
+	add_test(s, test_type_name_lookup_invalid);
+
+	add_test(s, test_code_names);
+	add_test(s, test_code_name_lookup);
+	add_test(s, test_code_names_invalid);
+	add_test(s, test_code_name_lookup_invalid);
+	add_test(s, test_code_names_max);
+
+	add_test(s, test_value_names);
+	add_test(s, test_value_names_invalid);
+
+	add_test(s, test_properties);
+	add_test(s, test_properties_invalid);
+
+	return s;
+}
diff --git a/test/test-event-names.c b/test/test-event-names.c
new file mode 100644
index 0000000000000000000000000000000000000000..9da51c3d29b169d8930abd529e1c4e80e700c76a
--- /dev/null
+++ b/test/test-event-names.c
@@ -0,0 +1,314 @@
+// SPDX-License-Identifier: MIT
+/*
+ * Copyright © 2013 Red Hat, Inc.
+ */
+
+#include "config.h"
+#include "test-common.h"
+
+START_TEST(test_limits)
+{
+	ck_assert(libevdev_event_type_get_name(EV_MAX + 1) == NULL);
+	ck_assert(libevdev_event_code_get_name(EV_ABS, ABS_MAX + 1) == NULL);
+	ck_assert(libevdev_event_code_get_name(EV_REL, REL_MAX + 1) == NULL);
+	ck_assert(libevdev_event_code_get_name(EV_KEY, KEY_MAX + 1) == NULL);
+	ck_assert(libevdev_event_code_get_name(EV_LED, LED_MAX + 1) == NULL);
+	ck_assert(libevdev_event_code_get_name(EV_SW, SW_MAX + 1) == NULL);
+	ck_assert(libevdev_event_code_get_name(EV_MSC, MSC_MAX + 1) == NULL);
+	ck_assert(libevdev_event_code_get_name(EV_SND, SND_MAX + 1) == NULL);
+	ck_assert(libevdev_event_code_get_name(EV_REP, REP_MAX + 1) == NULL);
+	ck_assert(libevdev_event_code_get_name(EV_FF, FF_MAX + 1) == NULL);
+	ck_assert(libevdev_event_code_get_name(EV_MAX + 1, 0) == NULL);
+	ck_assert(libevdev_event_value_get_name(EV_ABS, ABS_MT_TOOL_TYPE, MT_TOOL_MAX + 1) == NULL);
+}
+END_TEST
+
+START_TEST(test_type_name)
+{
+	ck_assert_str_eq(libevdev_event_type_get_name(EV_SYN), "EV_SYN");
+	ck_assert_str_eq(libevdev_event_type_get_name(EV_REL), "EV_REL");
+	ck_assert_str_eq(libevdev_event_type_get_name(EV_ABS), "EV_ABS");
+	ck_assert_str_eq(libevdev_event_type_get_name(EV_MSC), "EV_MSC");
+	ck_assert_str_eq(libevdev_event_type_get_name(EV_SW),  "EV_SW");
+	ck_assert_str_eq(libevdev_event_type_get_name(EV_LED), "EV_LED");
+	ck_assert_str_eq(libevdev_event_type_get_name(EV_SND), "EV_SND");
+	ck_assert_str_eq(libevdev_event_type_get_name(EV_REP), "EV_REP");
+	ck_assert_str_eq(libevdev_event_type_get_name(EV_FF),  "EV_FF");
+	ck_assert_str_eq(libevdev_event_type_get_name(EV_PWR), "EV_PWR");
+	ck_assert_str_eq(libevdev_event_type_get_name(EV_FF_STATUS), "EV_FF_STATUS");
+	ck_assert_str_eq(libevdev_event_type_get_name(EV_MAX), "EV_MAX");
+}
+END_TEST
+
+START_TEST(test_code_abs_name)
+{
+	/* pick out a few only */
+	ck_assert_str_eq(libevdev_event_code_get_name(EV_ABS, ABS_X), "ABS_X");
+	ck_assert_str_eq(libevdev_event_code_get_name(EV_ABS, ABS_Y), "ABS_Y");
+
+	ck_assert_str_eq(libevdev_event_code_get_name(EV_ABS, ABS_MT_SLOT), "ABS_MT_SLOT");
+	ck_assert_str_eq(libevdev_event_code_get_name(EV_ABS, ABS_MISC), "ABS_MISC");
+	ck_assert_str_eq(libevdev_event_code_get_name(EV_ABS, ABS_MAX), "ABS_MAX");
+
+	ck_assert(libevdev_event_code_get_name(EV_ABS, ABS_MAX - 1) == NULL);
+
+}
+END_TEST
+
+START_TEST(test_code_rel_name)
+{
+	/* pick out a few only */
+	ck_assert_str_eq(libevdev_event_code_get_name(EV_REL, REL_X), "REL_X");
+	ck_assert_str_eq(libevdev_event_code_get_name(EV_REL, REL_Y), "REL_Y");
+	ck_assert_str_eq(libevdev_event_code_get_name(EV_REL, REL_MISC), "REL_MISC");
+	ck_assert_str_eq(libevdev_event_code_get_name(EV_REL, REL_MAX), "REL_MAX");
+
+	ck_assert(libevdev_event_code_get_name(EV_REL, REL_MAX - 1) == NULL);
+
+}
+END_TEST
+
+START_TEST(test_code_key_name)
+{
+	/* pick out a few only */
+	ck_assert_str_eq(libevdev_event_code_get_name(EV_KEY, KEY_RESERVED), "KEY_RESERVED");
+	ck_assert_str_eq(libevdev_event_code_get_name(EV_KEY, KEY_ESC), "KEY_ESC");
+	ck_assert_str_eq(libevdev_event_code_get_name(EV_KEY, KEY_1), "KEY_1");
+	ck_assert_str_eq(libevdev_event_code_get_name(EV_KEY, KEY_2), "KEY_2");
+	ck_assert_str_eq(libevdev_event_code_get_name(EV_KEY, KEY_UNKNOWN), "KEY_UNKNOWN");
+
+	ck_assert_str_eq(libevdev_event_code_get_name(EV_KEY, BTN_0), "BTN_0");
+	ck_assert_str_eq(libevdev_event_code_get_name(EV_KEY, BTN_LEFT), "BTN_LEFT");
+	ck_assert_str_eq(libevdev_event_code_get_name(EV_KEY, BTN_TRIGGER), "BTN_TRIGGER");
+	ck_assert_str_eq(libevdev_event_code_get_name(EV_KEY, BTN_A), "BTN_SOUTH");
+	ck_assert_str_eq(libevdev_event_code_get_name(EV_KEY, BTN_TOOL_PEN), "BTN_TOOL_PEN");
+
+	ck_assert_str_eq(libevdev_event_code_get_name(EV_KEY, KEY_TOUCHPAD_TOGGLE), "KEY_TOUCHPAD_TOGGLE");
+	ck_assert_str_eq(libevdev_event_code_get_name(EV_KEY, BTN_TRIGGER_HAPPY), "BTN_TRIGGER_HAPPY1");
+
+	ck_assert_str_eq(libevdev_event_code_get_name(EV_KEY, KEY_MAX), "KEY_MAX");
+	ck_assert(libevdev_event_code_get_name(EV_KEY, KEY_MAX - 1) == NULL);
+
+	/* special cases that resolve to something else */
+	ck_assert_str_eq(libevdev_event_code_get_name(EV_KEY, KEY_HANGUEL), "KEY_HANGEUL");
+	ck_assert_str_eq(libevdev_event_code_get_name(EV_KEY, KEY_SCREENLOCK), "KEY_COFFEE");
+	ck_assert_str_eq(libevdev_event_code_get_name(EV_KEY, BTN_MISC), "BTN_0");
+	ck_assert_str_eq(libevdev_event_code_get_name(EV_KEY, BTN_MOUSE), "BTN_LEFT");
+	ck_assert_str_eq(libevdev_event_code_get_name(EV_KEY, BTN_JOYSTICK), "BTN_TRIGGER");
+	ck_assert_str_eq(libevdev_event_code_get_name(EV_KEY, BTN_GAMEPAD), "BTN_SOUTH");
+	ck_assert_str_eq(libevdev_event_code_get_name(EV_KEY, BTN_DIGI), "BTN_TOOL_PEN");
+	ck_assert_str_eq(libevdev_event_code_get_name(EV_KEY, BTN_WHEEL), "BTN_GEAR_DOWN");
+	ck_assert_str_eq(libevdev_event_code_get_name(EV_KEY, BTN_TRIGGER_HAPPY), "BTN_TRIGGER_HAPPY1");
+
+}
+END_TEST
+
+START_TEST(test_code_led_name)
+{
+	/* pick out a few only */
+	ck_assert_str_eq(libevdev_event_code_get_name(EV_LED, LED_NUML), "LED_NUML");
+	ck_assert_str_eq(libevdev_event_code_get_name(EV_LED, LED_KANA), "LED_KANA");
+	ck_assert_str_eq(libevdev_event_code_get_name(EV_LED, LED_MAX), "LED_MAX");
+
+	ck_assert(libevdev_event_code_get_name(EV_LED, LED_MAX - 1) == NULL);
+
+}
+END_TEST
+
+START_TEST(test_code_snd_name)
+{
+	/* pick out a few only */
+	ck_assert_str_eq(libevdev_event_code_get_name(EV_SND, SND_CLICK), "SND_CLICK");
+	ck_assert_str_eq(libevdev_event_code_get_name(EV_SND, SND_TONE), "SND_TONE");
+	ck_assert_str_eq(libevdev_event_code_get_name(EV_SND, SND_MAX), "SND_MAX");
+
+	ck_assert(libevdev_event_code_get_name(EV_SND, SND_MAX - 1) == NULL);
+
+}
+END_TEST
+
+START_TEST(test_code_rep_name)
+{
+	ck_assert_str_eq(libevdev_event_code_get_name(EV_REP, REP_DELAY), "REP_DELAY");
+	ck_assert_str_eq(libevdev_event_code_get_name(EV_REP, REP_PERIOD), "REP_PERIOD");
+	ck_assert_str_eq(libevdev_event_code_get_name(EV_REP, REP_MAX), "REP_PERIOD");
+
+}
+END_TEST
+
+START_TEST(test_code_msc_name)
+{
+	/* pick out a few only */
+	ck_assert_str_eq(libevdev_event_code_get_name(EV_MSC, MSC_SERIAL), "MSC_SERIAL");
+	ck_assert_str_eq(libevdev_event_code_get_name(EV_MSC, MSC_RAW), "MSC_RAW");
+#ifdef MSC_TIMESTAMP
+	ck_assert_str_eq(libevdev_event_code_get_name(EV_MSC, MSC_TIMESTAMP), "MSC_TIMESTAMP");
+#endif
+	ck_assert_str_eq(libevdev_event_code_get_name(EV_MSC, MSC_MAX), "MSC_MAX");
+
+	ck_assert(libevdev_event_code_get_name(EV_MSC, MSC_MAX - 1) == NULL);
+
+}
+END_TEST
+
+START_TEST(test_code_sw_name)
+{
+	/* pick out a few only */
+	ck_assert_str_eq(libevdev_event_code_get_name(EV_SW, SW_LID), "SW_LID");
+	ck_assert_str_eq(libevdev_event_code_get_name(EV_SW, SW_RFKILL_ALL), "SW_RFKILL_ALL");
+	ck_assert_str_eq(libevdev_event_code_get_name(EV_SW, SW_LINEIN_INSERT), "SW_LINEIN_INSERT");
+	ck_assert_str_eq(libevdev_event_code_get_name(EV_SW, SW_PEN_INSERTED), "SW_PEN_INSERTED");
+	ck_assert_str_eq(libevdev_event_code_get_name(EV_SW, SW_MAX), "SW_MACHINE_COVER");
+}
+END_TEST
+
+START_TEST(test_code_ff_name)
+{
+	/* pick out a few only */
+	ck_assert_str_eq(libevdev_event_code_get_name(EV_FF, FF_STATUS_STOPPED), "FF_STATUS_STOPPED");
+	ck_assert_str_eq(libevdev_event_code_get_name(EV_FF, FF_FRICTION), "FF_FRICTION");
+	ck_assert_str_eq(libevdev_event_code_get_name(EV_FF, FF_CUSTOM), "FF_CUSTOM");
+	ck_assert_str_eq(libevdev_event_code_get_name(EV_FF, FF_MAX), "FF_MAX");
+
+	ck_assert(libevdev_event_code_get_name(EV_FF, FF_MAX - 1) == NULL);
+
+}
+END_TEST
+
+START_TEST(test_code_syn_name)
+{
+	ck_assert_str_eq(libevdev_event_code_get_name(EV_SYN, SYN_REPORT), "SYN_REPORT");
+	ck_assert_str_eq(libevdev_event_code_get_name(EV_SYN, SYN_CONFIG), "SYN_CONFIG");
+	ck_assert_str_eq(libevdev_event_code_get_name(EV_SYN, SYN_MT_REPORT), "SYN_MT_REPORT");
+	ck_assert_str_eq(libevdev_event_code_get_name(EV_SYN, SYN_DROPPED), "SYN_DROPPED");
+	ck_assert_str_eq(libevdev_event_code_get_name(EV_SYN, SYN_MAX), "SYN_MAX");
+}
+END_TEST
+
+START_TEST(test_value_name)
+{
+	unsigned int type, code;
+	int value;
+
+	for (type = 0; type < EV_MAX; type++) {
+		int max = libevdev_event_type_get_max(type);
+
+		if (max == -1)
+			continue;
+
+		for (code = 0; code < (unsigned int)max; code++) {
+			if (type == EV_ABS && code == ABS_MT_TOOL_TYPE)
+				continue;
+
+			for (value = 0; value < 0xff; value++) {
+				ck_assert(libevdev_event_value_get_name(type, code, value) == NULL);
+			}
+		}
+	}
+
+	ck_assert_str_eq(libevdev_event_value_get_name(EV_ABS, ABS_MT_TOOL_TYPE, MT_TOOL_FINGER), "MT_TOOL_FINGER");
+	ck_assert_str_eq(libevdev_event_value_get_name(EV_ABS, ABS_MT_TOOL_TYPE, MT_TOOL_PALM), "MT_TOOL_PALM");
+	ck_assert_str_eq(libevdev_event_value_get_name(EV_ABS, ABS_MT_TOOL_TYPE, MT_TOOL_PEN), "MT_TOOL_PEN");
+	ck_assert_str_eq(libevdev_event_value_get_name(EV_ABS, ABS_MT_TOOL_TYPE, MT_TOOL_MAX), "MT_TOOL_MAX");
+	ck_assert(libevdev_event_value_get_name(EV_ABS, ABS_MT_TOOL_TYPE, -1) == NULL);
+}
+END_TEST
+
+START_TEST(test_prop_name)
+{
+	ck_assert_str_eq(libevdev_property_get_name(INPUT_PROP_POINTER), "INPUT_PROP_POINTER");
+	ck_assert_str_eq(libevdev_property_get_name(INPUT_PROP_DIRECT), "INPUT_PROP_DIRECT");
+	ck_assert_str_eq(libevdev_property_get_name(INPUT_PROP_BUTTONPAD), "INPUT_PROP_BUTTONPAD");
+	ck_assert_str_eq(libevdev_property_get_name(INPUT_PROP_SEMI_MT), "INPUT_PROP_SEMI_MT");
+	ck_assert_str_eq(libevdev_property_get_name(INPUT_PROP_MAX), "INPUT_PROP_MAX");
+
+	ck_assert(libevdev_property_get_name(INPUT_PROP_MAX - 1) == NULL);
+	ck_assert(libevdev_property_get_name(INPUT_PROP_MAX + 1) == NULL);
+}
+END_TEST
+
+START_TEST(test_event_type_max)
+{
+	ck_assert_int_eq(libevdev_event_type_get_max(EV_ABS), ABS_MAX);
+	ck_assert_int_eq(libevdev_event_type_get_max(EV_REL), REL_MAX);
+	ck_assert_int_eq(libevdev_event_type_get_max(EV_KEY), KEY_MAX);
+
+	ck_assert_int_eq(libevdev_event_type_get_max(EV_MAX - 1), -1);
+	ck_assert_int_eq(libevdev_event_type_get_max(EV_MAX + 1), -1);
+
+}
+END_TEST
+
+START_TEST(test_event_type)
+{
+	struct input_event ev;
+	int i = 0;
+
+	ev.type = EV_REL;
+
+	ck_assert_int_eq(libevdev_event_is_type(&ev, EV_REL), 1);
+	for (i = 0; i < EV_CNT; i++) {
+		if (i == ev.type)
+			continue;
+		ck_assert_int_eq(libevdev_event_is_type(&ev, i), 0);
+	}
+	ck_assert_int_eq(libevdev_event_is_type(&ev, EV_MAX + 1), 0);
+}
+END_TEST
+
+START_TEST(test_event_code)
+{
+	struct input_event ev;
+	int i = 0;
+
+	ev.type = EV_REL;
+	ev.code = REL_Y;
+
+	ck_assert_int_eq(libevdev_event_is_code(&ev, EV_REL, REL_Y), 1);
+	for (i = 0; i < EV_CNT; i++) {
+		int j;
+		if (i == ev.type || i == EV_SYN)
+			continue;
+
+		for (j = 0; j < libevdev_event_type_get_max(i); i++) {
+			ck_assert_int_eq(libevdev_event_is_code(&ev, i, j), 0);
+		}
+	}
+	ck_assert_int_eq(libevdev_event_is_code(&ev, EV_MAX + 1, ev.code), 0);
+	ck_assert_int_eq(libevdev_event_is_code(&ev, EV_REL, REL_MAX + 1), 0);
+
+	ev.type = EV_SYN;
+	ev.code = SYN_REPORT;
+	ck_assert_int_eq(libevdev_event_is_code(&ev, EV_SYN, SYN_REPORT), 1);
+	ck_assert_int_eq(libevdev_event_is_code(&ev, EV_SYN, SYN_DROPPED), 0);
+}
+END_TEST
+
+TEST_SUITE(event_name_suite)
+{
+	Suite *s = suite_create("Event names");
+
+	add_test(s, test_limits);
+	add_test(s, test_event_type_max);
+
+	add_test(s, test_type_name);
+
+	add_test(s, test_code_abs_name);
+	add_test(s, test_code_rel_name);
+	add_test(s, test_code_key_name);
+	add_test(s, test_code_led_name);
+	add_test(s, test_code_snd_name);
+	add_test(s, test_code_rep_name);
+	add_test(s, test_code_msc_name);
+	add_test(s, test_code_sw_name);
+	add_test(s, test_code_ff_name);
+	add_test(s, test_code_syn_name);
+
+	add_test(s, test_value_name);
+	add_test(s, test_prop_name);
+
+	add_test(s, test_event_type);
+	add_test(s, test_event_code);
+
+	return s;
+}
diff --git a/test/test-int-queue.c b/test/test-int-queue.c
new file mode 100644
index 0000000000000000000000000000000000000000..c34a2e873782648fb3222afc6189871dc0d0f159
--- /dev/null
+++ b/test/test-int-queue.c
@@ -0,0 +1,338 @@
+// SPDX-License-Identifier: MIT
+/*
+ * Copyright © 2013 Red Hat, Inc.
+ */
+
+#include "config.h"
+#include 
+#include 
+#include "test-common.h"
+
+START_TEST(test_queue_alloc)
+{
+	struct libevdev dev;
+	int rc;
+
+	rc = queue_alloc(&dev, 0);
+	ck_assert_int_eq(rc, -ENOMEM);
+
+	rc = queue_alloc(&dev, 100);
+	ck_assert_int_eq(rc, 0);
+
+	ck_assert_int_eq(dev.queue_size, 100);
+	ck_assert_int_eq(dev.queue_next, 0);
+
+	queue_free(&dev);
+	ck_assert_int_eq(dev.queue_size, 0);
+	ck_assert_int_eq(dev.queue_next, 0);
+
+}
+END_TEST
+
+START_TEST(test_queue_sizes)
+{
+	struct libevdev dev = {0};
+
+	queue_alloc(&dev, 0);
+	ck_assert_int_eq(queue_num_elements(&dev), 0);
+	ck_assert_int_eq(queue_num_free_elements(&dev), 0);
+	ck_assert_int_eq(queue_size(&dev), 0);
+
+	queue_alloc(&dev, 100);
+	ck_assert_int_eq(queue_num_elements(&dev), 0);
+	ck_assert_int_eq(queue_num_free_elements(&dev), 100);
+	ck_assert_int_eq(queue_size(&dev), 100);
+
+	queue_free(&dev);
+
+	ck_assert_int_eq(queue_num_elements(&dev), 0);
+	ck_assert_int_eq(queue_num_free_elements(&dev), 0);
+	ck_assert_int_eq(queue_size(&dev), 0);
+}
+END_TEST
+
+START_TEST(test_queue_push)
+{
+	struct libevdev dev = {0};
+	struct input_event *ev;
+
+	queue_alloc(&dev, 0);
+	ev = queue_push(&dev);
+	ck_assert(ev == NULL);
+
+	queue_alloc(&dev, 2);
+	ev = queue_push(&dev);
+	ck_assert(ev == dev.queue);
+	ck_assert_int_eq(queue_num_elements(&dev), 1);
+	ck_assert_int_eq(queue_num_free_elements(&dev), 1);
+
+	ev = queue_push(&dev);
+	ck_assert(ev == dev.queue + 1);
+
+	ev = queue_push(&dev);
+	ck_assert(ev == NULL);
+
+	queue_free(&dev);
+	ev = queue_push(&dev);
+	ck_assert(ev == NULL);
+
+}
+END_TEST
+
+START_TEST(test_queue_pop)
+{
+	struct libevdev dev = {0};
+	struct input_event ev, *e, tmp;
+	int rc;
+
+	queue_alloc(&dev, 0);
+	rc = queue_pop(&dev, &ev);
+	ck_assert_int_eq(rc, 1);
+
+	queue_alloc(&dev, 2);
+	e = queue_push(&dev);
+	memset(e, 0xab, sizeof(*e));
+	ck_assert_int_eq(queue_num_elements(&dev), 1);
+	ck_assert_int_eq(queue_num_free_elements(&dev), 1);
+
+	rc = queue_pop(&dev, &ev);
+	ck_assert_int_eq(rc, 0);
+	memset(&tmp, 0xab, sizeof(tmp));
+	rc = memcmp(&tmp, &ev, sizeof(tmp));
+	ck_assert_int_eq(rc, 0);
+
+	ck_assert_int_eq(queue_num_elements(&dev), 0);
+	ck_assert_int_eq(queue_num_free_elements(&dev), 2);
+
+	rc = queue_pop(&dev, &ev);
+	ck_assert_int_eq(rc, 1);
+
+	queue_free(&dev);
+}
+END_TEST
+
+START_TEST(test_queue_peek)
+{
+	struct libevdev dev = {0};
+	struct input_event ev, *e, tmp;
+	int rc;
+
+	queue_alloc(&dev, 0);
+	rc = queue_peek(&dev, 0, &ev);
+	ck_assert_int_eq(rc, 1);
+
+	queue_alloc(&dev, 2);
+	e = queue_push(&dev);
+	memset(e, 0xab, sizeof(*e));
+
+	rc = queue_peek(&dev, 0, &ev);
+	ck_assert_int_eq(rc, 0);
+	memset(&tmp, 0xab, sizeof(tmp));
+	rc = memcmp(&tmp, &ev, sizeof(tmp));
+	ck_assert_int_eq(rc, 0);
+
+	ck_assert_int_eq(queue_num_elements(&dev), 1);
+	e = queue_push(&dev);
+	memset(e, 0xbc, sizeof(*e));
+
+	rc = queue_peek(&dev, 1, &ev);
+	ck_assert_int_eq(rc, 0);
+	memset(&tmp, 0xbc, sizeof(tmp));
+	rc = memcmp(&tmp, &ev, sizeof(tmp));
+	ck_assert_int_eq(rc, 0);
+
+	rc = queue_peek(&dev, 0, &ev);
+	ck_assert_int_eq(rc, 0);
+	memset(&tmp, 0xab, sizeof(tmp));
+	rc = memcmp(&tmp, &ev, sizeof(tmp));
+	ck_assert_int_eq(rc, 0);
+
+	ck_assert_int_eq(queue_num_elements(&dev), 2);
+
+	queue_free(&dev);
+}
+END_TEST
+
+START_TEST(test_queue_shift)
+{
+	struct libevdev dev = {0};
+	struct input_event ev, *first, *second, e1, e2;
+	int rc;
+
+	ck_assert_int_eq(queue_shift(&dev, &ev), 1);
+
+	queue_alloc(&dev, 10);
+	ck_assert_int_eq(queue_shift(&dev, &ev), 1);
+
+	first = queue_push(&dev);
+	ck_assert(first != NULL);
+	memset(first, 0xab, sizeof(*first));
+
+	e1 = *first;
+
+	second = queue_push(&dev);
+	ck_assert(second != NULL);
+	memset(second, 0x12, sizeof(*second));
+
+	e2 = *second;
+
+	rc = queue_shift(&dev, &ev);
+	ck_assert_int_eq(rc, 0);
+	rc = memcmp(&ev, &e1, sizeof(ev));
+	ck_assert_int_eq(rc, 0);
+
+	rc = queue_shift(&dev, &ev);
+	ck_assert_int_eq(rc, 0);
+	rc = memcmp(&ev, &e2, sizeof(ev));
+	ck_assert_int_eq(rc, 0);
+
+	ck_assert_int_eq(queue_shift(&dev, &ev), 1);
+
+	queue_free(&dev);
+}
+END_TEST
+
+START_TEST(test_queue_shift_multiple)
+{
+	struct libevdev dev = {0};
+	struct input_event ev, *first, *second, e1, e2;
+	struct input_event events[5];
+	int rc;
+
+	ck_assert_int_eq(queue_shift_multiple(&dev, 1, &ev), 0);
+	ck_assert_int_eq(queue_shift_multiple(&dev, 0, &ev), 0);
+
+	queue_alloc(&dev, 10);
+	ck_assert_int_eq(queue_shift_multiple(&dev, 1, &ev), 0);
+	ck_assert_int_eq(queue_shift_multiple(&dev, 0, &ev), 0);
+
+	first = queue_push(&dev);
+	ck_assert(first != NULL);
+	memset(first, 0xab, sizeof(*first));
+	e1 = *first;
+
+	second = queue_push(&dev);
+	ck_assert(second != NULL);
+	memset(second, 0x12, sizeof(*second));
+	e2 = *second;
+
+	rc = queue_shift_multiple(&dev, 5, events);
+	ck_assert_int_eq(rc, 2);
+	rc = memcmp(&events[0], &e1, sizeof(ev));
+	ck_assert_int_eq(rc, 0);
+	rc = memcmp(&events[1], &e2, sizeof(ev));
+	ck_assert_int_eq(rc, 0);
+
+	first = queue_push(&dev);
+	ck_assert(first != NULL);
+	memset(first, 0xab, sizeof(*first));
+	e1 = *first;
+
+	second = queue_push(&dev);
+	ck_assert(second != NULL);
+	memset(second, 0x12, sizeof(*second));
+	e2 = *second;
+
+	rc = queue_shift_multiple(&dev, 1, events);
+	ck_assert_int_eq(rc, 1);
+	rc = memcmp(&events[0], &e1, sizeof(ev));
+	ck_assert_int_eq(rc, 0);
+
+	rc = queue_shift_multiple(&dev, 1, events);
+	ck_assert_int_eq(rc, 1);
+	rc = memcmp(&events[0], &e2, sizeof(ev));
+	ck_assert_int_eq(rc, 0);
+
+	ck_assert_int_eq(queue_shift_multiple(&dev, 1, events), 0);
+
+	queue_free(&dev);
+}
+END_TEST
+
+START_TEST(test_queue_next_element)
+{
+	struct libevdev dev = {0};
+	struct input_event ev, *first, *second;
+	int rc;
+
+	queue_alloc(&dev, 0);
+	first = queue_next_element(&dev);
+	ck_assert(first == NULL);
+
+	queue_alloc(&dev, 2);
+	first = queue_next_element(&dev);
+	ck_assert(first != NULL);
+	memset(first, 0xab, sizeof(*first));
+
+	second = queue_next_element(&dev);
+	ck_assert(second != NULL);
+	memset(second, 0xbc, sizeof(*second));
+
+	/* queue_next_element does not advance, so we overwrite */
+	memset(&ev, 0xbc, sizeof(ev));
+	rc = memcmp(&ev, first, sizeof(ev));
+	ck_assert_int_eq(rc, 0);
+
+	ck_assert_int_eq(queue_num_elements(&dev), 0);
+
+	first = queue_next_element(&dev);
+	ck_assert(first != NULL);
+	memset(first, 0xab, sizeof(*first));
+
+	queue_set_num_elements(&dev, 1);
+	ck_assert_int_eq(queue_num_elements(&dev), 1);
+
+	second = queue_next_element(&dev);
+	ck_assert(second != NULL);
+	memset(second, 0xbc, sizeof(*second));
+
+	memset(&ev, 0xab, sizeof(ev));
+	rc = memcmp(&ev, first, sizeof(ev));
+	ck_assert_int_eq(rc, 0);
+
+	queue_free(&dev);
+}
+END_TEST
+
+START_TEST(test_queue_set_num_elements)
+{
+	struct libevdev dev = {0};
+
+	queue_alloc(&dev, 0);
+	ck_assert_int_eq(queue_set_num_elements(&dev, 1), 1);
+
+	queue_alloc(&dev, 2);
+	ck_assert_int_eq(queue_set_num_elements(&dev, 3), 1);
+	ck_assert_int_eq(queue_set_num_elements(&dev, 2), 0);
+
+	queue_free(&dev);
+}
+END_TEST
+
+TEST_SUITE(queue_suite)
+{
+	Suite *s = suite_create("Event queue");
+
+	TCase *tc = tcase_create("Queue allocation");
+	tcase_add_test(tc, test_queue_alloc);
+	tcase_add_test(tc, test_queue_sizes);
+	suite_add_tcase(s, tc);
+
+	tc = tcase_create("Queue push/pop/peek");
+	tcase_add_test(tc, test_queue_push);
+	tcase_add_test(tc, test_queue_pop);
+	tcase_add_test(tc, test_queue_peek);
+	suite_add_tcase(s, tc);
+
+	tc = tcase_create("Queue shift");
+	tcase_add_test(tc, test_queue_shift);
+	tcase_add_test(tc, test_queue_shift_multiple);
+	suite_add_tcase(s, tc);
+
+	tc = tcase_create("Queue next elem");
+	tcase_add_test(tc, test_queue_next_element);
+	tcase_add_test(tc, test_queue_set_num_elements);
+	suite_add_tcase(s, tc);
+
+	return s;
+}
diff --git a/test/test-kernel.c b/test/test-kernel.c
new file mode 100644
index 0000000000000000000000000000000000000000..bbd12f2bd51b729e064e56a696f8cea887902b25
--- /dev/null
+++ b/test/test-kernel.c
@@ -0,0 +1,160 @@
+// SPDX-License-Identifier: MIT
+/*
+ * Copyright © 2014 Red Hat, Inc.
+ */
+
+#include "config.h"
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+#include 
+#include "test-common.h"
+
+START_TEST(test_revoke)
+{
+	struct uinput_device* uidev;
+	struct libevdev *dev, *dev2;
+	int rc, fd;
+	struct input_event ev1, ev2;
+	int dev_fd;
+
+	test_create_device(&uidev, &dev,
+			   EV_SYN, SYN_REPORT,
+			   EV_REL, REL_X,
+			   EV_REL, REL_Y,
+			   EV_REL, REL_WHEEL,
+			   EV_KEY, BTN_LEFT,
+			   EV_KEY, BTN_MIDDLE,
+			   EV_KEY, BTN_RIGHT,
+			   -1);
+
+	fd = open(uinput_device_get_devnode(uidev), O_RDONLY|O_NONBLOCK);
+	ck_assert_int_gt(fd, -1);
+	rc = libevdev_new_from_fd(fd, &dev2);
+	ck_assert_msg(rc == 0, "Failed to create second device: %s", strerror(-rc));
+
+	uinput_device_event(uidev, EV_REL, REL_X, 1);
+	uinput_device_event(uidev, EV_SYN, SYN_REPORT, 0);
+
+	for (int i = 0; i < 2; i++) {
+		rc = libevdev_next_event(dev, LIBEVDEV_READ_FLAG_NORMAL, &ev1);
+		ck_assert_int_eq(rc, LIBEVDEV_READ_STATUS_SUCCESS);
+
+		rc = libevdev_next_event(dev2, LIBEVDEV_READ_FLAG_NORMAL, &ev2);
+		ck_assert_int_eq(rc, LIBEVDEV_READ_STATUS_SUCCESS);
+
+		ck_assert_int_eq(ev1.type, ev2.type);
+		ck_assert_int_eq(ev1.code, ev2.code);
+		ck_assert_int_eq(ev1.value, ev2.value);
+	}
+
+	/* revoke first device, expect it closed, second device still open */
+	dev_fd = libevdev_get_fd(dev);
+	ck_assert_int_ge(dev_fd, 0);
+	rc = ioctl(dev_fd, EVIOCREVOKE, NULL);
+	if (rc == -1 && errno == EINVAL) {
+		fprintf(stderr, "WARNING: skipping EVIOCREVOKE test, not suported by current kernel\n");
+		goto out;
+	}
+	ck_assert_msg(rc == 0, "Failed to revoke device: %s", strerror(errno));
+
+	uinput_device_event(uidev, EV_REL, REL_X, 1);
+	uinput_device_event(uidev, EV_SYN, SYN_REPORT, 0);
+
+	rc = libevdev_next_event(dev, LIBEVDEV_READ_FLAG_NORMAL, &ev1);
+	ck_assert_int_eq(rc, -ENODEV);
+
+	rc = libevdev_next_event(dev2, LIBEVDEV_READ_FLAG_NORMAL, &ev2);
+	ck_assert_int_eq(rc, LIBEVDEV_READ_STATUS_SUCCESS);
+
+out:
+	uinput_device_free(uidev);
+	libevdev_free(dev);
+	libevdev_free(dev2);
+	close(fd);
+}
+END_TEST
+
+START_TEST(test_revoke_invalid)
+{
+	struct uinput_device* uidev;
+	struct libevdev *dev;
+	int rc;
+	int dev_fd;
+
+	test_create_device(&uidev, &dev,
+			   EV_SYN, SYN_REPORT,
+			   EV_REL, REL_X,
+			   EV_REL, REL_Y,
+			   EV_REL, REL_WHEEL,
+			   EV_KEY, BTN_LEFT,
+			   EV_KEY, BTN_MIDDLE,
+			   EV_KEY, BTN_RIGHT,
+			   -1);
+
+	dev_fd = libevdev_get_fd(dev);
+	ck_assert_int_ge(dev_fd, 0);
+	/* ioctl requires 0 as value */
+	rc = ioctl(dev_fd, EVIOCREVOKE, 1);
+	ck_assert_int_eq(rc, -1);
+	ck_assert_int_eq(errno, EINVAL);
+
+	uinput_device_free(uidev);
+	libevdev_free(dev);
+}
+END_TEST
+
+START_TEST(test_revoke_fail_after)
+{
+	struct uinput_device* uidev;
+	struct libevdev *dev, *dev2 = NULL;
+	int rc, fd;
+
+	test_create_device(&uidev, &dev,
+			   EV_SYN, SYN_REPORT,
+			   EV_REL, REL_X,
+			   EV_REL, REL_Y,
+			   EV_REL, REL_WHEEL,
+			   EV_KEY, BTN_LEFT,
+			   EV_KEY, BTN_MIDDLE,
+			   EV_KEY, BTN_RIGHT,
+			   -1);
+
+	fd = open(uinput_device_get_devnode(uidev), O_RDONLY|O_NONBLOCK);
+	ck_assert_int_gt(fd, -1);
+
+	rc = ioctl(fd, EVIOCREVOKE, NULL);
+	if (rc == -1 && errno == EINVAL) {
+		fprintf(stderr, "WARNING: skipping EVIOCREVOKE test, not suported by current kernel\n");
+		goto out;
+	}
+	ck_assert_msg(rc == 0, "Failed to revoke device: %s", strerror(errno));
+
+	rc = libevdev_new_from_fd(fd, &dev2);
+	ck_assert_int_eq(rc, -ENODEV);
+
+out:
+	uinput_device_free(uidev);
+	libevdev_free(dev);
+	close(fd);
+}
+END_TEST
+
+TEST_SUITE_ROOT_PRIVILEGES(kernel)
+{
+	Suite *s = suite_create("kernel");
+
+	add_test(s, test_revoke);
+	add_test(s, test_revoke_invalid);
+	add_test(s, test_revoke_fail_after);
+
+	return s;
+}
diff --git a/test/test-libevdev-events.c b/test/test-libevdev-events.c
new file mode 100644
index 0000000000000000000000000000000000000000..287c572f09c6e416e9a88ea1e477a3446c4d317f
--- /dev/null
+++ b/test/test-libevdev-events.c
@@ -0,0 +1,2084 @@
+// SPDX-License-Identifier: MIT
+/*
+ * Copyright © 2013 Red Hat, Inc.
+ */
+
+#include "config.h"
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "test-common.h"
+
+START_TEST(test_next_event)
+{
+	struct uinput_device* uidev;
+	struct libevdev *dev;
+	int rc;
+	struct input_event ev;
+
+	test_create_device(&uidev, &dev,
+			   EV_REL, REL_X,
+			   EV_REL, REL_Y,
+			   EV_KEY, BTN_LEFT,
+			   -1);
+
+	rc = libevdev_next_event(dev, LIBEVDEV_READ_FLAG_NORMAL, &ev);
+	ck_assert_int_eq(rc, -EAGAIN);
+
+	uinput_device_event(uidev, EV_KEY, BTN_LEFT, 1);
+	uinput_device_event(uidev, EV_SYN, SYN_REPORT, 0);
+	rc = libevdev_next_event(dev, LIBEVDEV_READ_FLAG_NORMAL, &ev);
+	ck_assert_int_eq(rc, LIBEVDEV_READ_STATUS_SUCCESS);
+	assert_event(&ev, EV_KEY, BTN_LEFT, 1);
+
+	libevdev_free(dev);
+	uinput_device_free(uidev);
+
+}
+END_TEST
+
+START_TEST(test_next_event_invalid_fd)
+{
+	struct uinput_device* uidev;
+	struct libevdev *dev;
+	int rc;
+	struct input_event ev;
+
+	libevdev_set_log_function(test_logfunc_ignore_error, NULL);
+
+	dev = libevdev_new();
+	rc = libevdev_next_event(dev, LIBEVDEV_READ_FLAG_NORMAL, &ev);
+	ck_assert_int_eq(rc, -EBADF);
+	libevdev_free(dev);
+
+	test_create_device(&uidev, &dev,
+			   EV_REL, REL_X,
+			   EV_REL, REL_Y,
+			   EV_KEY, BTN_LEFT,
+			   -1);
+
+	/* invalid (missing) flag */
+	rc = libevdev_next_event(dev, 0x10, &ev);
+	ck_assert_int_eq(rc, -EINVAL);
+
+	/* set an invalid fd */
+	rc = libevdev_change_fd(dev, -3);
+	ck_assert_int_eq(rc, 0);
+	rc = libevdev_next_event(dev, LIBEVDEV_READ_FLAG_NORMAL, &ev);
+	ck_assert_int_eq(rc, -EBADF);
+
+	libevdev_set_log_function(test_logfunc_abort_on_error, NULL);
+
+	libevdev_free(dev);
+	uinput_device_free(uidev);
+}
+END_TEST
+
+START_TEST(test_next_event_blocking)
+{
+	struct uinput_device* uidev;
+	struct libevdev *dev;
+	int fd, flags;
+	int rc;
+	struct input_event ev;
+
+	test_create_device(&uidev, &dev,
+			   EV_REL, REL_X,
+			   EV_REL, REL_Y,
+			   EV_KEY, BTN_LEFT,
+			   -1);
+
+	fd = libevdev_get_fd(dev);
+	flags = fcntl(fd, F_GETFL) & ~O_NONBLOCK;
+	rc = fcntl(fd, F_SETFL, flags);
+	ck_assert_int_eq(rc, 0);
+
+	uinput_device_event(uidev, EV_KEY, BTN_LEFT, 1);
+	uinput_device_event(uidev, EV_SYN, SYN_REPORT, 0);
+	rc = libevdev_next_event(dev, LIBEVDEV_READ_FLAG_BLOCKING, &ev);
+	ck_assert_int_eq(rc, LIBEVDEV_READ_STATUS_SUCCESS);
+	assert_event(&ev, EV_KEY, BTN_LEFT, 1);
+
+	libevdev_free(dev);
+	uinput_device_free(uidev);
+}
+END_TEST
+
+START_TEST(test_syn_dropped_event)
+{
+	struct uinput_device* uidev;
+	struct libevdev *dev;
+	int rc;
+	struct input_event ev;
+	int pipefd[2];
+
+	test_create_device(&uidev, &dev,
+			   EV_SYN, SYN_REPORT,
+			   EV_SYN, SYN_DROPPED,
+			   EV_REL, REL_X,
+			   EV_REL, REL_Y,
+			   EV_KEY, BTN_LEFT,
+			   -1);
+
+	/* This is a bit complicated:
+	   we can't get SYN_DROPPED through uinput, so we push two events down
+	   uinput, and process those. Then write a SYN_DROPPED on a pipe,
+	   switch the fd and read one event off the wire. Switch back, so
+	   that when we do read off the SYN_DROPPED we have the fd back on
+	   the device and the ioctls work.
+	 */
+	uinput_device_event(uidev, EV_KEY, BTN_LEFT, 1);
+	uinput_device_event(uidev, EV_SYN, SYN_REPORT, 0);
+	rc = libevdev_next_event(dev, LIBEVDEV_READ_FLAG_NORMAL, &ev);
+	ck_assert_int_eq(rc, LIBEVDEV_READ_STATUS_SUCCESS);
+	assert_event(&ev, EV_KEY, BTN_LEFT, 1);
+
+	rc = libevdev_next_event(dev, LIBEVDEV_READ_FLAG_NORMAL, &ev);
+	ck_assert_int_eq(rc, LIBEVDEV_READ_STATUS_SUCCESS);
+	assert_event(&ev, EV_SYN, SYN_REPORT, 0);
+
+	rc = pipe2(pipefd, O_NONBLOCK);
+	ck_assert_int_eq(rc, 0);
+
+	libevdev_change_fd(dev, pipefd[0]);
+	ev.type = EV_SYN;
+	ev.code = SYN_DROPPED;
+	ev.value = 0;
+	rc = write(pipefd[1], &ev, sizeof(ev));
+	ck_assert_int_eq(rc, sizeof(ev));
+
+	rc = libevdev_next_event(dev, LIBEVDEV_READ_FLAG_NORMAL, &ev);
+	ck_assert_int_eq(rc, LIBEVDEV_READ_STATUS_SYNC);
+	assert_event(&ev, EV_SYN, SYN_DROPPED, 0);
+
+	libevdev_change_fd(dev, uinput_device_get_fd(uidev));
+	/* only check for the rc, nothing actually changed on the device */
+
+	libevdev_free(dev);
+	uinput_device_free(uidev);
+
+	close(pipefd[0]);
+	close(pipefd[1]);
+
+}
+END_TEST
+
+START_TEST(test_event_type_filtered)
+{
+	struct uinput_device* uidev;
+	struct libevdev *dev;
+	int rc;
+	struct input_event ev;
+
+	test_create_device(&uidev, &dev,
+			   EV_REL, REL_X,
+			   EV_REL, REL_Y,
+			   EV_KEY, BTN_LEFT,
+			   -1);
+
+	libevdev_disable_event_type(dev, EV_REL);
+
+	rc = libevdev_next_event(dev, LIBEVDEV_READ_FLAG_NORMAL, &ev);
+	ck_assert_int_eq(rc, -EAGAIN);
+
+	uinput_device_event(uidev, EV_REL, REL_X, 1);
+	uinput_device_event(uidev, EV_KEY, REL_Y, 1);
+	uinput_device_event(uidev, EV_SYN, SYN_REPORT, 0);
+	rc = libevdev_next_event(dev, LIBEVDEV_READ_FLAG_NORMAL, &ev);
+	ck_assert_int_eq(rc, LIBEVDEV_READ_STATUS_SUCCESS);
+	assert_event(&ev, EV_SYN, SYN_REPORT, 0);
+
+	rc = libevdev_next_event(dev, LIBEVDEV_READ_FLAG_NORMAL, &ev);
+	ck_assert_int_eq(rc, -EAGAIN);
+
+	libevdev_free(dev);
+	uinput_device_free(uidev);
+
+}
+END_TEST
+
+START_TEST(test_event_code_filtered)
+{
+	struct uinput_device* uidev;
+	struct libevdev *dev;
+	int rc;
+	struct input_event ev;
+
+	test_create_device(&uidev, &dev,
+			   EV_REL, REL_X,
+			   EV_REL, REL_Y,
+			   EV_KEY, BTN_LEFT,
+			   -1);
+
+	libevdev_disable_event_code(dev, EV_REL, REL_X);
+
+	rc = libevdev_next_event(dev, LIBEVDEV_READ_FLAG_NORMAL, &ev);
+	ck_assert_int_eq(rc, -EAGAIN);
+
+	uinput_device_event(uidev, EV_REL, REL_X, 1);
+	uinput_device_event(uidev, EV_REL, REL_Y, 1);
+	uinput_device_event(uidev, EV_SYN, SYN_REPORT, 0);
+	rc = libevdev_next_event(dev, LIBEVDEV_READ_FLAG_NORMAL, &ev);
+	ck_assert_int_eq(rc, LIBEVDEV_READ_STATUS_SUCCESS);
+	assert_event(&ev, EV_REL, REL_Y, 1);
+
+	rc = libevdev_next_event(dev, LIBEVDEV_READ_FLAG_NORMAL, &ev);
+	ck_assert_int_eq(rc, LIBEVDEV_READ_STATUS_SUCCESS);
+	assert_event(&ev, EV_SYN, SYN_REPORT, 0);
+
+	rc = libevdev_next_event(dev, LIBEVDEV_READ_FLAG_NORMAL, &ev);
+	ck_assert_int_eq(rc, -EAGAIN);
+
+	libevdev_free(dev);
+	uinput_device_free(uidev);
+
+}
+END_TEST
+
+START_TEST(test_has_event_pending)
+{
+	struct uinput_device* uidev;
+	struct libevdev *dev;
+	int rc;
+	struct input_event ev;
+
+	test_create_device(&uidev, &dev,
+			   EV_REL, REL_X,
+			   EV_REL, REL_Y,
+			   EV_KEY, BTN_LEFT,
+			   -1);
+
+	ck_assert_int_eq(libevdev_has_event_pending(dev), 0);
+
+	uinput_device_event(uidev, EV_REL, REL_X, 1);
+	uinput_device_event(uidev, EV_REL, REL_Y, 1);
+	uinput_device_event(uidev, EV_SYN, SYN_REPORT, 0);
+
+	ck_assert_int_eq(libevdev_has_event_pending(dev), 1);
+
+	libevdev_next_event(dev, LIBEVDEV_READ_FLAG_NORMAL, &ev);
+
+	ck_assert_int_eq(libevdev_has_event_pending(dev), 1);
+
+	while ((rc = libevdev_next_event(dev, LIBEVDEV_READ_FLAG_NORMAL, &ev)) != -EAGAIN)
+			;
+
+	ck_assert_int_eq(libevdev_has_event_pending(dev), 0);
+
+	libevdev_change_fd(dev, -1);
+	ck_assert_int_eq(libevdev_has_event_pending(dev), -EBADF);
+
+	libevdev_free(dev);
+	uinput_device_free(uidev);
+
+}
+END_TEST
+
+START_TEST(test_has_event_pending_invalid_fd)
+{
+	struct libevdev *dev;
+	int rc;
+
+	libevdev_set_log_function(test_logfunc_ignore_error, NULL);
+
+	dev = libevdev_new();
+	rc = libevdev_has_event_pending(dev);
+	ck_assert_int_eq(rc, -EBADF);
+
+	libevdev_set_log_function(test_logfunc_abort_on_error, NULL);
+
+	libevdev_free(dev);
+}
+END_TEST
+
+START_TEST(test_syn_delta_button)
+{
+	struct uinput_device* uidev;
+	struct libevdev *dev;
+	int rc;
+	struct input_event ev;
+
+	test_create_device(&uidev, &dev,
+			   EV_SYN, SYN_REPORT,
+			   EV_SYN, SYN_DROPPED,
+			   EV_REL, REL_X,
+			   EV_REL, REL_Y,
+			   EV_KEY, BTN_LEFT,
+			   EV_KEY, BTN_MIDDLE,
+			   EV_KEY, BTN_RIGHT,
+			   EV_KEY, KEY_MAX,
+			   -1);
+
+	uinput_device_event(uidev, EV_KEY, BTN_LEFT, 1);
+	uinput_device_event(uidev, EV_KEY, BTN_RIGHT, 1);
+	uinput_device_event(uidev, EV_KEY, KEY_MAX, 1);
+	uinput_device_event(uidev, EV_SYN, SYN_REPORT, 0);
+	rc = libevdev_next_event(dev, LIBEVDEV_READ_FLAG_FORCE_SYNC, &ev);
+	ck_assert_int_eq(rc, LIBEVDEV_READ_STATUS_SYNC);
+
+	rc = libevdev_next_event(dev, LIBEVDEV_READ_FLAG_SYNC, &ev);
+	ck_assert_int_eq(rc, LIBEVDEV_READ_STATUS_SYNC);
+	assert_event(&ev, EV_KEY, BTN_LEFT, 1);
+	rc = libevdev_next_event(dev, LIBEVDEV_READ_FLAG_SYNC, &ev);
+	ck_assert_int_eq(rc, LIBEVDEV_READ_STATUS_SYNC);
+	assert_event(&ev, EV_KEY, BTN_RIGHT, 1);
+	rc = libevdev_next_event(dev, LIBEVDEV_READ_FLAG_SYNC, &ev);
+	ck_assert_int_eq(rc, LIBEVDEV_READ_STATUS_SYNC);
+	assert_event(&ev, EV_KEY, KEY_MAX, 1);
+	rc = libevdev_next_event(dev, LIBEVDEV_READ_FLAG_SYNC, &ev);
+	ck_assert_int_eq(rc, LIBEVDEV_READ_STATUS_SYNC);
+	assert_event(&ev, EV_SYN, SYN_REPORT, 0);
+	rc = libevdev_next_event(dev, LIBEVDEV_READ_FLAG_SYNC, &ev);
+	ck_assert_int_eq(rc, -EAGAIN);
+
+	ck_assert(libevdev_get_event_value(dev, EV_KEY, BTN_LEFT));
+	ck_assert(libevdev_get_event_value(dev, EV_KEY, BTN_RIGHT));
+	ck_assert(!libevdev_get_event_value(dev, EV_KEY, BTN_MIDDLE));
+	ck_assert(libevdev_get_event_value(dev, EV_KEY, KEY_MAX));
+
+	uinput_device_free(uidev);
+	libevdev_free(dev);
+}
+END_TEST
+
+START_TEST(test_syn_delta_abs)
+{
+	struct uinput_device* uidev;
+	struct libevdev *dev;
+	int rc;
+	struct input_event ev;
+	struct input_absinfo abs[3] = {
+		{ .value = ABS_X, .maximum = 1000 },
+		{ .value = ABS_Y, .maximum = 1000 },
+		{ .value = ABS_MAX, .maximum = 1000 },
+	};
+
+	test_create_abs_device(&uidev, &dev,
+			       ARRAY_LENGTH(abs), abs,
+			       EV_SYN, SYN_REPORT,
+			       EV_SYN, SYN_DROPPED,
+			       EV_KEY, BTN_LEFT,
+			       EV_KEY, BTN_MIDDLE,
+			       EV_KEY, BTN_RIGHT,
+			       -1);
+
+	uinput_device_event(uidev, EV_ABS, ABS_X, 100);
+	uinput_device_event(uidev, EV_ABS, ABS_Y, 500);
+	uinput_device_event(uidev, EV_ABS, ABS_MAX, 700);
+	uinput_device_event(uidev, EV_SYN, SYN_REPORT, 0);
+	rc = libevdev_next_event(dev, LIBEVDEV_READ_FLAG_FORCE_SYNC, &ev);
+	ck_assert_int_eq(rc, LIBEVDEV_READ_STATUS_SYNC);
+
+	rc = libevdev_next_event(dev, LIBEVDEV_READ_FLAG_SYNC, &ev);
+	ck_assert_int_eq(rc, LIBEVDEV_READ_STATUS_SYNC);
+	assert_event(&ev, EV_ABS, ABS_X, 100);
+	rc = libevdev_next_event(dev, LIBEVDEV_READ_FLAG_SYNC, &ev);
+	ck_assert_int_eq(rc, LIBEVDEV_READ_STATUS_SYNC);
+	assert_event(&ev, EV_ABS, ABS_Y, 500);
+	rc = libevdev_next_event(dev, LIBEVDEV_READ_FLAG_SYNC, &ev);
+	ck_assert_int_eq(rc, LIBEVDEV_READ_STATUS_SYNC);
+	ck_assert_int_eq(ev.type, EV_ABS);
+	ck_assert_int_eq(ev.code, ABS_MAX);
+	ck_assert_int_eq(ev.value, 700);
+	assert_event(&ev, EV_ABS, ABS_MAX, 700);
+	rc = libevdev_next_event(dev, LIBEVDEV_READ_FLAG_SYNC, &ev);
+	ck_assert_int_eq(rc, LIBEVDEV_READ_STATUS_SYNC);
+	assert_event(&ev, EV_SYN, SYN_REPORT, 0);
+	rc = libevdev_next_event(dev, LIBEVDEV_READ_FLAG_SYNC, &ev);
+	ck_assert_int_eq(rc, -EAGAIN);
+
+	uinput_device_free(uidev);
+	libevdev_free(dev);
+}
+END_TEST
+
+START_TEST(test_syn_delta_mt)
+{
+	struct uinput_device* uidev;
+	struct libevdev *dev;
+	int rc;
+	struct input_event ev;
+	struct input_absinfo abs[6] = {
+		{ .value = ABS_X, .maximum = 1000 },
+		{ .value = ABS_Y, .maximum = 1000 },
+		{ .value = ABS_MT_POSITION_X, .maximum = 1000 },
+		{ .value = ABS_MT_POSITION_Y, .maximum = 1000 },
+		{ .value = ABS_MT_SLOT, .maximum = 1 },
+		{ .value = ABS_MT_TRACKING_ID, .minimum = -1, .maximum = 2 },
+	};
+
+	test_create_abs_device(&uidev, &dev,
+			       ARRAY_LENGTH(abs), abs,
+			       EV_SYN, SYN_REPORT,
+			       -1);
+
+	uinput_device_event_multiple(uidev,
+				     EV_ABS, ABS_MT_SLOT, 0,
+				     EV_ABS, ABS_X, 100,
+				     EV_ABS, ABS_Y, 500,
+				     EV_ABS, ABS_MT_POSITION_X, 100,
+				     EV_ABS, ABS_MT_POSITION_Y, 500,
+				     EV_ABS, ABS_MT_TRACKING_ID, 1,
+				     EV_ABS, ABS_MT_SLOT, 1,
+				     EV_ABS, ABS_X, 1,
+				     EV_ABS, ABS_Y, 5,
+				     EV_ABS, ABS_MT_POSITION_X, 1,
+				     EV_ABS, ABS_MT_POSITION_Y, 5,
+				     EV_ABS, ABS_MT_TRACKING_ID, 2,
+				     EV_SYN, SYN_REPORT, 0,
+				     -1, -1);
+
+	rc = libevdev_next_event(dev, LIBEVDEV_READ_FLAG_FORCE_SYNC, &ev);
+	ck_assert_int_eq(rc, LIBEVDEV_READ_STATUS_SYNC);
+
+	ck_assert_int_eq(libevdev_get_current_slot(dev), 0);
+	rc = libevdev_next_event(dev, LIBEVDEV_READ_FLAG_SYNC, &ev);
+	ck_assert_int_eq(rc, LIBEVDEV_READ_STATUS_SYNC);
+	assert_event(&ev, EV_ABS, ABS_X, 1);
+	rc = libevdev_next_event(dev, LIBEVDEV_READ_FLAG_SYNC, &ev);
+	ck_assert_int_eq(rc, LIBEVDEV_READ_STATUS_SYNC);
+	assert_event(&ev, EV_ABS, ABS_Y, 5);
+	rc = libevdev_next_event(dev, LIBEVDEV_READ_FLAG_SYNC, &ev);
+	ck_assert_int_eq(rc, LIBEVDEV_READ_STATUS_SYNC);
+	assert_event(&ev, EV_ABS, ABS_MT_SLOT, 0);
+	rc = libevdev_next_event(dev, LIBEVDEV_READ_FLAG_SYNC, &ev);
+	ck_assert_int_eq(rc, LIBEVDEV_READ_STATUS_SYNC);
+	assert_event(&ev, EV_ABS, ABS_MT_POSITION_X, 100);
+	rc = libevdev_next_event(dev, LIBEVDEV_READ_FLAG_SYNC, &ev);
+	ck_assert_int_eq(rc, LIBEVDEV_READ_STATUS_SYNC);
+	assert_event(&ev, EV_ABS, ABS_MT_POSITION_Y, 500);
+	rc = libevdev_next_event(dev, LIBEVDEV_READ_FLAG_SYNC, &ev);
+	ck_assert_int_eq(rc, LIBEVDEV_READ_STATUS_SYNC);
+	assert_event(&ev, EV_ABS, ABS_MT_TRACKING_ID, 1);
+	rc = libevdev_next_event(dev, LIBEVDEV_READ_FLAG_SYNC, &ev);
+	ck_assert_int_eq(rc, LIBEVDEV_READ_STATUS_SYNC);
+	assert_event(&ev, EV_ABS, ABS_MT_SLOT, 1);
+	ck_assert_int_eq(libevdev_get_current_slot(dev), 1);
+
+	rc = libevdev_next_event(dev, LIBEVDEV_READ_FLAG_SYNC, &ev);
+	ck_assert_int_eq(rc, LIBEVDEV_READ_STATUS_SYNC);
+	assert_event(&ev, EV_ABS, ABS_MT_POSITION_X, 1);
+	rc = libevdev_next_event(dev, LIBEVDEV_READ_FLAG_SYNC, &ev);
+	ck_assert_int_eq(rc, LIBEVDEV_READ_STATUS_SYNC);
+	assert_event(&ev, EV_ABS, ABS_MT_POSITION_Y, 5);
+	rc = libevdev_next_event(dev, LIBEVDEV_READ_FLAG_SYNC, &ev);
+	ck_assert_int_eq(rc, LIBEVDEV_READ_STATUS_SYNC);
+	assert_event(&ev, EV_ABS, ABS_MT_TRACKING_ID, 2);
+
+	rc = libevdev_next_event(dev, LIBEVDEV_READ_FLAG_SYNC, &ev);
+	ck_assert_int_eq(rc, LIBEVDEV_READ_STATUS_SYNC);
+	assert_event(&ev, EV_SYN, SYN_REPORT, 0);
+	rc = libevdev_next_event(dev, LIBEVDEV_READ_FLAG_SYNC, &ev);
+	ck_assert_int_eq(rc, -EAGAIN);
+
+	uinput_device_free(uidev);
+	libevdev_free(dev);
+}
+END_TEST
+
+START_TEST(test_syn_delta_mt_reset_slot)
+{
+	struct uinput_device* uidev;
+	struct libevdev *dev;
+	int rc;
+	struct input_event ev,
+			   last_slot_event = { .type = 0};
+	struct input_absinfo abs[6] = {
+		{ .value = ABS_X, .maximum = 1000 },
+		{ .value = ABS_Y, .maximum = 1000 },
+		{ .value = ABS_MT_POSITION_X, .maximum = 1000 },
+		{ .value = ABS_MT_POSITION_Y, .maximum = 1000 },
+		{ .value = ABS_MT_SLOT, .maximum = 1 },
+		{ .value = ABS_MT_TRACKING_ID, .minimum = -1, .maximum = 2 },
+	};
+
+	test_create_abs_device(&uidev, &dev,
+			       ARRAY_LENGTH(abs), abs,
+			       EV_SYN, SYN_REPORT,
+			       -1);
+
+	uinput_device_event_multiple(uidev,
+				     EV_ABS, ABS_MT_SLOT, 1,
+				     EV_ABS, ABS_MT_POSITION_X, 100,
+				     EV_ABS, ABS_MT_POSITION_Y, 500,
+				     EV_ABS, ABS_MT_TRACKING_ID, 1,
+				     EV_ABS, ABS_MT_SLOT, 0,
+				     EV_ABS, ABS_MT_POSITION_X, 1,
+				     EV_ABS, ABS_MT_POSITION_Y, 5,
+				     EV_ABS, ABS_MT_TRACKING_ID, 2,
+				     EV_SYN, SYN_REPORT, 0,
+				     -1, -1);
+
+	rc = libevdev_next_event(dev, LIBEVDEV_READ_FLAG_FORCE_SYNC, &ev);
+	ck_assert_int_eq(rc, LIBEVDEV_READ_STATUS_SYNC);
+
+	do {
+		rc = libevdev_next_event(dev, LIBEVDEV_READ_FLAG_SYNC, &ev);
+		if (libevdev_event_is_code(&ev, EV_ABS, ABS_MT_SLOT))
+			last_slot_event = ev;
+	} while (rc != -EAGAIN);
+
+	ck_assert(libevdev_event_is_code(&last_slot_event, EV_ABS, ABS_MT_SLOT));
+	ck_assert_int_eq(last_slot_event.value, 0);
+	ck_assert_int_eq(libevdev_get_current_slot(dev), 0);
+
+	last_slot_event.type = 0;
+
+	/* same thing again, this time swap the numbers */
+	uinput_device_event_multiple(uidev,
+				     EV_ABS, ABS_MT_SLOT, 0,
+				     EV_ABS, ABS_MT_POSITION_X, 100,
+				     EV_ABS, ABS_MT_POSITION_Y, 500,
+				     EV_ABS, ABS_MT_TRACKING_ID, 1,
+				     EV_ABS, ABS_MT_SLOT, 1,
+				     EV_ABS, ABS_MT_POSITION_X, 1,
+				     EV_ABS, ABS_MT_POSITION_Y, 5,
+				     EV_ABS, ABS_MT_TRACKING_ID, 2,
+				     EV_SYN, SYN_REPORT, 0,
+				     -1, -1);
+
+	rc = libevdev_next_event(dev, LIBEVDEV_READ_FLAG_FORCE_SYNC, &ev);
+	ck_assert_int_eq(rc, LIBEVDEV_READ_STATUS_SYNC);
+
+	do {
+		rc = libevdev_next_event(dev, LIBEVDEV_READ_FLAG_SYNC, &ev);
+		if (libevdev_event_is_code(&ev, EV_ABS, ABS_MT_SLOT))
+			last_slot_event = ev;
+	} while (rc != -EAGAIN);
+
+	ck_assert(libevdev_event_is_code(&last_slot_event, EV_ABS, ABS_MT_SLOT));
+	ck_assert_int_eq(last_slot_event.value, 1);
+	ck_assert_int_eq(libevdev_get_current_slot(dev), 1);
+
+	uinput_device_free(uidev);
+	libevdev_free(dev);
+}
+END_TEST
+
+START_TEST(test_syn_delta_led)
+{
+	struct uinput_device* uidev;
+	struct libevdev *dev;
+	int rc;
+	struct input_event ev;
+
+	test_create_device(&uidev, &dev,
+			   EV_SYN, SYN_REPORT,
+			   EV_SYN, SYN_DROPPED,
+			   EV_LED, LED_NUML,
+			   EV_LED, LED_CAPSL,
+			   EV_LED, LED_MAX,
+			   -1);
+
+	uinput_device_event(uidev, EV_LED, LED_NUML, 1);
+	uinput_device_event(uidev, EV_LED, LED_CAPSL, 1);
+	uinput_device_event(uidev, EV_LED, LED_MAX, 1);
+	uinput_device_event(uidev, EV_SYN, SYN_REPORT, 0);
+	rc = libevdev_next_event(dev, LIBEVDEV_READ_FLAG_FORCE_SYNC, &ev);
+	ck_assert_int_eq(rc, LIBEVDEV_READ_STATUS_SYNC);
+
+	rc = libevdev_next_event(dev, LIBEVDEV_READ_FLAG_SYNC, &ev);
+	ck_assert_int_eq(rc, LIBEVDEV_READ_STATUS_SYNC);
+	assert_event(&ev, EV_LED, LED_NUML, 1);
+	rc = libevdev_next_event(dev, LIBEVDEV_READ_FLAG_SYNC, &ev);
+	ck_assert_int_eq(rc, LIBEVDEV_READ_STATUS_SYNC);
+	assert_event(&ev, EV_LED, LED_CAPSL, 1);
+	rc = libevdev_next_event(dev, LIBEVDEV_READ_FLAG_SYNC, &ev);
+	ck_assert_int_eq(rc, LIBEVDEV_READ_STATUS_SYNC);
+	assert_event(&ev, EV_LED, LED_MAX, 1);
+	rc = libevdev_next_event(dev, LIBEVDEV_READ_FLAG_SYNC, &ev);
+	ck_assert_int_eq(rc, LIBEVDEV_READ_STATUS_SYNC);
+	assert_event(&ev, EV_SYN, SYN_REPORT, 0);
+	rc = libevdev_next_event(dev, LIBEVDEV_READ_FLAG_SYNC, &ev);
+	ck_assert_int_eq(rc, -EAGAIN);
+
+	ck_assert_int_eq(libevdev_get_event_value(dev, EV_LED, LED_NUML), 1);
+	ck_assert_int_eq(libevdev_get_event_value(dev, EV_LED, LED_CAPSL), 1);
+	ck_assert_int_eq(libevdev_get_event_value(dev, EV_LED, LED_MAX), 1);
+
+	uinput_device_free(uidev);
+	libevdev_free(dev);
+}
+END_TEST
+
+START_TEST(test_syn_delta_sw)
+{
+	struct uinput_device* uidev;
+	struct libevdev *dev;
+	int rc;
+	struct input_event ev;
+
+	test_create_device(&uidev, &dev,
+			   EV_SYN, SYN_REPORT,
+			   EV_SYN, SYN_DROPPED,
+			   EV_SW, SW_HEADPHONE_INSERT,
+			   EV_SW, SW_MICROPHONE_INSERT,
+			   EV_SW, SW_MAX,
+			   -1);
+
+	uinput_device_event(uidev, EV_SW, SW_HEADPHONE_INSERT, 1);
+	uinput_device_event(uidev, EV_SW, SW_MICROPHONE_INSERT, 1);
+	uinput_device_event(uidev, EV_SW, SW_MAX, 1);
+	uinput_device_event(uidev, EV_SYN, SYN_REPORT, 0);
+	rc = libevdev_next_event(dev, LIBEVDEV_READ_FLAG_FORCE_SYNC, &ev);
+	ck_assert_int_eq(rc, LIBEVDEV_READ_STATUS_SYNC);
+
+	rc = libevdev_next_event(dev, LIBEVDEV_READ_FLAG_SYNC, &ev);
+	ck_assert_int_eq(rc, LIBEVDEV_READ_STATUS_SYNC);
+	assert_event(&ev, EV_SW, SW_HEADPHONE_INSERT, 1);
+	rc = libevdev_next_event(dev, LIBEVDEV_READ_FLAG_SYNC, &ev);
+	ck_assert_int_eq(rc, LIBEVDEV_READ_STATUS_SYNC);
+	assert_event(&ev, EV_SW, SW_MICROPHONE_INSERT, 1);
+	rc = libevdev_next_event(dev, LIBEVDEV_READ_FLAG_SYNC, &ev);
+	ck_assert_int_eq(rc, LIBEVDEV_READ_STATUS_SYNC);
+	assert_event(&ev, EV_SW, SW_MAX, 1);
+	rc = libevdev_next_event(dev, LIBEVDEV_READ_FLAG_SYNC, &ev);
+	ck_assert_int_eq(rc, LIBEVDEV_READ_STATUS_SYNC);
+	assert_event(&ev, EV_SYN, SYN_REPORT, 0);
+	rc = libevdev_next_event(dev, LIBEVDEV_READ_FLAG_SYNC, &ev);
+	ck_assert_int_eq(rc, -EAGAIN);
+
+	ck_assert_int_eq(libevdev_get_event_value(dev, EV_SW, SW_HEADPHONE_INSERT), 1);
+	ck_assert_int_eq(libevdev_get_event_value(dev, EV_SW, SW_MICROPHONE_INSERT), 1);
+	ck_assert_int_eq(libevdev_get_event_value(dev, EV_SW, SW_MAX), 1);
+
+	uinput_device_free(uidev);
+	libevdev_free(dev);
+}
+END_TEST
+
+START_TEST(test_syn_delta_tracking_ids)
+{
+	struct uinput_device* uidev;
+	struct libevdev *dev;
+	int rc;
+	struct input_event ev;
+	int i;
+	const int num_slots = 15;
+	int slot = -1;
+	unsigned long terminated[NLONGS(num_slots)];
+	unsigned long restarted[NLONGS(num_slots)];
+	struct input_absinfo abs[6] = {
+		{ .value = ABS_X, .maximum = 1000 },
+		{ .value = ABS_Y, .maximum = 1000 },
+		{ .value = ABS_MT_POSITION_X, .maximum = 1000 },
+		{ .value = ABS_MT_POSITION_Y, .maximum = 1000 },
+		{ .value = ABS_MT_SLOT, .maximum = num_slots },
+		{ .value = ABS_MT_TRACKING_ID, .minimum = -1, .maximum = 0xff },
+	};
+
+	test_create_abs_device(&uidev, &dev,
+			       ARRAY_LENGTH(abs), abs,
+			       EV_SYN, SYN_REPORT,
+			       -1);
+
+	/* Test the sync process to make sure we get touches terminated when
+	 * the tracking id changes:
+	 * 1) start a bunch of touch points
+	 * 2) read data into libevdev, make sure state is up-to-date
+	 * 3) change touchpoints
+	 * 3.1) change the tracking ID on some (indicating terminated and
+	 * re-started touchpoint)
+	 * 3.2) change the tracking ID to -1 on some (indicating termianted
+	 * touchpoint)
+	 * 3.3) just update the data on others
+	 * 4) force a sync on the device
+	 * 5) make sure we get the right tracking ID changes in the caller
+	 */
+
+	/* Start a bunch of touch points  */
+	for (i = num_slots; i >= 0; i--) {
+		uinput_device_event_multiple(uidev,
+					     EV_ABS, ABS_MT_SLOT, i,
+					     EV_ABS, ABS_MT_TRACKING_ID, i,
+					     EV_ABS, ABS_X, 100 + i,
+					     EV_ABS, ABS_Y, 500 + i,
+					     EV_ABS, ABS_MT_POSITION_X, 100 + i,
+					     EV_ABS, ABS_MT_POSITION_Y, 500 + i,
+					     EV_SYN, SYN_REPORT, 0,
+					     -1, -1);
+		do {
+			rc = libevdev_next_event(dev, LIBEVDEV_READ_FLAG_NORMAL, &ev);
+			ck_assert_int_ne(rc, LIBEVDEV_READ_STATUS_SYNC);
+		} while (rc >= 0);
+	}
+
+	/* we have a bunch of touches now, and libevdev knows it. Change all
+	 * touches */
+	for (i = num_slots; i >= 0; i--) {
+		uinput_device_event(uidev, EV_ABS, ABS_MT_SLOT, i);
+		if (i % 3 == 0) {
+			/* change some slots with a new tracking id */
+			uinput_device_event_multiple(uidev,
+						     EV_ABS, ABS_MT_TRACKING_ID, num_slots + i,
+						     EV_ABS, ABS_X, 200 + i,
+						     EV_ABS, ABS_Y, 700 + i,
+						     EV_ABS, ABS_MT_POSITION_X, 200 + i,
+						     EV_ABS, ABS_MT_POSITION_Y, 700 + i,
+						     -1, -1);
+		} else if (i % 3 == 1) {
+			/* stop others */
+			uinput_device_event(uidev, EV_ABS, ABS_MT_TRACKING_ID, -1);
+		} else {
+			/* just update */
+			uinput_device_event_multiple(uidev,
+						     EV_ABS, ABS_X, 200 + i,
+						     EV_ABS, ABS_Y, 700 + i,
+						     EV_ABS, ABS_MT_POSITION_X, 200 + i,
+						     EV_ABS, ABS_MT_POSITION_Y, 700 + i,
+						     -1, -1);
+		}
+		uinput_device_event(uidev, EV_SYN, SYN_REPORT, 0);
+	}
+
+	/* Force sync */
+	rc = libevdev_next_event(dev, LIBEVDEV_READ_FLAG_FORCE_SYNC, &ev);
+	ck_assert_int_eq(rc, LIBEVDEV_READ_STATUS_SYNC);
+
+	/* now check for the right tracking IDs */
+	memset(terminated, 0, sizeof(terminated));
+	memset(restarted, 0, sizeof(restarted));
+	slot = -1;
+	while ((rc = libevdev_next_event(dev, LIBEVDEV_READ_FLAG_SYNC, &ev)) != -EAGAIN) {
+		if (libevdev_event_is_code(&ev, EV_SYN, SYN_REPORT))
+			continue;
+
+		if (libevdev_event_is_code(&ev, EV_ABS, ABS_MT_SLOT)) {
+			slot = ev.value;
+			continue;
+		}
+
+		if (libevdev_event_is_code(&ev, EV_ABS, ABS_X) ||
+		    libevdev_event_is_code(&ev, EV_ABS, ABS_Y))
+			continue;
+
+		ck_assert_int_ne(slot, -1);
+
+		if (libevdev_event_is_code(&ev, EV_ABS, ABS_MT_TRACKING_ID)) {
+			if (slot % 3 == 0) {
+				if (!bit_is_set(terminated, slot)) {
+					ck_assert_int_eq(ev.value, -1);
+					set_bit(terminated, slot);
+				} else {
+					ck_assert_int_eq(ev.value, num_slots + slot);
+					set_bit(restarted, slot);
+				}
+			} else if (slot % 3 == 1) {
+				ck_assert(!bit_is_set(terminated, slot));
+				ck_assert_int_eq(ev.value, -1);
+				set_bit(terminated, slot);
+			} else
+				ck_abort();
+
+			continue;
+		}
+
+		switch(ev.code) {
+			case ABS_MT_POSITION_X:
+				ck_assert_int_eq(ev.value, 200 + slot);
+				break;
+			case ABS_MT_POSITION_Y:
+				ck_assert_int_eq(ev.value, 700 + slot);
+				break;
+			default:
+				ck_abort();
+		}
+	}
+
+	for (i = 0; i < num_slots; i++) {
+		if (i % 3 == 0) {
+			ck_assert(bit_is_set(terminated, i));
+			ck_assert(bit_is_set(restarted, i));
+		} else if (i % 3 == 1) {
+			ck_assert(bit_is_set(terminated, i));
+			ck_assert(!bit_is_set(restarted, i));
+		} else {
+			ck_assert(!bit_is_set(terminated, i));
+			ck_assert(!bit_is_set(restarted, i));
+		}
+	}
+
+	uinput_device_free(uidev);
+	libevdev_free(dev);
+}
+END_TEST
+
+START_TEST(test_syn_delta_tracking_ids_btntool)
+{
+       struct uinput_device* uidev;
+       struct libevdev *dev;
+       int rc;
+       struct input_event ev;
+       const int num_slots = 5;
+       struct input_absinfo abs[6] = {
+               { .value = ABS_X, .maximum = 1000 },
+               { .value = ABS_Y, .maximum = 1000 },
+               { .value = ABS_MT_POSITION_X, .maximum = 1000 },
+               { .value = ABS_MT_POSITION_Y, .maximum = 1000 },
+               { .value = ABS_MT_SLOT, .maximum = num_slots },
+               { .value = ABS_MT_TRACKING_ID, .minimum = -1, .maximum = 0xffff },
+       };
+       bool have_doubletap = false,
+            have_quadtap = false,
+            have_quinttap = false;
+
+       test_create_abs_device(&uidev, &dev,
+                              ARRAY_LENGTH(abs), abs,
+                              EV_KEY, BTN_TOOL_FINGER,
+                              EV_KEY, BTN_TOOL_DOUBLETAP,
+                              EV_KEY, BTN_TOOL_TRIPLETAP,
+                              EV_KEY, BTN_TOOL_QUADTAP,
+                              EV_KEY, BTN_TOOL_QUINTTAP,
+                              EV_SYN, SYN_REPORT,
+                              -1);
+
+       /* Test the sync process to make sure we get the BTN_TOOL bits for
+        * touches adjusted correctly when the tracking id changes:
+        * 1) start a bunch of touch points
+        * 2) read data into libevdev, make sure state is up-to-date
+        * 3) change touchpoints
+        * 3.1) change the tracking ID on some (indicating terminated and
+        * re-started touchpoint)
+        * 3.2) change the tracking ID to -1 on some (indicating termianted
+        * touchpoint)
+        * 3.3) just update the data on others
+        * 4) force a sync on the device
+        * 5) make sure we get the right BTN_TOOL_ changes in the caller
+        */
+       for (int i = 0; i < num_slots; i++) {
+               uinput_device_event_multiple(uidev,
+                                            EV_ABS, ABS_MT_SLOT, i,
+                                            EV_ABS, ABS_MT_TRACKING_ID, 111,
+                                            EV_ABS, ABS_X, 100 + 10 * i,
+                                            EV_ABS, ABS_Y, 100 + 10 * i,
+                                            EV_ABS, ABS_MT_POSITION_X, 100,
+                                            EV_ABS, ABS_MT_POSITION_Y, 100,
+                                            -1, -1);
+               switch (i) {
+               case 0:
+                       uinput_device_event(uidev, EV_KEY, BTN_TOOL_FINGER, 1);
+                       break;
+               case 1:
+                       uinput_device_event(uidev, EV_KEY, BTN_TOOL_FINGER, 0);
+                       uinput_device_event(uidev, EV_KEY, BTN_TOOL_DOUBLETAP, 1);
+                       break;
+               case 2:
+                       uinput_device_event(uidev, EV_KEY, BTN_TOOL_DOUBLETAP, 0);
+                       uinput_device_event(uidev, EV_KEY, BTN_TOOL_TRIPLETAP, 1);
+                       break;
+               case 3:
+                       uinput_device_event(uidev, EV_KEY, BTN_TOOL_TRIPLETAP, 0);
+                       uinput_device_event(uidev, EV_KEY, BTN_TOOL_QUADTAP, 1);
+                       break;
+               case 4:
+                       uinput_device_event(uidev, EV_KEY, BTN_TOOL_QUADTAP, 0);
+                       uinput_device_event(uidev, EV_KEY, BTN_TOOL_QUINTTAP, 1);
+                       break;
+               default:
+                       ck_abort();
+               }
+               uinput_device_event(uidev, EV_SYN, SYN_REPORT, 0);
+       }
+
+       do {
+               rc = libevdev_next_event(dev, LIBEVDEV_READ_FLAG_NORMAL, &ev);
+               ck_assert_int_ne(rc, LIBEVDEV_READ_STATUS_SYNC);
+       } while (rc >= 0);
+
+       /* we have a bunch of touches now, and libevdev knows it.
+        * - stop touch 0
+        * - stop and restart touch 1 and 4
+        * - leave 2, 3 unchanged
+        */
+       uinput_device_event_multiple(uidev,
+                                    EV_ABS, ABS_MT_SLOT, 0,
+                                    EV_ABS, ABS_MT_TRACKING_ID, -1,
+                                    EV_KEY, BTN_TOOL_QUINTTAP, 0,
+                                    EV_KEY, BTN_TOOL_QUADTAP, 1,
+                                    EV_SYN, SYN_REPORT, 0,
+                                    -1, -1);
+       uinput_device_event_multiple(uidev,
+                                    EV_ABS, ABS_MT_SLOT, 1,
+                                    EV_ABS, ABS_MT_TRACKING_ID, -1,
+                                    EV_KEY, BTN_TOOL_QUADTAP, 0,
+                                    EV_KEY, BTN_TOOL_TRIPLETAP, 1,
+                                    EV_SYN, SYN_REPORT, 0,
+                                    -1, -1);
+       uinput_device_event_multiple(uidev,
+                                    EV_ABS, ABS_MT_SLOT, 1,
+                                    EV_ABS, ABS_MT_TRACKING_ID, 666,
+                                    EV_ABS, ABS_X, 666,
+                                    EV_ABS, ABS_Y, 666,
+                                    EV_ABS, ABS_MT_POSITION_X, 666,
+                                    EV_ABS, ABS_MT_POSITION_Y, 666,
+                                    EV_KEY, BTN_TOOL_TRIPLETAP, 0,
+                                    EV_KEY, BTN_TOOL_QUADTAP, 1,
+                                    EV_SYN, SYN_REPORT, 0,
+                                    -1, -1);
+       uinput_device_event_multiple(uidev,
+                                    EV_ABS, ABS_MT_SLOT, 4,
+                                    EV_ABS, ABS_MT_TRACKING_ID, -1,
+                                    EV_KEY, BTN_TOOL_QUADTAP, 0,
+                                    EV_KEY, BTN_TOOL_TRIPLETAP, 1,
+                                    EV_SYN, SYN_REPORT, 0,
+                                    -1, -1);
+       uinput_device_event_multiple(uidev,
+                                    EV_ABS, ABS_MT_SLOT, 4,
+                                    EV_ABS, ABS_MT_TRACKING_ID, 777,
+                                    EV_ABS, ABS_X, 777,
+                                    EV_ABS, ABS_Y, 777,
+                                    EV_ABS, ABS_MT_POSITION_X, 777,
+                                    EV_ABS, ABS_MT_POSITION_Y, 777,
+                                    EV_KEY, BTN_TOOL_QUADTAP, 1,
+                                    EV_KEY, BTN_TOOL_TRIPLETAP, 0,
+                                    EV_SYN, SYN_REPORT, 0,
+                                    -1, -1);
+
+       /* Force sync */
+       rc = libevdev_next_event(dev, LIBEVDEV_READ_FLAG_FORCE_SYNC, &ev);
+       ck_assert_int_eq(rc, LIBEVDEV_READ_STATUS_SYNC);
+
+       /* In the first sync frame, we expect us to drop to 2 touches - we
+        * started with 5, 1 stopped, 2 stopped+restarted */
+       while ((rc = libevdev_next_event(dev, LIBEVDEV_READ_FLAG_SYNC, &ev)) != -EAGAIN) {
+               if (libevdev_event_is_code(&ev, EV_KEY, BTN_TOOL_QUINTTAP)) {
+                       ck_assert(!have_quinttap);
+                       assert_event(&ev, EV_KEY, BTN_TOOL_QUINTTAP, 0);
+                       have_quinttap = true;
+               }
+
+               if (libevdev_event_is_code(&ev, EV_KEY, BTN_TOOL_TRIPLETAP))
+		       ck_abort();
+
+               if (libevdev_event_is_code(&ev, EV_KEY, BTN_TOOL_DOUBLETAP)) {
+                       ck_assert(!have_doubletap);
+                       assert_event(&ev, EV_KEY, BTN_TOOL_DOUBLETAP, 1);
+                       have_doubletap = true;
+               }
+
+               ck_assert(!libevdev_event_is_code(&ev, EV_KEY, BTN_TOOL_TRIPLETAP));
+               ck_assert(!libevdev_event_is_code(&ev, EV_KEY, BTN_TOOL_QUADTAP));
+               ck_assert(!libevdev_event_is_code(&ev, EV_KEY, BTN_TOOL_FINGER));
+
+               if (libevdev_event_is_code(&ev, EV_SYN, SYN_REPORT)) {
+                       ck_assert(have_doubletap);
+                       ck_assert(have_quinttap);
+                       break;
+               }
+       }
+
+       have_doubletap = false;
+       have_quadtap = false;
+
+       /* In the second sync frame, we expect to go back to 4 touches,
+        * recovering the two stopped+started touches */
+       while ((rc = libevdev_next_event(dev, LIBEVDEV_READ_FLAG_SYNC, &ev)) != -EAGAIN) {
+               if (libevdev_event_is_code(&ev, EV_KEY, BTN_TOOL_QUADTAP)) {
+                       ck_assert(!have_quadtap);
+                       assert_event(&ev, EV_KEY, BTN_TOOL_QUADTAP, 1);
+                       have_quadtap = true;
+               }
+
+               if (libevdev_event_is_code(&ev, EV_KEY, BTN_TOOL_TRIPLETAP))
+		       ck_abort();
+
+               if (libevdev_event_is_code(&ev, EV_KEY, BTN_TOOL_DOUBLETAP)) {
+                       ck_assert(!have_doubletap);
+                       assert_event(&ev, EV_KEY, BTN_TOOL_DOUBLETAP, 0);
+                       have_doubletap = true;
+               }
+
+               ck_assert(!libevdev_event_is_code(&ev, EV_KEY, BTN_TOOL_TRIPLETAP));
+               ck_assert(!libevdev_event_is_code(&ev, EV_KEY, BTN_TOOL_QUINTTAP));
+               ck_assert(!libevdev_event_is_code(&ev, EV_KEY, BTN_TOOL_FINGER));
+
+               if (libevdev_event_is_code(&ev, EV_SYN, SYN_REPORT)) {
+                       ck_assert(have_doubletap);
+                       ck_assert(have_quadtap);
+                       break;
+               }
+       }
+
+        uinput_device_free(uidev);
+        libevdev_free(dev);
+}
+END_TEST
+
+START_TEST(test_syn_delta_late_sync)
+{
+	struct uinput_device* uidev;
+	struct libevdev *dev;
+	int rc;
+	struct input_event ev;
+	struct input_absinfo abs[6] = {
+		{ .value = ABS_X, .maximum = 1000 },
+		{ .value = ABS_Y, .maximum = 1000 },
+		{ .value = ABS_MT_POSITION_X, .maximum = 1000 },
+		{ .value = ABS_MT_POSITION_Y, .maximum = 1000 },
+		{ .value = ABS_MT_SLOT, .maximum = 1 },
+		{ .value = ABS_MT_TRACKING_ID, .minimum = -1, .maximum = 0xff},
+	};
+	int i, slot;
+
+	test_create_abs_device(&uidev, &dev,
+			       ARRAY_LENGTH(abs), abs,
+			       EV_SYN, SYN_REPORT,
+			       -1);
+
+	/* emulate a touch down, make sure libevdev sees it */
+	uinput_device_event_multiple(uidev,
+				     EV_ABS, ABS_MT_SLOT, 0,
+				     EV_ABS, ABS_MT_TRACKING_ID, 1,
+				     EV_ABS, ABS_X, 100,
+				     EV_ABS, ABS_Y, 500,
+				     EV_ABS, ABS_MT_POSITION_X, 100,
+				     EV_ABS, ABS_MT_POSITION_Y, 500,
+				     EV_SYN, SYN_REPORT, 0,
+				     -1, -1);
+	do {
+		rc = libevdev_next_event(dev, LIBEVDEV_READ_FLAG_NORMAL, &ev);
+		ck_assert_int_ne(rc, LIBEVDEV_READ_STATUS_SYNC);
+	} while (rc >= 0);
+
+	/* force enough events to trigger a SYN_DROPPED */
+	for (i = 0; i < 100; i++) {
+		uinput_device_event_multiple(uidev,
+					     EV_ABS, ABS_X, 100 + i,
+					     EV_ABS, ABS_Y, 500 + i,
+					     EV_ABS, ABS_MT_POSITION_X, 100 + i,
+					     EV_ABS, ABS_MT_POSITION_Y, 500 + i,
+					     EV_SYN, SYN_REPORT, 0,
+					     -1, -1);
+	}
+
+	rc = libevdev_next_event(dev, LIBEVDEV_READ_FLAG_NORMAL, &ev);
+	ck_assert_int_eq(rc, LIBEVDEV_READ_STATUS_SYNC);
+
+	/* trigger the tracking ID change after getting the SYN_DROPPED */
+	uinput_device_event_multiple(uidev,
+				     EV_ABS, ABS_MT_SLOT, 0,
+				     EV_ABS, ABS_MT_TRACKING_ID, -1,
+				     EV_ABS, ABS_X, 200,
+				     EV_ABS, ABS_Y, 600,
+				     EV_ABS, ABS_MT_POSITION_X, 200,
+				     EV_ABS, ABS_MT_POSITION_Y, 600,
+				     EV_SYN, SYN_REPORT, 0,
+				     -1, -1);
+
+	slot = 0;
+
+	/* Now sync the device, expect the data to be equal to the last event*/
+	while ((rc = libevdev_next_event(dev, LIBEVDEV_READ_FLAG_SYNC, &ev)) != -EAGAIN) {
+		if (ev.type == EV_SYN)
+			continue;
+
+		ck_assert_int_eq(ev.type, EV_ABS);
+		switch(ev.code) {
+			case ABS_MT_SLOT:
+				slot = ev.value;
+				break;
+			case ABS_MT_TRACKING_ID:
+				if (slot == 0)
+					ck_assert_int_eq(ev.value, -1);
+				break;
+			case ABS_X:
+			case ABS_MT_POSITION_X:
+				ck_assert_int_eq(ev.value, 200);
+				break;
+			case ABS_Y:
+			case ABS_MT_POSITION_Y:
+				ck_assert_int_eq(ev.value, 600);
+				break;
+		}
+	}
+
+	/* And a new tracking ID */
+	uinput_device_event_multiple(uidev,
+				     EV_ABS, ABS_MT_SLOT, 0,
+				     EV_ABS, ABS_MT_TRACKING_ID, 2,
+				     EV_ABS, ABS_X, 201,
+				     EV_ABS, ABS_Y, 601,
+				     EV_ABS, ABS_MT_POSITION_X, 201,
+				     EV_ABS, ABS_MT_POSITION_Y, 601,
+				     EV_SYN, SYN_REPORT, 0,
+				     -1, -1);
+
+	while ((rc = libevdev_next_event(dev, LIBEVDEV_READ_FLAG_NORMAL, &ev)) != -EAGAIN) {
+		ck_assert_int_ne(rc, LIBEVDEV_READ_STATUS_SYNC);
+
+		if (ev.type == EV_SYN)
+			continue;
+
+		ck_assert_int_eq(ev.type, EV_ABS);
+
+		switch(ev.code) {
+			case ABS_MT_SLOT:
+				ck_assert_int_eq(ev.value, 0);
+				break;
+			case ABS_MT_TRACKING_ID:
+				ck_assert_int_eq(ev.value, 2);
+				break;
+			case ABS_X:
+			case ABS_MT_POSITION_X:
+				ck_assert_int_eq(ev.value, 201);
+				break;
+			case ABS_Y:
+			case ABS_MT_POSITION_Y:
+				ck_assert_int_eq(ev.value, 601);
+				break;
+		}
+	}
+
+	/* Now we basically re-do the exact same test, just with the
+	   tracking ID order inverted */
+
+	/* drop the tracking ID, make sure libevdev sees it */
+	uinput_device_event(uidev, EV_ABS, ABS_MT_SLOT, 0);
+	uinput_device_event(uidev, EV_ABS, ABS_MT_TRACKING_ID, -1);
+	uinput_device_event(uidev, EV_SYN, SYN_REPORT, 0);
+	do {
+		rc = libevdev_next_event(dev, LIBEVDEV_READ_FLAG_NORMAL, &ev);
+		ck_assert_int_ne(rc, LIBEVDEV_READ_STATUS_SYNC);
+	} while (rc >= 0);
+
+	/* force enough events to trigger a SYN_DROPPED */
+	for (i = 0; i < 100; i++) {
+		uinput_device_event_multiple(uidev,
+					     EV_ABS, ABS_X, 100 + i,
+					     EV_ABS, ABS_Y, 500 + i,
+					     EV_ABS, ABS_MT_POSITION_X, 100 + i,
+					     EV_ABS, ABS_MT_POSITION_Y, 500 + i,
+					     EV_SYN, SYN_REPORT, 0,
+					     -1, -1);
+	}
+
+	rc = libevdev_next_event(dev, LIBEVDEV_READ_FLAG_NORMAL, &ev);
+	ck_assert_int_eq(rc, LIBEVDEV_READ_STATUS_SYNC);
+
+	/* trigger the new tracking ID after getting the SYN_DROPPED */
+	uinput_device_event_multiple(uidev,
+				     EV_ABS, ABS_MT_SLOT, 0,
+				     EV_ABS, ABS_MT_TRACKING_ID, 5,
+				     EV_ABS, ABS_X, 200,
+				     EV_ABS, ABS_Y, 600,
+				     EV_ABS, ABS_MT_POSITION_X, 200,
+				     EV_ABS, ABS_MT_POSITION_Y, 600,
+				     EV_SYN, SYN_REPORT, 0,
+				     -1, -1);
+
+	slot = 0;
+
+	/* Now sync the device, expect the data to be equal to the last event*/
+	while ((rc = libevdev_next_event(dev, LIBEVDEV_READ_FLAG_SYNC, &ev)) != -EAGAIN) {
+		if (ev.type == EV_SYN)
+			continue;
+
+		ck_assert_int_eq(ev.type, EV_ABS);
+		switch(ev.code) {
+			case ABS_MT_SLOT:
+				slot = ev.value;
+				break;
+			case ABS_MT_TRACKING_ID:
+				if (slot == 0)
+					ck_assert_int_eq(ev.value, 5);
+				break;
+			case ABS_X:
+			case ABS_MT_POSITION_X:
+				ck_assert_int_eq(ev.value, 200);
+				break;
+			case ABS_Y:
+			case ABS_MT_POSITION_Y:
+				ck_assert_int_eq(ev.value, 600);
+				break;
+		}
+	}
+
+	/* Drop the tracking ID */
+	uinput_device_event(uidev, EV_ABS, ABS_MT_SLOT, 0);
+	uinput_device_event(uidev, EV_ABS, ABS_MT_TRACKING_ID, -1);
+	uinput_device_event(uidev, EV_SYN, SYN_REPORT, 0);
+
+	while ((rc = libevdev_next_event(dev, LIBEVDEV_READ_FLAG_NORMAL, &ev)) != -EAGAIN) {
+		ck_assert_int_ne(rc, LIBEVDEV_READ_STATUS_SYNC);
+
+		if (ev.type == EV_SYN)
+			continue;
+
+		ck_assert_int_eq(ev.type, EV_ABS);
+
+		switch(ev.code) {
+			case ABS_MT_SLOT:
+				ck_assert_int_eq(ev.value, 0);
+				break;
+			case ABS_MT_TRACKING_ID:
+				ck_assert_int_eq(ev.value, -1);
+				break;
+		}
+	}
+
+	uinput_device_free(uidev);
+	libevdev_free(dev);
+}
+END_TEST
+
+START_TEST(test_syn_delta_fake_mt)
+{
+	struct uinput_device* uidev;
+	struct libevdev *dev;
+	int rc;
+	struct input_event ev;
+	struct input_absinfo abs[] = {
+		{ .value = ABS_X, .minimum = 0, .maximum = 1000 },
+		{ .value = ABS_Y, .minimum = 0, .maximum = 1000 },
+		{ .value = ABS_MT_POSITION_X, .minimum = 0, .maximum = 1000 },
+		{ .value = ABS_MT_POSITION_Y, .minimum = 0, .maximum = 1000 },
+		{ .value = ABS_MT_SLOT - 1, .minimum = 0, .maximum = 2 }};
+		/* don't set ABS_MT_SLOT here, otherwise uinput will init
+		 * slots and the behavior is different to real devices with
+		 * such events */
+	unsigned long received[NLONGS(ABS_CNT)] = {0};
+
+	test_create_abs_device(&uidev, &dev, ARRAY_LENGTH(abs), abs, -1);
+	/* first set of events */
+	uinput_device_event_multiple(uidev,
+				     EV_ABS, ABS_X, 200,
+				     EV_ABS, ABS_Y, 400,
+				     EV_ABS, ABS_MT_POSITION_X, 100,
+				     EV_ABS, ABS_MT_POSITION_Y, 500,
+				     EV_ABS, ABS_MT_SLOT - 1, 1,
+				     EV_SYN, SYN_REPORT, 0,
+				     -1, -1);
+
+	/* second set of events */
+	uinput_device_event_multiple(uidev,
+				     EV_ABS, ABS_X, 201,
+				     EV_ABS, ABS_Y, 401,
+				     EV_ABS, ABS_MT_POSITION_X, 101,
+				     EV_ABS, ABS_MT_POSITION_Y, 501,
+				     EV_ABS, ABS_MT_SLOT - 1, 2,
+				     EV_SYN, SYN_REPORT, 0,
+				     -1, -1);
+
+	rc = libevdev_next_event(dev, LIBEVDEV_READ_FLAG_FORCE_SYNC, &ev);
+	ck_assert_int_eq(rc, LIBEVDEV_READ_STATUS_SYNC);
+
+	while ((rc = libevdev_next_event(dev, LIBEVDEV_READ_STATUS_SYNC, &ev)) != -EAGAIN) {
+		if (ev.type != EV_ABS)
+			continue;
+
+		ck_assert(!bit_is_set(received, ev.code));
+
+		switch(ev.code) {
+			/* see comment below for ABS_MT_POSITION_X
+			 * and ABS_MT_POSITION_Y */
+			case ABS_MT_POSITION_X:
+			case ABS_MT_POSITION_Y:
+				ck_abort();
+				break;
+
+			case ABS_MT_SLOT - 1: ck_assert_int_eq(ev.value, 2); break;
+			case ABS_X: ck_assert_int_eq(ev.value, 201); break;
+			case ABS_Y: ck_assert_int_eq(ev.value, 401); break;
+			default:
+				ck_abort();
+		}
+
+		set_bit(received, ev.code);
+	}
+
+	/* Dont' expect ABS_MT values, they are ignored during the sync
+	 * process */
+	ck_assert(!bit_is_set(received, ABS_MT_POSITION_X));
+	ck_assert(!bit_is_set(received, ABS_MT_POSITION_Y));
+	ck_assert(bit_is_set(received, ABS_MT_SLOT - 1));
+	ck_assert(bit_is_set(received, ABS_X));
+	ck_assert(bit_is_set(received, ABS_Y));
+
+	ck_assert_int_eq(libevdev_get_event_value(dev, EV_ABS, ABS_X), 201);
+	ck_assert_int_eq(libevdev_get_event_value(dev, EV_ABS, ABS_Y), 401);
+	ck_assert_int_eq(libevdev_get_event_value(dev, EV_ABS, ABS_MT_SLOT - 1), 2);
+
+	uinput_device_free(uidev);
+	libevdev_free(dev);
+}
+END_TEST
+
+START_TEST(test_skipped_sync)
+{
+	struct uinput_device* uidev;
+	struct libevdev *dev;
+	int rc;
+	struct input_event ev;
+	struct input_absinfo abs[2] = {
+		{ .value = ABS_X, .maximum = 1000 },
+		{ .value = ABS_Y, .maximum = 1000 },
+	};
+
+	test_create_abs_device(&uidev, &dev,
+			       ARRAY_LENGTH(abs), abs,
+			       EV_SYN, SYN_REPORT,
+			       EV_SYN, SYN_DROPPED,
+			       EV_KEY, BTN_LEFT,
+			       EV_KEY, BTN_MIDDLE,
+			       EV_KEY, BTN_RIGHT,
+			       -1);
+
+	uinput_device_event(uidev, EV_KEY, BTN_LEFT, 1);
+	uinput_device_event(uidev, EV_ABS, ABS_X, 100);
+	uinput_device_event(uidev, EV_ABS, ABS_Y, 500);
+	uinput_device_event(uidev, EV_SYN, SYN_REPORT, 0);
+	rc = libevdev_next_event(dev, LIBEVDEV_READ_FLAG_FORCE_SYNC, &ev);
+	ck_assert_int_eq(rc, LIBEVDEV_READ_STATUS_SYNC);
+
+	rc = libevdev_next_event(dev, LIBEVDEV_READ_FLAG_NORMAL, &ev);
+	ck_assert_int_eq(rc, -EAGAIN);
+
+	ck_assert_int_eq(libevdev_get_event_value(dev, EV_KEY, BTN_LEFT), 1);
+	ck_assert_int_eq(libevdev_get_event_value(dev, EV_ABS, ABS_X), 100);
+	ck_assert_int_eq(libevdev_get_event_value(dev, EV_ABS, ABS_Y), 500);
+
+	uinput_device_free(uidev);
+	libevdev_free(dev);
+}
+END_TEST
+
+START_TEST(test_incomplete_sync)
+{
+	struct uinput_device* uidev;
+	struct libevdev *dev;
+	int rc;
+	struct input_event ev;
+	struct input_absinfo abs[2] = {
+		{ .value = ABS_X, .maximum = 1000 },
+		{ .value = ABS_Y, .maximum = 1000 },
+	};
+
+	test_create_abs_device(&uidev, &dev,
+			       ARRAY_LENGTH(abs), abs,
+			       EV_SYN, SYN_REPORT,
+			       EV_SYN, SYN_DROPPED,
+			       EV_KEY, BTN_LEFT,
+			       EV_KEY, BTN_MIDDLE,
+			       EV_KEY, BTN_RIGHT,
+			       -1);
+
+	uinput_device_event(uidev, EV_KEY, BTN_LEFT, 1);
+	uinput_device_event(uidev, EV_ABS, ABS_X, 100);
+	uinput_device_event(uidev, EV_ABS, ABS_Y, 500);
+	uinput_device_event(uidev, EV_SYN, SYN_REPORT, 0);
+	rc = libevdev_next_event(dev, LIBEVDEV_READ_FLAG_FORCE_SYNC, &ev);
+	ck_assert_int_eq(rc, LIBEVDEV_READ_STATUS_SYNC);
+
+	rc = libevdev_next_event(dev, LIBEVDEV_READ_FLAG_SYNC, &ev);
+	ck_assert_int_eq(rc, LIBEVDEV_READ_STATUS_SYNC);
+	assert_event(&ev, EV_KEY, BTN_LEFT, 1);
+
+	rc = libevdev_next_event(dev, LIBEVDEV_READ_FLAG_NORMAL, &ev);
+	ck_assert_int_eq(rc, -EAGAIN);
+
+	ck_assert_int_eq(libevdev_get_event_value(dev, EV_KEY, BTN_LEFT), 1);
+	ck_assert_int_eq(libevdev_get_event_value(dev, EV_ABS, ABS_X), 100);
+	ck_assert_int_eq(libevdev_get_event_value(dev, EV_ABS, ABS_Y), 500);
+
+	uinput_device_free(uidev);
+	libevdev_free(dev);
+}
+END_TEST
+
+START_TEST(test_empty_sync)
+{
+	struct uinput_device* uidev;
+	struct libevdev *dev;
+	int rc;
+	struct input_event ev;
+
+	test_create_device(&uidev, &dev,
+			   EV_SYN, SYN_REPORT,
+			   EV_SYN, SYN_DROPPED,
+			   EV_KEY, BTN_LEFT,
+			   EV_KEY, BTN_MIDDLE,
+			   EV_KEY, BTN_RIGHT,
+			   -1);
+
+	rc = libevdev_next_event(dev, LIBEVDEV_READ_FLAG_FORCE_SYNC, &ev);
+	ck_assert_int_eq(rc, LIBEVDEV_READ_STATUS_SYNC);
+
+	rc = libevdev_next_event(dev, LIBEVDEV_READ_FLAG_SYNC, &ev);
+	ck_assert_int_eq(rc, -EAGAIN);
+
+	uinput_device_free(uidev);
+	libevdev_free(dev);
+}
+END_TEST
+
+START_TEST(test_event_values)
+{
+	struct uinput_device* uidev;
+	struct libevdev *dev;
+	int rc;
+	struct input_event ev;
+	struct input_absinfo abs[2] = {
+		{ .value = ABS_X, .maximum = 1000 },
+		{ .value = ABS_Y, .maximum = 1000 },
+	};
+	int value;
+
+	test_create_abs_device(&uidev, &dev,
+			       ARRAY_LENGTH(abs), abs,
+			       EV_SYN, SYN_REPORT,
+			       EV_SYN, SYN_DROPPED,
+			       EV_REL, REL_X,
+			       EV_REL, REL_Y,
+			       EV_KEY, BTN_LEFT,
+			       EV_KEY, BTN_MIDDLE,
+			       EV_KEY, BTN_RIGHT,
+			       -1);
+
+	uinput_device_event(uidev, EV_KEY, BTN_LEFT, 1);
+	uinput_device_event(uidev, EV_ABS, ABS_X, 100);
+	uinput_device_event(uidev, EV_ABS, ABS_Y, 500);
+	uinput_device_event(uidev, EV_SYN, SYN_REPORT, 0);
+
+	/* must still be on old values */
+	ck_assert_int_eq(libevdev_get_event_value(dev, EV_KEY, BTN_LEFT), 0);
+	ck_assert_int_eq(libevdev_get_event_value(dev, EV_ABS, ABS_X), 0);
+	ck_assert_int_eq(libevdev_get_event_value(dev, EV_ABS, ABS_Y), 0);
+	ck_assert_int_eq(libevdev_get_event_value(dev, EV_REL, REL_X), 0);
+	ck_assert_int_eq(libevdev_get_event_value(dev, EV_REL, REL_Y), 0);
+
+	ck_assert_int_eq(libevdev_fetch_event_value(dev, EV_KEY, BTN_LEFT, &value), 1);
+	ck_assert_int_eq(value, 0);
+
+	do {
+		rc = libevdev_next_event(dev, LIBEVDEV_READ_FLAG_NORMAL, &ev);
+	} while (rc == 0);
+	ck_assert_int_eq(rc, -EAGAIN);
+
+	ck_assert_int_eq(libevdev_get_event_value(dev, EV_KEY, BTN_LEFT), 1);
+	ck_assert_int_eq(libevdev_get_event_value(dev, EV_ABS, ABS_X), 100);
+	ck_assert_int_eq(libevdev_get_event_value(dev, EV_ABS, ABS_Y), 500);
+
+	/* always 0 */
+	ck_assert_int_eq(libevdev_get_event_value(dev, EV_REL, REL_X), 0);
+	ck_assert_int_eq(libevdev_get_event_value(dev, EV_REL, REL_Y), 0);
+
+	ck_assert_int_eq(libevdev_fetch_event_value(dev, EV_KEY, BTN_LEFT, &value), 1);
+	ck_assert_int_eq(value, 1);
+	ck_assert_int_eq(libevdev_fetch_event_value(dev, EV_ABS, ABS_X, &value), 1);
+	ck_assert_int_eq(value, 100);
+	ck_assert_int_eq(libevdev_fetch_event_value(dev, EV_ABS, ABS_Y, &value), 1);
+	ck_assert_int_eq(value, 500);
+
+	uinput_device_free(uidev);
+	libevdev_free(dev);
+
+}
+END_TEST
+
+START_TEST(test_event_values_invalid)
+{
+	struct uinput_device* uidev;
+	struct libevdev *dev;
+	struct input_absinfo abs[2] = {
+		{ .value = ABS_X, .maximum = 1000 },
+		{ .value = ABS_Y, .maximum = 1000 },
+	};
+	int value;
+
+	test_create_abs_device(&uidev, &dev,
+			       ARRAY_LENGTH(abs), abs,
+			       EV_SYN, SYN_REPORT,
+			       EV_SYN, SYN_DROPPED,
+			       EV_REL, REL_X,
+			       EV_REL, REL_Y,
+			       EV_KEY, BTN_LEFT,
+			       EV_KEY, BTN_MIDDLE,
+			       EV_KEY, BTN_RIGHT,
+			       -1);
+
+	ck_assert_int_eq(libevdev_get_event_value(dev, EV_KEY, BTN_EXTRA), 0);
+	ck_assert_int_eq(libevdev_get_event_value(dev, EV_ABS, ABS_Z), 0);
+	ck_assert_int_eq(libevdev_get_event_value(dev, EV_REL, REL_Z), 0);
+
+	value = 0xab;
+	ck_assert_int_eq(libevdev_fetch_event_value(dev, EV_KEY, BTN_EXTRA, &value), 0);
+	ck_assert_int_eq(value, 0xab);
+	ck_assert_int_eq(libevdev_fetch_event_value(dev, EV_ABS, ABS_Z, &value), 0);
+	ck_assert_int_eq(value, 0xab);
+	ck_assert_int_eq(libevdev_fetch_event_value(dev, EV_REL, REL_Z, &value), 0);
+	ck_assert_int_eq(value, 0xab);
+
+	uinput_device_free(uidev);
+	libevdev_free(dev);
+
+}
+END_TEST
+
+START_TEST(test_mt_event_values)
+{
+	struct uinput_device* uidev;
+	struct libevdev *dev;
+	int rc;
+	struct input_event ev;
+	struct input_absinfo abs[5] = {
+		{ .value = ABS_X, .maximum = 1000 },
+		{ .value = ABS_Y, .maximum = 1000 },
+		{ .value = ABS_MT_POSITION_X, .maximum = 1000 },
+		{ .value = ABS_MT_POSITION_Y, .maximum = 1000 },
+		{ .value = ABS_MT_SLOT, .maximum = 2 },
+	};
+	int value;
+	test_create_abs_device(&uidev, &dev,
+			       ARRAY_LENGTH(abs), abs,
+			       EV_SYN, SYN_REPORT,
+			       -1);
+
+	uinput_device_event_multiple(uidev,
+				     EV_ABS, ABS_MT_SLOT, 0,
+				     EV_ABS, ABS_X, 100,
+				     EV_ABS, ABS_Y, 500,
+				     EV_ABS, ABS_MT_POSITION_X, 100,
+				     EV_ABS, ABS_MT_POSITION_Y, 500,
+				     EV_ABS, ABS_MT_SLOT, 1,
+				     EV_ABS, ABS_X, 1,
+				     EV_ABS, ABS_Y, 5,
+				     EV_ABS, ABS_MT_POSITION_X, 1,
+				     EV_ABS, ABS_MT_POSITION_Y, 5,
+				     EV_SYN, SYN_REPORT, 0,
+				     -1, -1);
+
+	/* must still be on old values */
+	ck_assert_int_eq(libevdev_get_current_slot(dev), 0);
+	ck_assert_int_eq(libevdev_get_slot_value(dev, 0, ABS_MT_POSITION_X), 0);
+	ck_assert_int_eq(libevdev_get_slot_value(dev, 0, ABS_MT_POSITION_Y), 0);
+	ck_assert_int_eq(libevdev_get_slot_value(dev, 1, ABS_MT_POSITION_X), 0);
+	ck_assert_int_eq(libevdev_get_slot_value(dev, 1, ABS_MT_POSITION_Y), 0);
+
+	do {
+		rc = libevdev_next_event(dev, LIBEVDEV_READ_FLAG_NORMAL, &ev);
+	} while (rc == LIBEVDEV_READ_STATUS_SUCCESS);
+	ck_assert_int_eq(rc, -EAGAIN);
+
+	ck_assert_int_eq(libevdev_get_current_slot(dev), 1);
+	ck_assert_int_eq(libevdev_get_slot_value(dev, 0, ABS_MT_POSITION_X), 100);
+	ck_assert_int_eq(libevdev_get_slot_value(dev, 0, ABS_MT_POSITION_Y), 500);
+	ck_assert_int_eq(libevdev_get_slot_value(dev, 1, ABS_MT_POSITION_X), 1);
+	ck_assert_int_eq(libevdev_get_slot_value(dev, 1, ABS_MT_POSITION_Y), 5);
+
+	ck_assert_int_eq(libevdev_fetch_slot_value(dev, 0, ABS_MT_POSITION_X, &value), 1);
+	ck_assert_int_eq(value, 100);
+	ck_assert_int_eq(libevdev_fetch_slot_value(dev, 0, ABS_MT_POSITION_Y, &value), 1);
+	ck_assert_int_eq(value, 500);
+	ck_assert_int_eq(libevdev_fetch_slot_value(dev, 1, ABS_MT_POSITION_X, &value), 1);
+	ck_assert_int_eq(value, 1);
+	ck_assert_int_eq(libevdev_fetch_slot_value(dev, 1, ABS_MT_POSITION_Y, &value), 1);
+	ck_assert_int_eq(value, 5);
+
+	uinput_device_free(uidev);
+	libevdev_free(dev);
+
+}
+END_TEST
+
+START_TEST(test_mt_event_values_invalid)
+{
+	struct uinput_device* uidev;
+	struct libevdev *dev;
+	struct input_absinfo abs[5] = {
+		{ .value = ABS_X, .maximum = 1000 },
+		{ .value = ABS_Y, .maximum = 1000 },
+		{ .value = ABS_MT_POSITION_X, .maximum = 1000 },
+		{ .value = ABS_MT_POSITION_Y, .maximum = 1000 },
+		{ .value = ABS_MT_SLOT, .maximum = 2 },
+	};
+	int value;
+
+	test_create_abs_device(&uidev, &dev,
+			       ARRAY_LENGTH(abs), abs,
+			       EV_SYN, SYN_REPORT,
+			       -1);
+
+	ck_assert_int_eq(libevdev_get_current_slot(dev), 0);
+	ck_assert_int_eq(libevdev_get_slot_value(dev, 0, ABS_MT_TOUCH_MINOR), 0);
+	value = 0xab;
+	ck_assert_int_eq(libevdev_fetch_slot_value(dev, 0, ABS_MT_TOUCH_MINOR, &value), 0);
+	ck_assert_int_eq(value, 0xab);
+
+	ck_assert_int_eq(libevdev_get_slot_value(dev, 10, ABS_MT_POSITION_X), 0);
+	ck_assert_int_eq(libevdev_get_slot_value(dev, 0, ABS_X), 0);
+
+	uinput_device_free(uidev);
+	libevdev_free(dev);
+}
+END_TEST
+
+START_TEST(test_mt_slot_ranges_invalid)
+{
+	struct uinput_device* uidev;
+	struct libevdev *dev;
+	struct input_event ev[2];
+	int rc;
+	int num_slots = 2;
+	struct input_absinfo abs[5] = {
+		{ .value = ABS_X, .maximum = 1000 },
+		{ .value = ABS_Y, .maximum = 1000 },
+		{ .value = ABS_MT_POSITION_X, .maximum = 1000 },
+		{ .value = ABS_MT_POSITION_Y, .maximum = 1000 },
+		{ .value = ABS_MT_SLOT, .maximum = num_slots - 1 },
+	};
+	int pipefd[2];
+
+	test_create_abs_device(&uidev, &dev,
+			       ARRAY_LENGTH(abs), abs,
+			       EV_SYN, SYN_REPORT,
+			       -1);
+
+	rc = pipe2(pipefd, O_NONBLOCK);
+	ck_assert_int_eq(rc, 0);
+	libevdev_change_fd(dev, pipefd[0]);
+
+	memset(ev, 0, sizeof(ev));
+	ev[0].type = EV_ABS;
+	ev[0].code = ABS_MT_SLOT;
+	ev[0].value = num_slots;
+	ev[1].type = EV_SYN;
+	ev[1].code = SYN_REPORT;
+	ev[1].value = 0;
+	rc = write(pipefd[1], ev, sizeof(ev));
+	ck_assert_int_eq(rc, sizeof(ev));
+
+	libevdev_set_log_function(test_logfunc_ignore_error, NULL);
+
+	libevdev_next_event(dev, LIBEVDEV_READ_FLAG_NORMAL, ev);
+	ck_assert(libevdev_event_is_code(ev, EV_ABS, ABS_MT_SLOT));
+	ck_assert_int_eq(ev[0].value, num_slots - 1);
+
+	/* drain the EV_SYN */
+	libevdev_next_event(dev, LIBEVDEV_READ_FLAG_NORMAL, ev);
+
+	ev[0].type = EV_ABS;
+	ev[0].code = ABS_MT_SLOT;
+	ev[0].value = -1;
+	ev[1].type = EV_SYN;
+	ev[1].code = SYN_REPORT;
+	ev[1].value = 0;
+	rc = write(pipefd[1], ev, sizeof(ev));
+	ck_assert_int_eq(rc, sizeof(ev));
+
+	libevdev_next_event(dev, LIBEVDEV_READ_FLAG_NORMAL, ev);
+	ck_assert(libevdev_event_is_code(ev, EV_ABS, ABS_MT_SLOT));
+	ck_assert_int_eq(ev[0].value, num_slots - 1);
+
+	ck_assert_int_eq(libevdev_get_current_slot(dev), num_slots - 1);
+
+	ck_assert_int_eq(libevdev_set_event_value(dev, EV_ABS, ABS_MT_SLOT, num_slots), -1);
+	ck_assert_int_eq(libevdev_set_event_value(dev, EV_ABS, ABS_MT_SLOT, -1), -1);
+
+	libevdev_set_log_function(test_logfunc_abort_on_error, NULL);
+
+	uinput_device_free(uidev);
+	libevdev_free(dev);
+}
+END_TEST
+
+START_TEST(test_mt_tracking_id_discard)
+{
+	struct uinput_device* uidev;
+	struct libevdev *dev;
+	int rc;
+	struct input_event ev;
+	struct input_absinfo abs[6] = {
+		{ .value = ABS_X, .maximum = 1000 },
+		{ .value = ABS_Y, .maximum = 1000 },
+		{ .value = ABS_MT_POSITION_X, .maximum = 1000 },
+		{ .value = ABS_MT_POSITION_Y, .maximum = 1000 },
+		{ .value = ABS_MT_SLOT, .maximum = 10 },
+		{ .value = ABS_MT_TRACKING_ID, .minimum = -1, .maximum = 500 },
+	};
+
+	test_create_abs_device(&uidev, &dev,
+			       ARRAY_LENGTH(abs), abs,
+			       EV_SYN, SYN_REPORT,
+			       -1);
+
+	uinput_device_event(uidev, EV_ABS, ABS_MT_SLOT, 1);
+	uinput_device_event(uidev, EV_ABS, ABS_MT_TRACKING_ID, 1);
+	uinput_device_event(uidev, EV_SYN, SYN_REPORT, 0);
+
+	/* second tracking ID on same slot */
+	uinput_device_event(uidev, EV_ABS, ABS_MT_TRACKING_ID, 2);
+	uinput_device_event(uidev, EV_SYN, SYN_REPORT, 0);
+
+	libevdev_set_log_function(test_logfunc_ignore_error, NULL);
+
+	rc = libevdev_next_event(dev, LIBEVDEV_READ_FLAG_NORMAL, &ev);
+	ck_assert_int_eq(rc, LIBEVDEV_READ_STATUS_SUCCESS);
+	assert_event(&ev, EV_ABS, ABS_MT_SLOT, 1);
+
+	rc = libevdev_next_event(dev, LIBEVDEV_READ_FLAG_NORMAL, &ev);
+	ck_assert_int_eq(rc, LIBEVDEV_READ_STATUS_SUCCESS);
+	assert_event(&ev, EV_ABS, ABS_MT_TRACKING_ID, 1);
+
+	rc = libevdev_next_event(dev, LIBEVDEV_READ_FLAG_NORMAL, &ev);
+	ck_assert_int_eq(rc, LIBEVDEV_READ_STATUS_SUCCESS);
+	assert_event(&ev, EV_SYN, SYN_REPORT, 0);
+
+	/* expect tracking ID discarded */
+
+	rc = libevdev_next_event(dev, LIBEVDEV_READ_FLAG_NORMAL, &ev);
+	ck_assert_int_eq(rc, LIBEVDEV_READ_STATUS_SUCCESS);
+	assert_event(&ev, EV_SYN, SYN_REPORT, 0);
+
+	rc = libevdev_next_event(dev, LIBEVDEV_READ_FLAG_NORMAL, &ev);
+	ck_assert_int_eq(rc, -EAGAIN);
+
+	libevdev_set_log_function(test_logfunc_abort_on_error, NULL);
+
+	uinput_device_free(uidev);
+	libevdev_free(dev);
+}
+END_TEST
+
+START_TEST(test_mt_tracking_id_discard_neg_1)
+{
+	struct uinput_device* uidev;
+	struct libevdev *dev;
+	int rc;
+	struct input_event ev;
+	struct input_absinfo abs[6] = {
+		{ .value = ABS_X, .maximum = 1000 },
+		{ .value = ABS_Y, .maximum = 1000 },
+		{ .value = ABS_MT_POSITION_X, .maximum = 1000 },
+		{ .value = ABS_MT_POSITION_Y, .maximum = 1000 },
+		{ .value = ABS_MT_SLOT, .maximum = 10 },
+		{ .value = ABS_MT_TRACKING_ID, .minimum = -1, .maximum = 500 },
+	};
+	int pipefd[2];
+	struct input_event events[] = {
+		{ .type = EV_ABS, .code = ABS_MT_TRACKING_ID, .value = -1 },
+		{ .type = EV_SYN, .code = SYN_REPORT, .value = 0 },
+	};
+
+	rc = pipe2(pipefd, O_NONBLOCK);
+	ck_assert_int_eq(rc, 0);
+
+	test_create_abs_device(&uidev, &dev,
+			       ARRAY_LENGTH(abs), abs,
+			       EV_SYN, SYN_REPORT,
+			       -1);
+	uinput_device_event(uidev, EV_ABS, ABS_MT_SLOT, 1);
+	uinput_device_event(uidev, EV_ABS, ABS_MT_TRACKING_ID, 1);
+	uinput_device_event(uidev, EV_SYN, SYN_REPORT, 0);
+
+	while (libevdev_next_event(dev, LIBEVDEV_READ_FLAG_NORMAL, &ev) != -EAGAIN)
+		;
+
+	libevdev_set_log_function(test_logfunc_ignore_error, NULL);
+
+	/* two -1 tracking ids, need to use the pipe here, the kernel will
+	   filter it otherwise */
+	libevdev_change_fd(dev, pipefd[0]);
+
+	rc = write(pipefd[1], events, sizeof(events));
+	ck_assert_int_eq(rc, sizeof(events));
+	rc = write(pipefd[1], events, sizeof(events));
+	ck_assert_int_eq(rc, sizeof(events));
+
+	rc = libevdev_next_event(dev, LIBEVDEV_READ_FLAG_NORMAL, &ev);
+	ck_assert_int_eq(rc, LIBEVDEV_READ_STATUS_SUCCESS);
+	assert_event(&ev, EV_ABS, ABS_MT_TRACKING_ID, -1);
+	rc = libevdev_next_event(dev, LIBEVDEV_READ_FLAG_NORMAL, &ev);
+	ck_assert_int_eq(rc, LIBEVDEV_READ_STATUS_SUCCESS);
+	assert_event(&ev, EV_SYN, SYN_REPORT, 0);
+
+	/* expect second tracking ID discarded */
+
+	rc = libevdev_next_event(dev, LIBEVDEV_READ_FLAG_NORMAL, &ev);
+	ck_assert_int_eq(rc, LIBEVDEV_READ_STATUS_SUCCESS);
+	assert_event(&ev, EV_SYN, SYN_REPORT, 0);
+
+	rc = libevdev_next_event(dev, LIBEVDEV_READ_FLAG_NORMAL, &ev);
+	ck_assert_int_eq(rc, -EAGAIN);
+
+	libevdev_set_log_function(test_logfunc_abort_on_error, NULL);
+
+	uinput_device_free(uidev);
+	libevdev_free(dev);
+}
+END_TEST
+
+START_TEST(test_ev_rep_values)
+{
+	struct uinput_device* uidev;
+	struct libevdev *dev;
+	int delay = 500, period = 200;
+	test_create_device(&uidev, &dev,
+			   EV_KEY, BTN_LEFT,
+			   EV_REL, REL_X,
+			   EV_REL, REL_Y,
+			   EV_SYN, SYN_REPORT,
+			   -1);
+
+	libevdev_enable_event_code(dev, EV_REP, REP_DELAY, &delay);
+	libevdev_enable_event_code(dev, EV_REP, REP_PERIOD, &period);
+
+	ck_assert_int_eq(libevdev_has_event_type(dev, EV_REP), 1);
+	ck_assert_int_eq(libevdev_has_event_code(dev, EV_REP, REP_DELAY), 1);
+	ck_assert_int_eq(libevdev_has_event_code(dev, EV_REP, REP_PERIOD), 1);
+	ck_assert_int_eq(libevdev_get_event_value(dev, EV_REP, REP_DELAY), 500);
+	ck_assert_int_eq(libevdev_get_event_value(dev, EV_REP, REP_PERIOD), 200);
+
+	uinput_device_free(uidev);
+	libevdev_free(dev);
+}
+END_TEST
+
+START_TEST(test_event_value_setters)
+{
+	struct uinput_device* uidev;
+	struct libevdev *dev;
+	struct input_absinfo abs[2] = {
+		{ .value = ABS_X, .maximum = 1000 },
+		{ .value = ABS_Y, .maximum = 1000 },
+	};
+
+	test_create_abs_device(&uidev, &dev,
+			       ARRAY_LENGTH(abs), abs,
+			       EV_SYN, SYN_REPORT,
+			       EV_REL, REL_X,
+			       EV_REL, REL_Y,
+			       EV_KEY, BTN_LEFT,
+			       EV_KEY, BTN_MIDDLE,
+			       EV_KEY, BTN_RIGHT,
+			       EV_LED, LED_NUML,
+			       EV_LED, LED_CAPSL,
+			       EV_SW, SW_HEADPHONE_INSERT,
+			       EV_SW, SW_TABLET_MODE,
+			       -1);
+
+	ck_assert_int_eq(libevdev_get_event_value(dev, EV_KEY, BTN_LEFT), 0);
+	ck_assert_int_eq(libevdev_get_event_value(dev, EV_ABS, ABS_X), 0);
+	ck_assert_int_eq(libevdev_get_event_value(dev, EV_ABS, ABS_Y), 0);
+	ck_assert_int_eq(libevdev_get_event_value(dev, EV_REL, REL_X), 0);
+	ck_assert_int_eq(libevdev_get_event_value(dev, EV_REL, REL_Y), 0);
+
+	ck_assert_int_eq(libevdev_set_event_value(dev, EV_KEY, BTN_LEFT, 1), 0);
+	ck_assert_int_eq(libevdev_set_event_value(dev, EV_KEY, BTN_RIGHT, 1), 0);
+
+	ck_assert_int_eq(libevdev_get_event_value(dev, EV_KEY, BTN_LEFT), 1);
+	ck_assert_int_eq(libevdev_get_event_value(dev, EV_KEY, BTN_RIGHT), 1);
+
+	ck_assert_int_eq(libevdev_set_event_value(dev, EV_ABS, ABS_X, 10), 0);
+	ck_assert_int_eq(libevdev_set_event_value(dev, EV_ABS, ABS_Y, 20), 0);
+
+	ck_assert_int_eq(libevdev_get_event_value(dev, EV_ABS, ABS_X), 10);
+	ck_assert_int_eq(libevdev_get_event_value(dev, EV_ABS, ABS_Y), 20);
+
+	ck_assert_int_eq(libevdev_set_event_value(dev, EV_LED, LED_NUML, 1), 0);
+	ck_assert_int_eq(libevdev_set_event_value(dev, EV_LED, LED_CAPSL, 1), 0);
+
+	ck_assert_int_eq(libevdev_get_event_value(dev, EV_LED, LED_NUML), 1);
+	ck_assert_int_eq(libevdev_get_event_value(dev, EV_LED, LED_CAPSL), 1);
+
+	ck_assert_int_eq(libevdev_set_event_value(dev, EV_SW, SW_HEADPHONE_INSERT, 1), 0);
+	ck_assert_int_eq(libevdev_set_event_value(dev, EV_SW, SW_TABLET_MODE, 1), 0);
+
+	ck_assert_int_eq(libevdev_get_event_value(dev, EV_SW, SW_HEADPHONE_INSERT), 1);
+	ck_assert_int_eq(libevdev_get_event_value(dev, EV_SW, SW_TABLET_MODE), 1);
+
+	uinput_device_free(uidev);
+	libevdev_free(dev);
+
+}
+END_TEST
+
+START_TEST(test_event_value_setters_invalid)
+{
+	struct uinput_device* uidev;
+	struct libevdev *dev;
+	struct input_absinfo abs[2] = {
+		{ .value = ABS_X, .maximum = 1000 },
+		{ .value = ABS_Y, .maximum = 1000 },
+	};
+
+	test_create_abs_device(&uidev, &dev,
+			       ARRAY_LENGTH(abs), abs,
+			       EV_SYN, SYN_REPORT,
+			       EV_REL, REL_X,
+			       EV_REL, REL_Y,
+			       EV_KEY, BTN_LEFT,
+			       EV_KEY, BTN_MIDDLE,
+			       EV_KEY, BTN_RIGHT,
+			       -1);
+
+	ck_assert_int_eq(libevdev_set_event_value(dev, EV_REL, REL_X, 1), -1);
+	ck_assert_int_eq(libevdev_set_event_value(dev, EV_SW, SW_DOCK, 1), -1);
+	ck_assert_int_eq(libevdev_set_event_value(dev, EV_ABS, ABS_Z, 1), -1);
+	ck_assert_int_eq(libevdev_set_event_value(dev, EV_MAX + 1, 0, 1), -1);
+	ck_assert_int_eq(libevdev_set_event_value(dev, EV_SYN, SYN_REPORT, 0), -1);
+
+	uinput_device_free(uidev);
+	libevdev_free(dev);
+
+}
+END_TEST
+
+START_TEST(test_event_mt_value_setters)
+{
+	struct uinput_device* uidev;
+	struct libevdev *dev;
+	struct input_absinfo abs[5] = {
+		{ .value = ABS_X, .maximum = 1000 },
+		{ .value = ABS_Y, .maximum = 1000 },
+		{ .value = ABS_MT_POSITION_X, .maximum = 1000 },
+		{ .value = ABS_MT_POSITION_Y, .maximum = 1000 },
+		{ .value = ABS_MT_SLOT, .maximum = 2 },
+	};
+
+	test_create_abs_device(&uidev, &dev,
+			       ARRAY_LENGTH(abs), abs,
+			       EV_SYN, SYN_REPORT,
+			       -1);
+
+	ck_assert_int_eq(libevdev_set_slot_value(dev, 1, ABS_MT_POSITION_X, 1), 0);
+	ck_assert_int_eq(libevdev_set_slot_value(dev, 1, ABS_MT_POSITION_Y, 2), 0);
+	ck_assert_int_eq(libevdev_set_slot_value(dev, 0, ABS_MT_POSITION_X, 3), 0);
+	ck_assert_int_eq(libevdev_set_slot_value(dev, 0, ABS_MT_POSITION_Y, 4), 0);
+
+	ck_assert_int_eq(libevdev_get_slot_value(dev, 1, ABS_MT_POSITION_X), 1);
+	ck_assert_int_eq(libevdev_get_slot_value(dev, 1, ABS_MT_POSITION_Y), 2);
+	ck_assert_int_eq(libevdev_get_slot_value(dev, 0, ABS_MT_POSITION_X), 3);
+	ck_assert_int_eq(libevdev_get_slot_value(dev, 0, ABS_MT_POSITION_Y), 4);
+
+	ck_assert_int_eq(libevdev_set_slot_value(dev, 1, ABS_MT_SLOT, 1), 0);
+	ck_assert_int_eq(libevdev_get_slot_value(dev, 1, ABS_MT_SLOT), 1);
+	ck_assert_int_eq(libevdev_get_current_slot(dev), 1);
+
+	uinput_device_free(uidev);
+	libevdev_free(dev);
+}
+END_TEST
+
+START_TEST(test_event_mt_value_setters_invalid)
+{
+	struct uinput_device* uidev;
+	struct libevdev *dev;
+	struct input_absinfo abs[5] = {
+		{ .value = ABS_X, .maximum = 1000 },
+		{ .value = ABS_Y, .maximum = 1000 },
+		{ .value = ABS_MT_POSITION_X, .maximum = 1000 },
+		{ .value = ABS_MT_POSITION_Y, .maximum = 1000 },
+		{ .value = ABS_MT_SLOT, .maximum = 2 },
+	};
+
+	test_create_abs_device(&uidev, &dev,
+			       ARRAY_LENGTH(abs), abs,
+			       EV_SYN, SYN_REPORT,
+			       -1);
+
+	/* invalid axis */
+	ck_assert_int_eq(libevdev_set_slot_value(dev, 1, ABS_Z, 1), -1);
+	/* valid, but non-mt axis */
+	ck_assert_int_eq(libevdev_set_slot_value(dev, 1, ABS_X, 1), -1);
+	/* invalid mt axis */
+	ck_assert_int_eq(libevdev_set_slot_value(dev, 1, ABS_MT_PRESSURE, 1), -1);
+	/* invalid slot no */
+	ck_assert_int_eq(libevdev_set_slot_value(dev, 4, ABS_X, 1), -1);
+
+	uinput_device_free(uidev);
+	libevdev_free(dev);
+}
+END_TEST
+
+START_TEST(test_event_mt_value_setters_current_slot)
+{
+	struct uinput_device* uidev;
+	struct libevdev *dev;
+	struct input_absinfo abs[5] = {
+		{ .value = ABS_X, .maximum = 1000 },
+		{ .value = ABS_Y, .maximum = 1000 },
+		{ .value = ABS_MT_POSITION_X, .maximum = 1000 },
+		{ .value = ABS_MT_POSITION_Y, .maximum = 1000 },
+		{ .value = ABS_MT_SLOT, .maximum = 2 },
+	};
+
+	test_create_abs_device(&uidev, &dev,
+			       ARRAY_LENGTH(abs), abs,
+			       EV_SYN, SYN_REPORT,
+			       -1);
+
+	/* set_event_value/get_event_value works on the current slot */
+
+	ck_assert_int_eq(libevdev_get_current_slot(dev), 0);
+	ck_assert_int_eq(libevdev_set_event_value(dev, EV_ABS, ABS_MT_POSITION_X, 1), 0);
+	ck_assert_int_eq(libevdev_get_event_value(dev, EV_ABS, ABS_MT_POSITION_X), 1);
+	ck_assert_int_eq(libevdev_get_slot_value(dev, 0, ABS_MT_POSITION_X), 1);
+
+	ck_assert_int_eq(libevdev_set_event_value(dev, EV_ABS, ABS_MT_SLOT, 1), 0);
+	ck_assert_int_eq(libevdev_get_current_slot(dev), 1);
+	ck_assert_int_eq(libevdev_set_event_value(dev, EV_ABS, ABS_MT_POSITION_X, 2), 0);
+	ck_assert_int_eq(libevdev_get_event_value(dev, EV_ABS, ABS_MT_POSITION_X), 2);
+	ck_assert_int_eq(libevdev_get_slot_value(dev, 1, ABS_MT_POSITION_X), 2);
+
+	/* set slot 0, but current is still slot 1 */
+	ck_assert_int_eq(libevdev_set_slot_value(dev, 0, ABS_MT_POSITION_X, 3), 0);
+	ck_assert_int_eq(libevdev_get_event_value(dev, EV_ABS, ABS_MT_POSITION_X), 2);
+
+	ck_assert_int_eq(libevdev_set_event_value(dev, EV_ABS, ABS_MT_SLOT, 0), 0);
+	ck_assert_int_eq(libevdev_get_current_slot(dev), 0);
+	ck_assert_int_eq(libevdev_get_event_value(dev, EV_ABS, ABS_MT_POSITION_X), 3);
+
+	uinput_device_free(uidev);
+	libevdev_free(dev);
+}
+END_TEST
+
+TEST_SUITE_ROOT_PRIVILEGES(libevdev_events)
+{
+	Suite *s = suite_create("libevdev event tests");
+
+	add_test(s, test_next_event);
+	add_test(s, test_next_event_invalid_fd);
+	add_test(s, test_next_event_blocking);
+	add_test(s, test_syn_dropped_event);
+	add_test(s, test_event_type_filtered);
+	add_test(s, test_event_code_filtered);
+	add_test(s, test_has_event_pending);
+	add_test(s, test_has_event_pending_invalid_fd);
+
+	add_test(s, test_syn_delta_button);
+	add_test(s, test_syn_delta_abs);
+	add_test(s, test_syn_delta_mt);
+	add_test(s, test_syn_delta_mt_reset_slot);
+	add_test(s, test_syn_delta_led);
+	add_test(s, test_syn_delta_sw);
+	add_test(s, test_syn_delta_fake_mt);
+	add_test(s, test_syn_delta_late_sync);
+	add_test(s, test_syn_delta_tracking_ids);
+	add_test(s, test_syn_delta_tracking_ids_btntool);
+
+	add_test(s, test_skipped_sync);
+	add_test(s, test_incomplete_sync);
+	add_test(s, test_empty_sync);
+
+	add_test(s, test_event_values);
+	add_test(s, test_event_values_invalid);
+	add_test(s, test_mt_event_values);
+	add_test(s, test_mt_event_values_invalid);
+	add_test(s, test_mt_slot_ranges_invalid);
+	add_test(s, test_mt_tracking_id_discard);
+	add_test(s, test_mt_tracking_id_discard_neg_1);
+	add_test(s, test_ev_rep_values);
+
+	add_test(s, test_event_value_setters);
+	add_test(s, test_event_value_setters_invalid);
+	add_test(s, test_event_mt_value_setters);
+	add_test(s, test_event_mt_value_setters_invalid);
+	add_test(s, test_event_mt_value_setters_current_slot);
+
+	return s;
+}
diff --git a/test/test-libevdev-has-event.c b/test/test-libevdev-has-event.c
new file mode 100644
index 0000000000000000000000000000000000000000..1d42e196a3ebe559b9330fd1f2030cf524ff0162
--- /dev/null
+++ b/test/test-libevdev-has-event.c
@@ -0,0 +1,1194 @@
+// SPDX-License-Identifier: MIT
+/*
+ * Copyright © 2013 Red Hat, Inc.
+ */
+
+#include "config.h"
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "test-common.h"
+
+static int evbits[] = {
+	EV_SYN, EV_KEY, EV_REL, EV_ABS, EV_MSC,
+	EV_SW, EV_LED, EV_SND, EV_FF,
+	/* Intentionally skipping these, they're different
+	 * EV_PWR, EV_FF_STATUS, EV_REP, */
+	-1,
+};
+
+START_TEST(test_has_ev_bit)
+{
+	int *evbit = evbits;
+
+	while(*evbit != -1) {
+		struct uinput_device* uidev;
+		struct libevdev *dev;
+		int i;
+
+		if (*evbit == EV_ABS) {
+			struct input_absinfo abs = { ABS_X, 0, 2, 0, 0, 0};
+			test_create_abs_device(&uidev, &dev,
+					       1, &abs,
+					       -1);
+		} else
+			test_create_device(&uidev, &dev,
+					   *evbit, 0,
+					   -1);
+
+		ck_assert_msg(libevdev_has_event_type(dev, EV_SYN), "for event type %d\n", *evbit);
+		ck_assert_msg(libevdev_has_event_type(dev, *evbit), "for event type %d\n", *evbit);
+
+		for (i = 0; i <= EV_MAX; i++) {
+			if (i == EV_SYN || i == *evbit)
+				continue;
+
+			ck_assert_msg(!libevdev_has_event_type(dev, i), "for event type %d\n", i);
+		}
+
+		libevdev_free(dev);
+		uinput_device_free(uidev);
+
+		evbit++;
+	}
+}
+END_TEST
+
+START_TEST(test_ev_bit_limits)
+{
+	int *evbit = evbits;
+
+	while(*evbit != -1) {
+		struct uinput_device* uidev;
+		struct libevdev *dev;
+
+		if (*evbit == EV_ABS) {
+			struct input_absinfo abs = { ABS_X, 0, 2, 0, 0, 0};
+			test_create_abs_device(&uidev, &dev,
+					       1, &abs,
+					       -1);
+		} else
+			test_create_device(&uidev, &dev,
+					   *evbit, 0,
+					   -1);
+
+		ck_assert_int_eq(libevdev_has_event_type(dev, EV_MAX + 1), 0);
+		ck_assert_int_eq(libevdev_has_event_type(dev, INT_MAX), 0);
+		ck_assert_int_eq(libevdev_has_event_type(dev, UINT_MAX), 0);
+
+		libevdev_free(dev);
+		uinput_device_free(uidev);
+
+		evbit++;
+	}
+}
+END_TEST
+
+START_TEST(test_event_codes)
+{
+	int *evbit = evbits;
+
+	while(*evbit != -1) {
+		struct uinput_device* uidev;
+		struct libevdev *dev;
+		int code, max;
+		if (*evbit == EV_SYN) {
+			evbit++;
+			continue;
+		}
+
+#ifdef __FreeBSD__
+		/* Force feedback events are not supported by FreeBSD */
+		if (*evbit == EV_FF) {
+			evbit++;
+			continue;
+		}
+#endif
+
+		max = libevdev_event_type_get_max(*evbit);
+
+		for (code = 1; code < max; code += 10) {
+			if (*evbit == EV_ABS) {
+				struct input_absinfo abs = { code, 0, 2, 0, 0, 0};
+				test_create_abs_device(&uidev, &dev,
+						       1, &abs,
+						       -1);
+			} else
+				test_create_device(&uidev, &dev,
+						   *evbit, code,
+						   -1);
+
+			ck_assert_msg(libevdev_has_event_type(dev, *evbit), "for event type %d\n", *evbit);
+			ck_assert_msg(libevdev_has_event_code(dev, *evbit, code), "for type %d code %d", *evbit, code);
+			ck_assert_msg(libevdev_has_event_code(dev, EV_SYN, SYN_REPORT), "for EV_SYN");
+			/* always false */
+			ck_assert_msg(!libevdev_has_event_code(dev, EV_PWR, 0), "for EV_PWR");
+
+			libevdev_free(dev);
+			uinput_device_free(uidev);
+		}
+
+		evbit++;
+	}
+}
+END_TEST
+
+START_TEST(test_event_code_limits)
+{
+	int *evbit = evbits;
+
+	while(*evbit != -1) {
+		struct uinput_device* uidev;
+		struct libevdev *dev;
+		int max;
+
+		if (*evbit == EV_SYN) {
+			evbit++;
+			continue;
+		}
+
+		max = libevdev_event_type_get_max(*evbit);
+		ck_assert(max != -1);
+
+		if (*evbit == EV_ABS) {
+			struct input_absinfo abs = { ABS_X, 0, 2, 0, 0, 0};
+			test_create_abs_device(&uidev, &dev,
+					       1, &abs,
+					       -1);
+		} else
+			test_create_device(&uidev, &dev,
+					   *evbit, 1,
+					   -1);
+
+		ck_assert_msg(!libevdev_has_event_code(dev, *evbit, max), "for type %d code %d", *evbit, max);
+		ck_assert_msg(!libevdev_has_event_code(dev, *evbit, INT_MAX), "for type %d code %d", *evbit, INT_MAX);
+		ck_assert_msg(!libevdev_has_event_code(dev, *evbit, UINT_MAX), "for type %d code %d", *evbit, UINT_MAX);
+
+		libevdev_free(dev);
+		uinput_device_free(uidev);
+
+		evbit++;
+	}
+}
+END_TEST
+
+START_TEST(test_ev_rep)
+{
+	struct libevdev *dev;
+	struct uinput_device* uidev;
+	int rc;
+	int rep, delay;
+	const int KERNEL_DEFAULT_REP = 250;
+	const int KERNEL_DEFAULT_DELAY = 33;
+
+	/* EV_REP is special, it's always fully set if set at all,
+	   can't test this through uinput though */
+	uidev = uinput_device_new(TEST_DEVICE_NAME);
+	ck_assert(uidev != NULL);
+	rc = uinput_device_set_bit(uidev, EV_REP);
+	ck_assert_int_eq(rc, 0);
+
+	rc = uinput_device_create(uidev);
+	ck_assert_int_eq(rc, 0);
+
+	rc = libevdev_new_from_fd(uinput_device_get_fd(uidev), &dev);
+	ck_assert_int_eq(rc, 0);
+
+	ck_assert_int_eq(libevdev_has_event_type(dev, EV_REP), 1);
+	ck_assert_int_eq(libevdev_has_event_code(dev, EV_REP, REP_DELAY), 1);
+	ck_assert_int_eq(libevdev_has_event_code(dev, EV_REP, REP_PERIOD), 1);
+
+	ck_assert_int_eq(libevdev_get_repeat(dev, &rep, &delay), 0);
+	/* default values as set by the kernel,
+	   see drivers/input/input.c:input_register_device() */
+	ck_assert_int_eq(rep, KERNEL_DEFAULT_REP);
+	ck_assert_int_eq(delay, KERNEL_DEFAULT_DELAY);
+
+	libevdev_free(dev);
+	uinput_device_free(uidev);
+}
+END_TEST
+
+START_TEST(test_ev_rep_values)
+{
+	struct uinput_device* uidev;
+	struct libevdev *dev;
+	int delay = 0xab, period = 0xbc;
+
+	/* EV_REP is special, it's always fully set if set at all, can't set
+	   it through uinput though. */
+	test_create_device(&uidev, &dev, -1);
+
+	ck_assert_int_eq(libevdev_get_repeat(dev, NULL, NULL), -1);
+	ck_assert_int_eq(libevdev_get_repeat(dev, &delay, NULL), -1);
+	ck_assert_int_eq(libevdev_get_repeat(dev, NULL, &period), -1);
+	ck_assert_int_eq(libevdev_get_repeat(dev, &delay, &period), -1);
+
+	ck_assert_int_eq(delay, 0xab);
+	ck_assert_int_eq(period, 0xbc);
+
+	uinput_device_free(uidev);
+	libevdev_free(dev);
+}
+END_TEST
+
+START_TEST(test_input_props)
+{
+	struct uinput_device* uidev;
+	struct libevdev *dev;
+	int rc, i;
+	struct input_absinfo abs = { .value = 0, .minimum = 0, .maximum = 2};
+
+	uidev = uinput_device_new(TEST_DEVICE_NAME);
+	rc = uinput_device_set_abs_bit(uidev, ABS_X, &abs);
+	ck_assert_int_eq(rc, 0);
+	uinput_device_set_prop(uidev, INPUT_PROP_DIRECT);
+	uinput_device_set_prop(uidev, INPUT_PROP_BUTTONPAD);
+	rc = uinput_device_create(uidev);
+	ck_assert_msg(rc == 0, "Failed to create uinput device: %s", strerror(-rc));
+
+	rc = libevdev_new_from_fd(uinput_device_get_fd(uidev), &dev);
+	ck_assert_msg(rc == 0, "Failed to create device: %s", strerror(-rc));
+
+	for (i = 0; i < INPUT_PROP_CNT; i++) {
+		if (i == INPUT_PROP_DIRECT || i == INPUT_PROP_BUTTONPAD)
+			ck_assert_int_eq(libevdev_has_property(dev, i), 1);
+		else
+			ck_assert_int_eq(libevdev_has_property(dev, i), 0);
+	}
+
+	ck_assert_int_eq(libevdev_has_property(dev, INPUT_PROP_MAX + 1), 0);
+	ck_assert_int_eq(libevdev_has_property(dev, INPUT_PROP_MAX), 0);
+
+	uinput_device_free(uidev);
+	libevdev_free(dev);
+}
+END_TEST
+
+START_TEST(test_set_input_props)
+{
+	struct uinput_device* uidev;
+	struct libevdev *dev;
+	int rc, fd;
+	struct input_absinfo abs = { .value = 0, .minimum = 0, .maximum = 2};
+
+	dev = libevdev_new();
+	ck_assert_int_eq(libevdev_enable_property(dev, INPUT_PROP_MAX + 1), -1);
+	ck_assert_int_eq(libevdev_enable_property(dev, INPUT_PROP_DIRECT), 0);
+	ck_assert_int_eq(libevdev_enable_property(dev, INPUT_PROP_BUTTONPAD), 0);
+	ck_assert_int_eq(libevdev_has_property(dev, INPUT_PROP_DIRECT), 1);
+	ck_assert_int_eq(libevdev_has_property(dev, INPUT_PROP_BUTTONPAD), 1);
+
+	uidev = uinput_device_new(TEST_DEVICE_NAME);
+	rc = uinput_device_set_abs_bit(uidev, ABS_X, &abs);
+	ck_assert_int_eq(rc, 0);
+	uinput_device_set_prop(uidev, INPUT_PROP_BUTTONPAD);
+	rc = uinput_device_create(uidev);
+	ck_assert_msg(rc == 0, "Failed to create uinput device: %s", strerror(-rc));
+
+	fd = uinput_device_get_fd(uidev);
+	rc = libevdev_set_fd(dev, fd);
+	ck_assert_msg(rc == 0, "Failed to create device: %s", strerror(-rc));
+
+	ck_assert_int_eq(libevdev_has_property(dev, INPUT_PROP_DIRECT), 0);
+	ck_assert_int_eq(libevdev_has_property(dev, INPUT_PROP_BUTTONPAD), 1);
+
+	/* Test disabling the properties too */
+	ck_assert_int_eq(libevdev_disable_property(dev, INPUT_PROP_MAX + 1), -1);
+	ck_assert_int_eq(libevdev_disable_property(dev, INPUT_PROP_DIRECT), 0);
+	ck_assert_int_eq(libevdev_disable_property(dev, INPUT_PROP_BUTTONPAD), 0);
+	ck_assert_int_eq(libevdev_has_property(dev, INPUT_PROP_DIRECT), 0);
+	ck_assert_int_eq(libevdev_has_property(dev, INPUT_PROP_BUTTONPAD), 0);
+
+	uinput_device_free(uidev);
+	libevdev_free(dev);
+}
+END_TEST
+
+START_TEST(test_slot_init_value)
+{
+	struct uinput_device *uidev;
+	struct libevdev *dev;
+	int rc;
+	const int nabs = 6;
+	int i;
+	int fd;
+	struct input_absinfo abs[] = {
+		{ .value = ABS_X, .minimum = 0, .maximum = 1000 },
+		{ .value = ABS_Y, .minimum = 0, .maximum = 1000 },
+		{ .value = ABS_MT_POSITION_X, .minimum = 0, .maximum = 1000 },
+		{ .value = ABS_MT_POSITION_Y, .minimum = 0, .maximum = 1000 },
+		{ .value = ABS_MT_TRACKING_ID, .minimum = -1, .maximum = 2 },
+		{ .value = ABS_MT_SLOT, .minimum = 0, .maximum = 1 }
+	};
+
+	uidev = uinput_device_new(TEST_DEVICE_NAME);
+
+	for (i = 0; i < nabs; i++) {
+		rc = uinput_device_set_abs_bit(uidev, abs[i].value, &abs[i]);
+		ck_assert_int_eq(rc, 0);
+	}
+
+	rc = uinput_device_create(uidev);
+	ck_assert_msg(rc == 0, "Failed to create uinput device: %s", strerror(-rc));
+
+	fd = uinput_device_get_fd(uidev);
+	rc = fcntl(fd, F_SETFL, O_NONBLOCK);
+	ck_assert_msg(rc == 0, "fcntl failed: %s", strerror(errno));
+
+	uinput_device_event(uidev, EV_ABS, ABS_MT_SLOT, 0);
+	uinput_device_event(uidev, EV_ABS, ABS_X, 100);
+	uinput_device_event(uidev, EV_ABS, ABS_Y, 500);
+	uinput_device_event(uidev, EV_ABS, ABS_MT_POSITION_X, 100);
+	uinput_device_event(uidev, EV_ABS, ABS_MT_POSITION_Y, 500);
+	uinput_device_event(uidev, EV_ABS, ABS_MT_TRACKING_ID, 1);
+	uinput_device_event(uidev, EV_ABS, ABS_MT_SLOT, 1);
+	uinput_device_event(uidev, EV_ABS, ABS_X, 1);
+	uinput_device_event(uidev, EV_ABS, ABS_Y, 5);
+	uinput_device_event(uidev, EV_ABS, ABS_MT_POSITION_X, 1);
+	uinput_device_event(uidev, EV_ABS, ABS_MT_POSITION_Y, 5);
+	uinput_device_event(uidev, EV_ABS, ABS_MT_TRACKING_ID, 2);
+	uinput_device_event(uidev, EV_SYN, SYN_REPORT, 0);
+
+	rc = libevdev_new_from_fd(fd, &dev);
+	ck_assert_int_eq(rc, 0);
+
+	ck_assert_int_eq(libevdev_get_current_slot(dev), 1);
+	ck_assert_int_eq(libevdev_get_slot_value(dev, 0, ABS_MT_POSITION_X), 100);
+	ck_assert_int_eq(libevdev_get_slot_value(dev, 0, ABS_MT_POSITION_Y), 500);
+	ck_assert_int_eq(libevdev_get_slot_value(dev, 1, ABS_MT_POSITION_X), 1);
+	ck_assert_int_eq(libevdev_get_slot_value(dev, 1, ABS_MT_POSITION_Y), 5);
+
+	uinput_device_free(uidev);
+	libevdev_free(dev);
+}
+END_TEST
+
+START_TEST(test_no_slots)
+{
+	struct uinput_device* uidev;
+	struct libevdev *dev;
+	struct input_absinfo abs[] = {
+		{ .value = ABS_X, .minimum = 0, .maximum = 2 },
+		{ .value = ABS_Y, .minimum = 0, .maximum = 2 },
+		{ .value = ABS_MT_POSITION_X, .minimum = 0, .maximum = 2 },
+		{ .value = ABS_MT_POSITION_Y, .minimum = 0, .maximum = 2 }
+	};
+
+	test_create_abs_device(&uidev, &dev, 4, abs,
+			       -1);
+
+	ck_assert_int_eq(libevdev_get_num_slots(dev), -1);
+	ck_assert_int_eq(libevdev_get_current_slot(dev), -1);
+
+	uinput_device_free(uidev);
+	libevdev_free(dev);
+}
+END_TEST
+
+START_TEST(test_slot_number)
+{
+	struct uinput_device* uidev;
+	struct libevdev *dev;
+	const int nslots = 4;
+	struct input_absinfo abs[] = {
+		{ .value = ABS_X, .minimum = 0, .maximum = 2 },
+		{ .value = ABS_Y, .minimum = 0, .maximum = 2 },
+		{ .value = ABS_MT_POSITION_X, .minimum = 0, .maximum = 2 },
+		{ .value = ABS_MT_POSITION_Y, .minimum = 0, .maximum = 2 },
+		{ .value = ABS_MT_SLOT, .minimum = 0, .maximum = nslots - 1 }
+	};
+
+	test_create_abs_device(&uidev, &dev, 5, abs,
+			       -1);
+
+	ck_assert_int_eq(libevdev_get_num_slots(dev), nslots);
+	ck_assert_int_eq(libevdev_get_current_slot(dev), 0);
+
+	uinput_device_free(uidev);
+	libevdev_free(dev);
+}
+END_TEST
+
+START_TEST(test_invalid_mt_device)
+{
+	struct uinput_device* uidev;
+	struct libevdev *dev;
+	const int nslots = 4;
+	int value;
+	struct input_absinfo abs[] = {
+		{ .value = ABS_X, .minimum = 0, .maximum = 2 },
+		{ .value = ABS_Y, .minimum = 0, .maximum = 2 },
+		{ .value = ABS_MT_POSITION_X, .minimum = 0, .maximum = 2 },
+		{ .value = ABS_MT_POSITION_Y, .minimum = 0, .maximum = 2 },
+		{ .value = ABS_MT_SLOT - 1, .minimum = 0, .maximum = 2 },
+		{ .value = ABS_MT_SLOT, .minimum = 0, .maximum = nslots - 1 }
+	};
+
+	test_create_abs_device(&uidev, &dev, 6, abs,
+			       -1);
+
+	ck_assert_int_eq(libevdev_get_num_slots(dev), -1);
+	ck_assert_int_eq(libevdev_get_current_slot(dev), -1);
+	ck_assert_int_eq(libevdev_set_slot_value(dev, 0, ABS_MT_POSITION_X, 0), -1);
+	ck_assert_int_eq(libevdev_fetch_slot_value(dev, 0, ABS_MT_POSITION_X, &value), 0);
+
+	ck_assert(libevdev_has_event_code(dev, EV_ABS, ABS_MT_SLOT - 1));
+	ck_assert(libevdev_has_event_code(dev, EV_ABS, ABS_MT_SLOT));
+
+	ck_assert_int_eq(libevdev_set_event_value(dev, EV_ABS, ABS_MT_SLOT, 1), 0);
+	ck_assert(libevdev_get_event_value(dev, EV_ABS, ABS_MT_SLOT) == 1);
+
+	uinput_device_free(uidev);
+	libevdev_free(dev);
+}
+END_TEST
+
+START_TEST(test_device_name)
+{
+	struct uinput_device* uidev;
+	struct libevdev *dev;
+	struct input_id ids = {1, 2, 3, 4};
+	const char *str;
+	int rc;
+
+	dev = libevdev_new();
+
+	str = libevdev_get_name(dev);
+	ck_assert(str != NULL);
+	ck_assert_int_eq(strlen(str), 0);
+
+	rc = uinput_device_new_with_events(&uidev, TEST_DEVICE_NAME, &ids,
+					   EV_REL, REL_X,
+					   -1);
+	ck_assert_msg(rc == 0, "Failed to create uinput device: %s", strerror(-rc));
+	rc = libevdev_set_fd(dev, uinput_device_get_fd(uidev));
+	ck_assert_msg(rc == 0, "Failed to init device: %s", strerror(-rc));;
+
+	str = libevdev_get_name(dev);
+	ck_assert_int_eq(strcmp(str, TEST_DEVICE_NAME), 0);
+
+	str = libevdev_get_phys(dev);
+	ck_assert(str == NULL);
+
+	str = libevdev_get_uniq(dev);
+	ck_assert(str == NULL);
+
+	ck_assert_int_eq(libevdev_get_id_bustype(dev), ids.bustype);
+	ck_assert_int_eq(libevdev_get_id_vendor(dev), ids.vendor);
+	ck_assert_int_eq(libevdev_get_id_product(dev), ids.product);
+	ck_assert_int_eq(libevdev_get_id_version(dev), ids.version);
+	ck_assert_int_eq(libevdev_get_driver_version(dev), EV_VERSION);
+
+	uinput_device_free(uidev);
+	libevdev_free(dev);
+}
+END_TEST
+
+START_TEST(test_device_set_name)
+{
+	struct uinput_device* uidev;
+	struct libevdev *dev;
+	struct input_id ids = {1, 2, 3, 4};
+	const char *str;
+	int rc;
+
+	dev = libevdev_new();
+
+	libevdev_set_name(dev, "the name");
+	libevdev_set_phys(dev, "the phys");
+	libevdev_set_uniq(dev, "the uniq");
+
+	str = libevdev_get_name(dev);
+	ck_assert(str != NULL);
+	ck_assert_int_eq(strcmp(str, "the name"), 0);
+
+	str = libevdev_get_phys(dev);
+	ck_assert(str != NULL);
+	ck_assert_int_eq(strcmp(str, "the phys"), 0);
+
+	str = libevdev_get_uniq(dev);
+	ck_assert(str != NULL);
+	ck_assert_int_eq(strcmp(str, "the uniq"), 0);
+
+	rc = uinput_device_new_with_events(&uidev, TEST_DEVICE_NAME, &ids,
+					   EV_REL, REL_X,
+					   -1);
+	ck_assert_msg(rc == 0, "Failed to create uinput device: %s", strerror(-rc));
+	rc = libevdev_set_fd(dev, uinput_device_get_fd(uidev));
+	ck_assert_msg(rc == 0, "Failed to init device: %s", strerror(-rc));;
+
+	str = libevdev_get_name(dev);
+	ck_assert_int_eq(strcmp(str, TEST_DEVICE_NAME), 0);
+
+	str = libevdev_get_phys(dev);
+	ck_assert(str == NULL);
+
+	str = libevdev_get_uniq(dev);
+	ck_assert(str == NULL);
+
+	uinput_device_free(uidev);
+	libevdev_free(dev);
+}
+END_TEST
+
+START_TEST(test_device_set_ids)
+{
+	struct uinput_device* uidev;
+	struct libevdev *dev;
+	struct input_id ids = {1, 2, 3, 4};
+	int rc;
+
+	dev = libevdev_new();
+
+	libevdev_set_id_product(dev, 10);
+	libevdev_set_id_vendor(dev, 20);
+	libevdev_set_id_bustype(dev, 30);
+	libevdev_set_id_version(dev, 40);
+
+	ck_assert_int_eq(libevdev_get_id_product(dev), 10);
+	ck_assert_int_eq(libevdev_get_id_vendor(dev), 20);
+	ck_assert_int_eq(libevdev_get_id_bustype(dev), 30);
+	ck_assert_int_eq(libevdev_get_id_version(dev), 40);
+
+	rc = uinput_device_new_with_events(&uidev, TEST_DEVICE_NAME, &ids,
+					   EV_REL, REL_X,
+					   -1);
+	ck_assert_msg(rc == 0, "Failed to create uinput device: %s", strerror(-rc));
+	rc = libevdev_set_fd(dev, uinput_device_get_fd(uidev));
+	ck_assert_msg(rc == 0, "Failed to init device: %s", strerror(-rc));;
+
+	ck_assert_int_eq(libevdev_get_id_bustype(dev), ids.bustype);
+	ck_assert_int_eq(libevdev_get_id_vendor(dev), ids.vendor);
+	ck_assert_int_eq(libevdev_get_id_product(dev), ids.product);
+	ck_assert_int_eq(libevdev_get_id_version(dev), ids.version);
+
+	uinput_device_free(uidev);
+	libevdev_free(dev);
+}
+END_TEST
+
+START_TEST(test_device_get_abs_info)
+{
+	struct uinput_device* uidev;
+	struct libevdev *dev;
+	struct input_absinfo abs;
+	const struct input_absinfo *a;
+	int rc;
+
+	uidev = uinput_device_new(TEST_DEVICE_NAME);
+	ck_assert(uidev != NULL);
+
+	abs.minimum = 0;
+	abs.maximum = 1000;
+	abs.fuzz = 1;
+	abs.flat = 2;
+	abs.resolution = 3;
+	abs.value = 0;
+
+	uinput_device_set_abs_bit(uidev, ABS_X, &abs);
+	uinput_device_set_abs_bit(uidev, ABS_MT_POSITION_X, &abs);
+
+	abs.minimum = -500;
+	abs.maximum = 500;
+	abs.fuzz = 10;
+	abs.flat = 20;
+	abs.resolution = 30;
+	abs.value = 0;
+
+	uinput_device_set_abs_bit(uidev, ABS_Y, &abs);
+	uinput_device_set_abs_bit(uidev, ABS_MT_POSITION_Y, &abs);
+
+	rc = uinput_device_create(uidev);
+	ck_assert_msg(rc == 0, "Failed to create device: %s", strerror(-rc));
+
+	rc = libevdev_new_from_fd(uinput_device_get_fd(uidev), &dev);
+	ck_assert_msg(rc == 0, "Failed to init device: %s", strerror(-rc));;
+
+	ck_assert_int_eq(libevdev_get_abs_minimum(dev, ABS_MAX + 1), 0);
+	ck_assert_int_eq(libevdev_get_abs_maximum(dev, ABS_MAX + 1), 0);
+	ck_assert_int_eq(libevdev_get_abs_fuzz(dev, ABS_MAX + 1), 0);
+	ck_assert_int_eq(libevdev_get_abs_flat(dev, ABS_MAX + 1), 0);
+	ck_assert_int_eq(libevdev_get_abs_resolution(dev, ABS_MAX + 1), 0);
+	ck_assert(!libevdev_get_abs_info(dev, ABS_MAX + 1));
+
+	ck_assert_int_eq(libevdev_get_abs_minimum(dev, ABS_X), 0);
+	ck_assert_int_eq(libevdev_get_abs_maximum(dev, ABS_X), 1000);
+	ck_assert_int_eq(libevdev_get_abs_fuzz(dev, ABS_X), 1);
+	ck_assert_int_eq(libevdev_get_abs_flat(dev, ABS_X), 2);
+	ck_assert_int_eq(libevdev_get_abs_resolution(dev, ABS_X), 3);
+	a = libevdev_get_abs_info(dev, ABS_X);
+	ck_assert(a != NULL);
+	ck_assert_int_eq(a->minimum, 0);
+	ck_assert_int_eq(a->maximum, 1000);
+	ck_assert_int_eq(a->fuzz, 1);
+	ck_assert_int_eq(a->flat, 2);
+	ck_assert_int_eq(a->resolution, 3);
+
+	ck_assert_int_eq(libevdev_get_abs_minimum(dev, ABS_MT_POSITION_X), 0);
+	ck_assert_int_eq(libevdev_get_abs_maximum(dev, ABS_MT_POSITION_X), 1000);
+	ck_assert_int_eq(libevdev_get_abs_fuzz(dev, ABS_MT_POSITION_X), 1);
+	ck_assert_int_eq(libevdev_get_abs_flat(dev, ABS_MT_POSITION_X), 2);
+	ck_assert_int_eq(libevdev_get_abs_resolution(dev, ABS_MT_POSITION_X), 3);
+	a = libevdev_get_abs_info(dev, ABS_MT_POSITION_X);
+	ck_assert(a != NULL);
+	ck_assert_int_eq(a->minimum, 0);
+	ck_assert_int_eq(a->maximum, 1000);
+	ck_assert_int_eq(a->fuzz, 1);
+	ck_assert_int_eq(a->flat, 2);
+	ck_assert_int_eq(a->resolution, 3);
+
+	ck_assert_int_eq(libevdev_get_abs_minimum(dev, ABS_Y), -500);
+	ck_assert_int_eq(libevdev_get_abs_maximum(dev, ABS_Y), 500);
+	ck_assert_int_eq(libevdev_get_abs_fuzz(dev, ABS_Y), 10);
+	ck_assert_int_eq(libevdev_get_abs_flat(dev, ABS_Y), 20);
+	ck_assert_int_eq(libevdev_get_abs_resolution(dev, ABS_Y), 30);
+	a = libevdev_get_abs_info(dev, ABS_Y);
+	ck_assert(a != NULL);
+	ck_assert_int_eq(a->minimum, -500);
+	ck_assert_int_eq(a->maximum, 500);
+	ck_assert_int_eq(a->fuzz, 10);
+	ck_assert_int_eq(a->flat, 20);
+	ck_assert_int_eq(a->resolution, 30);
+
+	ck_assert_int_eq(libevdev_get_abs_minimum(dev, ABS_MT_POSITION_Y), -500);
+	ck_assert_int_eq(libevdev_get_abs_maximum(dev, ABS_MT_POSITION_Y), 500);
+	ck_assert_int_eq(libevdev_get_abs_fuzz(dev, ABS_MT_POSITION_Y), 10);
+	ck_assert_int_eq(libevdev_get_abs_flat(dev, ABS_MT_POSITION_Y), 20);
+	ck_assert_int_eq(libevdev_get_abs_resolution(dev, ABS_MT_POSITION_Y), 30);
+	a = libevdev_get_abs_info(dev, ABS_MT_POSITION_Y);
+	ck_assert(a != NULL);
+	ck_assert_int_eq(a->minimum, -500);
+	ck_assert_int_eq(a->maximum, 500);
+	ck_assert_int_eq(a->fuzz, 10);
+	ck_assert_int_eq(a->flat, 20);
+	ck_assert_int_eq(a->resolution, 30);
+
+	uinput_device_free(uidev);
+	libevdev_free(dev);
+}
+END_TEST
+
+START_TEST(test_device_set_abs)
+{
+	struct uinput_device* uidev;
+	struct libevdev *dev;
+	struct input_absinfo abs[2];
+	struct input_absinfo a;
+
+	memset(abs, 0, sizeof(abs));
+	abs[0].value = ABS_X;
+	abs[0].maximum = 1000;
+
+	abs[1].value = ABS_Y;
+	abs[1].maximum = 1000;
+
+	test_create_abs_device(&uidev, &dev,
+			       2, abs,
+			       EV_SYN,
+			       -1);
+
+	libevdev_set_abs_minimum(dev, ABS_X, 1);
+	libevdev_set_abs_minimum(dev, ABS_Y, 5);
+	ck_assert_int_eq(libevdev_get_abs_minimum(dev, ABS_X),  1);
+	ck_assert_int_eq(libevdev_get_abs_minimum(dev, ABS_Y),  5);
+
+	libevdev_set_abs_maximum(dev, ABS_X, 3000);
+	libevdev_set_abs_maximum(dev, ABS_Y, 5000);
+	ck_assert_int_eq(libevdev_get_abs_maximum(dev, ABS_X),  3000);
+	ck_assert_int_eq(libevdev_get_abs_maximum(dev, ABS_Y),  5000);
+
+	libevdev_set_abs_fuzz(dev, ABS_X, 3);
+	libevdev_set_abs_fuzz(dev, ABS_Y, 5);
+	ck_assert_int_eq(libevdev_get_abs_fuzz(dev, ABS_X),  3);
+	ck_assert_int_eq(libevdev_get_abs_fuzz(dev, ABS_Y),  5);
+
+	libevdev_set_abs_flat(dev, ABS_X, 8);
+	libevdev_set_abs_flat(dev, ABS_Y, 15);
+	ck_assert_int_eq(libevdev_get_abs_flat(dev, ABS_X),  8);
+	ck_assert_int_eq(libevdev_get_abs_flat(dev, ABS_Y),  15);
+
+	libevdev_set_abs_resolution(dev, ABS_X, 80);
+	libevdev_set_abs_resolution(dev, ABS_Y, 150);
+	ck_assert_int_eq(libevdev_get_abs_resolution(dev, ABS_X),  80);
+	ck_assert_int_eq(libevdev_get_abs_resolution(dev, ABS_Y),  150);
+
+	a.value = 0;
+	a.minimum = 10;
+	a.maximum = 100;
+	a.fuzz = 13;
+	a.flat = 1;
+	a.resolution = 16;
+
+	libevdev_set_abs_info(dev, ABS_X, &a);
+	ck_assert_int_eq(memcmp(&a, libevdev_get_abs_info(dev, ABS_X), sizeof(a)), 0);
+
+	libevdev_set_abs_minimum(dev, ABS_Z, 10);
+	ck_assert_int_eq(libevdev_has_event_code(dev, EV_ABS, ABS_Z),  0);
+
+	uinput_device_free(uidev);
+	libevdev_free(dev);
+}
+END_TEST
+
+START_TEST(test_device_enable_bit)
+{
+	struct uinput_device* uidev;
+	struct libevdev *dev, *dev2;
+	struct input_absinfo abs = { .value = ABS_X, .minimum = 0, .maximum = 2 };
+	int rc;
+
+	test_create_abs_device(&uidev, &dev, 1, &abs,
+			       -1);
+
+	ck_assert(!libevdev_has_event_code(dev, EV_ABS, ABS_Y));
+	ck_assert(!libevdev_has_event_type(dev, EV_REL));
+	ck_assert(!libevdev_has_event_code(dev, EV_REL, REL_X));
+
+	abs.minimum = 0;
+	abs.maximum = 100;
+	abs.fuzz = 1;
+	abs.flat = 2;
+	abs.resolution = 3;
+
+	ck_assert_int_eq(libevdev_enable_event_code(dev, EV_ABS, ABS_Y, &abs), 0);
+	ck_assert(libevdev_has_event_code(dev, EV_ABS, ABS_Y));
+
+	ck_assert_int_eq(libevdev_enable_event_type(dev, EV_REL), 0);
+	ck_assert(libevdev_has_event_type(dev, EV_REL));
+	ck_assert(!libevdev_has_event_code(dev, EV_REL, REL_X));
+
+	ck_assert_int_eq(libevdev_enable_event_code(dev, EV_REL, REL_X, NULL), 0);
+	ck_assert(libevdev_has_event_code(dev, EV_REL, REL_X));
+
+	/* make sure kernel device is unchanged */
+	rc = libevdev_new_from_fd(uinput_device_get_fd(uidev), &dev2);
+	ck_assert_msg(rc == 0, "Failed to init device: %s", strerror(-rc));
+	ck_assert(libevdev_has_event_code(dev2, EV_ABS, ABS_X));
+	ck_assert(!libevdev_has_event_code(dev2, EV_ABS, ABS_Y));
+	ck_assert(!libevdev_has_event_type(dev2, EV_REL));
+	ck_assert(!libevdev_has_event_code(dev2, EV_REL, REL_X));
+	libevdev_free(dev2);
+
+	uinput_device_free(uidev);
+	libevdev_free(dev);
+}
+END_TEST
+
+START_TEST(test_device_enable_bit_invalid)
+{
+	struct uinput_device* uidev;
+	struct libevdev *dev;
+	struct input_absinfo abs = { .value = ABS_X, .minimum = 0, .maximum = 1 };
+
+	test_create_abs_device(&uidev, &dev, 1, &abs,
+			       -1);
+
+	ck_assert_int_eq(libevdev_enable_event_code(dev, EV_ABS, ABS_MAX + 1, &abs), -1);
+	ck_assert_int_eq(libevdev_enable_event_code(dev, EV_MAX + 1, ABS_MAX + 1, &abs), -1);
+	ck_assert_int_eq(libevdev_enable_event_type(dev, EV_MAX + 1), -1);
+	/* there's a gap between EV_SW and EV_LED */
+	ck_assert_int_eq(libevdev_enable_event_type(dev, EV_LED - 1), -1);
+	ck_assert_int_eq(libevdev_enable_event_code(dev, EV_LED - 1, 0, NULL), -1);
+
+	ck_assert_int_eq(libevdev_enable_event_code(dev, EV_ABS, ABS_Y, NULL), -1);
+	ck_assert_int_eq(libevdev_enable_event_code(dev, EV_REP, REP_DELAY, NULL), -1);
+	ck_assert_int_eq(libevdev_enable_event_code(dev, EV_REL, REL_X, &abs), -1);
+
+	uinput_device_free(uidev);
+	libevdev_free(dev);
+}
+END_TEST
+
+START_TEST(test_device_disable_bit)
+{
+	struct uinput_device* uidev;
+	struct libevdev *dev, *dev2;
+	int rc;
+	struct input_absinfo abs[2] = {
+		{ .value = ABS_X, .minimum = 0, .maximum = 1 },
+		{ .value = ABS_Y, .minimum = 0, .maximum = 1 },
+	};
+
+	test_create_abs_device(&uidev, &dev,
+			       2, abs,
+			       EV_REL, REL_X,
+			       EV_REL, REL_Y,
+			       -1);
+
+	ck_assert(libevdev_has_event_code(dev, EV_ABS, ABS_X));
+	ck_assert(libevdev_has_event_code(dev, EV_ABS, ABS_Y));
+	ck_assert(libevdev_has_event_type(dev, EV_REL));
+	ck_assert(libevdev_has_event_code(dev, EV_REL, REL_X));
+	ck_assert(libevdev_has_event_code(dev, EV_REL, REL_Y));
+
+	ck_assert_int_eq(libevdev_disable_event_code(dev, EV_ABS, ABS_Y), 0);
+	ck_assert(!libevdev_has_event_code(dev, EV_ABS, ABS_Y));
+
+	ck_assert_int_eq(libevdev_disable_event_code(dev, EV_REL, REL_X), 0);
+	ck_assert(!libevdev_has_event_code(dev, EV_REL, REL_X));
+	ck_assert(libevdev_has_event_code(dev, EV_REL, REL_Y));
+	ck_assert(libevdev_has_event_type(dev, EV_REL));
+
+	ck_assert_int_eq(libevdev_disable_event_type(dev, EV_REL), 0);
+	ck_assert(!libevdev_has_event_type(dev, EV_REL));
+	ck_assert(!libevdev_has_event_code(dev, EV_REL, REL_X));
+	ck_assert(!libevdev_has_event_code(dev, EV_REL, REL_Y));
+
+	/* make sure kernel device is unchanged */
+	rc = libevdev_new_from_fd(uinput_device_get_fd(uidev), &dev2);
+	ck_assert_msg(rc == 0, "Failed to init device: %s", strerror(-rc));
+	ck_assert(libevdev_has_event_code(dev2, EV_ABS, ABS_X));
+	ck_assert(libevdev_has_event_code(dev2, EV_ABS, ABS_Y));
+	ck_assert(libevdev_has_event_type(dev2, EV_REL));
+	ck_assert(libevdev_has_event_code(dev2, EV_REL, REL_X));
+	ck_assert(libevdev_has_event_code(dev2, EV_REL, REL_Y));
+	libevdev_free(dev2);
+
+	uinput_device_free(uidev);
+	libevdev_free(dev);
+}
+END_TEST
+
+START_TEST(test_device_disable_bit_invalid)
+{
+	struct uinput_device* uidev;
+	struct libevdev *dev;
+	struct input_absinfo abs = { .value = ABS_X, .minimum = 0, .maximum = 1 };
+
+	test_create_abs_device(&uidev, &dev, 1, &abs, -1);
+
+	/* there's a gap between EV_SW and EV_LED */
+	ck_assert_int_eq(libevdev_disable_event_type(dev, EV_LED - 1), -1);
+	ck_assert_int_eq(libevdev_disable_event_code(dev, EV_LED - 1, 0), -1);
+	ck_assert_int_eq(libevdev_disable_event_code(dev, EV_ABS, ABS_MAX + 1), -1);
+	ck_assert_int_eq(libevdev_disable_event_code(dev, EV_MAX + 1, ABS_MAX + 1), -1);
+	ck_assert_int_eq(libevdev_disable_event_type(dev, EV_MAX + 1), -1);
+	ck_assert_int_eq(libevdev_disable_event_type(dev, EV_SYN), -1);
+	ck_assert_int_eq(libevdev_disable_event_code(dev, EV_SYN, SYN_REPORT), -1);
+
+	uinput_device_free(uidev);
+	libevdev_free(dev);
+}
+END_TEST
+
+START_TEST(test_device_kernel_change_axis)
+{
+	struct uinput_device* uidev;
+	struct libevdev *dev, *dev2;
+	struct input_absinfo abs;
+	int rc;
+
+	uidev = uinput_device_new(TEST_DEVICE_NAME);
+	ck_assert(uidev != NULL);
+
+	abs.minimum = 0;
+	abs.maximum = 1000;
+	abs.fuzz = 1;
+	abs.flat = 2;
+	abs.resolution = 3;
+	abs.value = 0;
+
+	uinput_device_set_abs_bit(uidev, ABS_X, &abs);
+
+	rc = uinput_device_create(uidev);
+	ck_assert_msg(rc == 0, "Failed to create device: %s", strerror(-rc));
+
+	rc = libevdev_new_from_fd(uinput_device_get_fd(uidev), &dev);
+	ck_assert_msg(rc == 0, "Failed to init device: %s", strerror(-rc));;
+
+	ck_assert_int_eq(libevdev_get_abs_minimum(dev, ABS_X), 0);
+	ck_assert_int_eq(libevdev_get_abs_maximum(dev, ABS_X), 1000);
+	ck_assert_int_eq(libevdev_get_abs_fuzz(dev, ABS_X), 1);
+	ck_assert_int_eq(libevdev_get_abs_flat(dev, ABS_X), 2);
+	ck_assert_int_eq(libevdev_get_abs_resolution(dev, ABS_X), 3);
+
+	abs.minimum = 500;
+	abs.maximum = 5000;
+	abs.fuzz = 10;
+	abs.flat = 20;
+	abs.resolution = 30;
+	rc = libevdev_kernel_set_abs_info(dev, ABS_X, &abs);
+	ck_assert_int_eq(rc, 0);
+
+	ck_assert_int_eq(libevdev_get_abs_minimum(dev, ABS_X), 500);
+	ck_assert_int_eq(libevdev_get_abs_maximum(dev, ABS_X), 5000);
+	ck_assert_int_eq(libevdev_get_abs_fuzz(dev, ABS_X), 10);
+	ck_assert_int_eq(libevdev_get_abs_flat(dev, ABS_X), 20);
+	ck_assert_int_eq(libevdev_get_abs_resolution(dev, ABS_X), 30);
+
+	/* make sure kernel device is changed */
+	rc = libevdev_new_from_fd(uinput_device_get_fd(uidev), &dev2);
+	ck_assert_msg(rc == 0, "Failed to init device: %s", strerror(-rc));
+	ck_assert_int_eq(libevdev_get_abs_minimum(dev2, ABS_X), 500);
+	ck_assert_int_eq(libevdev_get_abs_maximum(dev2, ABS_X), 5000);
+	ck_assert_int_eq(libevdev_get_abs_fuzz(dev2, ABS_X), 10);
+	ck_assert_int_eq(libevdev_get_abs_flat(dev2, ABS_X), 20);
+	ck_assert_int_eq(libevdev_get_abs_resolution(dev2, ABS_X), 30);
+	libevdev_free(dev2);
+
+	libevdev_free(dev);
+	uinput_device_free(uidev);
+}
+END_TEST
+
+START_TEST(test_device_kernel_change_axis_invalid)
+{
+	struct uinput_device* uidev;
+	struct libevdev *dev;
+	struct input_absinfo abs;
+	int rc;
+
+	uidev = uinput_device_new(TEST_DEVICE_NAME);
+	ck_assert(uidev != NULL);
+
+	abs.minimum = 0;
+	abs.maximum = 1000;
+	abs.fuzz = 1;
+	abs.flat = 2;
+	abs.resolution = 3; /* FIXME: value is unused, we can't test resolution */
+	abs.value = 0;
+
+	uinput_device_set_abs_bit(uidev, ABS_X, &abs);
+
+	rc = uinput_device_create(uidev);
+	ck_assert_msg(rc == 0, "Failed to create device: %s", strerror(-rc));
+
+	rc = libevdev_new_from_fd(uinput_device_get_fd(uidev), &dev);
+	ck_assert_msg(rc == 0, "Failed to init device: %s", strerror(-rc));;
+
+	rc = libevdev_kernel_set_abs_info(dev, ABS_MAX + 1, &abs);
+	ck_assert_int_eq(rc, -EINVAL);
+
+	libevdev_free(dev);
+	uinput_device_free(uidev);
+}
+END_TEST
+
+START_TEST(test_device_kernel_set_abs_invalid_fd)
+{
+	struct uinput_device* uidev;
+	struct libevdev *dev;
+	struct input_absinfo abs[2];
+	struct input_absinfo a;
+	int rc;
+
+	libevdev_set_log_function(test_logfunc_ignore_error, NULL);
+
+	memset(abs, 0, sizeof(abs));
+	abs[0].value = ABS_X;
+	abs[0].maximum = 1000;
+
+	abs[1].value = ABS_Y;
+	abs[1].maximum = 1000;
+
+	dev = libevdev_new();
+	rc = libevdev_kernel_set_abs_info(dev, ABS_X, &a);
+	ck_assert_int_eq(rc, -EBADF);
+	libevdev_free(dev);
+
+	test_create_abs_device(&uidev, &dev,
+			       2, abs,
+			       EV_SYN,
+			       -1);
+
+	libevdev_change_fd(dev, -2);
+	rc = libevdev_kernel_set_abs_info(dev, ABS_X, &a);
+	ck_assert_int_eq(rc, -EBADF);
+
+	libevdev_set_log_function(test_logfunc_abort_on_error, NULL);
+
+	uinput_device_free(uidev);
+	libevdev_free(dev);
+}
+END_TEST
+
+START_TEST(test_led_valid)
+{
+	struct uinput_device* uidev;
+	struct libevdev *dev;
+	int rc;
+
+	test_create_device(&uidev, &dev,
+			   EV_LED, LED_NUML,
+			   EV_LED, LED_CAPSL,
+			   EV_LED, LED_COMPOSE,
+			   -1);
+
+	rc = libevdev_kernel_set_led_value(dev, LED_NUML, LIBEVDEV_LED_ON);
+	ck_assert_int_eq(rc, 0);
+	rc = libevdev_kernel_set_led_value(dev, LED_NUML, LIBEVDEV_LED_OFF);
+	ck_assert_int_eq(rc, 0);
+
+	rc = libevdev_kernel_set_led_values(dev,
+					    LED_NUML, LIBEVDEV_LED_OFF,
+					    LED_CAPSL, LIBEVDEV_LED_ON,
+					    LED_COMPOSE, LIBEVDEV_LED_OFF,
+					    -1);
+	ck_assert_int_eq(rc, 0);
+	ck_assert_int_eq(0, libevdev_get_event_value(dev, EV_LED, LED_NUML));
+	ck_assert_int_eq(1, libevdev_get_event_value(dev, EV_LED, LED_CAPSL));
+	ck_assert_int_eq(0, libevdev_get_event_value(dev, EV_LED, LED_COMPOSE));
+
+	rc = libevdev_kernel_set_led_values(dev,
+					    LED_NUML, LIBEVDEV_LED_ON,
+					    LED_CAPSL, LIBEVDEV_LED_OFF,
+					    LED_COMPOSE, LIBEVDEV_LED_ON,
+					    -1);
+	ck_assert_int_eq(rc, 0);
+	ck_assert_int_eq(1, libevdev_get_event_value(dev, EV_LED, LED_NUML));
+	ck_assert_int_eq(0, libevdev_get_event_value(dev, EV_LED, LED_CAPSL));
+	ck_assert_int_eq(1, libevdev_get_event_value(dev, EV_LED, LED_COMPOSE));
+
+	/* make sure we ignore unset leds */
+	rc = libevdev_kernel_set_led_values(dev,
+					    LED_NUML, LIBEVDEV_LED_ON,
+					    LED_CAPSL, LIBEVDEV_LED_OFF,
+					    LED_SCROLLL, LIBEVDEV_LED_OFF,
+					    LED_COMPOSE, LIBEVDEV_LED_ON,
+					    -1);
+	ck_assert_int_eq(rc, 0);
+	ck_assert_int_eq(1, libevdev_get_event_value(dev, EV_LED, LED_NUML));
+	ck_assert_int_eq(0, libevdev_get_event_value(dev, EV_LED, LED_CAPSL));
+	ck_assert_int_eq(1, libevdev_get_event_value(dev, EV_LED, LED_COMPOSE));
+
+	libevdev_free(dev);
+	uinput_device_free(uidev);
+}
+END_TEST
+
+START_TEST(test_led_invalid)
+{
+	struct uinput_device* uidev;
+	struct libevdev *dev;
+	int rc;
+
+	test_create_device(&uidev, &dev,
+			   EV_LED, LED_NUML,
+			   EV_LED, LED_CAPSL,
+			   EV_LED, LED_COMPOSE,
+			   -1);
+
+	rc = libevdev_kernel_set_led_value(dev, LED_MAX + 1, LIBEVDEV_LED_ON);
+	ck_assert_int_eq(rc, -EINVAL);
+
+	rc = libevdev_kernel_set_led_value(dev, LED_NUML, LIBEVDEV_LED_OFF + 1);
+	ck_assert_int_eq(rc, -EINVAL);
+
+	rc = libevdev_kernel_set_led_value(dev, LED_SCROLLL, LIBEVDEV_LED_ON);
+	ck_assert_int_eq(rc, 0);
+
+	rc = libevdev_kernel_set_led_values(dev,
+					    LED_NUML, LIBEVDEV_LED_OFF + 1,
+					    -1);
+	ck_assert_int_eq(rc, -EINVAL);
+
+	rc = libevdev_kernel_set_led_values(dev,
+					    LED_MAX + 1, LIBEVDEV_LED_ON,
+					    LED_NUML, LIBEVDEV_LED_OFF + 1,
+					    -1);
+	ck_assert_int_eq(rc, -EINVAL);
+
+	rc = libevdev_kernel_set_led_values(dev,
+					    LED_SCROLLL, LIBEVDEV_LED_OFF,
+					    -1);
+	ck_assert_int_eq(rc, 0);
+
+	libevdev_free(dev);
+	uinput_device_free(uidev);
+}
+END_TEST
+
+START_TEST(test_led_same)
+{
+	struct uinput_device* uidev;
+	struct libevdev *dev;
+	int rc;
+
+	test_create_device(&uidev, &dev,
+			   EV_LED, LED_NUML,
+			   EV_LED, LED_CAPSL,
+			   EV_LED, LED_COMPOSE,
+			   -1);
+
+	rc = libevdev_kernel_set_led_values(dev,
+					    LED_NUML, LIBEVDEV_LED_OFF,
+					    LED_NUML, LIBEVDEV_LED_ON,
+					    LED_NUML, LIBEVDEV_LED_OFF,
+					    LED_NUML, LIBEVDEV_LED_ON,
+					    LED_NUML, LIBEVDEV_LED_OFF,
+					    LED_NUML, LIBEVDEV_LED_ON,
+					    LED_NUML, LIBEVDEV_LED_OFF,
+					    LED_NUML, LIBEVDEV_LED_ON,
+					    LED_NUML, LIBEVDEV_LED_OFF,
+					    LED_NUML, LIBEVDEV_LED_ON,
+					    LED_NUML, LIBEVDEV_LED_OFF,
+					    LED_NUML, LIBEVDEV_LED_ON,
+					    LED_NUML, LIBEVDEV_LED_OFF,
+					    LED_NUML, LIBEVDEV_LED_ON,
+					    LED_NUML, LIBEVDEV_LED_OFF,
+					    LED_NUML, LIBEVDEV_LED_ON,
+					    LED_NUML, LIBEVDEV_LED_OFF,
+					    LED_NUML, LIBEVDEV_LED_ON,
+					    LED_NUML, LIBEVDEV_LED_OFF,
+					    LED_NUML, LIBEVDEV_LED_ON,
+					    LED_NUML, LIBEVDEV_LED_OFF,
+					    LED_NUML, LIBEVDEV_LED_ON,
+					    LED_NUML, LIBEVDEV_LED_OFF,
+					    LED_NUML, LIBEVDEV_LED_ON,
+					    /* more than LED_CNT */
+					    -1);
+	ck_assert_int_eq(rc, 0);
+	ck_assert_int_eq(1, libevdev_get_event_value(dev, EV_LED, LED_NUML));
+	ck_assert_int_eq(0, libevdev_get_event_value(dev, EV_LED, LED_CAPSL));
+	ck_assert_int_eq(0, libevdev_get_event_value(dev, EV_LED, LED_COMPOSE));
+
+	libevdev_free(dev);
+	uinput_device_free(uidev);
+}
+END_TEST
+
+TEST_SUITE_ROOT_PRIVILEGES(has_events)
+{
+	Suite *s = suite_create("libevdev_has_event tests");
+
+	add_test(s, test_ev_bit_limits);
+	add_test(s, test_has_ev_bit);
+
+	add_test(s, test_event_codes);
+	add_test(s, test_event_code_limits);
+
+	add_test(s, test_ev_rep);
+	add_test(s, test_ev_rep_values);
+
+	add_test(s, test_input_props);
+	add_test(s, test_set_input_props);
+
+	add_test(s, test_no_slots);
+	add_test(s, test_slot_number);
+	add_test(s, test_slot_init_value);
+	add_test(s, test_invalid_mt_device);
+
+	add_test(s, test_device_name);
+	add_test(s, test_device_set_name);
+	add_test(s, test_device_set_ids);
+	add_test(s, test_device_get_abs_info);
+
+	add_test(s, test_device_set_abs);
+	add_test(s, test_device_enable_bit);
+	add_test(s, test_device_enable_bit_invalid);
+	add_test(s, test_device_disable_bit);
+	add_test(s, test_device_disable_bit_invalid);
+	add_test(s, test_device_kernel_change_axis);
+	add_test(s, test_device_kernel_change_axis_invalid);
+	add_test(s, test_device_kernel_set_abs_invalid_fd);
+
+	add_test(s, test_led_valid);
+	add_test(s, test_led_invalid);
+	add_test(s, test_led_same);
+
+	return s;
+}
diff --git a/test/test-libevdev-init.c b/test/test-libevdev-init.c
new file mode 100644
index 0000000000000000000000000000000000000000..2bc2af1cac787a804c5c77d8bc46f41302d3f4d5
--- /dev/null
+++ b/test/test-libevdev-init.c
@@ -0,0 +1,704 @@
+// SPDX-License-Identifier: MIT
+/*
+ * Copyright © 2013 Red Hat, Inc.
+ */
+
+#include "config.h"
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+#include "test-common.h"
+
+START_TEST(test_new_device)
+{
+	struct libevdev *dev;
+
+	dev = libevdev_new();
+	ck_assert(dev != NULL);
+	libevdev_free(dev);
+}
+END_TEST
+
+START_TEST(test_free_device)
+{
+	libevdev_free(NULL);
+}
+END_TEST
+
+START_TEST(test_init_from_invalid_fd)
+{
+	int rc;
+	struct libevdev *dev = NULL;
+
+	rc = libevdev_new_from_fd(-1, &dev);
+
+	ck_assert(dev == NULL);
+	ck_assert_int_eq(rc, -EBADF);
+
+	rc = libevdev_new_from_fd(STDIN_FILENO, &dev);
+	ck_assert(dev == NULL);
+	ck_assert_int_eq(rc, -ENOTTY);
+}
+END_TEST
+
+START_TEST(test_init_and_change_fd)
+{
+	struct uinput_device* uidev;
+	struct libevdev *dev;
+	int rc;
+
+	dev = libevdev_new();
+	ck_assert(dev != NULL);
+	ck_assert_int_eq(libevdev_set_fd(dev, -1), -EBADF);
+
+	libevdev_set_log_function(test_logfunc_ignore_error, NULL);
+	ck_assert_int_eq(libevdev_change_fd(dev, -1), -1);
+	libevdev_set_log_function(test_logfunc_abort_on_error, NULL);
+
+	rc = uinput_device_new_with_events(&uidev,
+					   TEST_DEVICE_NAME, DEFAULT_IDS,
+					   EV_SYN, SYN_REPORT,
+					   EV_REL, REL_X,
+					   EV_REL, REL_Y,
+					   EV_REL, REL_WHEEL,
+					   EV_KEY, BTN_LEFT,
+					   EV_KEY, BTN_MIDDLE,
+					   EV_KEY, BTN_RIGHT,
+					   -1);
+	ck_assert_msg(rc == 0, "Failed to create uinput device: %s", strerror(-rc));
+	ck_assert_int_eq(libevdev_set_fd(dev, uinput_device_get_fd(uidev)), 0);
+
+	libevdev_set_log_function(test_logfunc_ignore_error, NULL);
+	ck_assert_int_eq(libevdev_set_fd(dev, 0), -EBADF);
+	libevdev_set_log_function(test_logfunc_abort_on_error, NULL);
+
+	ck_assert_int_eq(libevdev_get_fd(dev), uinput_device_get_fd(uidev));
+
+	ck_assert_int_eq(libevdev_change_fd(dev, 0), 0);
+	ck_assert_int_eq(libevdev_get_fd(dev), 0);
+
+	uinput_device_free(uidev);
+	libevdev_free(dev);
+}
+END_TEST
+
+static int log_fn_called = 0;
+static char *logdata = "test";
+static void logfunc(enum libevdev_log_priority priority,
+		    void *data,
+		    const char *file, int line, const char *func,
+		    const char *f, va_list args) {
+	ck_assert_int_eq(strcmp(logdata, data), 0);
+	log_fn_called++;
+}
+
+START_TEST(test_log_init)
+{
+	struct libevdev *dev = NULL;
+	enum libevdev_log_priority old;
+
+	old = libevdev_get_log_priority();
+
+	libevdev_set_log_priority(LIBEVDEV_LOG_DEBUG);
+
+	libevdev_set_log_function(logfunc, NULL);
+	libevdev_set_log_function(NULL, NULL);
+
+	dev = libevdev_new();
+	ck_assert(dev != NULL);
+
+	libevdev_set_log_function(logfunc, logdata);
+	libevdev_next_event(dev, LIBEVDEV_READ_FLAG_NORMAL, NULL);
+
+	libevdev_set_log_function(NULL, NULL);
+	libevdev_next_event(dev, LIBEVDEV_READ_FLAG_NORMAL, NULL);
+
+	libevdev_set_log_function(logfunc, logdata);
+	libevdev_next_event(dev, LIBEVDEV_READ_FLAG_NORMAL, NULL);
+
+	/* libevdev_next_event(dev, LIBEVDEV_READ_FLAG_NORMAL, NULL) should
+	   trigger a log message. We called it three times, but only twice
+	   with the logfunc set, thus, ensure we only called the logfunc
+	   twice */
+	ck_assert_int_eq(log_fn_called, 2);
+
+	libevdev_free(dev);
+
+	libevdev_set_log_function(test_logfunc_abort_on_error, NULL);
+
+	log_fn_called = 0;
+
+	libevdev_set_log_priority(old);
+}
+END_TEST
+
+START_TEST(test_log_default_priority)
+{
+	ck_assert_int_eq(libevdev_get_log_priority(), LIBEVDEV_LOG_INFO);
+}
+END_TEST
+
+START_TEST(test_log_set_get_priority)
+{
+	enum libevdev_log_priority pri;
+	enum libevdev_log_priority old;
+
+	old = libevdev_get_log_priority();
+
+	pri = LIBEVDEV_LOG_DEBUG;
+	libevdev_set_log_priority(pri);
+	ck_assert_int_eq(libevdev_get_log_priority(), pri);
+
+	pri = LIBEVDEV_LOG_INFO;
+	libevdev_set_log_priority(pri);
+	ck_assert_int_eq(libevdev_get_log_priority(), pri);
+
+	pri = LIBEVDEV_LOG_ERROR;
+	libevdev_set_log_priority(pri);
+	ck_assert_int_eq(libevdev_get_log_priority(), pri);
+
+	/* debug and above is clamped */
+	pri = LIBEVDEV_LOG_DEBUG + 1;
+	libevdev_set_log_priority(pri);
+	ck_assert_int_eq(libevdev_get_log_priority(), LIBEVDEV_LOG_DEBUG);
+
+	/*  error and below is not clamped, we need this for another test */
+	pri = LIBEVDEV_LOG_ERROR - 1;
+	libevdev_set_log_priority(pri);
+	ck_assert_int_eq(libevdev_get_log_priority(), pri);
+
+	libevdev_set_log_priority(old);
+}
+END_TEST
+
+START_TEST(test_log_priority)
+{
+	struct libevdev *dev = NULL;
+	enum libevdev_log_priority old;
+
+	old = libevdev_get_log_priority();
+
+	libevdev_set_log_function(logfunc, logdata);
+
+	dev = libevdev_new();
+	ck_assert(dev != NULL);
+
+	libevdev_set_log_priority(LIBEVDEV_LOG_DEBUG);
+	libevdev_next_event(dev, LIBEVDEV_READ_FLAG_NORMAL, NULL);
+	ck_assert_int_eq(log_fn_called, 1);
+
+	libevdev_set_log_priority(LIBEVDEV_LOG_INFO);
+	libevdev_next_event(dev, LIBEVDEV_READ_FLAG_NORMAL, NULL);
+	ck_assert_int_eq(log_fn_called, 2);
+
+	libevdev_set_log_priority(LIBEVDEV_LOG_ERROR);
+	libevdev_next_event(dev, LIBEVDEV_READ_FLAG_NORMAL, NULL);
+	ck_assert_int_eq(log_fn_called, 3);
+
+	/* we don't have any log msgs > ERROR at the moment, so test it by
+	   setting an invalid priority. */
+	libevdev_set_log_priority(LIBEVDEV_LOG_ERROR - 1);
+	libevdev_next_event(dev, LIBEVDEV_READ_FLAG_NORMAL, NULL);
+	ck_assert_int_eq(log_fn_called, 3);
+
+	libevdev_free(dev);
+
+	libevdev_set_log_function(test_logfunc_abort_on_error, NULL);
+
+	log_fn_called = 0;
+
+	libevdev_set_log_priority(old);
+}
+END_TEST
+
+static char *logdata_1 = "foo";
+static char *logdata_2 = "bar";
+static int log_data_fn_called = 0;
+static void logfunc_data(enum libevdev_log_priority priority,
+			 void *data,
+			 const char *file, int line, const char *func,
+			 const char *f, va_list args) {
+	switch(log_data_fn_called) {
+		case 0: ck_assert(data == logdata_1); break;
+		case 1: ck_assert(data == logdata_2); break;
+		case 2: ck_assert(data == NULL); break;
+		default:
+			ck_abort();
+	}
+	log_data_fn_called++;
+}
+
+START_TEST(test_log_data)
+{
+	struct libevdev *dev = NULL;
+
+	dev = libevdev_new();
+	ck_assert(dev != NULL);
+
+	libevdev_set_log_function(logfunc_data, logdata_1);
+	libevdev_next_event(dev, LIBEVDEV_READ_FLAG_NORMAL, NULL);
+
+	libevdev_set_log_function(logfunc_data, logdata_2);
+	libevdev_next_event(dev, LIBEVDEV_READ_FLAG_NORMAL, NULL);
+
+	libevdev_set_log_function(logfunc_data, NULL);
+	libevdev_next_event(dev, LIBEVDEV_READ_FLAG_NORMAL, NULL);
+
+	libevdev_free(dev);
+}
+END_TEST
+
+struct libevdev *devlogdata;
+static int dev_log_fn_called = 0;
+static void devlogfunc(const struct libevdev *dev,
+		    enum libevdev_log_priority priority,
+		    void *data,
+		    const char *file, int line, const char *func,
+		    const char *f, va_list args)
+{
+	ck_assert(dev == data);
+	dev_log_fn_called++;
+}
+
+START_TEST(test_device_log_init)
+{
+	struct libevdev *dev = NULL;
+	enum libevdev_log_priority old;
+
+	old = libevdev_get_log_priority();
+	libevdev_set_log_priority(LIBEVDEV_LOG_DEBUG);
+	libevdev_set_log_function(logfunc, logdata);
+
+	/* error for NULL device */
+	libevdev_set_device_log_function(NULL, NULL,
+					 LIBEVDEV_LOG_ERROR, NULL);
+	ck_assert_int_eq(log_fn_called, 1);
+
+	/* error for NULL device */
+	libevdev_set_device_log_function(NULL, devlogfunc,
+					 LIBEVDEV_LOG_ERROR, NULL);
+	ck_assert_int_eq(log_fn_called, 2);
+
+	log_fn_called = 0;
+
+	dev = libevdev_new();
+	ck_assert(dev != NULL);
+
+	libevdev_set_device_log_function(dev, NULL,
+					 LIBEVDEV_LOG_ERROR, NULL);
+
+	/* libevdev_next_event(dev, LIBEVDEV_READ_FLAG_NORMAL, NULL) should
+	   trigger a log message. */
+
+	/* expect global handler triggered */
+	libevdev_next_event(dev, LIBEVDEV_READ_FLAG_NORMAL, NULL);
+	ck_assert_int_eq(log_fn_called, 1);
+	ck_assert_int_eq(dev_log_fn_called, 0);
+
+	/* expect device handler triggered */
+	libevdev_set_device_log_function(dev, devlogfunc,
+					 LIBEVDEV_LOG_ERROR, dev);
+	libevdev_next_event(dev, LIBEVDEV_READ_FLAG_NORMAL, NULL);
+	ck_assert_int_eq(log_fn_called, 1);
+	ck_assert_int_eq(dev_log_fn_called, 1);
+
+	/* device handler set, but priority filters. don't expect any log
+	   handler to be called.
+	   we don't have any log msgs > ERROR at the moment, so test it by
+	   setting an invalid priority. */
+	libevdev_set_device_log_function(dev, devlogfunc,
+					 LIBEVDEV_LOG_ERROR - 1, dev);
+	libevdev_next_event(dev, LIBEVDEV_READ_FLAG_NORMAL, NULL);
+	ck_assert_int_eq(log_fn_called, 1);
+	ck_assert_int_eq(dev_log_fn_called, 1);
+
+	libevdev_free(dev);
+
+	log_fn_called = 0;
+	libevdev_set_log_priority(old);
+	libevdev_set_log_function(test_logfunc_abort_on_error, NULL);
+
+}
+END_TEST
+
+START_TEST(test_device_init)
+{
+	struct uinput_device* uidev;
+	struct libevdev *dev;
+	int rc;
+
+	rc = uinput_device_new_with_events(&uidev,
+					   TEST_DEVICE_NAME, DEFAULT_IDS,
+					   EV_SYN, SYN_REPORT,
+					   EV_REL, REL_X,
+					   EV_REL, REL_Y,
+					   EV_REL, REL_WHEEL,
+					   EV_KEY, BTN_LEFT,
+					   EV_KEY, BTN_MIDDLE,
+					   EV_KEY, BTN_RIGHT,
+					   -1);
+	ck_assert_msg(rc == 0, "Failed to create uinput device: %s", strerror(-rc));
+
+	dev = libevdev_new();
+	ck_assert(dev != NULL);
+	rc = libevdev_set_fd(dev, uinput_device_get_fd(uidev));
+	ck_assert_msg(rc == 0, "Failed to init device: %s", strerror(-rc));;
+
+	uinput_device_free(uidev);
+	libevdev_free(dev);
+}
+END_TEST
+
+START_TEST(test_device_init_from_fd)
+{
+	struct uinput_device* uidev;
+	struct libevdev *dev;
+	int rc;
+
+	rc = uinput_device_new_with_events(&uidev,
+					   TEST_DEVICE_NAME, DEFAULT_IDS,
+					   EV_SYN, SYN_REPORT,
+					   EV_REL, REL_X,
+					   EV_REL, REL_Y,
+					   EV_REL, REL_WHEEL,
+					   EV_KEY, BTN_LEFT,
+					   EV_KEY, BTN_MIDDLE,
+					   EV_KEY, BTN_RIGHT,
+					   -1);
+	ck_assert_msg(rc == 0, "Failed to create uinput device: %s", strerror(-rc));
+
+	rc = libevdev_new_from_fd(uinput_device_get_fd(uidev), &dev);
+	ck_assert_msg(rc == 0, "Failed to init device: %s", strerror(-rc));;
+
+	uinput_device_free(uidev);
+	libevdev_free(dev);
+}
+END_TEST
+
+START_TEST(test_device_grab)
+{
+	struct uinput_device* uidev;
+	struct libevdev *dev;
+	int rc;
+
+	test_create_device(&uidev, &dev,
+			   EV_SYN, SYN_REPORT,
+			   EV_REL, REL_X,
+			   EV_REL, REL_Y,
+			   EV_REL, REL_WHEEL,
+			   EV_KEY, BTN_LEFT,
+			   EV_KEY, BTN_MIDDLE,
+			   EV_KEY, BTN_RIGHT,
+			   -1);
+
+	libevdev_set_log_function(test_logfunc_ignore_error, NULL);
+	rc = libevdev_grab(dev, 0);
+	ck_assert_int_eq(rc, -EINVAL);
+	rc = libevdev_grab(dev, 1);
+	ck_assert_int_eq(rc, -EINVAL);
+	libevdev_set_log_function(test_logfunc_abort_on_error, NULL);
+
+	rc = libevdev_grab(dev, LIBEVDEV_UNGRAB);
+	ck_assert_int_eq(rc, 0);
+	rc = libevdev_grab(dev, LIBEVDEV_GRAB);
+	ck_assert_int_eq(rc, 0);
+	rc = libevdev_grab(dev, LIBEVDEV_GRAB);
+	ck_assert_int_eq(rc, 0);
+	rc = libevdev_grab(dev, LIBEVDEV_UNGRAB);
+	ck_assert_int_eq(rc, 0);
+
+	uinput_device_free(uidev);
+	libevdev_free(dev);
+}
+END_TEST
+
+START_TEST(test_device_grab_invalid_fd)
+{
+	struct uinput_device* uidev;
+	struct libevdev *dev;
+	int rc;
+
+	libevdev_set_log_function(test_logfunc_ignore_error, NULL);
+
+	dev = libevdev_new();
+	rc = libevdev_grab(dev, 0);
+	ck_assert_int_eq(rc, -EBADF);
+	libevdev_free(dev);
+
+	test_create_device(&uidev, &dev,
+			   EV_SYN, SYN_REPORT,
+			   EV_REL, REL_X,
+			   EV_REL, REL_Y,
+			   EV_REL, REL_WHEEL,
+			   EV_KEY, BTN_LEFT,
+			   EV_KEY, BTN_MIDDLE,
+			   EV_KEY, BTN_RIGHT,
+			   -1);
+	libevdev_change_fd(dev, -2);
+	rc = libevdev_grab(dev, 0);
+	ck_assert_int_eq(rc, -EBADF);
+
+	libevdev_set_log_function(test_logfunc_abort_on_error, NULL);
+
+	uinput_device_free(uidev);
+	libevdev_free(dev);
+}
+END_TEST
+
+START_TEST(test_device_grab_change_fd)
+{
+	struct libevdev_uinput *uidev;
+	struct libevdev *dev, *other;
+	struct input_event e;
+	int rc;
+	int other_fd;
+	int dev_fd;
+
+	dev = libevdev_new();
+	libevdev_set_name(dev, "libevdev test device");
+	libevdev_enable_event_code(dev, EV_REL, REL_X, NULL);
+	libevdev_enable_event_code(dev, EV_REL, REL_Y, NULL);
+	libevdev_enable_event_code(dev, EV_KEY, BTN_LEFT, NULL);
+
+	rc = libevdev_uinput_create_from_device(dev,
+						LIBEVDEV_UINPUT_OPEN_MANAGED,
+						&uidev);
+	ck_assert_int_eq(rc, 0);
+	libevdev_free(dev);
+
+	dev_fd = open(libevdev_uinput_get_devnode(uidev),
+		      O_RDONLY|O_NONBLOCK);
+	ck_assert_int_ne(dev_fd, -1);
+	rc = libevdev_new_from_fd(dev_fd, &dev);
+	ck_assert_int_eq(rc, 0);
+
+	other_fd = open(libevdev_uinput_get_devnode(uidev),
+			O_RDONLY|O_NONBLOCK);
+	ck_assert_int_ne(other_fd, -1);
+	rc = libevdev_new_from_fd(other_fd, &other);
+	ck_assert_int_eq(rc, 0);
+
+	/* check we're getting the events before the grab */
+	libevdev_uinput_write_event(uidev, EV_REL, REL_X, -1);
+	libevdev_uinput_write_event(uidev, EV_SYN, SYN_REPORT, 0);
+	rc = libevdev_next_event(other, LIBEVDEV_READ_FLAG_NORMAL, &e);
+	ck_assert_int_eq(rc, LIBEVDEV_READ_STATUS_SUCCESS);
+	rc = libevdev_next_event(other, LIBEVDEV_READ_FLAG_NORMAL, &e);
+	ck_assert_int_eq(rc, LIBEVDEV_READ_STATUS_SUCCESS);
+	rc = libevdev_next_event(other, LIBEVDEV_READ_FLAG_NORMAL, &e);
+	ck_assert_int_eq(rc, -EAGAIN);
+
+	/* no events after the grab */
+	rc = libevdev_grab(dev, LIBEVDEV_GRAB);
+	ck_assert_int_eq(rc, 0);
+	libevdev_uinput_write_event(uidev, EV_REL, REL_X, -1);
+	libevdev_uinput_write_event(uidev, EV_SYN, SYN_REPORT, 0);
+	rc = libevdev_grab(dev, LIBEVDEV_GRAB);
+	ck_assert_int_eq(rc, 0);
+	rc = libevdev_next_event(other, LIBEVDEV_READ_FLAG_NORMAL, &e);
+	ck_assert_int_eq(rc, -EAGAIN);
+
+	/* swapping the fd removes the grab */
+	close(dev_fd);
+	dev_fd = open(libevdev_uinput_get_devnode(uidev),
+		      O_RDONLY|O_NONBLOCK);
+	ck_assert_int_ne(dev_fd, -1);
+	rc = libevdev_change_fd(dev, dev_fd);
+	ck_assert_int_eq(rc, 0);
+
+	/* check we're getting the events again */
+	libevdev_uinput_write_event(uidev, EV_REL, REL_X, -1);
+	libevdev_uinput_write_event(uidev, EV_SYN, SYN_REPORT, 0);
+	rc = libevdev_next_event(other, LIBEVDEV_READ_FLAG_NORMAL, &e);
+	ck_assert_int_eq(rc, LIBEVDEV_READ_STATUS_SUCCESS);
+	rc = libevdev_next_event(other, LIBEVDEV_READ_FLAG_NORMAL, &e);
+	ck_assert_int_eq(rc, LIBEVDEV_READ_STATUS_SUCCESS);
+	rc = libevdev_next_event(other, LIBEVDEV_READ_FLAG_NORMAL, &e);
+	ck_assert_int_eq(rc, -EAGAIN);
+
+	/* no events after the grab */
+	rc = libevdev_grab(dev, LIBEVDEV_GRAB);
+	ck_assert_int_eq(rc, 0);
+	libevdev_uinput_write_event(uidev, EV_REL, REL_X, -1);
+	libevdev_uinput_write_event(uidev, EV_SYN, SYN_REPORT, 0);
+	rc = libevdev_next_event(other, LIBEVDEV_READ_FLAG_NORMAL, &e);
+	ck_assert_int_eq(rc, -EAGAIN);
+
+	libevdev_uinput_destroy(uidev);
+	libevdev_free(dev);
+	libevdev_free(other);
+	close(dev_fd);
+	close(other_fd);
+}
+END_TEST
+
+START_TEST(test_set_clock_id)
+{
+	struct uinput_device* uidev;
+	struct libevdev *dev;
+	int clockid;
+	int rc;
+
+	test_create_device(&uidev, &dev,
+			   EV_SYN, SYN_REPORT,
+			   EV_REL, REL_X,
+			   EV_REL, REL_Y,
+			   EV_REL, REL_WHEEL,
+			   EV_KEY, BTN_LEFT,
+			   EV_KEY, BTN_MIDDLE,
+			   EV_KEY, BTN_RIGHT,
+			   -1);
+
+	rc = libevdev_set_clock_id(dev, CLOCK_REALTIME);
+	ck_assert_int_eq(rc, 0);
+
+	rc = libevdev_set_clock_id(dev, CLOCK_MONOTONIC);
+	ck_assert_int_eq(rc, 0);
+
+#ifdef __FreeBSD__
+	clockid = CLOCK_MONOTONIC_FAST;
+#else
+	clockid = CLOCK_MONOTONIC_RAW;
+#endif
+
+	rc = libevdev_set_clock_id(dev, clockid);
+	ck_assert_int_eq(rc, -EINVAL);
+
+	uinput_device_free(uidev);
+	libevdev_free(dev);
+}
+END_TEST
+
+START_TEST(test_set_clock_id_invalid_fd)
+{
+	struct uinput_device* uidev;
+	struct libevdev *dev;
+	int rc;
+
+	libevdev_set_log_function(test_logfunc_ignore_error, NULL);
+
+	dev = libevdev_new();
+	rc = libevdev_set_clock_id(dev, CLOCK_MONOTONIC);
+	ck_assert_int_eq(rc, -EBADF);
+	libevdev_free(dev);
+
+	test_create_device(&uidev, &dev,
+			   EV_SYN, SYN_REPORT,
+			   EV_REL, REL_X,
+			   EV_REL, REL_Y,
+			   EV_REL, REL_WHEEL,
+			   EV_KEY, BTN_LEFT,
+			   EV_KEY, BTN_MIDDLE,
+			   EV_KEY, BTN_RIGHT,
+			   -1);
+	libevdev_change_fd(dev, -2);
+	rc = libevdev_set_clock_id(dev, CLOCK_MONOTONIC);
+	ck_assert_int_eq(rc, -EBADF);
+
+	uinput_device_free(uidev);
+	libevdev_free(dev);
+}
+END_TEST
+
+START_TEST(test_clock_id_events)
+{
+	struct uinput_device* uidev;
+	struct libevdev *dev, *dev2;
+	int rc, fd;
+	struct input_event ev1, ev2;
+	struct timespec t1_real, t2_real;
+	struct timespec t1_mono, t2_mono;
+	int64_t t1, t2;
+
+	test_create_device(&uidev, &dev,
+			   EV_SYN, SYN_REPORT,
+			   EV_REL, REL_X,
+			   EV_REL, REL_Y,
+			   EV_REL, REL_WHEEL,
+			   EV_KEY, BTN_LEFT,
+			   EV_KEY, BTN_MIDDLE,
+			   EV_KEY, BTN_RIGHT,
+			   -1);
+
+	fd = open(uinput_device_get_devnode(uidev), O_RDONLY);
+	ck_assert_int_gt(fd, -1);
+
+	rc = libevdev_new_from_fd(fd, &dev2);
+	ck_assert_msg(rc == 0, "Failed to create second device: %s", strerror(-rc));
+
+	rc = libevdev_set_clock_id(dev2, CLOCK_MONOTONIC);
+	ck_assert_int_eq(rc, 0);
+
+	clock_gettime(CLOCK_REALTIME, &t1_real);
+	clock_gettime(CLOCK_MONOTONIC, &t1_mono);
+	uinput_device_event(uidev, EV_REL, REL_X, 1);
+	uinput_device_event(uidev, EV_SYN, SYN_REPORT, 0);
+	clock_gettime(CLOCK_REALTIME, &t2_real);
+	clock_gettime(CLOCK_MONOTONIC, &t2_mono);
+
+	rc = libevdev_next_event(dev, LIBEVDEV_READ_FLAG_NORMAL, &ev1);
+	ck_assert_int_eq(rc, LIBEVDEV_READ_STATUS_SUCCESS);
+
+	rc = libevdev_next_event(dev2, LIBEVDEV_READ_FLAG_NORMAL, &ev2);
+	ck_assert_int_eq(rc, LIBEVDEV_READ_STATUS_SUCCESS);
+
+	ck_assert_int_eq(ev1.type, ev2.type);
+	ck_assert_int_eq(ev1.code, ev2.code);
+	ck_assert_int_eq(ev1.value, ev2.value);
+
+	t1 = ev1.input_event_sec * 1000000LL + ev1.input_event_usec;
+	t2 = ev2.input_event_sec * 1000000LL + ev2.input_event_usec;
+	ck_assert_int_ne(t1, t2);
+
+	ck_assert_int_ge(ev1.input_event_sec, t1_real.tv_sec);
+	ck_assert_int_ge(ev1.input_event_usec, t1_real.tv_nsec/1000);
+	ck_assert_int_le(ev1.input_event_sec, t2_real.tv_sec);
+	ck_assert_int_le(ev1.input_event_usec, t2_real.tv_nsec/1000);
+
+	ck_assert_int_ge(ev2.input_event_sec, t1_mono.tv_sec);
+	ck_assert_int_ge(ev2.input_event_usec, t1_mono.tv_nsec/1000);
+	ck_assert_int_le(ev2.input_event_sec, t2_mono.tv_sec);
+	ck_assert_int_le(ev2.input_event_usec, t2_mono.tv_nsec/1000);
+
+	uinput_device_free(uidev);
+	libevdev_free(dev);
+	libevdev_free(dev2);
+	close(fd);
+}
+END_TEST
+
+TEST_SUITE_ROOT_PRIVILEGES(libevdev_init_test)
+{
+	Suite *s = suite_create("libevdev init tests");
+
+	add_test(s, test_new_device);
+	add_test(s, test_free_device);
+	add_test(s, test_init_from_invalid_fd);
+	add_test(s, test_init_and_change_fd);
+
+	add_test(s, test_log_init);
+	add_test(s, test_log_priority);
+	add_test(s, test_log_set_get_priority);
+	add_test(s, test_log_default_priority);
+	add_test(s, test_log_data);
+	add_test(s, test_device_log_init);
+
+	add_test(s, test_device_init);
+	add_test(s, test_device_init_from_fd);
+
+	add_test(s, test_device_grab);
+	add_test(s, test_device_grab_invalid_fd);
+	add_test(s, test_device_grab_change_fd);
+
+	add_test(s, test_set_clock_id);
+	add_test(s, test_set_clock_id_invalid_fd);
+	add_test(s, test_clock_id_events);
+
+	return s;
+}
diff --git a/test/test-link.c b/test/test-link.c
new file mode 100644
index 0000000000000000000000000000000000000000..a66ea8684fac5b360f84c5ae8c4f91af2f581ddc
--- /dev/null
+++ b/test/test-link.c
@@ -0,0 +1,6 @@
+#include 
+#include 
+
+int main(void) {
+	return libevdev_new_from_fd(0, NULL);
+}
diff --git a/test/test-main.c b/test/test-main.c
new file mode 100644
index 0000000000000000000000000000000000000000..95357409a060632590c6045ab580f1ab494695d0
--- /dev/null
+++ b/test/test-main.c
@@ -0,0 +1,117 @@
+// SPDX-License-Identifier: MIT
+/*
+ * Copyright © 2013 Red Hat, Inc.
+ */
+
+#include "config.h"
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "test-common.h"
+
+static int
+is_debugger_attached(void)
+{
+	int rc = 1;
+	/*
+	 * FreeBSD does not support PTRACE_ATTACH, disable attaching a debugger
+	 * on FreeBSD by skipping the rest of the function and just return 1.
+	 */
+#ifndef __FreeBSD__
+	int status;
+	int pid = fork();
+
+	if (pid == -1)
+		return 0;
+
+	if (pid == 0) {
+		int ppid = getppid();
+		if (ptrace(PTRACE_ATTACH, ppid, NULL, NULL) == 0) {
+			waitpid(ppid, NULL, 0);
+			ptrace(PTRACE_CONT, NULL, NULL);
+			ptrace(PTRACE_DETACH, ppid, NULL, NULL);
+			rc = 0;
+		}
+		_exit(rc);
+	} else {
+		waitpid(pid, &status, 0);
+		rc = WEXITSTATUS(status);
+	}
+
+#endif /* !__FreeBSD__ */
+	return rc;
+}
+
+static bool
+device_nodes_exist(void)
+{
+	struct stat st;
+	int rc;
+
+	rc = stat("/dev/uinput", &st);
+	if (rc == -1 && errno == ENOENT)
+		return false;
+
+	rc = stat("/dev/input", &st);
+	if (rc == -1 && errno == ENOENT)
+		return false;
+
+	/* Any issues but ENOENT we just let the test suite blow up later */
+	return true;
+}
+
+extern const struct libevdev_test __start_test_section, __stop_test_section;
+
+int main(void)
+{
+	const struct libevdev_test *t;
+	const struct rlimit corelimit = {0, 0};
+	int failed;
+
+	for (t = &__start_test_section; t < &__stop_test_section; t++) {
+		if (t->needs_root_privileges) {
+			if (getenv("LIBEVDEV_SKIP_ROOT_TESTS"))
+				return 77;
+
+			if (getuid() != 0) {
+				fprintf(stderr, "This test needs to run as root\n");
+				return 77;
+			}
+			if (!device_nodes_exist()) {
+				fprintf(stderr, "This test needs /dev/input and /dev/uinput to exist\n");
+				return 77;
+			}
+
+			break;
+		}
+	}
+
+	if (is_debugger_attached())
+		setenv("CK_FORK", "no", 0);
+
+	if (setrlimit(RLIMIT_CORE, &corelimit) != 0)
+		perror("WARNING: Core dumps not disabled. Reason");
+
+	libevdev_set_log_function(test_logfunc_abort_on_error, NULL);
+
+	SRunner *sr = srunner_create(NULL);
+	for (t = &__start_test_section; t < &__stop_test_section; t++) {
+		srunner_add_suite(sr, t->setup());
+	}
+
+	srunner_run_all(sr, CK_NORMAL);
+
+	failed = srunner_ntests_failed(sr);
+	srunner_free(sr);
+
+	return failed;
+}
diff --git a/test/test-static-symbols-leak.sh b/test/test-static-symbols-leak.sh
new file mode 100644
index 0000000000000000000000000000000000000000..9564a2ad9e743402e00afc3b8c4ed7fd796873a7
--- /dev/null
+++ b/test/test-static-symbols-leak.sh
@@ -0,0 +1,21 @@
+#!/usr/bin/env bash
+#
+# Hack to check for leaking symbols in the static library.
+# See https://bugs.freedesktop.org/show_bug.cgi?id=82785
+# Note the spaces in the expressions! After the first grep, each line
+# is " T symbol_name"
+
+test -z "$RUNNING_ON_VALGRIND" || exit 77
+
+builddir="$1"
+
+test -f "$builddir/test-static-link" || (echo "Unable to find test file" && exit 1)
+nm --extern-only "$builddir/test-static-link" |
+	grep -o -e " T .*" | \
+	grep -v -e " main\$" \
+		-e " atexit" \
+		-e " mangle_path" \
+		-e " *gcov.*" \
+		-e " _.*" \
+		-e " libevdev_*" && \
+		echo "Leaking symbols found" && exit 1 || exit 0
diff --git a/test/test-uinput.c b/test/test-uinput.c
new file mode 100644
index 0000000000000000000000000000000000000000..cf1c32d746bf7830bf2e3061cf1653cb0466a7f2
--- /dev/null
+++ b/test/test-uinput.c
@@ -0,0 +1,463 @@
+// SPDX-License-Identifier: MIT
+/*
+ * Copyright © 2013 Red Hat, Inc.
+ */
+
+#include "config.h"
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "test-common.h"
+#define UINPUT_NODE "/dev/uinput"
+
+START_TEST(test_uinput_create_device)
+{
+	struct libevdev *dev, *dev2;
+	struct libevdev_uinput *uidev;
+	int fd, uinput_fd;
+	unsigned int type, code;
+	int rc;
+	const char *devnode;
+
+	dev = libevdev_new();
+	ck_assert(dev != NULL);
+	libevdev_set_name(dev, TEST_DEVICE_NAME);
+	libevdev_enable_event_type(dev, EV_SYN);
+	libevdev_enable_event_type(dev, EV_REL);
+	libevdev_enable_event_code(dev, EV_REL, REL_X, NULL);
+	libevdev_enable_event_code(dev, EV_REL, REL_Y, NULL);
+	libevdev_enable_event_code(dev, EV_REL, REL_MAX, NULL);
+
+	rc = libevdev_uinput_create_from_device(dev, LIBEVDEV_UINPUT_OPEN_MANAGED, &uidev);
+	ck_assert_int_eq(rc, 0);
+	ck_assert(uidev != NULL);
+
+	uinput_fd = libevdev_uinput_get_fd(uidev);
+	ck_assert_int_gt(uinput_fd, -1);
+
+	devnode = libevdev_uinput_get_devnode(uidev);
+	ck_assert(devnode != NULL);
+
+	fd = open(devnode, O_RDONLY);
+	ck_assert_int_gt(fd, -1);
+	rc = libevdev_new_from_fd(fd, &dev2);
+	ck_assert_int_eq(rc, 0);
+
+	for (type = 0; type < EV_CNT; type++) {
+		int max = libevdev_event_type_get_max(type);
+		if (max == -1)
+			continue;
+
+		for (code = 0; code < (unsigned int)max; code++) {
+			ck_assert_int_eq(libevdev_has_event_code(dev, type, code),
+					 libevdev_has_event_code(dev2, type, code));
+		}
+	}
+
+	libevdev_free(dev);
+	libevdev_free(dev2);
+	libevdev_uinput_destroy(uidev);
+	close(fd);
+
+	/* uinput fd is managed, so make sure it did get closed */
+	ck_assert_int_eq(close(uinput_fd), -1);
+	ck_assert_int_eq(errno, EBADF);
+
+}
+END_TEST
+
+START_TEST(test_uinput_create_device_invalid)
+{
+	struct libevdev *dev;
+	struct libevdev_uinput *uidev = NULL;
+	int rc;
+
+	dev = libevdev_new();
+	ck_assert(dev != NULL);
+	libevdev_set_name(dev, TEST_DEVICE_NAME);
+	libevdev_enable_event_type(dev, EV_SYN);
+	libevdev_enable_event_type(dev, EV_REL);
+	libevdev_enable_event_code(dev, EV_REL, REL_X, NULL);
+	libevdev_enable_event_code(dev, EV_REL, REL_Y, NULL);
+
+	libevdev_set_log_function(test_logfunc_ignore_error, NULL);
+	rc = libevdev_uinput_create_from_device(dev, -1, &uidev);
+	ck_assert_int_eq(rc, -EBADF);
+	ck_assert(uidev == NULL);
+	libevdev_set_log_function(test_logfunc_abort_on_error, NULL);
+
+	libevdev_free(dev);
+}
+END_TEST
+
+START_TEST(test_uinput_create_device_from_fd)
+{
+	struct libevdev *dev, *dev2;
+	struct libevdev_uinput *uidev;
+	int fd, fd2;
+	unsigned int type, code;
+	int rc;
+	const char *devnode;
+
+	dev = libevdev_new();
+	ck_assert(dev != NULL);
+	libevdev_set_name(dev, TEST_DEVICE_NAME);
+	libevdev_enable_event_type(dev, EV_SYN);
+	libevdev_enable_event_type(dev, EV_REL);
+	libevdev_enable_event_code(dev, EV_REL, REL_X, NULL);
+	libevdev_enable_event_code(dev, EV_REL, REL_Y, NULL);
+
+	fd = open(UINPUT_NODE, O_RDWR);
+	ck_assert_int_gt(fd, -1);
+
+	rc = libevdev_uinput_create_from_device(dev, fd, &uidev);
+	ck_assert_int_eq(rc, 0);
+	ck_assert(uidev != NULL);
+
+	ck_assert_int_eq(libevdev_uinput_get_fd(uidev), fd);
+
+	devnode = libevdev_uinput_get_devnode(uidev);
+	ck_assert(devnode != NULL);
+
+	fd2 = open(devnode, O_RDONLY);
+	ck_assert_int_gt(fd2, -1);
+	rc = libevdev_new_from_fd(fd2, &dev2);
+	ck_assert_int_eq(rc, 0);
+
+	for (type = 0; type < EV_CNT; type++) {
+		int max = libevdev_event_type_get_max(type);
+		if (max == -1)
+			continue;
+
+		for (code = 0; code < (unsigned int)max; code++) {
+			ck_assert_int_eq(libevdev_has_event_code(dev, type, code),
+					 libevdev_has_event_code(dev2, type, code));
+		}
+	}
+
+	libevdev_free(dev);
+	libevdev_free(dev2);
+	libevdev_uinput_destroy(uidev);
+	close(fd);
+	close(fd2);
+}
+END_TEST
+
+#ifdef __FreeBSD__
+START_TEST(test_uinput_check_devnode_bsd)
+{
+	struct libevdev *dev;
+	struct libevdev_uinput *uidev, *uidev2;
+	const char *devnode, *devnode2;
+	int fd, fd2;
+	int rc;
+
+	dev = libevdev_new();
+	ck_assert(dev != NULL);
+	libevdev_set_name(dev, TEST_DEVICE_NAME);
+	libevdev_enable_event_type(dev, EV_SYN);
+	libevdev_enable_event_type(dev, EV_REL);
+	libevdev_enable_event_code(dev, EV_REL, REL_X, NULL);
+	libevdev_enable_event_code(dev, EV_REL, REL_Y, NULL);
+
+	fd = open(UINPUT_NODE, O_RDWR);
+	ck_assert_int_gt(fd, -1);
+	fd2 = open(UINPUT_NODE, O_RDWR);
+	ck_assert_int_gt(fd2, -1);
+
+	rc = libevdev_uinput_create_from_device(dev, fd, &uidev);
+	ck_assert_int_eq(rc, 0);
+
+	/* create a second one */
+	libevdev_set_name(dev, TEST_DEVICE_NAME " 2");
+	rc = libevdev_uinput_create_from_device(dev, fd2, &uidev2);
+	ck_assert_int_eq(rc, 0);
+
+	devnode = libevdev_uinput_get_devnode(uidev);
+	ck_assert(devnode != NULL);
+
+	/* get syspath twice returns same pointer */
+	devnode2 = libevdev_uinput_get_devnode(uidev);
+	ck_assert(devnode == devnode2);
+
+	/* second dev has different devnode */
+	devnode2 = libevdev_uinput_get_devnode(uidev2);
+	ck_assert(strcmp(devnode, devnode2) != 0);
+
+	libevdev_uinput_destroy(uidev2);
+	libevdev_uinput_destroy(uidev);
+
+	close(fd2);
+	close(fd);
+
+	libevdev_free(dev);
+}
+END_TEST
+
+START_TEST(test_uinput_check_syspath_bsd)
+{
+	struct libevdev *dev;
+	struct libevdev_uinput *uidev;
+	const char *syspath;
+	int fd;
+	int rc;
+
+	dev = libevdev_new();
+	ck_assert(dev != NULL);
+	libevdev_set_name(dev, TEST_DEVICE_NAME);
+	libevdev_enable_event_type(dev, EV_SYN);
+	libevdev_enable_event_type(dev, EV_REL);
+	libevdev_enable_event_code(dev, EV_REL, REL_X, NULL);
+	libevdev_enable_event_code(dev, EV_REL, REL_Y, NULL);
+
+	fd = open(UINPUT_NODE, O_RDWR);
+	ck_assert_int_gt(fd, -1);
+
+	rc = libevdev_uinput_create_from_device(dev, fd, &uidev);
+	ck_assert_int_eq(rc, 0);
+
+	syspath = libevdev_uinput_get_syspath(uidev);
+	/* FreeBSD should always return NULL for libevdev_unput_get_syspath() */
+	ck_assert(syspath == NULL);
+
+	libevdev_uinput_destroy(uidev);
+
+	close(fd);
+
+	libevdev_free(dev);
+}
+END_TEST
+
+#else /* !__FreeBSD__ */
+
+START_TEST(test_uinput_check_syspath_time)
+{
+	struct libevdev *dev;
+	struct libevdev_uinput *uidev, *uidev2;
+	const char *syspath, *syspath2;
+	int fd, fd2;
+	int rc;
+
+	dev = libevdev_new();
+	ck_assert(dev != NULL);
+	libevdev_set_name(dev, TEST_DEVICE_NAME);
+	libevdev_enable_event_type(dev, EV_SYN);
+	libevdev_enable_event_type(dev, EV_REL);
+	libevdev_enable_event_code(dev, EV_REL, REL_X, NULL);
+	libevdev_enable_event_code(dev, EV_REL, REL_Y, NULL);
+
+	fd = open(UINPUT_NODE, O_RDWR);
+	ck_assert_int_gt(fd, -1);
+	fd2 = open(UINPUT_NODE, O_RDWR);
+	ck_assert_int_gt(fd2, -1);
+
+	rc = libevdev_uinput_create_from_device(dev, fd, &uidev);
+	ck_assert_int_eq(rc, 0);
+
+	/* sleep for 1.5 seconds. sysfs resolution is 1 second, so
+	   creating both devices without delay means
+	   libevdev_uinput_get_syspath can't actually differ between
+	   them. By waiting, we get different ctime for uidev and uidev2,
+	   and exercise that part of the code.
+	 */
+	usleep(1500000);
+
+	/* create a second one to test the syspath time filtering code */
+	rc = libevdev_uinput_create_from_device(dev, fd2, &uidev2);
+	ck_assert_int_eq(rc, 0);
+
+	syspath = libevdev_uinput_get_syspath(uidev);
+	ck_assert(syspath != NULL);
+
+	/* get syspath twice returns same pointer */
+	syspath2 = libevdev_uinput_get_syspath(uidev);
+	ck_assert(syspath == syspath2);
+
+	/* second dev has different syspath */
+	syspath2 = libevdev_uinput_get_syspath(uidev2);
+	ck_assert(strcmp(syspath, syspath2) != 0);
+
+	libevdev_free(dev);
+	libevdev_uinput_destroy(uidev);
+	libevdev_uinput_destroy(uidev2);
+
+	close(fd);
+	close(fd2);
+}
+END_TEST
+
+START_TEST(test_uinput_check_syspath_name)
+{
+	struct libevdev *dev;
+	struct libevdev_uinput *uidev, *uidev2;
+	const char *syspath, *syspath2;
+	int fd, fd2;
+	int rc;
+
+	dev = libevdev_new();
+	ck_assert(dev != NULL);
+	libevdev_set_name(dev, TEST_DEVICE_NAME);
+	libevdev_enable_event_type(dev, EV_SYN);
+	libevdev_enable_event_type(dev, EV_REL);
+	libevdev_enable_event_code(dev, EV_REL, REL_X, NULL);
+	libevdev_enable_event_code(dev, EV_REL, REL_Y, NULL);
+
+	fd = open(UINPUT_NODE, O_RDWR);
+	ck_assert_int_gt(fd, -1);
+	fd2 = open(UINPUT_NODE, O_RDWR);
+	ck_assert_int_gt(fd2, -1);
+
+	rc = libevdev_uinput_create_from_device(dev, fd, &uidev);
+	ck_assert_int_eq(rc, 0);
+
+	/* create a second one to stress the syspath filtering code */
+	libevdev_set_name(dev, TEST_DEVICE_NAME " 2");
+	rc = libevdev_uinput_create_from_device(dev, fd2, &uidev2);
+	ck_assert_int_eq(rc, 0);
+
+	syspath = libevdev_uinput_get_syspath(uidev);
+	ck_assert(syspath != NULL);
+
+	/* get syspath twice returns same pointer */
+	syspath2 = libevdev_uinput_get_syspath(uidev);
+	ck_assert(syspath == syspath2);
+
+	/* second dev has different syspath */
+	syspath2 = libevdev_uinput_get_syspath(uidev2);
+	ck_assert(strcmp(syspath, syspath2) != 0);
+
+	libevdev_free(dev);
+	libevdev_uinput_destroy(uidev);
+	libevdev_uinput_destroy(uidev2);
+
+	close(fd);
+	close(fd2);
+}
+END_TEST
+
+#endif /* __FreeBSD __ */
+
+START_TEST(test_uinput_events)
+{
+	struct libevdev *dev;
+	struct libevdev_uinput *uidev;
+	int fd, fd2;
+	int rc;
+	const char *devnode;
+	int i;
+	const int nevents = 5;
+	struct input_event events[] = { {{0, 0}, EV_REL, REL_X, 1},
+					{{0, 0}, EV_REL, REL_Y, -1},
+					{{0, 0}, EV_SYN, SYN_REPORT, 0},
+					{{0, 0}, EV_KEY, BTN_LEFT, 1},
+					{{0, 0}, EV_SYN, SYN_REPORT, 0}};
+	struct input_event events_read[nevents];
+
+	dev = libevdev_new();
+	ck_assert(dev != NULL);
+	libevdev_set_name(dev, TEST_DEVICE_NAME);
+	libevdev_enable_event_type(dev, EV_SYN);
+	libevdev_enable_event_type(dev, EV_REL);
+	libevdev_enable_event_type(dev, EV_KEY);
+	libevdev_enable_event_code(dev, EV_REL, REL_X, NULL);
+	libevdev_enable_event_code(dev, EV_REL, REL_Y, NULL);
+	libevdev_enable_event_code(dev, EV_KEY, BTN_LEFT, NULL);
+
+	fd = open(UINPUT_NODE, O_RDWR);
+	ck_assert_int_gt(fd, -1);
+
+	rc = libevdev_uinput_create_from_device(dev, fd, &uidev);
+	ck_assert_int_eq(rc, 0);
+	ck_assert(uidev != NULL);
+
+	devnode = libevdev_uinput_get_devnode(uidev);
+	ck_assert(devnode != NULL);
+
+	fd2 = open(devnode, O_RDONLY);
+
+	for (i = 0; i < nevents; i++)
+		libevdev_uinput_write_event(uidev, events[i].type, events[i].code, events[i].value);
+
+	rc = read(fd2, events_read, sizeof(events_read));
+	ck_assert_int_eq(rc, sizeof(events_read));
+
+	for (i = 0; i < nevents; i++) {
+		ck_assert_int_eq(events[i].type, events_read[i].type);
+		ck_assert_int_eq(events[i].code, events_read[i].code);
+		ck_assert_int_eq(events[i].value, events_read[i].value);
+	}
+
+	libevdev_free(dev);
+	libevdev_uinput_destroy(uidev);
+	close(fd);
+	close(fd2);
+}
+END_TEST
+
+START_TEST(test_uinput_properties)
+{
+	struct libevdev *dev, *dev2;
+	struct libevdev_uinput *uidev;
+	int fd;
+	int rc;
+	const char *devnode;
+
+	dev = libevdev_new();
+	ck_assert(dev != NULL);
+	libevdev_set_name(dev, TEST_DEVICE_NAME);
+	libevdev_enable_event_type(dev, EV_SYN);
+	libevdev_enable_event_type(dev, EV_REL);
+	libevdev_enable_event_type(dev, EV_KEY);
+	libevdev_enable_event_code(dev, EV_REL, REL_X, NULL);
+	libevdev_enable_event_code(dev, EV_REL, REL_Y, NULL);
+	libevdev_enable_event_code(dev, EV_KEY, BTN_LEFT, NULL);
+	libevdev_enable_property(dev, INPUT_PROP_BUTTONPAD);
+	libevdev_enable_property(dev, INPUT_PROP_MAX);
+
+	rc = libevdev_uinput_create_from_device(dev, LIBEVDEV_UINPUT_OPEN_MANAGED, &uidev);
+	ck_assert_int_eq(rc, 0);
+	ck_assert(uidev != NULL);
+
+	devnode = libevdev_uinput_get_devnode(uidev);
+	ck_assert(devnode != NULL);
+
+	fd = open(devnode, O_RDONLY);
+	ck_assert_int_gt(fd, -1);
+	rc = libevdev_new_from_fd(fd, &dev2);
+	ck_assert_int_eq(rc, 0);
+
+	ck_assert(libevdev_has_property(dev2, INPUT_PROP_BUTTONPAD));
+	ck_assert(libevdev_has_property(dev2, INPUT_PROP_MAX));
+
+	libevdev_free(dev);
+	libevdev_free(dev2);
+	libevdev_uinput_destroy(uidev);
+	close(fd);
+}
+END_TEST
+
+TEST_SUITE_ROOT_PRIVILEGES(uinput_suite)
+{
+	Suite *s = suite_create("libevdev uinput device tests");
+
+	add_test(s, test_uinput_create_device);
+	add_test(s, test_uinput_create_device_invalid);
+	add_test(s, test_uinput_create_device_from_fd);
+#ifdef __FreeBSD__
+	add_test(s, test_uinput_check_devnode_bsd);
+	add_test(s, test_uinput_check_syspath_bsd);
+#else
+	add_test(s, test_uinput_check_syspath_time);
+	add_test(s, test_uinput_check_syspath_name);
+#endif
+
+	add_test(s, test_uinput_events);
+
+	add_test(s, test_uinput_properties);
+
+	return s;
+}
diff --git a/test/valgrind.suppressions b/test/valgrind.suppressions
new file mode 100644
index 0000000000000000000000000000000000000000..5fee7aa7168eaa5d30a82b951b34613959663de8
--- /dev/null
+++ b/test/valgrind.suppressions
@@ -0,0 +1,27 @@
+{
+   
+   Memcheck:Param
+   timer_create(evp)
+   fun:timer_create@@GLIBC_2.3.3
+}
+{
+   
+   Memcheck:Param
+   ioctl(generic)
+   fun:ioctl
+   fun:libevdev_grab
+}
+{
+   
+   Memcheck:Param
+   ioctl(generic)
+   fun:ioctl
+   fun:test_revoke*
+}
+{
+   
+   Memcheck:Leak
+   ...
+   fun:reader_loop
+   fun:main
+}
diff --git a/third_party_libevdev.diff b/third_party_libevdev.diff
new file mode 100644
index 0000000000000000000000000000000000000000..b5b44ea14974776dd85a291cc70ee44da5b4ed70
--- /dev/null
+++ b/third_party_libevdev.diff
@@ -0,0 +1,33835 @@
+diff -Naur third-party-libevdev-bak/COPYING third-party-new/COPYING
+--- third-party-libevdev-bak/COPYING	2023-03-28 10:49:53.360511300 +0800
++++ third-party-new/COPYING	2023-04-03 14:16:25.837444300 +0800
+@@ -1,23 +1,26 @@
++SPDX-License-Identifier: MIT
++
+ Copyright © 2013 Red Hat, Inc.
+ Copyright © 2013 David Herrmann 
+ 
+-Permission to use, copy, modify, distribute, and sell this software and its
+-documentation for any purpose is hereby granted without fee, provided that
+-the above copyright notice appear in all copies and that both that copyright
+-notice and this permission notice appear in supporting documentation, and
+-that the name of the copyright holders not be used in advertising or
+-publicity pertaining to distribution of the software without specific,
+-written prior permission.  The copyright holders make no representations
+-about the suitability of this software for any purpose.  It is provided "as
+-is" without express or implied warranty.
++Permission is hereby granted, free of charge, to any person obtaining a copy
++of this software and associated documentation files (the "Software"), to
++deal in the Software without restriction, including without limitation the
++rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
++sell copies of the Software, and to permit persons to whom the Software is
++furnished to do so, subject to the following conditions:
++
++The above copyright notice and this permission notice (including the next
++paragraph) shall be included in all copies or substantial portions of the
++Software.
+ 
+-THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+-INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+-EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+-CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+-DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+-TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+-OF THIS SOFTWARE.
++THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
++IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
++FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
++AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
++LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
++FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
++IN THE SOFTWARE.
+ 
+ The following license is from a Linux kernel header file and there is no GPL
+ code this package links to.
+diff -Naur third-party-libevdev-bak/Makefile.in third-party-new/Makefile.in
+--- third-party-libevdev-bak/Makefile.in	1970-01-01 08:00:00.000000000 +0800
++++ third-party-new/Makefile.in	2023-04-03 14:17:08.314291900 +0800
+@@ -0,0 +1,911 @@
++# Makefile.in generated by automake 1.16.5 from Makefile.am.
++# @configure_input@
++
++# Copyright (C) 1994-2021 Free Software Foundation, Inc.
++
++# This Makefile.in is free software; the Free Software Foundation
++# gives unlimited permission to copy and/or distribute it,
++# with or without modifications, as long as this notice is preserved.
++
++# This program is distributed in the hope that it will be useful,
++# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
++# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
++# PARTICULAR PURPOSE.
++
++@SET_MAKE@
++
++VPATH = @srcdir@
++am__is_gnu_make = { \
++  if test -z '$(MAKELEVEL)'; then \
++    false; \
++  elif test -n '$(MAKE_HOST)'; then \
++    true; \
++  elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
++    true; \
++  else \
++    false; \
++  fi; \
++}
++am__make_running_with_option = \
++  case $${target_option-} in \
++      ?) ;; \
++      *) echo "am__make_running_with_option: internal error: invalid" \
++              "target option '$${target_option-}' specified" >&2; \
++         exit 1;; \
++  esac; \
++  has_opt=no; \
++  sane_makeflags=$$MAKEFLAGS; \
++  if $(am__is_gnu_make); then \
++    sane_makeflags=$$MFLAGS; \
++  else \
++    case $$MAKEFLAGS in \
++      *\\[\ \	]*) \
++        bs=\\; \
++        sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
++          | sed "s/$$bs$$bs[$$bs $$bs	]*//g"`;; \
++    esac; \
++  fi; \
++  skip_next=no; \
++  strip_trailopt () \
++  { \
++    flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
++  }; \
++  for flg in $$sane_makeflags; do \
++    test $$skip_next = yes && { skip_next=no; continue; }; \
++    case $$flg in \
++      *=*|--*) continue;; \
++        -*I) strip_trailopt 'I'; skip_next=yes;; \
++      -*I?*) strip_trailopt 'I';; \
++        -*O) strip_trailopt 'O'; skip_next=yes;; \
++      -*O?*) strip_trailopt 'O';; \
++        -*l) strip_trailopt 'l'; skip_next=yes;; \
++      -*l?*) strip_trailopt 'l';; \
++      -[dEDm]) skip_next=yes;; \
++      -[JT]) skip_next=yes;; \
++    esac; \
++    case $$flg in \
++      *$$target_option*) has_opt=yes; break;; \
++    esac; \
++  done; \
++  test $$has_opt = yes
++am__make_dryrun = (target_option=n; $(am__make_running_with_option))
++am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
++pkgdatadir = $(datadir)/@PACKAGE@
++pkgincludedir = $(includedir)/@PACKAGE@
++pkglibdir = $(libdir)/@PACKAGE@
++pkglibexecdir = $(libexecdir)/@PACKAGE@
++am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
++install_sh_DATA = $(install_sh) -c -m 644
++install_sh_PROGRAM = $(install_sh) -c
++install_sh_SCRIPT = $(install_sh) -c
++INSTALL_HEADER = $(INSTALL_DATA)
++transform = $(program_transform_name)
++NORMAL_INSTALL = :
++PRE_INSTALL = :
++POST_INSTALL = :
++NORMAL_UNINSTALL = :
++PRE_UNINSTALL = :
++POST_UNINSTALL = :
++build_triplet = @build@
++host_triplet = @host@
++subdir = .
++ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
++am__aclocal_m4_deps = $(top_srcdir)/m4/attributes.m4 \
++	$(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \
++	$(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \
++	$(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac
++am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
++	$(ACLOCAL_M4)
++DIST_COMMON = $(srcdir)/Makefile.am $(top_srcdir)/configure \
++	$(am__configure_deps) $(am__DIST_COMMON)
++am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \
++ configure.lineno config.status.lineno
++mkinstalldirs = $(install_sh) -d
++CONFIG_HEADER = config.h
++CONFIG_CLEAN_FILES = libevdev.pc
++CONFIG_CLEAN_VPATH_FILES =
++AM_V_P = $(am__v_P_@AM_V@)
++am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
++am__v_P_0 = false
++am__v_P_1 = :
++AM_V_GEN = $(am__v_GEN_@AM_V@)
++am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
++am__v_GEN_0 = @echo "  GEN     " $@;
++am__v_GEN_1 = 
++AM_V_at = $(am__v_at_@AM_V@)
++am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
++am__v_at_0 = @
++am__v_at_1 = 
++SOURCES =
++DIST_SOURCES =
++RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \
++	ctags-recursive dvi-recursive html-recursive info-recursive \
++	install-data-recursive install-dvi-recursive \
++	install-exec-recursive install-html-recursive \
++	install-info-recursive install-pdf-recursive \
++	install-ps-recursive install-recursive installcheck-recursive \
++	installdirs-recursive pdf-recursive ps-recursive \
++	tags-recursive uninstall-recursive
++am__can_run_installinfo = \
++  case $$AM_UPDATE_INFO_DIR in \
++    n|no|NO) false;; \
++    *) (install-info --version) >/dev/null 2>&1;; \
++  esac
++am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
++am__vpath_adj = case $$p in \
++    $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
++    *) f=$$p;; \
++  esac;
++am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
++am__install_max = 40
++am__nobase_strip_setup = \
++  srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
++am__nobase_strip = \
++  for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
++am__nobase_list = $(am__nobase_strip_setup); \
++  for p in $$list; do echo "$$p $$p"; done | \
++  sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
++  $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
++    if (++n[$$2] == $(am__install_max)) \
++      { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
++    END { for (dir in files) print dir, files[dir] }'
++am__base_list = \
++  sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
++  sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
++am__uninstall_files_from_dir = { \
++  test -z "$$files" \
++    || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
++    || { echo " ( cd '$$dir' && rm -f" $$files ")"; \
++         $(am__cd) "$$dir" && rm -f $$files; }; \
++  }
++am__installdirs = "$(DESTDIR)$(pkgconfigdir)"
++DATA = $(pkgconfig_DATA)
++RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive	\
++  distclean-recursive maintainer-clean-recursive
++am__recursive_targets = \
++  $(RECURSIVE_TARGETS) \
++  $(RECURSIVE_CLEAN_TARGETS) \
++  $(am__extra_recursive_targets)
++AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \
++	cscope distdir distdir-am dist dist-all distcheck
++am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) \
++	config.h.in
++# Read a list of newline-separated strings from the standard input,
++# and print each of them once, without duplicates.  Input order is
++# *not* preserved.
++am__uniquify_input = $(AWK) '\
++  BEGIN { nonempty = 0; } \
++  { items[$$0] = 1; nonempty = 1; } \
++  END { if (nonempty) { for (i in items) print i; }; } \
++'
++# Make sure the list of sources is unique.  This is necessary because,
++# e.g., the same source file might be shared among _SOURCES variables
++# for different programs/libraries.
++am__define_uniq_tagged_files = \
++  list='$(am__tagged_files)'; \
++  unique=`for i in $$list; do \
++    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
++  done | $(am__uniquify_input)`
++DIST_SUBDIRS = $(SUBDIRS)
++am__DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/config.h.in \
++	$(srcdir)/libevdev.pc.in $(top_srcdir)/build-aux/compile \
++	$(top_srcdir)/build-aux/config.guess \
++	$(top_srcdir)/build-aux/config.sub \
++	$(top_srcdir)/build-aux/install-sh \
++	$(top_srcdir)/build-aux/ltmain.sh \
++	$(top_srcdir)/build-aux/missing COPYING README.md \
++	build-aux/compile build-aux/config.guess build-aux/config.sub \
++	build-aux/install-sh build-aux/ltmain.sh build-aux/missing
++DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
++distdir = $(PACKAGE)-$(VERSION)
++top_distdir = $(distdir)
++am__remove_distdir = \
++  if test -d "$(distdir)"; then \
++    find "$(distdir)" -type d ! -perm -200 -exec chmod u+w {} ';' \
++      && rm -rf "$(distdir)" \
++      || { sleep 5 && rm -rf "$(distdir)"; }; \
++  else :; fi
++am__post_remove_distdir = $(am__remove_distdir)
++am__relativize = \
++  dir0=`pwd`; \
++  sed_first='s,^\([^/]*\)/.*$$,\1,'; \
++  sed_rest='s,^[^/]*/*,,'; \
++  sed_last='s,^.*/\([^/]*\)$$,\1,'; \
++  sed_butlast='s,/*[^/]*$$,,'; \
++  while test -n "$$dir1"; do \
++    first=`echo "$$dir1" | sed -e "$$sed_first"`; \
++    if test "$$first" != "."; then \
++      if test "$$first" = ".."; then \
++        dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \
++        dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \
++      else \
++        first2=`echo "$$dir2" | sed -e "$$sed_first"`; \
++        if test "$$first2" = "$$first"; then \
++          dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \
++        else \
++          dir2="../$$dir2"; \
++        fi; \
++        dir0="$$dir0"/"$$first"; \
++      fi; \
++    fi; \
++    dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \
++  done; \
++  reldir="$$dir2"
++GZIP_ENV = --best
++DIST_ARCHIVES = $(distdir).tar.xz
++DIST_TARGETS = dist-xz
++# Exists only to be overridden by the user if desired.
++AM_DISTCHECK_DVI_TARGET = dvi
++distuninstallcheck_listfiles = find . -type f -print
++am__distuninstallcheck_listfiles = $(distuninstallcheck_listfiles) \
++  | sed 's|^\./|$(prefix)/|' | grep -v '$(infodir)/dir$$'
++distcleancheck_listfiles = find . -type f -print
++ACLOCAL = @ACLOCAL@
++AMTAR = @AMTAR@
++AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
++AR = @AR@
++AUTOCONF = @AUTOCONF@
++AUTOHEADER = @AUTOHEADER@
++AUTOMAKE = @AUTOMAKE@
++AWK = @AWK@
++CC = @CC@
++CCDEPMODE = @CCDEPMODE@
++CFLAGS = @CFLAGS@
++CHECK_CFLAGS = @CHECK_CFLAGS@
++CHECK_LIBS = @CHECK_LIBS@
++CPPFLAGS = @CPPFLAGS@
++CSCOPE = @CSCOPE@
++CTAGS = @CTAGS@
++CYGPATH_W = @CYGPATH_W@
++DEFS = @DEFS@
++DEPDIR = @DEPDIR@
++DLLTOOL = @DLLTOOL@
++DOXYGEN = @DOXYGEN@
++DSYMUTIL = @DSYMUTIL@
++DUMPBIN = @DUMPBIN@
++ECHO_C = @ECHO_C@
++ECHO_N = @ECHO_N@
++ECHO_T = @ECHO_T@
++EGREP = @EGREP@
++ETAGS = @ETAGS@
++EXEEXT = @EXEEXT@
++FGREP = @FGREP@
++GCC_CFLAGS = @GCC_CFLAGS@
++GCOV_CFLAGS = @GCOV_CFLAGS@
++GCOV_LDFLAGS = @GCOV_LDFLAGS@
++GNU_LD_FLAGS = @GNU_LD_FLAGS@
++GREP = @GREP@
++INSTALL = @INSTALL@
++INSTALL_DATA = @INSTALL_DATA@
++INSTALL_PROGRAM = @INSTALL_PROGRAM@
++INSTALL_SCRIPT = @INSTALL_SCRIPT@
++INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
++LD = @LD@
++LDFLAGS = @LDFLAGS@
++LIBEVDEV_LT_VERSION = @LIBEVDEV_LT_VERSION@
++LIBOBJS = @LIBOBJS@
++LIBS = @LIBS@
++LIBTOOL = @LIBTOOL@
++LIPO = @LIPO@
++LN_S = @LN_S@
++LTLIBOBJS = @LTLIBOBJS@
++LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
++MAKEINFO = @MAKEINFO@
++MANIFEST_TOOL = @MANIFEST_TOOL@
++MKDIR_P = @MKDIR_P@
++NM = @NM@
++NMEDIT = @NMEDIT@
++OBJDUMP = @OBJDUMP@
++OBJEXT = @OBJEXT@
++OS = @OS@
++OTOOL = @OTOOL@
++OTOOL64 = @OTOOL64@
++PACKAGE = @PACKAGE@
++PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
++PACKAGE_NAME = @PACKAGE_NAME@
++PACKAGE_STRING = @PACKAGE_STRING@
++PACKAGE_TARNAME = @PACKAGE_TARNAME@
++PACKAGE_URL = @PACKAGE_URL@
++PACKAGE_VERSION = @PACKAGE_VERSION@
++PATH_SEPARATOR = @PATH_SEPARATOR@
++PKG_CONFIG = @PKG_CONFIG@
++PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
++PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
++PYTHON = @PYTHON@
++PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
++PYTHON_PLATFORM = @PYTHON_PLATFORM@
++PYTHON_PREFIX = @PYTHON_PREFIX@
++PYTHON_VERSION = @PYTHON_VERSION@
++RANLIB = @RANLIB@
++SED = @SED@
++SET_MAKE = @SET_MAKE@
++SHELL = @SHELL@
++STRIP = @STRIP@
++VALGRIND = @VALGRIND@
++VERSION = @VERSION@
++abs_builddir = @abs_builddir@
++abs_srcdir = @abs_srcdir@
++abs_top_builddir = @abs_top_builddir@
++abs_top_srcdir = @abs_top_srcdir@
++ac_ct_AR = @ac_ct_AR@
++ac_ct_CC = @ac_ct_CC@
++ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
++am__include = @am__include@
++am__leading_dot = @am__leading_dot@
++am__quote = @am__quote@
++am__tar = @am__tar@
++am__untar = @am__untar@
++bindir = @bindir@
++build = @build@
++build_alias = @build_alias@
++build_cpu = @build_cpu@
++build_os = @build_os@
++build_vendor = @build_vendor@
++builddir = @builddir@
++datadir = @datadir@
++datarootdir = @datarootdir@
++docdir = @docdir@
++dvidir = @dvidir@
++exec_prefix = @exec_prefix@
++host = @host@
++host_alias = @host_alias@
++host_cpu = @host_cpu@
++host_os = @host_os@
++host_vendor = @host_vendor@
++htmldir = @htmldir@
++includedir = @includedir@
++infodir = @infodir@
++install_sh = @install_sh@
++libdir = @libdir@
++libexecdir = @libexecdir@
++localedir = @localedir@
++localstatedir = @localstatedir@
++mandir = @mandir@
++mkdir_p = @mkdir_p@
++oldincludedir = @oldincludedir@
++pdfdir = @pdfdir@
++pkgpyexecdir = @pkgpyexecdir@
++pkgpythondir = @pkgpythondir@
++prefix = @prefix@
++program_transform_name = @program_transform_name@
++psdir = @psdir@
++pyexecdir = @pyexecdir@
++pythondir = @pythondir@
++runstatedir = @runstatedir@
++sbindir = @sbindir@
++sharedstatedir = @sharedstatedir@
++srcdir = @srcdir@
++sysconfdir = @sysconfdir@
++target_alias = @target_alias@
++top_build_prefix = @top_build_prefix@
++top_builddir = @top_builddir@
++top_srcdir = @top_srcdir@
++ACLOCAL_AMFLAGS = -I m4 ${ACLOCAL_FLAGS}
++PRINT_DIRECTORY_FLAGS_1 = 
++PRINT_DIRECTORY_FLAGS_0 = --no-print-directory
++PRINT_DIRECTORY_FLAGS_ = $(PRINT_DIRECTORY_FLAGS_$(AM_DEFAULT_VERBOSITY))
++AM_MAKEFLAGS = $(PRINT_DIRECTORY_FLAGS_$(V))
++SUBDIRS = doc libevdev tools test
++pkgconfigdir = $(libdir)/pkgconfig
++pkgconfig_DATA = libevdev.pc
++EXTRA_DIST = libevdev.pc.in meson.build meson_options.txt
++all: config.h
++	$(MAKE) $(AM_MAKEFLAGS) all-recursive
++
++.SUFFIXES:
++am--refresh: Makefile
++	@:
++$(srcdir)/Makefile.in:  $(srcdir)/Makefile.am  $(am__configure_deps)
++	@for dep in $?; do \
++	  case '$(am__configure_deps)' in \
++	    *$$dep*) \
++	      echo ' cd $(srcdir) && $(AUTOMAKE) --foreign'; \
++	      $(am__cd) $(srcdir) && $(AUTOMAKE) --foreign \
++		&& exit 0; \
++	      exit 1;; \
++	  esac; \
++	done; \
++	echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign Makefile'; \
++	$(am__cd) $(top_srcdir) && \
++	  $(AUTOMAKE) --foreign Makefile
++Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
++	@case '$?' in \
++	  *config.status*) \
++	    echo ' $(SHELL) ./config.status'; \
++	    $(SHELL) ./config.status;; \
++	  *) \
++	    echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__maybe_remake_depfiles)'; \
++	    cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__maybe_remake_depfiles);; \
++	esac;
++
++$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
++	$(SHELL) ./config.status --recheck
++
++$(top_srcdir)/configure:  $(am__configure_deps)
++	$(am__cd) $(srcdir) && $(AUTOCONF)
++$(ACLOCAL_M4):  $(am__aclocal_m4_deps)
++	$(am__cd) $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS)
++$(am__aclocal_m4_deps):
++
++config.h: stamp-h1
++	@test -f $@ || rm -f stamp-h1
++	@test -f $@ || $(MAKE) $(AM_MAKEFLAGS) stamp-h1
++
++stamp-h1: $(srcdir)/config.h.in $(top_builddir)/config.status
++	@rm -f stamp-h1
++	cd $(top_builddir) && $(SHELL) ./config.status config.h
++$(srcdir)/config.h.in:  $(am__configure_deps) 
++	($(am__cd) $(top_srcdir) && $(AUTOHEADER))
++	rm -f stamp-h1
++	touch $@
++
++distclean-hdr:
++	-rm -f config.h stamp-h1
++libevdev.pc: $(top_builddir)/config.status $(srcdir)/libevdev.pc.in
++	cd $(top_builddir) && $(SHELL) ./config.status $@
++
++mostlyclean-libtool:
++	-rm -f *.lo
++
++clean-libtool:
++	-rm -rf .libs _libs
++
++distclean-libtool:
++	-rm -f libtool config.lt
++install-pkgconfigDATA: $(pkgconfig_DATA)
++	@$(NORMAL_INSTALL)
++	@list='$(pkgconfig_DATA)'; test -n "$(pkgconfigdir)" || list=; \
++	if test -n "$$list"; then \
++	  echo " $(MKDIR_P) '$(DESTDIR)$(pkgconfigdir)'"; \
++	  $(MKDIR_P) "$(DESTDIR)$(pkgconfigdir)" || exit 1; \
++	fi; \
++	for p in $$list; do \
++	  if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
++	  echo "$$d$$p"; \
++	done | $(am__base_list) | \
++	while read files; do \
++	  echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(pkgconfigdir)'"; \
++	  $(INSTALL_DATA) $$files "$(DESTDIR)$(pkgconfigdir)" || exit $$?; \
++	done
++
++uninstall-pkgconfigDATA:
++	@$(NORMAL_UNINSTALL)
++	@list='$(pkgconfig_DATA)'; test -n "$(pkgconfigdir)" || list=; \
++	files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
++	dir='$(DESTDIR)$(pkgconfigdir)'; $(am__uninstall_files_from_dir)
++
++# This directory's subdirectories are mostly independent; you can cd
++# into them and run 'make' without going through this Makefile.
++# To change the values of 'make' variables: instead of editing Makefiles,
++# (1) if the variable is set in 'config.status', edit 'config.status'
++#     (which will cause the Makefiles to be regenerated when you run 'make');
++# (2) otherwise, pass the desired values on the 'make' command line.
++$(am__recursive_targets):
++	@fail=; \
++	if $(am__make_keepgoing); then \
++	  failcom='fail=yes'; \
++	else \
++	  failcom='exit 1'; \
++	fi; \
++	dot_seen=no; \
++	target=`echo $@ | sed s/-recursive//`; \
++	case "$@" in \
++	  distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \
++	  *) list='$(SUBDIRS)' ;; \
++	esac; \
++	for subdir in $$list; do \
++	  echo "Making $$target in $$subdir"; \
++	  if test "$$subdir" = "."; then \
++	    dot_seen=yes; \
++	    local_target="$$target-am"; \
++	  else \
++	    local_target="$$target"; \
++	  fi; \
++	  ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
++	  || eval $$failcom; \
++	done; \
++	if test "$$dot_seen" = "no"; then \
++	  $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \
++	fi; test -z "$$fail"
++
++ID: $(am__tagged_files)
++	$(am__define_uniq_tagged_files); mkid -fID $$unique
++tags: tags-recursive
++TAGS: tags
++
++tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
++	set x; \
++	here=`pwd`; \
++	if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \
++	  include_option=--etags-include; \
++	  empty_fix=.; \
++	else \
++	  include_option=--include; \
++	  empty_fix=; \
++	fi; \
++	list='$(SUBDIRS)'; for subdir in $$list; do \
++	  if test "$$subdir" = .; then :; else \
++	    test ! -f $$subdir/TAGS || \
++	      set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \
++	  fi; \
++	done; \
++	$(am__define_uniq_tagged_files); \
++	shift; \
++	if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
++	  test -n "$$unique" || unique=$$empty_fix; \
++	  if test $$# -gt 0; then \
++	    $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
++	      "$$@" $$unique; \
++	  else \
++	    $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
++	      $$unique; \
++	  fi; \
++	fi
++ctags: ctags-recursive
++
++CTAGS: ctags
++ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
++	$(am__define_uniq_tagged_files); \
++	test -z "$(CTAGS_ARGS)$$unique" \
++	  || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
++	     $$unique
++
++GTAGS:
++	here=`$(am__cd) $(top_builddir) && pwd` \
++	  && $(am__cd) $(top_srcdir) \
++	  && gtags -i $(GTAGS_ARGS) "$$here"
++cscope: cscope.files
++	test ! -s cscope.files \
++	  || $(CSCOPE) -b -q $(AM_CSCOPEFLAGS) $(CSCOPEFLAGS) -i cscope.files $(CSCOPE_ARGS)
++clean-cscope:
++	-rm -f cscope.files
++cscope.files: clean-cscope cscopelist
++cscopelist: cscopelist-recursive
++
++cscopelist-am: $(am__tagged_files)
++	list='$(am__tagged_files)'; \
++	case "$(srcdir)" in \
++	  [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
++	  *) sdir=$(subdir)/$(srcdir) ;; \
++	esac; \
++	for i in $$list; do \
++	  if test -f "$$i"; then \
++	    echo "$(subdir)/$$i"; \
++	  else \
++	    echo "$$sdir/$$i"; \
++	  fi; \
++	done >> $(top_builddir)/cscope.files
++
++distclean-tags:
++	-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
++	-rm -f cscope.out cscope.in.out cscope.po.out cscope.files
++distdir: $(BUILT_SOURCES)
++	$(MAKE) $(AM_MAKEFLAGS) distdir-am
++
++distdir-am: $(DISTFILES)
++	$(am__remove_distdir)
++	test -d "$(distdir)" || mkdir "$(distdir)"
++	@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
++	topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
++	list='$(DISTFILES)'; \
++	  dist_files=`for file in $$list; do echo $$file; done | \
++	  sed -e "s|^$$srcdirstrip/||;t" \
++	      -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
++	case $$dist_files in \
++	  */*) $(MKDIR_P) `echo "$$dist_files" | \
++			   sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
++			   sort -u` ;; \
++	esac; \
++	for file in $$dist_files; do \
++	  if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
++	  if test -d $$d/$$file; then \
++	    dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
++	    if test -d "$(distdir)/$$file"; then \
++	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
++	    fi; \
++	    if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
++	      cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
++	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
++	    fi; \
++	    cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
++	  else \
++	    test -f "$(distdir)/$$file" \
++	    || cp -p $$d/$$file "$(distdir)/$$file" \
++	    || exit 1; \
++	  fi; \
++	done
++	@list='$(DIST_SUBDIRS)'; for subdir in $$list; do \
++	  if test "$$subdir" = .; then :; else \
++	    $(am__make_dryrun) \
++	      || test -d "$(distdir)/$$subdir" \
++	      || $(MKDIR_P) "$(distdir)/$$subdir" \
++	      || exit 1; \
++	    dir1=$$subdir; dir2="$(distdir)/$$subdir"; \
++	    $(am__relativize); \
++	    new_distdir=$$reldir; \
++	    dir1=$$subdir; dir2="$(top_distdir)"; \
++	    $(am__relativize); \
++	    new_top_distdir=$$reldir; \
++	    echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \
++	    echo "     am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \
++	    ($(am__cd) $$subdir && \
++	      $(MAKE) $(AM_MAKEFLAGS) \
++	        top_distdir="$$new_top_distdir" \
++	        distdir="$$new_distdir" \
++		am__remove_distdir=: \
++		am__skip_length_check=: \
++		am__skip_mode_fix=: \
++	        distdir) \
++	      || exit 1; \
++	  fi; \
++	done
++	-test -n "$(am__skip_mode_fix)" \
++	|| find "$(distdir)" -type d ! -perm -755 \
++		-exec chmod u+rwx,go+rx {} \; -o \
++	  ! -type d ! -perm -444 -links 1 -exec chmod a+r {} \; -o \
++	  ! -type d ! -perm -400 -exec chmod a+r {} \; -o \
++	  ! -type d ! -perm -444 -exec $(install_sh) -c -m a+r {} {} \; \
++	|| chmod -R a+r "$(distdir)"
++dist-gzip: distdir
++	tardir=$(distdir) && $(am__tar) | eval GZIP= gzip $(GZIP_ENV) -c >$(distdir).tar.gz
++	$(am__post_remove_distdir)
++
++dist-bzip2: distdir
++	tardir=$(distdir) && $(am__tar) | BZIP2=$${BZIP2--9} bzip2 -c >$(distdir).tar.bz2
++	$(am__post_remove_distdir)
++
++dist-lzip: distdir
++	tardir=$(distdir) && $(am__tar) | lzip -c $${LZIP_OPT--9} >$(distdir).tar.lz
++	$(am__post_remove_distdir)
++dist-xz: distdir
++	tardir=$(distdir) && $(am__tar) | XZ_OPT=$${XZ_OPT--e} xz -c >$(distdir).tar.xz
++	$(am__post_remove_distdir)
++
++dist-zstd: distdir
++	tardir=$(distdir) && $(am__tar) | zstd -c $${ZSTD_CLEVEL-$${ZSTD_OPT--19}} >$(distdir).tar.zst
++	$(am__post_remove_distdir)
++
++dist-tarZ: distdir
++	@echo WARNING: "Support for distribution archives compressed with" \
++		       "legacy program 'compress' is deprecated." >&2
++	@echo WARNING: "It will be removed altogether in Automake 2.0" >&2
++	tardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z
++	$(am__post_remove_distdir)
++
++dist-shar: distdir
++	@echo WARNING: "Support for shar distribution archives is" \
++	               "deprecated." >&2
++	@echo WARNING: "It will be removed altogether in Automake 2.0" >&2
++	shar $(distdir) | eval GZIP= gzip $(GZIP_ENV) -c >$(distdir).shar.gz
++	$(am__post_remove_distdir)
++
++dist-zip: distdir
++	-rm -f $(distdir).zip
++	zip -rq $(distdir).zip $(distdir)
++	$(am__post_remove_distdir)
++
++dist dist-all:
++	$(MAKE) $(AM_MAKEFLAGS) $(DIST_TARGETS) am__post_remove_distdir='@:'
++	$(am__post_remove_distdir)
++
++# This target untars the dist file and tries a VPATH configuration.  Then
++# it guarantees that the distribution is self-contained by making another
++# tarfile.
++distcheck: dist
++	case '$(DIST_ARCHIVES)' in \
++	*.tar.gz*) \
++	  eval GZIP= gzip $(GZIP_ENV) -dc $(distdir).tar.gz | $(am__untar) ;;\
++	*.tar.bz2*) \
++	  bzip2 -dc $(distdir).tar.bz2 | $(am__untar) ;;\
++	*.tar.lz*) \
++	  lzip -dc $(distdir).tar.lz | $(am__untar) ;;\
++	*.tar.xz*) \
++	  xz -dc $(distdir).tar.xz | $(am__untar) ;;\
++	*.tar.Z*) \
++	  uncompress -c $(distdir).tar.Z | $(am__untar) ;;\
++	*.shar.gz*) \
++	  eval GZIP= gzip $(GZIP_ENV) -dc $(distdir).shar.gz | unshar ;;\
++	*.zip*) \
++	  unzip $(distdir).zip ;;\
++	*.tar.zst*) \
++	  zstd -dc $(distdir).tar.zst | $(am__untar) ;;\
++	esac
++	chmod -R a-w $(distdir)
++	chmod u+w $(distdir)
++	mkdir $(distdir)/_build $(distdir)/_build/sub $(distdir)/_inst
++	chmod a-w $(distdir)
++	test -d $(distdir)/_build || exit 0; \
++	dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \
++	  && dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \
++	  && am__cwd=`pwd` \
++	  && $(am__cd) $(distdir)/_build/sub \
++	  && ../../configure \
++	    $(AM_DISTCHECK_CONFIGURE_FLAGS) \
++	    $(DISTCHECK_CONFIGURE_FLAGS) \
++	    --srcdir=../.. --prefix="$$dc_install_base" \
++	  && $(MAKE) $(AM_MAKEFLAGS) \
++	  && $(MAKE) $(AM_MAKEFLAGS) $(AM_DISTCHECK_DVI_TARGET) \
++	  && $(MAKE) $(AM_MAKEFLAGS) check \
++	  && $(MAKE) $(AM_MAKEFLAGS) install \
++	  && $(MAKE) $(AM_MAKEFLAGS) installcheck \
++	  && $(MAKE) $(AM_MAKEFLAGS) uninstall \
++	  && $(MAKE) $(AM_MAKEFLAGS) distuninstallcheck_dir="$$dc_install_base" \
++	        distuninstallcheck \
++	  && chmod -R a-w "$$dc_install_base" \
++	  && ({ \
++	       (cd ../.. && umask 077 && mkdir "$$dc_destdir") \
++	       && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" install \
++	       && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" uninstall \
++	       && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" \
++	            distuninstallcheck_dir="$$dc_destdir" distuninstallcheck; \
++	      } || { rm -rf "$$dc_destdir"; exit 1; }) \
++	  && rm -rf "$$dc_destdir" \
++	  && $(MAKE) $(AM_MAKEFLAGS) dist \
++	  && rm -rf $(DIST_ARCHIVES) \
++	  && $(MAKE) $(AM_MAKEFLAGS) distcleancheck \
++	  && cd "$$am__cwd" \
++	  || exit 1
++	$(am__post_remove_distdir)
++	@(echo "$(distdir) archives ready for distribution: "; \
++	  list='$(DIST_ARCHIVES)'; for i in $$list; do echo $$i; done) | \
++	  sed -e 1h -e 1s/./=/g -e 1p -e 1x -e '$$p' -e '$$x'
++distuninstallcheck:
++	@test -n '$(distuninstallcheck_dir)' || { \
++	  echo 'ERROR: trying to run $@ with an empty' \
++	       '$$(distuninstallcheck_dir)' >&2; \
++	  exit 1; \
++	}; \
++	$(am__cd) '$(distuninstallcheck_dir)' || { \
++	  echo 'ERROR: cannot chdir into $(distuninstallcheck_dir)' >&2; \
++	  exit 1; \
++	}; \
++	test `$(am__distuninstallcheck_listfiles) | wc -l` -eq 0 \
++	   || { echo "ERROR: files left after uninstall:" ; \
++	        if test -n "$(DESTDIR)"; then \
++	          echo "  (check DESTDIR support)"; \
++	        fi ; \
++	        $(distuninstallcheck_listfiles) ; \
++	        exit 1; } >&2
++distcleancheck: distclean
++	@if test '$(srcdir)' = . ; then \
++	  echo "ERROR: distcleancheck can only run from a VPATH build" ; \
++	  exit 1 ; \
++	fi
++	@test `$(distcleancheck_listfiles) | wc -l` -eq 0 \
++	  || { echo "ERROR: files left in build directory after distclean:" ; \
++	       $(distcleancheck_listfiles) ; \
++	       exit 1; } >&2
++check-am: all-am
++check: check-recursive
++all-am: Makefile $(DATA) config.h
++installdirs: installdirs-recursive
++installdirs-am:
++	for dir in "$(DESTDIR)$(pkgconfigdir)"; do \
++	  test -z "$$dir" || $(MKDIR_P) "$$dir"; \
++	done
++install: install-recursive
++install-exec: install-exec-recursive
++install-data: install-data-recursive
++uninstall: uninstall-recursive
++
++install-am: all-am
++	@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
++
++installcheck: installcheck-recursive
++install-strip:
++	if test -z '$(STRIP)'; then \
++	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
++	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
++	      install; \
++	else \
++	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
++	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
++	    "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
++	fi
++mostlyclean-generic:
++
++clean-generic:
++
++distclean-generic:
++	-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
++	-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
++
++maintainer-clean-generic:
++	@echo "This command is intended for maintainers to use"
++	@echo "it deletes files that may require special tools to rebuild."
++clean: clean-recursive
++
++clean-am: clean-generic clean-libtool mostlyclean-am
++
++distclean: distclean-recursive
++	-rm -f $(am__CONFIG_DISTCLEAN_FILES)
++	-rm -f Makefile
++distclean-am: clean-am distclean-generic distclean-hdr \
++	distclean-libtool distclean-tags
++
++dvi: dvi-recursive
++
++dvi-am:
++
++html: html-recursive
++
++html-am:
++
++info: info-recursive
++
++info-am:
++
++install-data-am: install-pkgconfigDATA
++
++install-dvi: install-dvi-recursive
++
++install-dvi-am:
++
++install-exec-am:
++
++install-html: install-html-recursive
++
++install-html-am:
++
++install-info: install-info-recursive
++
++install-info-am:
++
++install-man:
++
++install-pdf: install-pdf-recursive
++
++install-pdf-am:
++
++install-ps: install-ps-recursive
++
++install-ps-am:
++
++installcheck-am:
++
++maintainer-clean: maintainer-clean-recursive
++	-rm -f $(am__CONFIG_DISTCLEAN_FILES)
++	-rm -rf $(top_srcdir)/autom4te.cache
++	-rm -f Makefile
++maintainer-clean-am: distclean-am maintainer-clean-generic
++
++mostlyclean: mostlyclean-recursive
++
++mostlyclean-am: mostlyclean-generic mostlyclean-libtool
++
++pdf: pdf-recursive
++
++pdf-am:
++
++ps: ps-recursive
++
++ps-am:
++
++uninstall-am: uninstall-pkgconfigDATA
++
++.MAKE: $(am__recursive_targets) all install-am install-strip
++
++.PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am \
++	am--refresh check check-am clean clean-cscope clean-generic \
++	clean-libtool cscope cscopelist-am ctags ctags-am dist \
++	dist-all dist-bzip2 dist-gzip dist-lzip dist-shar dist-tarZ \
++	dist-xz dist-zip dist-zstd distcheck distclean \
++	distclean-generic distclean-hdr distclean-libtool \
++	distclean-tags distcleancheck distdir distuninstallcheck dvi \
++	dvi-am html html-am info info-am install install-am \
++	install-data install-data-am install-dvi install-dvi-am \
++	install-exec install-exec-am install-html install-html-am \
++	install-info install-info-am install-man install-pdf \
++	install-pdf-am install-pkgconfigDATA install-ps install-ps-am \
++	install-strip installcheck installcheck-am installdirs \
++	installdirs-am maintainer-clean maintainer-clean-generic \
++	mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \
++	ps ps-am tags tags-am uninstall uninstall-am \
++	uninstall-pkgconfigDATA
++
++.PRECIOUS: Makefile
++
++
++# Tell versions [3.59,3.63) of GNU make to not export all variables.
++# Otherwise a system limit (for SysV at least) may be exceeded.
++.NOEXPORT:
+diff -Naur third-party-libevdev-bak/OAT.xml third-party-new/OAT.xml
+--- third-party-libevdev-bak/OAT.xml	2023-03-28 10:49:53.360511300 +0800
++++ third-party-new/OAT.xml	2023-04-03 14:19:59.118242900 +0800
+@@ -1,5 +1,5 @@
+ 
+-
+         
+         
+-        
++        
+         
+         libevdev: Compatibility and Behavior across kernel versions
+         
+@@ -25,7 +25,7 @@
+         
+@@ -36,10 +36,10 @@
+                         
+
+ +- ++ + + +@@ -102,7 +102,7 @@ + + + +diff -Naur third-party-libevdev-bak/doc/html/deprecated.html third-party-new/doc/html/deprecated.html +--- third-party-libevdev-bak/doc/html/deprecated.html 2023-03-28 10:49:53.372511500 +0800 ++++ third-party-new/doc/html/deprecated.html 2023-04-01 15:53:28.368499700 +0800 +@@ -6,7 +6,7 @@ + + + +- ++ + + libevdev: Deprecated List + +@@ -25,7 +25,7 @@ + +@@ -36,10 +36,10 @@ +
+
+ +- ++ + + +@@ -73,12 +73,12 @@ +
+
+
++
Global libevdev_get_log_priority (void)
++
Use per-context logging instead, see libevdev_set_device_log_function().
+
Global libevdev_set_log_function (libevdev_log_func_t logfunc, void *data)
+
Use per-context logging instead, see libevdev_set_device_log_function().
+
Global libevdev_set_log_priority (enum libevdev_log_priority priority)
+-
Use per-context logging instead, see libevdev_set_device_log_function().
+-
Global libevdev_get_log_priority (void)
+-
Use per-context logging instead, see libevdev_set_device_log_function().
++
Use per-context logging instead, see libevdev_set_device_log_function().
+
+
+
+@@ -92,7 +92,7 @@ + + + +diff -Naur third-party-libevdev-bak/doc/html/dir_237a012ffe1a208b10d31c74b4ef545e.html third-party-new/doc/html/dir_237a012ffe1a208b10d31c74b4ef545e.html +--- third-party-libevdev-bak/doc/html/dir_237a012ffe1a208b10d31c74b4ef545e.html 2023-03-28 10:49:53.372511500 +0800 ++++ third-party-new/doc/html/dir_237a012ffe1a208b10d31c74b4ef545e.html 2023-04-01 15:53:39.853670200 +0800 +@@ -6,9 +6,9 @@ + + + +- ++ + +- libevdev: /home/whot/code/libevdev/release/libevdev/build.uQTRHZxVc0/libevdev Directory Reference ++ libevdev: /home/whot/code/libevdev/release/libevdev/build.eXgVwUduJp/libevdev Directory Reference + + + +@@ -25,7 +25,7 @@ + +@@ -36,10 +36,10 @@ +
+
+ +- ++ + + +@@ -95,7 +95,7 @@ + + + +diff -Naur third-party-libevdev-bak/doc/html/doxygen.css third-party-new/doc/html/doxygen.css +--- third-party-libevdev-bak/doc/html/doxygen.css 2023-03-28 10:49:53.372511500 +0800 ++++ third-party-new/doc/html/doxygen.css 2023-04-01 15:54:04.290717000 +0800 +@@ -1,4 +1,4 @@ +-/* The standard CSS for doxygen 1.8.20 */ ++/* The standard CSS for doxygen 1.9.1 */ + + body, table, div, p, dl { + font: 400 14px/22px Roboto,sans-serif; +@@ -103,30 +103,96 @@ + } + + span.legend { +- font-size: 70%; +- text-align: center; ++ font-size: 70%; ++ text-align: center; + } + + h3.version { +- font-size: 90%; +- text-align: center; ++ font-size: 90%; ++ text-align: center; + } + +-div.qindex, div.navtab{ +- background-color: #EBEFF6; +- border: 1px solid #A3B4D7; +- text-align: center; ++div.navtab { ++ border-right: 1px solid #A3B4D7; ++ padding-right: 15px; ++ text-align: right; ++ line-height: 110%; ++} ++ ++div.navtab table { ++ border-spacing: 0; ++} ++ ++td.navtab { ++ padding-right: 6px; ++ padding-left: 6px; ++} ++td.navtabHL { ++ background-image: url('tab_a.png'); ++ background-repeat:repeat-x; ++ padding-right: 6px; ++ padding-left: 6px; ++} ++ ++td.navtabHL a, td.navtabHL a:visited { ++ color: #fff; ++ text-shadow: 0px 1px 1px rgba(0, 0, 0, 1.0); ++} ++ ++a.navtab { ++ font-weight: bold; + } + +-div.qindex, div.navpath { ++div.qindex{ ++ text-align: center; + width: 100%; + line-height: 140%; ++ font-size: 130%; ++ color: #A0A0A0; + } + +-div.navtab { +- margin-right: 15px; ++dt.alphachar{ ++ font-size: 180%; ++ font-weight: bold; ++} ++ ++.alphachar a{ ++ color: black; ++} ++ ++.alphachar a:hover, .alphachar a:visited{ ++ text-decoration: none; + } + ++.classindex dl { ++ padding: 25px; ++ column-count:1 ++} ++ ++.classindex dd { ++ display:inline-block; ++ margin-left: 50px; ++ width: 90%; ++ line-height: 1.15em; ++} ++ ++.classindex dl.odd { ++ background-color: #F8F9FC; ++} ++ ++@media(min-width: 1120px) { ++ .classindex dl { ++ column-count:2 ++ } ++} ++ ++@media(min-width: 1320px) { ++ .classindex dl { ++ column-count:3 ++ } ++} ++ ++ + /* @group Link Styling */ + + a { +@@ -143,17 +209,6 @@ + text-decoration: underline; + } + +-a.qindex { +- font-weight: bold; +-} +- +-a.qindexHL { +- font-weight: bold; +- background-color: #9CAFD4; +- color: #FFFFFF; +- border: 1px double #869DCA; +-} +- + .contents a.qindexHL:visited { + color: #FFFFFF; + } +@@ -1426,6 +1481,12 @@ + margin-left: 45px; + } + ++span.emoji { ++ /* font family used at the site: https://unicode.org/emoji/charts/full-emoji-list.html ++ * font-family: "Noto Color Emoji", "Apple Color Emoji", "Segoe UI Emoji", Times, Symbola, Aegyptus, Code2000, Code2001, Code2002, Musica, serif, LastResort; ++ */ ++} ++ + .PageDocRTL-title div.toc li.level1 { + margin-left: 0 !important; + margin-right: 0; +diff -Naur third-party-libevdev-bak/doc/html/files.html third-party-new/doc/html/files.html +--- third-party-libevdev-bak/doc/html/files.html 2023-03-28 10:49:53.372511500 +0800 ++++ third-party-new/doc/html/files.html 2023-04-01 15:54:29.612789500 +0800 +@@ -6,7 +6,7 @@ + + + +- ++ + + libevdev: File List + +@@ -25,7 +25,7 @@ + +@@ -36,10 +36,10 @@ +
+
+ +- ++ + + +@@ -90,7 +90,7 @@ + + + +diff -Naur third-party-libevdev-bak/doc/html/globals.html third-party-new/doc/html/globals.html +--- third-party-libevdev-bak/doc/html/globals.html 2023-03-28 10:49:53.376511600 +0800 ++++ third-party-new/doc/html/globals.html 2023-04-01 15:54:54.760637400 +0800 +@@ -6,7 +6,7 @@ + + + +- ++ + + libevdev: Globals + +@@ -25,7 +25,7 @@ + +@@ -36,10 +36,10 @@ +
+
+ +- ++ + + +@@ -416,7 +416,7 @@ + + + +diff -Naur third-party-libevdev-bak/doc/html/globals_defs.html third-party-new/doc/html/globals_defs.html +--- third-party-libevdev-bak/doc/html/globals_defs.html 2023-03-28 10:49:53.376511600 +0800 ++++ third-party-new/doc/html/globals_defs.html 2023-04-01 15:55:04.052239300 +0800 +@@ -6,7 +6,7 @@ + + + +- ++ + + libevdev: Globals + +@@ -25,7 +25,7 @@ + +@@ -36,10 +36,10 @@ +
+
+ +- ++ + + +@@ -87,7 +87,7 @@ + + + +diff -Naur third-party-libevdev-bak/doc/html/globals_enum.html third-party-new/doc/html/globals_enum.html +--- third-party-libevdev-bak/doc/html/globals_enum.html 2023-03-28 10:49:53.376511600 +0800 ++++ third-party-new/doc/html/globals_enum.html 2023-04-01 15:55:13.962503800 +0800 +@@ -6,7 +6,7 @@ + + + +- ++ + + libevdev: Globals + +@@ -25,7 +25,7 @@ + +@@ -36,10 +36,10 @@ +
+
+ +- ++ + + +@@ -99,7 +99,7 @@ + + + +diff -Naur third-party-libevdev-bak/doc/html/globals_eval.html third-party-new/doc/html/globals_eval.html +--- third-party-libevdev-bak/doc/html/globals_eval.html 2023-03-28 10:49:53.376511600 +0800 ++++ third-party-new/doc/html/globals_eval.html 2023-04-01 15:55:22.112416100 +0800 +@@ -6,7 +6,7 @@ + + + +- ++ + + libevdev: Globals + +@@ -25,7 +25,7 @@ + +@@ -36,10 +36,10 @@ +
+
+ +- ++ + + +@@ -123,7 +123,7 @@ + + + +diff -Naur third-party-libevdev-bak/doc/html/globals_func.html third-party-new/doc/html/globals_func.html +--- third-party-libevdev-bak/doc/html/globals_func.html 2023-03-28 10:49:53.376511600 +0800 ++++ third-party-new/doc/html/globals_func.html 2023-04-01 15:58:47.652290800 +0800 +@@ -6,7 +6,7 @@ + + + +- ++ + + libevdev: Globals + +@@ -25,7 +25,7 @@ + +@@ -36,10 +36,10 @@ +
+
+ +- ++ + + +@@ -344,7 +344,7 @@ + + + +diff -Naur third-party-libevdev-bak/doc/html/globals_type.html third-party-new/doc/html/globals_type.html +--- third-party-libevdev-bak/doc/html/globals_type.html 2023-03-28 10:49:53.376511600 +0800 ++++ third-party-new/doc/html/globals_type.html 2023-04-01 15:59:25.040970100 +0800 +@@ -6,7 +6,7 @@ + + + +- ++ + + libevdev: Globals + +@@ -25,7 +25,7 @@ + +@@ -36,10 +36,10 @@ +
+
+ +- ++ + + +@@ -87,7 +87,7 @@ + + + +diff -Naur third-party-libevdev-bak/doc/html/group__bits.html third-party-new/doc/html/group__bits.html +--- third-party-libevdev-bak/doc/html/group__bits.html 2023-03-28 10:49:53.376511600 +0800 ++++ third-party-new/doc/html/group__bits.html 2023-04-01 15:59:37.771463600 +0800 +@@ -6,7 +6,7 @@ + + + +- ++ + + libevdev: Querying device capabilities + +@@ -25,7 +25,7 @@ + +@@ -36,10 +36,10 @@ +
+
+ +- ++ + + +@@ -179,6 +179,9 @@ +

This is a shortcut for

+
+
val = libevdev_get_event_value(dev, t, c);
++
int libevdev_has_event_type(const struct libevdev *dev, unsigned int type)
++
int libevdev_get_event_value(const struct libevdev *dev, unsigned int type, unsigned int code)
Behaviour of this function is undefined if the device does not provide the event.
++
int libevdev_has_event_code(const struct libevdev *dev, unsigned int type, unsigned int code)
+
Parameters
+
+ +@@ -489,7 +492,7 @@ +
+ +

Behaviour of this function is undefined if the device does not provide the event.

+-

If the device supports ABS_MT_SLOT, the value returned for any ABS_MT_* event code is the value of the currently active slot. You should use libevdev_get_slot_value() instead.

++

If the device supports ABS_MT_SLOT, the value returned for any ABS_MT_* event code is undefined. Use libevdev_get_slot_value() instead.

+
Parameters
+
devThe evdev device, already initialized with libevdev_set_fd()
+ +@@ -865,9 +868,6 @@ + + + +-
int libevdev_has_event_code(const struct libevdev *dev, unsigned int type, unsigned int code)
+-
int libevdev_get_event_value(const struct libevdev *dev, unsigned int type, unsigned int code)
Behaviour of this function is undefined if the device does not provide the event.
+-
int libevdev_has_event_type(const struct libevdev *dev, unsigned int type)
+ + + +@@ -878,7 +878,7 @@ + + + +diff -Naur third-party-libevdev-bak/doc/html/group__events.html third-party-new/doc/html/group__events.html +--- third-party-libevdev-bak/doc/html/group__events.html 2023-03-28 10:49:53.376511600 +0800 ++++ third-party-new/doc/html/group__events.html 2023-04-01 15:59:49.270095000 +0800 +@@ -6,7 +6,7 @@ + + + +- ++ + + libevdev: Event handling + +@@ -25,7 +25,7 @@ + +@@ -36,10 +36,10 @@ +
+
+ +- ++ + + +@@ -81,14 +81,14 @@ +
devThe evdev device, already initialized with libevdev_set_fd()
+ +- + +- + +

+ Enumerations

enum  libevdev_read_flag { LIBEVDEV_READ_FLAG_SYNC, +-LIBEVDEV_READ_FLAG_NORMAL, +-LIBEVDEV_READ_FLAG_FORCE_SYNC, +-LIBEVDEV_READ_FLAG_BLOCKING ++
enum  libevdev_read_flag { LIBEVDEV_READ_FLAG_SYNC ++, LIBEVDEV_READ_FLAG_NORMAL ++, LIBEVDEV_READ_FLAG_FORCE_SYNC ++, LIBEVDEV_READ_FLAG_BLOCKING + }
 
enum  libevdev_read_status { LIBEVDEV_READ_STATUS_SUCCESS, +-LIBEVDEV_READ_STATUS_SYNC ++
enum  libevdev_read_status { LIBEVDEV_READ_STATUS_SUCCESS ++, LIBEVDEV_READ_STATUS_SYNC + }
 
+@@ -263,7 +263,7 @@ + + + +diff -Naur third-party-libevdev-bak/doc/html/group__init.html third-party-new/doc/html/group__init.html +--- third-party-libevdev-bak/doc/html/group__init.html 2023-03-28 10:49:53.376511600 +0800 ++++ third-party-new/doc/html/group__init.html 2023-04-01 16:00:25.613680900 +0800 +@@ -6,7 +6,7 @@ + + + +- ++ + + libevdev: Initialization and setup + +@@ -25,7 +25,7 @@ + +@@ -36,10 +36,10 @@ +
+
+ +- ++ + + +@@ -81,8 +81,8 @@ +
+ +- + +

+ Enumerations

enum  libevdev_grab_mode { LIBEVDEV_GRAB, +-LIBEVDEV_UNGRAB ++
enum  libevdev_grab_mode { LIBEVDEV_GRAB ++, LIBEVDEV_UNGRAB + }
 
+@@ -120,10 +120,13 @@ +
return ENOMEM;
+
+
err = libevdev_set_fd(dev, fd);
+-
if (err < 0) {
++
if (err < 0)
+
printf("Failed (errno %d): %s\n", -err, strerror(-err));
+
+ ++
struct libevdev * libevdev_new(void)
Initialize a new libevdev device.
++
int libevdev_set_fd(struct libevdev *dev, int fd)
Set the fd for this struct and initialize internal data.
++
void libevdev_free(struct libevdev *dev)
Clean up and free the libevdev struct.
+

libevdev_set_fd() is the central call and initializes the internal structs for the device at the given fd. libevdev functions will fail if called before libevdev_set_fd() unless documented otherwise.

+

Enumeration Type Documentation

+ +@@ -181,6 +184,11 @@ + + +
; // noop
++
int libevdev_next_event(struct libevdev *dev, unsigned int flags, struct input_event *ev)
Get the next event from the device.
++
@ LIBEVDEV_READ_STATUS_SYNC
Depending on the libevdev_next_event() read flag:
Definition: libevdev.h:1090
++
@ LIBEVDEV_READ_FLAG_SYNC
Process data in sync mode.
Definition: libevdev.h:761
++
@ LIBEVDEV_READ_FLAG_FORCE_SYNC
Pretend the next event is a SYN_DROPPED and require the caller to sync.
Definition: libevdev.h:763
++
int libevdev_change_fd(struct libevdev *dev, int fd)
Change the fd for this device, without re-reading the actual device.
+

The fd may be open in O_RDONLY or O_RDWR.

+

After changing the fd, the device is assumed ungrabbed and a caller must call libevdev_grab() again.

+

It is an error to call this function before calling libevdev_set_fd().

+@@ -409,14 +417,6 @@ + + + +-
struct libevdev * libevdev_new(void)
Initialize a new libevdev device.
+-
int libevdev_set_fd(struct libevdev *dev, int fd)
Set the fd for this struct and initialize internal data.
+-
void libevdev_free(struct libevdev *dev)
Clean up and free the libevdev struct.
+-
@ LIBEVDEV_READ_FLAG_FORCE_SYNC
Pretend the next event is a SYN_DROPPED and require the caller to sync.
Definition: libevdev.h:760
+-
@ LIBEVDEV_READ_STATUS_SYNC
Depending on the libevdev_next_event() read flag:
Definition: libevdev.h:1087
+-
int libevdev_next_event(struct libevdev *dev, unsigned int flags, struct input_event *ev)
Get the next event from the device.
+-
int libevdev_change_fd(struct libevdev *dev, int fd)
Change the fd for this device, without re-reading the actual device.
+-
@ LIBEVDEV_READ_FLAG_SYNC
Process data in sync mode.
Definition: libevdev.h:758
+ + + +@@ -427,7 +427,7 @@ + + + +diff -Naur third-party-libevdev-bak/doc/html/group__kernel.html third-party-new/doc/html/group__kernel.html +--- third-party-libevdev-bak/doc/html/group__kernel.html 2023-03-28 10:49:53.376511600 +0800 ++++ third-party-new/doc/html/group__kernel.html 2023-04-01 16:00:37.939522800 +0800 +@@ -6,7 +6,7 @@ + + + +- ++ + + libevdev: Modifying the appearance or capabilities of the device + +@@ -25,7 +25,7 @@ + +@@ -36,10 +36,10 @@ +
+
+ +- ++ + + +@@ -81,8 +81,8 @@ +
+ +- + +

+ Enumerations

enum  libevdev_led_value { LIBEVDEV_LED_ON, +-LIBEVDEV_LED_OFF ++
enum  libevdev_led_value { LIBEVDEV_LED_ON ++, LIBEVDEV_LED_OFF + }
 
+@@ -583,6 +583,9 @@ +
+
LED_CAPSL, LIBEVDEV_LED_OFF,
+
-1);
++
int libevdev_kernel_set_led_values(struct libevdev *dev,...)
Turn multiple LEDs on or off simultaneously.
++
@ LIBEVDEV_LED_OFF
Turn the LED off.
Definition: libevdev.h:1921
++
@ LIBEVDEV_LED_ON
Turn the LED on.
Definition: libevdev.h:1920
+

If any LED code or value is invalid, this function returns -EINVAL and no LEDs are modified.

+
Note
enabling an LED requires write permissions on the device's file descriptor.
+
Parameters
+@@ -1309,9 +1312,6 @@ + + + +-
@ LIBEVDEV_LED_OFF
Turn the LED off.
Definition: libevdev.h:1919
+-
int libevdev_kernel_set_led_values(struct libevdev *dev,...)
Turn multiple LEDs on or off simultaneously.
+-
@ LIBEVDEV_LED_ON
Turn the LED on.
Definition: libevdev.h:1918
+ + + +@@ -1322,7 +1322,7 @@ + + + +diff -Naur third-party-libevdev-bak/doc/html/group__logging.html third-party-new/doc/html/group__logging.html +--- third-party-libevdev-bak/doc/html/group__logging.html 2023-03-28 10:49:53.376511600 +0800 ++++ third-party-new/doc/html/group__logging.html 2023-04-01 16:00:49.150108500 +0800 +@@ -6,7 +6,7 @@ + + + +- ++ + + libevdev: Library logging facilities + +@@ -25,7 +25,7 @@ + +@@ -36,10 +36,10 @@ +
+
+ +- ++ + + +@@ -91,9 +91,9 @@ +
+ +- + +

+ Enumerations

enum  libevdev_log_priority { LIBEVDEV_LOG_ERROR, +-LIBEVDEV_LOG_INFO, +-LIBEVDEV_LOG_DEBUG ++
enum  libevdev_log_priority { LIBEVDEV_LOG_ERROR ++, LIBEVDEV_LOG_INFO ++, LIBEVDEV_LOG_DEBUG + }
 
+@@ -364,7 +364,7 @@ + + + +diff -Naur third-party-libevdev-bak/doc/html/group__misc.html third-party-new/doc/html/group__misc.html +--- third-party-libevdev-bak/doc/html/group__misc.html 2023-03-28 10:49:53.376511600 +0800 ++++ third-party-new/doc/html/group__misc.html 2023-04-01 16:01:08.704374400 +0800 +@@ -6,7 +6,7 @@ + + + +- ++ + + libevdev: Miscellaneous helper functions + +@@ -25,7 +25,7 @@ + +@@ -36,10 +36,10 @@ +
+
+ +- ++ + + +@@ -365,7 +365,7 @@ + +

Helper function to check if an event is of a specific type and code.

+

This is virtually the same as:

 ev->type == type && ev->code == code
+-

with the exception that some sanity checks are performed to ensure type and code are valid.

++

with the exception that some sanity checks are performed to ensure type and code are valid.

+
Note
The ranges for types and codes are compiled into libevdev. If the kernel changes the max value, libevdev will not automatically pick these up.
+
Parameters
+
+@@ -407,7 +407,7 @@ + +

Helper function to check if an event is of a specific type.

+

This is virtually the same as:

 ev->type == type
+-

with the exception that some sanity checks are performed to ensure type is valid.

++

with the exception that some sanity checks are performed to ensure type is valid.

+
Note
The ranges for types are compiled into libevdev. If the kernel changes the max value, libevdev will not automatically pick these up.
+
Parameters
+
+@@ -866,7 +866,7 @@ + + + +diff -Naur third-party-libevdev-bak/doc/html/group__mt.html third-party-new/doc/html/group__mt.html +--- third-party-libevdev-bak/doc/html/group__mt.html 2023-03-28 10:49:53.376511600 +0800 ++++ third-party-new/doc/html/group__mt.html 2023-04-01 16:01:21.378960200 +0800 +@@ -6,7 +6,7 @@ + + + +- ++ + + libevdev: Multi-touch related functions + +@@ -25,7 +25,7 @@ + +@@ -36,10 +36,10 @@ +
+
+ +- ++ + + +@@ -144,6 +144,9 @@ +
libevdev_has_event_code(dev, EV_ABS, c) &&
+
slot < device->number_of_slots)
+
val = libevdev_get_slot_value(dev, slot, c);
++
int libevdev_has_event_type(const struct libevdev *dev, unsigned int type)
++
int libevdev_has_event_code(const struct libevdev *dev, unsigned int type, unsigned int code)
++
int libevdev_get_slot_value(const struct libevdev *dev, unsigned int slot, unsigned int code)
Return the current value of the code for the given slot.
+
Parameters
+
+ +@@ -265,9 +268,6 @@ + + + +-
int libevdev_has_event_code(const struct libevdev *dev, unsigned int type, unsigned int code)
+-
int libevdev_get_slot_value(const struct libevdev *dev, unsigned int slot, unsigned int code)
Return the current value of the code for the given slot.
+-
int libevdev_has_event_type(const struct libevdev *dev, unsigned int type)
+ + + +@@ -278,7 +278,7 @@ + + + +diff -Naur third-party-libevdev-bak/doc/html/group__uinput.html third-party-new/doc/html/group__uinput.html +--- third-party-libevdev-bak/doc/html/group__uinput.html 2023-03-28 10:49:53.376511600 +0800 ++++ third-party-new/doc/html/group__uinput.html 2023-04-01 16:01:45.668914500 +0800 +@@ -6,7 +6,7 @@ + + + +- ++ + + libevdev: uinput device creation + +@@ -25,7 +25,7 @@ + +@@ -36,10 +36,10 @@ +
+
+ +- ++ + + +@@ -103,14 +103,13 @@ +

Creation of uinput devices based on existing libevdev devices.

+

These functions help to create uinput devices that emulate libevdev devices. In the simplest form it serves to duplicate an existing device:

+
int err;
+-
int fd, new_fd, uifd;
++
int fd, uifd;
+
struct libevdev *dev;
+
struct libevdev_uinput *uidev;
+-
struct input_event ev[2];
+
+
fd = open("/dev/input/event0", O_RDONLY);
+
if (fd < 0)
+-
return err;
++
return -errno;
+
+
err = libevdev_new_from_fd(fd, &dev);
+
if (err != 0)
+@@ -128,7 +127,7 @@ +
err = libevdev_uinput_write_event(uidev, EV_REL, REL_X, -1);
+
if (err != 0)
+
return err;
+-
libevdev_uinput_write_event(uidev, EV_SYN, SYN_REPORT, 0);
++
err = libevdev_uinput_write_event(uidev, EV_SYN, SYN_REPORT, 0);
+
if (err != 0)
+
return err;
+
+@@ -136,6 +135,11 @@ + +
close(uifd);
+
close(fd);
++
int libevdev_new_from_fd(int fd, struct libevdev **dev)
Initialize a new libevdev device from the given fd.
++
void libevdev_free(struct libevdev *dev)
Clean up and free the libevdev struct.
++
int libevdev_uinput_write_event(const struct libevdev_uinput *uinput_dev, unsigned int type, unsigned int code, int value)
Post an event through the uinput device.
++
void libevdev_uinput_destroy(struct libevdev_uinput *uinput_dev)
Destroy a previously created uinput device and free associated memory.
++
int libevdev_uinput_create_from_device(const struct libevdev *dev, int uinput_fd, struct libevdev_uinput **uinput_dev)
Create a uinput device based on the given libevdev device.
+

Alternatively, a device can be constructed from scratch:

+
int err;
+
struct libevdev *dev;
+@@ -160,6 +164,11 @@ +
// ... do something ...
+
+ ++
struct libevdev * libevdev_new(void)
Initialize a new libevdev device.
++
int libevdev_enable_event_code(struct libevdev *dev, unsigned int type, unsigned int code, const void *data)
Forcibly enable an event code on this device, even if the underlying device does not support it.
++
int libevdev_enable_event_type(struct libevdev *dev, unsigned int type)
Forcibly enable an event type on this device, even if the underlying device does not support it.
++
void libevdev_set_name(struct libevdev *dev, const char *name)
Change the device's name as returned by libevdev_get_name().
++
@ LIBEVDEV_UINPUT_OPEN_MANAGED
let libevdev open and close /dev/uinput
Definition: libevdev-uinput.h:114
+

Function Documentation

+ +

◆ libevdev_uinput_create_from_device()

+@@ -318,9 +327,9 @@ +
+ +

Return the syspath representing this uinput device.

+-

If the UI_GET_SYSNAME ioctl not available, libevdev makes an educated guess. The UI_GET_SYSNAME ioctl is available since Linux 3.15.

++

If the UI_GET_SYSNAME ioctl is not available, libevdev makes an educated guess. The UI_GET_SYSNAME ioctl is available since Linux 3.15.

+

The syspath returned is the one of the input node itself (e.g. /sys/devices/virtual/input/input123), not the syspath of the device node returned with libevdev_uinput_get_devnode().

+-
Note
This function may return NULL if UI_GET_SYSNAME is not available. In that case, libevdev uses ctime and the device name to guess devices. To avoid false positives, wait at least wait at least 1.5s between creating devices that have the same name.
++
Note
This function may return NULL if UI_GET_SYSNAME is not available. In that case, libevdev uses ctime and the device name to guess devices. To avoid false positives, wait at least 1.5s between creating devices that have the same name.
+
+ FreeBSD does not have sysfs, on FreeBSD this function always returns NULL.
+
Parameters
+@@ -388,16 +397,6 @@ +
+
+ +-
int libevdev_uinput_create_from_device(const struct libevdev *dev, int uinput_fd, struct libevdev_uinput **uinput_dev)
Create a uinput device based on the given libevdev device.
+-
int libevdev_enable_event_type(struct libevdev *dev, unsigned int type)
Forcibly enable an event type on this device, even if the underlying device does not support it.
+-
@ LIBEVDEV_UINPUT_OPEN_MANAGED
let libevdev open and close /dev/uinput
Definition: libevdev-uinput.h:113
+-
struct libevdev * libevdev_new(void)
Initialize a new libevdev device.
+-
void libevdev_uinput_destroy(struct libevdev_uinput *uinput_dev)
Destroy a previously created uinput device and free associated memory.
+-
void libevdev_free(struct libevdev *dev)
Clean up and free the libevdev struct.
+-
void libevdev_set_name(struct libevdev *dev, const char *name)
Change the device's name as returned by libevdev_get_name().
+-
int libevdev_uinput_write_event(const struct libevdev_uinput *uinput_dev, unsigned int type, unsigned int code, int value)
Post an event through the uinput device.
+-
int libevdev_enable_event_code(struct libevdev *dev, unsigned int type, unsigned int code, const void *data)
Forcibly enable an event code on this device, even if the underlying device does not support it.
+-
int libevdev_new_from_fd(int fd, struct libevdev **dev)
Initialize a new libevdev device from the given fd.
+ + + +@@ -408,7 +407,7 @@ + + + +diff -Naur third-party-libevdev-bak/doc/html/index.html third-party-new/doc/html/index.html +--- third-party-libevdev-bak/doc/html/index.html 2023-03-28 10:49:53.376511600 +0800 ++++ third-party-new/doc/html/index.html 2023-04-01 16:18:18.545836000 +0800 +@@ -6,7 +6,7 @@ + + + +- ++ + + libevdev: Main Page + +@@ -25,7 +25,7 @@ + +@@ -36,10 +36,10 @@ +
+
+ +- ++ + + +@@ -94,9 +94,9 @@ +

+ Where does libevdev sit?

+

libevdev is essentially a read(2) on steroids for /dev/input/eventX devices. It sits below the process that handles input events, in between the kernel and that process. In the simplest case, e.g. an evtest-like tool the stack would look like this:

 kernel → libevdev → evtest
+-

For X.Org input modules, the stack would look like this:

 kernel → libevdev → xf86-input-evdev → X server → X client
+-

For anything using libinput (e.g. most Wayland compositors), the stack the stack would look like this:

 kernel → libevdev → libinput → Compositor → Wayland client
+-

libevdev does not have knowledge of X clients or Wayland clients, it is too low in the stack.

++

For X.Org input modules, the stack would look like this:

 kernel → libevdev → xf86-input-evdev → X server → X client
++

For anything using libinput (e.g. most Wayland compositors), the stack the stack would look like this:

 kernel → libevdev → libinput → Compositor → Wayland client
++

libevdev does not have knowledge of X clients or Wayland clients, it is too low in the stack.

+

+ Example

+

Below is a simple example that shows how libevdev could be used. This example opens a device, checks for relative axes and a left mouse button and if it finds them monitors the device to print the event.

+@@ -130,6 +130,17 @@ +
libevdev_event_code_get_name(ev.type, ev.code),
+
ev.value);
+
} while (rc == 1 || rc == 0 || rc == -EAGAIN);
++
int libevdev_get_id_vendor(const struct libevdev *dev)
++
int libevdev_get_id_product(const struct libevdev *dev)
++
int libevdev_has_event_type(const struct libevdev *dev, unsigned int type)
++
int libevdev_get_id_bustype(const struct libevdev *dev)
++
int libevdev_has_event_code(const struct libevdev *dev, unsigned int type, unsigned int code)
++
const char * libevdev_get_name(const struct libevdev *dev)
Retrieve the device's name, either as set by the caller or as read from the kernel.
++
int libevdev_next_event(struct libevdev *dev, unsigned int flags, struct input_event *ev)
Get the next event from the device.
++
@ LIBEVDEV_READ_FLAG_NORMAL
Process data in normal mode.
Definition: libevdev.h:762
++
int libevdev_new_from_fd(int fd, struct libevdev **dev)
Initialize a new libevdev device from the given fd.
++
const char * libevdev_event_code_get_name(unsigned int type, unsigned int code)
++
const char * libevdev_event_type_get_name(unsigned int type)
+

A more complete example is available with the libevdev-events tool here: https://gitlab.freedesktop.org/libevdev/libevdev/blob/master/tools/libevdev-events.c

+

+ Backwards compatibility with older kernel

+@@ -149,17 +160,6 @@ +

Please report bugs in the freedesktop.org GitLab instance: https://gitlab.freedesktop.org/libevdev/libevdev/issues/

+
+ +-
int libevdev_has_event_code(const struct libevdev *dev, unsigned int type, unsigned int code)
+-
const char * libevdev_event_code_get_name(unsigned int type, unsigned int code)
+-
int libevdev_has_event_type(const struct libevdev *dev, unsigned int type)
+-
int libevdev_get_id_bustype(const struct libevdev *dev)
+-
int libevdev_get_id_product(const struct libevdev *dev)
+-
int libevdev_get_id_vendor(const struct libevdev *dev)
+-
int libevdev_next_event(struct libevdev *dev, unsigned int flags, struct input_event *ev)
Get the next event from the device.
+-
const char * libevdev_event_type_get_name(unsigned int type)
+-
const char * libevdev_get_name(const struct libevdev *dev)
Retrieve the device's name, either as set by the caller or as read from the kernel.
+-
@ LIBEVDEV_READ_FLAG_NORMAL
Process data in normal mode.
Definition: libevdev.h:759
+-
int libevdev_new_from_fd(int fd, struct libevdev **dev)
Initialize a new libevdev device from the given fd.
+ + + +@@ -170,7 +170,7 @@ + + + +diff -Naur third-party-libevdev-bak/doc/html/ioctls.html third-party-new/doc/html/ioctls.html +--- third-party-libevdev-bak/doc/html/ioctls.html 2023-03-28 10:49:53.376511600 +0800 ++++ third-party-new/doc/html/ioctls.html 2023-04-01 16:18:35.055518500 +0800 +@@ -6,7 +6,7 @@ + + + +- ++ + + libevdev: evdev ioctls + +@@ -25,7 +25,7 @@ + +@@ -36,10 +36,10 @@ +
+
+ +- ++ + + +@@ -139,7 +139,7 @@ + + + +diff -Naur third-party-libevdev-bak/doc/html/kernel_header.html third-party-new/doc/html/kernel_header.html +--- third-party-libevdev-bak/doc/html/kernel_header.html 2023-03-28 10:49:53.380511700 +0800 ++++ third-party-new/doc/html/kernel_header.html 2023-04-01 16:29:31.535522500 +0800 +@@ -6,7 +6,7 @@ + + + +- ++ + + libevdev: Kernel header + +@@ -25,7 +25,7 @@ + +@@ -36,10 +36,10 @@ +
+
+ +- ++ + + +@@ -90,7 +90,7 @@ + + + +diff -Naur third-party-libevdev-bak/doc/html/libevdev-uinput_8h.html third-party-new/doc/html/libevdev-uinput_8h.html +--- third-party-libevdev-bak/doc/html/libevdev-uinput_8h.html 2023-03-28 10:49:53.380511700 +0800 ++++ third-party-new/doc/html/libevdev-uinput_8h.html 2023-04-03 10:47:05.692591800 +0800 +@@ -6,9 +6,9 @@ + + + +- ++ + +- libevdev: /home/whot/code/libevdev/release/libevdev/build.uQTRHZxVc0/libevdev/libevdev-uinput.h File Reference ++ libevdev: /home/whot/code/libevdev/release/libevdev/build.eXgVwUduJp/libevdev/libevdev-uinput.h File Reference + + + +@@ -25,7 +25,7 @@ + +@@ -36,10 +36,10 @@ +
+
+ +- ++ + + +@@ -140,7 +140,7 @@ + + + +diff -Naur third-party-libevdev-bak/doc/html/libevdev-uinput_8h_source.html third-party-new/doc/html/libevdev-uinput_8h_source.html +--- third-party-libevdev-bak/doc/html/libevdev-uinput_8h_source.html 2023-03-28 10:49:53.380511700 +0800 ++++ third-party-new/doc/html/libevdev-uinput_8h_source.html 2023-04-03 10:47:44.687742000 +0800 +@@ -6,9 +6,9 @@ + + + +- ++ + +- libevdev: /home/whot/code/libevdev/release/libevdev/build.uQTRHZxVc0/libevdev/libevdev-uinput.h Source File ++ libevdev: /home/whot/code/libevdev/release/libevdev/build.eXgVwUduJp/libevdev/libevdev-uinput.h Source File + + + +@@ -25,7 +25,7 @@ + +@@ -36,10 +36,10 @@ +
+
+ +- ++ + + +@@ -76,77 +76,79 @@ +
libevdev-uinput.h
+
+
+-Go to the documentation of this file.
1 /*
+-
2  * Copyright © 2013 Red Hat, Inc.
+-
3  *
+-
4  * Permission to use, copy, modify, distribute, and sell this software and its
+-
5  * documentation for any purpose is hereby granted without fee, provided that
+-
6  * the above copyright notice appear in all copies and that both that copyright
+-
7  * notice and this permission notice appear in supporting documentation, and
+-
8  * that the name of the copyright holders not be used in advertising or
+-
9  * publicity pertaining to distribution of the software without specific,
+-
10  * written prior permission. The copyright holders make no representations
+-
11  * about the suitability of this software for any purpose. It is provided "as
+-
12  * is" without express or implied warranty.
+-
13  *
+-
14  * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+-
15  * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+-
16  * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+-
17  * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+-
18  * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+-
19  * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+-
20  * OF THIS SOFTWARE.
+-
21  */
+-
22 
+-
23 #ifndef LIBEVDEV_UINPUT_H
+-
24 #define LIBEVDEV_UINPUT_H
+-
25 
+-
26 #ifdef __cplusplus
+-
27 extern "C" {
+-
28 #endif
+-
29 
+-
30 #include <libevdev/libevdev.h>
++Go to the documentation of this file.
1 /* SPDX-License-Identifier: MIT */
++
2 /*
++
3  * Copyright © 2013 Red Hat, Inc.
++
4  *
++
5  * Permission is hereby granted, free of charge, to any person obtaining a copy
++
6  * of this software and associated documentation files (the "Software"), to
++
7  * deal in the Software without restriction, including without limitation the
++
8  * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
++
9  * sell copies of the Software, and to permit persons to whom the Software is
++
10  * furnished to do so, subject to the following conditions:
++
11  *
++
12  * The above copyright notice and this permission notice (including the next
++
13  * paragraph) shall be included in all copies or substantial portions of the
++
14  * Software.
++
15  *
++
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
++
17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
++
18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
++
19  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
++
20  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
++
21  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
++
22  * IN THE SOFTWARE.
++
23  */
++
24 
++
25 #ifndef LIBEVDEV_UINPUT_H
++
26 #define LIBEVDEV_UINPUT_H
++
27 
++
28 #ifdef __cplusplus
++
29 extern "C" {
++
30 #endif
+
31 
+-
32 struct libevdev_uinput;
++
32 #include <libevdev/libevdev.h>
+
33 
+- +-
110  /* intentionally -2 to avoid to avoid code like the below from accidentally working:
+-
111  fd = open("/dev/uinput", O_RDWR); // fails, fd is -1
+-
112  libevdev_uinput_create_from_device(dev, fd, &uidev); // may hide the error */
+- +-
114 };
+-
115 
+-
153 int libevdev_uinput_create_from_device(const struct libevdev *dev,
+-
154  int uinput_fd,
+-
155  struct libevdev_uinput **uinput_dev);
+-
156 
+-
168 void libevdev_uinput_destroy(struct libevdev_uinput *uinput_dev);
+-
169 
+-
183 int libevdev_uinput_get_fd(const struct libevdev_uinput *uinput_dev);
+-
184 
+-
209 const char* libevdev_uinput_get_syspath(struct libevdev_uinput *uinput_dev);
+-
210 
+-
231 const char* libevdev_uinput_get_devnode(struct libevdev_uinput *uinput_dev);
+-
232 
+-
247 int libevdev_uinput_write_event(const struct libevdev_uinput *uinput_dev,
+-
248  unsigned int type,
+-
249  unsigned int code,
+-
250  int value);
+-
251 #ifdef __cplusplus
+-
252 }
+-
253 #endif
+-
254 
+-
255 #endif /* LIBEVDEV_UINPUT_H */
+-
+- ++
34 struct libevdev_uinput;
++
35 
++ ++
111  /* intentionally -2 to avoid code like below from accidentally working:
++
112  fd = open("/dev/uinput", O_RDWR); // fails, fd is -1
++
113  libevdev_uinput_create_from_device(dev, fd, &uidev); // may hide the error */
++ ++
115 };
++
116 
++
154 int libevdev_uinput_create_from_device(const struct libevdev *dev,
++
155  int uinput_fd,
++
156  struct libevdev_uinput **uinput_dev);
++
157 
++
169 void libevdev_uinput_destroy(struct libevdev_uinput *uinput_dev);
++
170 
++
184 int libevdev_uinput_get_fd(const struct libevdev_uinput *uinput_dev);
++
185 
++
210 const char* libevdev_uinput_get_syspath(struct libevdev_uinput *uinput_dev);
++
211 
++
232 const char* libevdev_uinput_get_devnode(struct libevdev_uinput *uinput_dev);
++
233 
++
248 int libevdev_uinput_write_event(const struct libevdev_uinput *uinput_dev,
++
249  unsigned int type,
++
250  unsigned int code,
++
251  int value);
++
252 #ifdef __cplusplus
++
253 }
++
254 #endif
++
255 
++
256 #endif /* LIBEVDEV_UINPUT_H */
++
int libevdev_uinput_write_event(const struct libevdev_uinput *uinput_dev, unsigned int type, unsigned int code, int value)
Post an event through the uinput device.
+
const char * libevdev_uinput_get_devnode(struct libevdev_uinput *uinput_dev)
Return the device node representing this uinput device.
+-
int libevdev_uinput_create_from_device(const struct libevdev *dev, int uinput_fd, struct libevdev_uinput **uinput_dev)
Create a uinput device based on the given libevdev device.
+-
@ LIBEVDEV_UINPUT_OPEN_MANAGED
let libevdev open and close /dev/uinput
Definition: libevdev-uinput.h:113
+-
const char * libevdev_uinput_get_syspath(struct libevdev_uinput *uinput_dev)
Return the syspath representing this uinput device.
+-
void libevdev_uinput_destroy(struct libevdev_uinput *uinput_dev)
Destroy a previously created uinput device and free associated memory.
+-
libevdev_uinput_open_mode
Definition: libevdev-uinput.h:109
+
int libevdev_uinput_get_fd(const struct libevdev_uinput *uinput_dev)
Return the file descriptor used to create this uinput device.
+-
int libevdev_uinput_write_event(const struct libevdev_uinput *uinput_dev, unsigned int type, unsigned int code, int value)
Post an event through the uinput device.
++
void libevdev_uinput_destroy(struct libevdev_uinput *uinput_dev)
Destroy a previously created uinput device and free associated memory.
++
const char * libevdev_uinput_get_syspath(struct libevdev_uinput *uinput_dev)
Return the syspath representing this uinput device.
++
int libevdev_uinput_create_from_device(const struct libevdev *dev, int uinput_fd, struct libevdev_uinput **uinput_dev)
Create a uinput device based on the given libevdev device.
++
libevdev_uinput_open_mode
Definition: libevdev-uinput.h:110
++
@ LIBEVDEV_UINPUT_OPEN_MANAGED
let libevdev open and close /dev/uinput
Definition: libevdev-uinput.h:114
++ ++
+ + +
+@@ -157,7 +159,7 @@ + + + +diff -Naur third-party-libevdev-bak/doc/html/libevdev_8h.html third-party-new/doc/html/libevdev_8h.html +--- third-party-libevdev-bak/doc/html/libevdev_8h.html 2023-03-28 10:49:53.380511700 +0800 ++++ third-party-new/doc/html/libevdev_8h.html 2023-04-01 16:29:44.951841700 +0800 +@@ -6,9 +6,9 @@ + + + +- ++ + +- libevdev: /home/whot/code/libevdev/release/libevdev/build.uQTRHZxVc0/libevdev/libevdev.h File Reference ++ libevdev: /home/whot/code/libevdev/release/libevdev/build.eXgVwUduJp/libevdev/libevdev.h File Reference + + + +@@ -25,7 +25,7 @@ + +@@ -36,10 +36,10 @@ +
+
+ +- ++ + + +@@ -104,27 +104,27 @@ +
devThe evdev device, already initialized with libevdev_set_fd()
+ +- + +- + +- + +- + +- + +

+ Enumerations

enum  libevdev_read_flag { LIBEVDEV_READ_FLAG_SYNC, +-LIBEVDEV_READ_FLAG_NORMAL, +-LIBEVDEV_READ_FLAG_FORCE_SYNC, +-LIBEVDEV_READ_FLAG_BLOCKING ++
enum  libevdev_read_flag { LIBEVDEV_READ_FLAG_SYNC ++, LIBEVDEV_READ_FLAG_NORMAL ++, LIBEVDEV_READ_FLAG_FORCE_SYNC ++, LIBEVDEV_READ_FLAG_BLOCKING + }
 
enum  libevdev_log_priority { LIBEVDEV_LOG_ERROR, +-LIBEVDEV_LOG_INFO, +-LIBEVDEV_LOG_DEBUG ++
enum  libevdev_log_priority { LIBEVDEV_LOG_ERROR ++, LIBEVDEV_LOG_INFO ++, LIBEVDEV_LOG_DEBUG + }
 
enum  libevdev_grab_mode { LIBEVDEV_GRAB, +-LIBEVDEV_UNGRAB ++
enum  libevdev_grab_mode { LIBEVDEV_GRAB ++, LIBEVDEV_UNGRAB + }
 
enum  libevdev_read_status { LIBEVDEV_READ_STATUS_SUCCESS, +-LIBEVDEV_READ_STATUS_SYNC ++
enum  libevdev_read_status { LIBEVDEV_READ_STATUS_SUCCESS ++, LIBEVDEV_READ_STATUS_SYNC + }
 
enum  libevdev_led_value { LIBEVDEV_LED_ON, +-LIBEVDEV_LED_OFF ++
enum  libevdev_led_value { LIBEVDEV_LED_ON ++, LIBEVDEV_LED_OFF + }
 
+@@ -409,7 +409,7 @@ + + + +diff -Naur third-party-libevdev-bak/doc/html/libevdev_8h_source.html third-party-new/doc/html/libevdev_8h_source.html +--- third-party-libevdev-bak/doc/html/libevdev_8h_source.html 2023-03-28 10:49:53.380511700 +0800 ++++ third-party-new/doc/html/libevdev_8h_source.html 2023-04-01 16:30:17.409507500 +0800 +@@ -6,9 +6,9 @@ + + + +- ++ + +- libevdev: /home/whot/code/libevdev/release/libevdev/build.uQTRHZxVc0/libevdev/libevdev.h Source File ++ libevdev: /home/whot/code/libevdev/release/libevdev/build.eXgVwUduJp/libevdev/libevdev.h Source File + + + +@@ -25,7 +25,7 @@ + +@@ -36,10 +36,10 @@ +
+
+ +- ++ + + +@@ -76,372 +76,375 @@ +
libevdev.h
+
+
+-Go to the documentation of this file.
1 /*
+-
2  * Copyright © 2013 Red Hat, Inc.
+-
3  *
+-
4  * Permission to use, copy, modify, distribute, and sell this software and its
+-
5  * documentation for any purpose is hereby granted without fee, provided that
+-
6  * the above copyright notice appear in all copies and that both that copyright
+-
7  * notice and this permission notice appear in supporting documentation, and
+-
8  * that the name of the copyright holders not be used in advertising or
+-
9  * publicity pertaining to distribution of the software without specific,
+-
10  * written prior permission. The copyright holders make no representations
+-
11  * about the suitability of this software for any purpose. It is provided "as
+-
12  * is" without express or implied warranty.
+-
13  *
+-
14  * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+-
15  * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+-
16  * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+-
17  * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+-
18  * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+-
19  * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+-
20  * OF THIS SOFTWARE.
+-
21  */
+-
22 
+-
23 #ifndef LIBEVDEV_H
+-
24 #define LIBEVDEV_H
++Go to the documentation of this file.
1 /* SPDX-License-Identifier: MIT */
++
2 /*
++
3  * Copyright © 2013 Red Hat, Inc.
++
4  *
++
5  * Permission is hereby granted, free of charge, to any person obtaining a copy
++
6  * of this software and associated documentation files (the "Software"), to
++
7  * deal in the Software without restriction, including without limitation the
++
8  * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
++
9  * sell copies of the Software, and to permit persons to whom the Software is
++
10  * furnished to do so, subject to the following conditions:
++
11  *
++
12  * The above copyright notice and this permission notice (including the next
++
13  * paragraph) shall be included in all copies or substantial portions of the
++
14  * Software.
++
15  *
++
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
++
17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
++
18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
++
19  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
++
20  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
++
21  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
++
22  * IN THE SOFTWARE.
++
23  *
++
24  */
+
25 
+-
26 #ifdef __cplusplus
+-
27 extern "C" {
+-
28 #endif
+-
29 
+-
30 #include <linux/input.h>
+-
31 #include <stdarg.h>
++
26 #ifndef LIBEVDEV_H
++
27 #define LIBEVDEV_H
++
28 
++
29 #ifdef __cplusplus
++
30 extern "C" {
++
31 #endif
+
32 
+-
33 #define LIBEVDEV_ATTRIBUTE_PRINTF(_format, _args) __attribute__ ((format (printf, _format, _args)))
+-
34 
+-
752 struct libevdev;
+-
753 
+- +- +- +- +- +-
763 };
+-
764 
+-
779 struct libevdev* libevdev_new(void);
+-
780 
+-
803 int libevdev_new_from_fd(int fd, struct libevdev **dev);
+-
804 
+-
818 void libevdev_free(struct libevdev *dev);
+-
819 
+- +- +- +-
826  LIBEVDEV_LOG_DEBUG = 30
+-
827 };
+-
828 
+-
845 typedef void (*libevdev_log_func_t)(enum libevdev_log_priority priority,
+-
846  void *data,
+-
847  const char *file, int line,
+-
848  const char *func,
+-
849  const char *format, va_list args)
+- +-
851 
+- +-
871 
+- +-
885 
+- +-
898 
+-
918 typedef void (*libevdev_device_log_func_t)(const struct libevdev *dev,
+-
919  enum libevdev_log_priority priority,
+-
920  void *data,
+-
921  const char *file, int line,
+-
922  const char *func,
+-
923  const char *format, va_list args)
+- +-
925 
+-
947 void libevdev_set_device_log_function(struct libevdev *dev,
+- +-
949  enum libevdev_log_priority priority,
+-
950  void *data);
+-
951 
+- +- +-
957  LIBEVDEV_UNGRAB = 4
+-
958 };
+-
959 
+-
982 int libevdev_grab(struct libevdev *dev, enum libevdev_grab_mode grab);
+-
983 
+-
1016 int libevdev_set_fd(struct libevdev* dev, int fd);
+-
1017 
+-
1056 int libevdev_change_fd(struct libevdev* dev, int fd);
+-
1057 
+-
1066 int libevdev_get_fd(const struct libevdev* dev);
+-
1067 
+- +- +- +-
1088 };
+-
1089 
+-
1140 int libevdev_next_event(struct libevdev *dev, unsigned int flags, struct input_event *ev);
+-
1141 
+-
1164 int libevdev_has_event_pending(struct libevdev *dev);
+-
1165 
+-
1180 const char* libevdev_get_name(const struct libevdev *dev);
+-
1181 
+-
1195 void libevdev_set_name(struct libevdev *dev, const char *name);
+-
1196 
+-
1212 const char * libevdev_get_phys(const struct libevdev *dev);
+-
1213 
+-
1227 void libevdev_set_phys(struct libevdev *dev, const char *phys);
+-
1228 
+-
1242 const char * libevdev_get_uniq(const struct libevdev *dev);
+-
1243 
+-
1257 void libevdev_set_uniq(struct libevdev *dev, const char *uniq);
+-
1258 
+-
1268 int libevdev_get_id_product(const struct libevdev *dev);
+-
1269 
+-
1281 void libevdev_set_id_product(struct libevdev *dev, int product_id);
+-
1282 
+-
1292 int libevdev_get_id_vendor(const struct libevdev *dev);
+-
1293 
+-
1305 void libevdev_set_id_vendor(struct libevdev *dev, int vendor_id);
+-
1306 
+-
1316 int libevdev_get_id_bustype(const struct libevdev *dev);
+-
1317 
+-
1329 void libevdev_set_id_bustype(struct libevdev *dev, int bustype);
+-
1330 
+-
1340 int libevdev_get_id_version(const struct libevdev *dev);
+-
1341 
+-
1353 void libevdev_set_id_version(struct libevdev *dev, int version);
+-
1354 
+-
1364 int libevdev_get_driver_version(const struct libevdev *dev);
+-
1365 
+-
1376 int libevdev_has_property(const struct libevdev *dev, unsigned int prop);
+-
1377 
+-
1389 int libevdev_enable_property(struct libevdev *dev, unsigned int prop);
+-
1390 
+-
1399 int libevdev_disable_property(struct libevdev *dev, unsigned int prop);
+-
1400 
+-
1411 int libevdev_has_event_type(const struct libevdev *dev, unsigned int type);
+-
1412 
+-
1424 int libevdev_has_event_code(const struct libevdev *dev, unsigned int type, unsigned int code);
+-
1425 
+-
1438 int libevdev_get_abs_minimum(const struct libevdev *dev, unsigned int code);
+-
1439 
+-
1452 int libevdev_get_abs_maximum(const struct libevdev *dev, unsigned int code);
+-
1453 
+-
1466 int libevdev_get_abs_fuzz(const struct libevdev *dev, unsigned int code);
+-
1467 
+-
1480 int libevdev_get_abs_flat(const struct libevdev *dev, unsigned int code);
+-
1481 
+-
1494 int libevdev_get_abs_resolution(const struct libevdev *dev, unsigned int code);
+-
1495 
+-
1509 const struct input_absinfo* libevdev_get_abs_info(const struct libevdev *dev, unsigned int code);
+-
1510 
+-
1533 int libevdev_get_event_value(const struct libevdev *dev, unsigned int type, unsigned int code);
+-
1534 
+-
1569 int libevdev_set_event_value(struct libevdev *dev, unsigned int type, unsigned int code, int value);
+-
1570 
+-
1596 int libevdev_fetch_event_value(const struct libevdev *dev, unsigned int type, unsigned int code, int *value);
+-
1597 
+-
1618 int libevdev_get_slot_value(const struct libevdev *dev, unsigned int slot, unsigned int code);
+-
1619 
+-
1648 int libevdev_set_slot_value(struct libevdev *dev, unsigned int slot, unsigned int code, int value);
+-
1649 
+-
1675 int libevdev_fetch_slot_value(const struct libevdev *dev, unsigned int slot, unsigned int code, int *value);
+-
1676 
+-
1690 int libevdev_get_num_slots(const struct libevdev *dev);
+-
1691 
+-
1707 int libevdev_get_current_slot(const struct libevdev *dev);
+-
1708 
+-
1720 void libevdev_set_abs_minimum(struct libevdev *dev, unsigned int code, int val);
+-
1721 
+-
1733 void libevdev_set_abs_maximum(struct libevdev *dev, unsigned int code, int val);
+-
1734 
+-
1746 void libevdev_set_abs_fuzz(struct libevdev *dev, unsigned int code, int val);
+-
1747 
+-
1759 void libevdev_set_abs_flat(struct libevdev *dev, unsigned int code, int val);
+-
1760 
+-
1772 void libevdev_set_abs_resolution(struct libevdev *dev, unsigned int code, int val);
+-
1773 
+-
1785 void libevdev_set_abs_info(struct libevdev *dev, unsigned int code, const struct input_absinfo *abs);
+-
1786 
+-
1804 int libevdev_enable_event_type(struct libevdev *dev, unsigned int type);
+-
1805 
+-
1832 int libevdev_disable_event_type(struct libevdev *dev, unsigned int type);
+-
1833 
+-
1867 int libevdev_enable_event_code(struct libevdev *dev, unsigned int type, unsigned int code, const void *data);
+-
1868 
+-
1896 int libevdev_disable_event_code(struct libevdev *dev, unsigned int type, unsigned int code);
+-
1897 
+-
1912 int libevdev_kernel_set_abs_info(struct libevdev *dev, unsigned int code, const struct input_absinfo *abs);
+-
1913 
+- +- +-
1919  LIBEVDEV_LED_OFF = 4
+-
1920 };
+-
1921 
+-
1935 int libevdev_kernel_set_led_value(struct libevdev *dev, unsigned int code, enum libevdev_led_value value);
+-
1936 
+-
1960 int libevdev_kernel_set_led_values(struct libevdev *dev, ...);
+-
1961 
+-
1976 int libevdev_set_clock_id(struct libevdev *dev, int clockid);
+-
1977 
+-
1999 int libevdev_event_is_type(const struct input_event *ev, unsigned int type);
+-
2000 
+-
2024 int libevdev_event_is_code(const struct input_event *ev, unsigned int type, unsigned int code);
+-
2025 
+-
2037 const char * libevdev_event_type_get_name(unsigned int type);
+-
2050 const char * libevdev_event_code_get_name(unsigned int type, unsigned int code);
+-
2051 
+-
2072 const char * libevdev_event_value_get_name(unsigned int type,
+-
2073  unsigned int code,
+-
2074  int value);
+-
2088 const char* libevdev_property_get_name(unsigned int prop);
+-
2089 
+-
2102 int libevdev_event_type_get_max(unsigned int type);
+-
2103 
+-
2118 int libevdev_event_type_from_name(const char *name);
+-
2119 
+-
2136 int libevdev_event_type_from_name_n(const char *name, size_t len);
+-
2137 
+-
2157 int libevdev_event_code_from_name(unsigned int type, const char *name);
+-
2158 
+-
2180 int libevdev_event_code_from_name_n(unsigned int type, const char *name,
+-
2181  size_t len);
+-
2182 
+-
2204 int libevdev_event_value_from_name(unsigned int type, unsigned int code,
+-
2205  const char *name);
+-
2206 
+-
2223 int
+- +-
2225 
+-
2244 int
+-
2245 libevdev_event_type_from_code_name_n(const char *name, size_t len);
+-
2246 
+-
2263 int
+- +-
2265 
+-
2284 int
+-
2285 libevdev_event_code_from_code_name_n(const char *name, size_t len);
+-
2286 
+-
2310 int libevdev_event_value_from_name_n(unsigned int type, unsigned int code,
+-
2311  const char *name, size_t len);
+-
2312 
+-
2325 int libevdev_property_from_name(const char *name);
+-
2326 
+-
2341 int libevdev_property_from_name_n(const char *name, size_t len);
+-
2342 
+-
2360 int libevdev_get_repeat(const struct libevdev *dev, int *delay, int *period);
+-
2361 
+-
2362 /********* DEPRECATED SECTION *********/
+-
2363 #if defined(__GNUC__) && __GNUC__ >= 4
+-
2364 #define LIBEVDEV_DEPRECATED __attribute__ ((deprecated))
+-
2365 #else
+-
2366 #define LIBEVDEV_DEPRECATED
+-
2367 #endif
+-
2368 
+-
2369 #ifdef __cplusplus
+-
2370 }
+-
2371 #endif
+-
2372 
+-
2373 #endif /* LIBEVDEV_H */
+-
+-
void libevdev_set_abs_resolution(struct libevdev *dev, unsigned int code, int val)
Change the resolution for the given EV_ABS event code, if the code exists.
+-
@ LIBEVDEV_UNGRAB
Ungrab the device if currently grabbed.
Definition: libevdev.h:957
+-
int libevdev_event_type_get_max(unsigned int type)
+-
int libevdev_has_event_code(const struct libevdev *dev, unsigned int type, unsigned int code)
+-
int libevdev_event_value_from_name_n(unsigned int type, unsigned int code, const char *name, size_t len)
Look up an event value by its type, code and name.
+-
const struct input_absinfo * libevdev_get_abs_info(const struct libevdev *dev, unsigned int code)
Get the axis info for the given axis, as advertised by the kernel.
+-
void libevdev_set_id_version(struct libevdev *dev, int version)
+-
int libevdev_event_type_from_name(const char *name)
Look up an event-type by its name.
+-
int libevdev_kernel_set_led_value(struct libevdev *dev, unsigned int code, enum libevdev_led_value value)
Turn an LED on or off.
++
33 #include <linux/input.h>
++
34 #include <stdarg.h>
++
35 
++
36 #define LIBEVDEV_ATTRIBUTE_PRINTF(_format, _args) __attribute__ ((format (printf, _format, _args)))
++
37 
++
755 struct libevdev;
++
756 
++ ++ ++ ++ ++ ++
766 };
++
767 
++
782 struct libevdev* libevdev_new(void);
++
783 
++
806 int libevdev_new_from_fd(int fd, struct libevdev **dev);
++
807 
++
821 void libevdev_free(struct libevdev *dev);
++
822 
++ ++ ++ ++
829  LIBEVDEV_LOG_DEBUG = 30
++
830 };
++
831 
++
848 typedef void (*libevdev_log_func_t)(enum libevdev_log_priority priority,
++
849  void *data,
++
850  const char *file, int line,
++
851  const char *func,
++
852  const char *format, va_list args)
++ ++
854 
++ ++
874 
++ ++
888 
++ ++
901 
++
921 typedef void (*libevdev_device_log_func_t)(const struct libevdev *dev,
++
922  enum libevdev_log_priority priority,
++
923  void *data,
++
924  const char *file, int line,
++
925  const char *func,
++
926  const char *format, va_list args)
++ ++
928 
++
950 void libevdev_set_device_log_function(struct libevdev *dev,
++ ++
952  enum libevdev_log_priority priority,
++
953  void *data);
++
954 
++ ++ ++
960  LIBEVDEV_UNGRAB = 4
++
961 };
++
962 
++
985 int libevdev_grab(struct libevdev *dev, enum libevdev_grab_mode grab);
++
986 
++
1019 int libevdev_set_fd(struct libevdev* dev, int fd);
++
1020 
++
1059 int libevdev_change_fd(struct libevdev* dev, int fd);
++
1060 
++
1069 int libevdev_get_fd(const struct libevdev* dev);
++
1070 
++ ++ ++ ++
1091 };
++
1092 
++
1143 int libevdev_next_event(struct libevdev *dev, unsigned int flags, struct input_event *ev);
++
1144 
++
1167 int libevdev_has_event_pending(struct libevdev *dev);
++
1168 
++
1183 const char* libevdev_get_name(const struct libevdev *dev);
++
1184 
++
1198 void libevdev_set_name(struct libevdev *dev, const char *name);
++
1199 
++
1215 const char * libevdev_get_phys(const struct libevdev *dev);
++
1216 
++
1230 void libevdev_set_phys(struct libevdev *dev, const char *phys);
++
1231 
++
1245 const char * libevdev_get_uniq(const struct libevdev *dev);
++
1246 
++
1260 void libevdev_set_uniq(struct libevdev *dev, const char *uniq);
++
1261 
++
1271 int libevdev_get_id_product(const struct libevdev *dev);
++
1272 
++
1284 void libevdev_set_id_product(struct libevdev *dev, int product_id);
++
1285 
++
1295 int libevdev_get_id_vendor(const struct libevdev *dev);
++
1296 
++
1308 void libevdev_set_id_vendor(struct libevdev *dev, int vendor_id);
++
1309 
++
1319 int libevdev_get_id_bustype(const struct libevdev *dev);
++
1320 
++
1332 void libevdev_set_id_bustype(struct libevdev *dev, int bustype);
++
1333 
++
1343 int libevdev_get_id_version(const struct libevdev *dev);
++
1344 
++
1356 void libevdev_set_id_version(struct libevdev *dev, int version);
++
1357 
++
1367 int libevdev_get_driver_version(const struct libevdev *dev);
++
1368 
++
1379 int libevdev_has_property(const struct libevdev *dev, unsigned int prop);
++
1380 
++
1392 int libevdev_enable_property(struct libevdev *dev, unsigned int prop);
++
1393 
++
1402 int libevdev_disable_property(struct libevdev *dev, unsigned int prop);
++
1403 
++
1414 int libevdev_has_event_type(const struct libevdev *dev, unsigned int type);
++
1415 
++
1427 int libevdev_has_event_code(const struct libevdev *dev, unsigned int type, unsigned int code);
++
1428 
++
1441 int libevdev_get_abs_minimum(const struct libevdev *dev, unsigned int code);
++
1442 
++
1455 int libevdev_get_abs_maximum(const struct libevdev *dev, unsigned int code);
++
1456 
++
1469 int libevdev_get_abs_fuzz(const struct libevdev *dev, unsigned int code);
++
1470 
++
1483 int libevdev_get_abs_flat(const struct libevdev *dev, unsigned int code);
++
1484 
++
1497 int libevdev_get_abs_resolution(const struct libevdev *dev, unsigned int code);
++
1498 
++
1512 const struct input_absinfo* libevdev_get_abs_info(const struct libevdev *dev, unsigned int code);
++
1513 
++
1535 int libevdev_get_event_value(const struct libevdev *dev, unsigned int type, unsigned int code);
++
1536 
++
1571 int libevdev_set_event_value(struct libevdev *dev, unsigned int type, unsigned int code, int value);
++
1572 
++
1598 int libevdev_fetch_event_value(const struct libevdev *dev, unsigned int type, unsigned int code, int *value);
++
1599 
++
1620 int libevdev_get_slot_value(const struct libevdev *dev, unsigned int slot, unsigned int code);
++
1621 
++
1650 int libevdev_set_slot_value(struct libevdev *dev, unsigned int slot, unsigned int code, int value);
++
1651 
++
1677 int libevdev_fetch_slot_value(const struct libevdev *dev, unsigned int slot, unsigned int code, int *value);
++
1678 
++
1692 int libevdev_get_num_slots(const struct libevdev *dev);
++
1693 
++
1709 int libevdev_get_current_slot(const struct libevdev *dev);
++
1710 
++
1722 void libevdev_set_abs_minimum(struct libevdev *dev, unsigned int code, int val);
++
1723 
++
1735 void libevdev_set_abs_maximum(struct libevdev *dev, unsigned int code, int val);
++
1736 
++
1748 void libevdev_set_abs_fuzz(struct libevdev *dev, unsigned int code, int val);
++
1749 
++
1761 void libevdev_set_abs_flat(struct libevdev *dev, unsigned int code, int val);
++
1762 
++
1774 void libevdev_set_abs_resolution(struct libevdev *dev, unsigned int code, int val);
++
1775 
++
1787 void libevdev_set_abs_info(struct libevdev *dev, unsigned int code, const struct input_absinfo *abs);
++
1788 
++
1806 int libevdev_enable_event_type(struct libevdev *dev, unsigned int type);
++
1807 
++
1834 int libevdev_disable_event_type(struct libevdev *dev, unsigned int type);
++
1835 
++
1869 int libevdev_enable_event_code(struct libevdev *dev, unsigned int type, unsigned int code, const void *data);
++
1870 
++
1898 int libevdev_disable_event_code(struct libevdev *dev, unsigned int type, unsigned int code);
++
1899 
++
1914 int libevdev_kernel_set_abs_info(struct libevdev *dev, unsigned int code, const struct input_absinfo *abs);
++
1915 
++ ++ ++
1921  LIBEVDEV_LED_OFF = 4
++
1922 };
++
1923 
++
1937 int libevdev_kernel_set_led_value(struct libevdev *dev, unsigned int code, enum libevdev_led_value value);
++
1938 
++
1962 int libevdev_kernel_set_led_values(struct libevdev *dev, ...);
++
1963 
++
1978 int libevdev_set_clock_id(struct libevdev *dev, int clockid);
++
1979 
++
2001 int libevdev_event_is_type(const struct input_event *ev, unsigned int type);
++
2002 
++
2026 int libevdev_event_is_code(const struct input_event *ev, unsigned int type, unsigned int code);
++
2027 
++
2039 const char * libevdev_event_type_get_name(unsigned int type);
++
2052 const char * libevdev_event_code_get_name(unsigned int type, unsigned int code);
++
2053 
++
2074 const char * libevdev_event_value_get_name(unsigned int type,
++
2075  unsigned int code,
++
2076  int value);
++
2090 const char* libevdev_property_get_name(unsigned int prop);
++
2091 
++
2104 int libevdev_event_type_get_max(unsigned int type);
++
2105 
++
2120 int libevdev_event_type_from_name(const char *name);
++
2121 
++
2138 int libevdev_event_type_from_name_n(const char *name, size_t len);
++
2139 
++
2159 int libevdev_event_code_from_name(unsigned int type, const char *name);
++
2160 
++
2182 int libevdev_event_code_from_name_n(unsigned int type, const char *name,
++
2183  size_t len);
++
2184 
++
2206 int libevdev_event_value_from_name(unsigned int type, unsigned int code,
++
2207  const char *name);
++
2208 
++
2225 int
++ ++
2227 
++
2246 int
++
2247 libevdev_event_type_from_code_name_n(const char *name, size_t len);
++
2248 
++
2265 int
++ ++
2267 
++
2286 int
++
2287 libevdev_event_code_from_code_name_n(const char *name, size_t len);
++
2288 
++
2312 int libevdev_event_value_from_name_n(unsigned int type, unsigned int code,
++
2313  const char *name, size_t len);
++
2314 
++
2327 int libevdev_property_from_name(const char *name);
++
2328 
++
2343 int libevdev_property_from_name_n(const char *name, size_t len);
++
2344 
++
2362 int libevdev_get_repeat(const struct libevdev *dev, int *delay, int *period);
++
2363 
++
2364 /********* DEPRECATED SECTION *********/
++
2365 #if defined(__GNUC__) && __GNUC__ >= 4
++
2366 #define LIBEVDEV_DEPRECATED __attribute__ ((deprecated))
++
2367 #else
++
2368 #define LIBEVDEV_DEPRECATED
++
2369 #endif
++
2370 
++
2371 #ifdef __cplusplus
++
2372 }
++
2373 #endif
++
2374 
++
2375 #endif /* LIBEVDEV_H */
++
int libevdev_get_id_vendor(const struct libevdev *dev)
++
int libevdev_fetch_event_value(const struct libevdev *dev, unsigned int type, unsigned int code, int *value)
Fetch the current value of the event type.
++
int libevdev_get_abs_fuzz(const struct libevdev *dev, unsigned int code)
Get the axis fuzz for the given axis, as advertised by the kernel.
++
int libevdev_get_id_product(const struct libevdev *dev)
++
int libevdev_get_driver_version(const struct libevdev *dev)
+
int libevdev_has_property(const struct libevdev *dev, unsigned int prop)
+-
int libevdev_event_type_from_code_name_n(const char *name, size_t len)
Look up an event type for a event code name.
+-
@ LIBEVDEV_GRAB
Grab the device if not currently grabbed.
Definition: libevdev.h:956
+-
int libevdev_event_value_from_name(unsigned int type, unsigned int code, const char *name)
Look up an event value by its type, code and name.
+-
@ LIBEVDEV_READ_FLAG_BLOCKING
The fd is not in O_NONBLOCK and a read may block.
Definition: libevdev.h:762
+-
int libevdev_property_from_name_n(const char *name, size_t len)
Look up an input property by its name.
+-
@ LIBEVDEV_LED_OFF
Turn the LED off.
Definition: libevdev.h:1919
++
int libevdev_has_event_type(const struct libevdev *dev, unsigned int type)
++
int libevdev_get_abs_minimum(const struct libevdev *dev, unsigned int code)
Get the minimum axis value for the given axis, as advertised by the kernel.
++
const char * libevdev_get_phys(const struct libevdev *dev)
Retrieve the device's physical location, either as set by the caller or as read from the kernel.
++
int libevdev_get_event_value(const struct libevdev *dev, unsigned int type, unsigned int code)
Behaviour of this function is undefined if the device does not provide the event.
++
int libevdev_get_abs_flat(const struct libevdev *dev, unsigned int code)
Get the axis flat for the given axis, as advertised by the kernel.
++
const struct input_absinfo * libevdev_get_abs_info(const struct libevdev *dev, unsigned int code)
Get the axis info for the given axis, as advertised by the kernel.
++
const char * libevdev_get_uniq(const struct libevdev *dev)
Retrieve the device's unique identifier, either as set by the caller or as read from the kernel.
+
int libevdev_get_abs_resolution(const struct libevdev *dev, unsigned int code)
Get the axis resolution for the given axis, as advertised by the kernel.
+-
int libevdev_event_type_from_name_n(const char *name, size_t len)
Look up an event-type by its name.
+-
libevdev_read_status
Definition: libevdev.h:1071
+-
int libevdev_enable_event_type(struct libevdev *dev, unsigned int type)
Forcibly enable an event type on this device, even if the underlying device does not support it.
+-
int libevdev_property_from_name(const char *name)
Look up an input property by its name.
+-
int libevdev_enable_property(struct libevdev *dev, unsigned int prop)
+-
int libevdev_kernel_set_led_values(struct libevdev *dev,...)
Turn multiple LEDs on or off simultaneously.
+-
int libevdev_fetch_event_value(const struct libevdev *dev, unsigned int type, unsigned int code, int *value)
Fetch the current value of the event type.
+-
void libevdev_set_log_function(libevdev_log_func_t logfunc, void *data)
Set a printf-style logging handler for library-internal logging.
+-
struct libevdev * libevdev_new(void)
Initialize a new libevdev device.
+-
int libevdev_get_slot_value(const struct libevdev *dev, unsigned int slot, unsigned int code)
Return the current value of the code for the given slot.
+-
libevdev_log_priority
Definition: libevdev.h:823
+
int libevdev_get_id_version(const struct libevdev *dev)
+-
#define LIBEVDEV_ATTRIBUTE_PRINTF(_format, _args)
Definition: libevdev.h:33
+-
void(* libevdev_log_func_t)(enum libevdev_log_priority priority, void *data, const char *file, int line, const char *func, const char *format, va_list args)
Logging function called by library-internal logging.
Definition: libevdev.h:845
+-
const char * libevdev_event_code_get_name(unsigned int type, unsigned int code)
+-
int libevdev_kernel_set_abs_info(struct libevdev *dev, unsigned int code, const struct input_absinfo *abs)
Set the device's EV_ABS axis to the value defined in the abs parameter.
+-
int libevdev_get_event_value(const struct libevdev *dev, unsigned int type, unsigned int code)
Behaviour of this function is undefined if the device does not provide the event.
+-
int libevdev_event_code_from_name_n(unsigned int type, const char *name, size_t len)
Look up an event code by its type and name.
+-
int libevdev_event_code_from_code_name_n(const char *name, size_t len)
Look up an event code by its name.
+-
int libevdev_set_slot_value(struct libevdev *dev, unsigned int slot, unsigned int code, int value)
Set the value for a given code for the given slot.
++
int libevdev_get_abs_maximum(const struct libevdev *dev, unsigned int code)
Get the maximum axis value for the given axis, as advertised by the kernel.
++
int libevdev_get_id_bustype(const struct libevdev *dev)
++
int libevdev_has_event_code(const struct libevdev *dev, unsigned int type, unsigned int code)
++
const char * libevdev_get_name(const struct libevdev *dev)
Retrieve the device's name, either as set by the caller or as read from the kernel.
++
int libevdev_get_repeat(const struct libevdev *dev, int *delay, int *period)
Get the repeat delay and repeat period values for this device.
++
libevdev_read_status
Definition: libevdev.h:1074
++
libevdev_read_flag
Definition: libevdev.h:760
++
int libevdev_next_event(struct libevdev *dev, unsigned int flags, struct input_event *ev)
Get the next event from the device.
++
int libevdev_has_event_pending(struct libevdev *dev)
Check if there are events waiting for us.
++
@ LIBEVDEV_READ_STATUS_SYNC
Depending on the libevdev_next_event() read flag:
Definition: libevdev.h:1090
++
@ LIBEVDEV_READ_STATUS_SUCCESS
libevdev_next_event() has finished without an error and an event is available for processing.
Definition: libevdev.h:1081
++
@ LIBEVDEV_READ_FLAG_BLOCKING
The fd is not in O_NONBLOCK and a read may block.
Definition: libevdev.h:765
++
@ LIBEVDEV_READ_FLAG_SYNC
Process data in sync mode.
Definition: libevdev.h:761
++
@ LIBEVDEV_READ_FLAG_FORCE_SYNC
Pretend the next event is a SYN_DROPPED and require the caller to sync.
Definition: libevdev.h:763
++
@ LIBEVDEV_READ_FLAG_NORMAL
Process data in normal mode.
Definition: libevdev.h:762
++
struct libevdev * libevdev_new(void)
Initialize a new libevdev device.
++
int libevdev_grab(struct libevdev *dev, enum libevdev_grab_mode grab)
Grab or ungrab the device through a kernel EVIOCGRAB.
+
int libevdev_set_fd(struct libevdev *dev, int fd)
Set the fd for this struct and initialize internal data.
+-
void libevdev_set_id_vendor(struct libevdev *dev, int vendor_id)
+-
void libevdev_set_abs_flat(struct libevdev *dev, unsigned int code, int val)
Change the flat for the given EV_ABS event code, if the code exists.
++
int libevdev_new_from_fd(int fd, struct libevdev **dev)
Initialize a new libevdev device from the given fd.
++
libevdev_grab_mode
Definition: libevdev.h:958
++
int libevdev_get_fd(const struct libevdev *dev)
++
int libevdev_change_fd(struct libevdev *dev, int fd)
Change the fd for this device, without re-reading the actual device.
+
void libevdev_free(struct libevdev *dev)
Clean up and free the libevdev struct.
+-
enum libevdev_log_priority libevdev_get_log_priority(void)
Return the current log priority level.
+-
int libevdev_get_repeat(const struct libevdev *dev, int *delay, int *period)
Get the repeat delay and repeat period values for this device.
+-
int libevdev_fetch_slot_value(const struct libevdev *dev, unsigned int slot, unsigned int code, int *value)
Fetch the current value of the code for the given slot.
++
@ LIBEVDEV_UNGRAB
Ungrab the device if currently grabbed.
Definition: libevdev.h:960
++
@ LIBEVDEV_GRAB
Grab the device if not currently grabbed.
Definition: libevdev.h:959
++
int libevdev_set_slot_value(struct libevdev *dev, unsigned int slot, unsigned int code, int value)
Set the value for a given code for the given slot.
++
void libevdev_set_abs_resolution(struct libevdev *dev, unsigned int code, int val)
Change the resolution for the given EV_ABS event code, if the code exists.
++
void libevdev_set_abs_maximum(struct libevdev *dev, unsigned int code, int val)
Change the maximum for the given EV_ABS event code, if the code exists.
++
int libevdev_set_clock_id(struct libevdev *dev, int clockid)
Set the clock ID to be used for timestamps.
++
int libevdev_kernel_set_abs_info(struct libevdev *dev, unsigned int code, const struct input_absinfo *abs)
Set the device's EV_ABS axis to the value defined in the abs parameter.
++
void libevdev_set_uniq(struct libevdev *dev, const char *uniq)
Change the device's unique identifier as returned by libevdev_get_uniq().
++
int libevdev_enable_event_code(struct libevdev *dev, unsigned int type, unsigned int code, const void *data)
Forcibly enable an event code on this device, even if the underlying device does not support it.
++
int libevdev_enable_event_type(struct libevdev *dev, unsigned int type)
Forcibly enable an event type on this device, even if the underlying device does not support it.
++
int libevdev_disable_event_code(struct libevdev *dev, unsigned int type, unsigned int code)
Forcibly disable an event code on this device, even if the underlying device provides it.
+
void libevdev_set_id_product(struct libevdev *dev, int product_id)
+-
@ LIBEVDEV_READ_FLAG_FORCE_SYNC
Pretend the next event is a SYN_DROPPED and require the caller to sync.
Definition: libevdev.h:760
+-
int libevdev_has_event_type(const struct libevdev *dev, unsigned int type)
++
int libevdev_set_event_value(struct libevdev *dev, unsigned int type, unsigned int code, int value)
Set the value for a given event type and code.
++
libevdev_led_value
Definition: libevdev.h:1919
++
void libevdev_set_id_vendor(struct libevdev *dev, int vendor_id)
++
int libevdev_disable_property(struct libevdev *dev, unsigned int prop)
++
int libevdev_kernel_set_led_values(struct libevdev *dev,...)
Turn multiple LEDs on or off simultaneously.
++
void libevdev_set_abs_fuzz(struct libevdev *dev, unsigned int code, int val)
Change the fuzz for the given EV_ABS event code, if the code exists.
++
int libevdev_kernel_set_led_value(struct libevdev *dev, unsigned int code, enum libevdev_led_value value)
Turn an LED on or off.
++
int libevdev_disable_event_type(struct libevdev *dev, unsigned int type)
Forcibly disable an event type on this device, even if the underlying device provides it.
++
void libevdev_set_abs_flat(struct libevdev *dev, unsigned int code, int val)
Change the flat for the given EV_ABS event code, if the code exists.
+
void libevdev_set_abs_minimum(struct libevdev *dev, unsigned int code, int val)
Change the minimum for the given EV_ABS event code, if the code exists.
+-
@ LIBEVDEV_LOG_INFO
informational messages
Definition: libevdev.h:825
+-
int libevdev_has_event_pending(struct libevdev *dev)
Check if there are events waiting for us.
+-
void libevdev_set_abs_info(struct libevdev *dev, unsigned int code, const struct input_absinfo *abs)
Change the abs info for the given EV_ABS event code, if the code exists.
+-
int libevdev_get_id_bustype(const struct libevdev *dev)
++
void libevdev_set_phys(struct libevdev *dev, const char *phys)
Change the device's physical location as returned by libevdev_get_phys().
+
void libevdev_set_name(struct libevdev *dev, const char *name)
Change the device's name as returned by libevdev_get_name().
+-
const char * libevdev_get_uniq(const struct libevdev *dev)
Retrieve the device's unique identifier, either as set by the caller or as read from the kernel.
++
void libevdev_set_id_version(struct libevdev *dev, int version)
+
void libevdev_set_id_bustype(struct libevdev *dev, int bustype)
+-
libevdev_read_flag
Definition: libevdev.h:757
+-
int libevdev_get_id_product(const struct libevdev *dev)
++
int libevdev_enable_property(struct libevdev *dev, unsigned int prop)
++
void libevdev_set_abs_info(struct libevdev *dev, unsigned int code, const struct input_absinfo *abs)
Change the abs info for the given EV_ABS event code, if the code exists.
++
@ LIBEVDEV_LED_OFF
Turn the LED off.
Definition: libevdev.h:1921
++
@ LIBEVDEV_LED_ON
Turn the LED on.
Definition: libevdev.h:1920
++
libevdev_log_priority
Definition: libevdev.h:826
++
enum libevdev_log_priority libevdev_get_log_priority(void)
Return the current log priority level.
+
void libevdev_set_device_log_function(struct libevdev *dev, libevdev_device_log_func_t logfunc, enum libevdev_log_priority priority, void *data)
Set a printf-style logging handler for library-internal logging for this device context.
+-
libevdev_led_value
Definition: libevdev.h:1917
+-
int libevdev_get_id_vendor(const struct libevdev *dev)
+-
void libevdev_set_uniq(struct libevdev *dev, const char *uniq)
Change the device's unique identifier as returned by libevdev_get_uniq().
+-
@ LIBEVDEV_LOG_ERROR
critical errors and application bugs
Definition: libevdev.h:824
+-
int libevdev_get_abs_flat(const struct libevdev *dev, unsigned int code)
Get the axis flat for the given axis, as advertised by the kernel.
+-
int libevdev_get_num_slots(const struct libevdev *dev)
Get the number of slots supported by this device.
+-
@ LIBEVDEV_READ_STATUS_SYNC
Depending on the libevdev_next_event() read flag:
Definition: libevdev.h:1087
+-
@ LIBEVDEV_LOG_DEBUG
debug information
Definition: libevdev.h:826
+-
int libevdev_next_event(struct libevdev *dev, unsigned int flags, struct input_event *ev)
Get the next event from the device.
+-
int libevdev_get_abs_minimum(const struct libevdev *dev, unsigned int code)
Get the minimum axis value for the given axis, as advertised by the kernel.
+-
int libevdev_disable_property(struct libevdev *dev, unsigned int prop)
+-
@ LIBEVDEV_READ_STATUS_SUCCESS
libevdev_next_event() has finished without an error and an event is available for processing.
Definition: libevdev.h:1078
+-
int libevdev_get_current_slot(const struct libevdev *dev)
Get the currently active slot.
++
void libevdev_set_log_function(libevdev_log_func_t logfunc, void *data)
Set a printf-style logging handler for library-internal logging.
++
void(* libevdev_device_log_func_t)(const struct libevdev *dev, enum libevdev_log_priority priority, void *data, const char *file, int line, const char *func, const char *format, va_list args)
Logging function called by library-internal logging for a specific libevdev context.
Definition: libevdev.h:921
++
void(* libevdev_log_func_t)(enum libevdev_log_priority priority, void *data, const char *file, int line, const char *func, const char *format, va_list args)
Logging function called by library-internal logging.
Definition: libevdev.h:848
++
void libevdev_set_log_priority(enum libevdev_log_priority priority)
Define the minimum level to be printed to the log handler.
++
@ LIBEVDEV_LOG_ERROR
critical errors and application bugs
Definition: libevdev.h:827
++
@ LIBEVDEV_LOG_INFO
informational messages
Definition: libevdev.h:828
++
@ LIBEVDEV_LOG_DEBUG
debug information
Definition: libevdev.h:829
++
int libevdev_event_code_from_name_n(unsigned int type, const char *name, size_t len)
Look up an event code by its type and name.
++
int libevdev_event_value_from_name(unsigned int type, unsigned int code, const char *name)
Look up an event value by its type, code and name.
+
int libevdev_event_is_code(const struct input_event *ev, unsigned int type, unsigned int code)
Helper function to check if an event is of a specific type and code.
+-
int libevdev_enable_event_code(struct libevdev *dev, unsigned int type, unsigned int code, const void *data)
Forcibly enable an event code on this device, even if the underlying device does not support it.
+-
const char * libevdev_property_get_name(unsigned int prop)
+-
const char * libevdev_event_value_get_name(unsigned int type, unsigned int code, int value)
This function resolves the event value for a code.
+-
int libevdev_get_driver_version(const struct libevdev *dev)
++
int libevdev_event_type_from_name_n(const char *name, size_t len)
Look up an event-type by its name.
++
int libevdev_event_code_from_code_name_n(const char *name, size_t len)
Look up an event code by its name.
++
int libevdev_event_type_from_name(const char *name)
Look up an event-type by its name.
+
int libevdev_event_code_from_name(unsigned int type, const char *name)
Look up an event code by its type and name.
+-
int libevdev_set_clock_id(struct libevdev *dev, int clockid)
Set the clock ID to be used for timestamps.
+-
int libevdev_get_abs_maximum(const struct libevdev *dev, unsigned int code)
Get the maximum axis value for the given axis, as advertised by the kernel.
+-
void libevdev_set_phys(struct libevdev *dev, const char *phys)
Change the device's physical location as returned by libevdev_get_phys().
+-
int libevdev_disable_event_code(struct libevdev *dev, unsigned int type, unsigned int code)
Forcibly disable an event code on this device, even if the underlying device provides it.
+-
int libevdev_change_fd(struct libevdev *dev, int fd)
Change the fd for this device, without re-reading the actual device.
+-
int libevdev_disable_event_type(struct libevdev *dev, unsigned int type)
Forcibly disable an event type on this device, even if the underlying device provides it.
+-
const char * libevdev_get_phys(const struct libevdev *dev)
Retrieve the device's physical location, either as set by the caller or as read from the kernel.
+-
int libevdev_get_fd(const struct libevdev *dev)
+-
int libevdev_get_abs_fuzz(const struct libevdev *dev, unsigned int code)
Get the axis fuzz for the given axis, as advertised by the kernel.
+-
void libevdev_set_abs_fuzz(struct libevdev *dev, unsigned int code, int val)
Change the fuzz for the given EV_ABS event code, if the code exists.
+-
const char * libevdev_event_type_get_name(unsigned int type)
+-
void libevdev_set_log_priority(enum libevdev_log_priority priority)
Define the minimum level to be printed to the log handler.
+-
int libevdev_event_code_from_code_name(const char *name)
Look up an event code by its name.
+-
int libevdev_grab(struct libevdev *dev, enum libevdev_grab_mode grab)
Grab or ungrab the device through a kernel EVIOCGRAB.
++
int libevdev_property_from_name(const char *name)
Look up an input property by its name.
++
int libevdev_property_from_name_n(const char *name, size_t len)
Look up an input property by its name.
++
int libevdev_event_type_from_code_name_n(const char *name, size_t len)
Look up an event type for a event code name.
++
const char * libevdev_event_code_get_name(unsigned int type, unsigned int code)
+
int libevdev_event_is_type(const struct input_event *ev, unsigned int type)
Helper function to check if an event is of a specific type.
+-
libevdev_grab_mode
Definition: libevdev.h:955
+-
const char * libevdev_get_name(const struct libevdev *dev)
Retrieve the device's name, either as set by the caller or as read from the kernel.
+-
@ LIBEVDEV_LED_ON
Turn the LED on.
Definition: libevdev.h:1918
+-
void libevdev_set_abs_maximum(struct libevdev *dev, unsigned int code, int val)
Change the maximum for the given EV_ABS event code, if the code exists.
+-
@ LIBEVDEV_READ_FLAG_NORMAL
Process data in normal mode.
Definition: libevdev.h:759
+-
@ LIBEVDEV_READ_FLAG_SYNC
Process data in sync mode.
Definition: libevdev.h:758
+-
void(* libevdev_device_log_func_t)(const struct libevdev *dev, enum libevdev_log_priority priority, void *data, const char *file, int line, const char *func, const char *format, va_list args)
Logging function called by library-internal logging for a specific libevdev context.
Definition: libevdev.h:918
+-
int libevdev_set_event_value(struct libevdev *dev, unsigned int type, unsigned int code, int value)
Set the value for a given event type and code.
++
int libevdev_event_code_from_code_name(const char *name)
Look up an event code by its name.
++
const char * libevdev_event_value_get_name(unsigned int type, unsigned int code, int value)
This function resolves the event value for a code.
++
int libevdev_event_type_get_max(unsigned int type)
++
const char * libevdev_event_type_get_name(unsigned int type)
++
const char * libevdev_property_get_name(unsigned int prop)
+
int libevdev_event_type_from_code_name(const char *name)
Look up an event type for a event code name.
+-
int libevdev_new_from_fd(int fd, struct libevdev **dev)
Initialize a new libevdev device from the given fd.
++
int libevdev_event_value_from_name_n(unsigned int type, unsigned int code, const char *name, size_t len)
Look up an event value by its type, code and name.
++
int libevdev_get_slot_value(const struct libevdev *dev, unsigned int slot, unsigned int code)
Return the current value of the code for the given slot.
++
int libevdev_fetch_slot_value(const struct libevdev *dev, unsigned int slot, unsigned int code, int *value)
Fetch the current value of the code for the given slot.
++
int libevdev_get_current_slot(const struct libevdev *dev)
Get the currently active slot.
++
int libevdev_get_num_slots(const struct libevdev *dev)
Get the number of slots supported by this device.
++
#define LIBEVDEV_ATTRIBUTE_PRINTF(_format, _args)
Definition: libevdev.h:36
++
+ + + +@@ -452,7 +455,7 @@ + + + +diff -Naur third-party-libevdev-bak/doc/html/modules.html third-party-new/doc/html/modules.html +--- third-party-libevdev-bak/doc/html/modules.html 2023-03-28 10:49:53.380511700 +0800 ++++ third-party-new/doc/html/modules.html 2023-04-03 10:49:22.111306600 +0800 +@@ -6,7 +6,7 @@ + + + +- ++ + + libevdev: Modules + +@@ -25,7 +25,7 @@ + +@@ -36,10 +36,10 @@ +
+
+ +- ++ + + +@@ -95,7 +95,7 @@ + + + +diff -Naur third-party-libevdev-bak/doc/html/pages.html third-party-new/doc/html/pages.html +--- third-party-libevdev-bak/doc/html/pages.html 2023-03-28 10:49:53.380511700 +0800 ++++ third-party-new/doc/html/pages.html 2023-04-03 10:50:28.099788400 +0800 +@@ -6,7 +6,7 @@ + + + +- ++ + + libevdev: Related Pages + +@@ -25,7 +25,7 @@ + +@@ -36,10 +36,10 @@ +
+
+ +- ++ + + +@@ -94,7 +94,7 @@ + + + +diff -Naur third-party-libevdev-bak/doc/html/search/all_0.html third-party-new/doc/html/search/all_0.html +--- third-party-libevdev-bak/doc/html/search/all_0.html 2023-03-28 10:49:53.380511700 +0800 ++++ third-party-new/doc/html/search/all_0.html 2023-04-01 15:28:57.446773800 +0800 +@@ -1,7 +1,8 @@ + +- ++ ++ + +- ++ + + + +@@ -10,14 +11,14 @@ +
+
Loading...
+
+- ++ +
Searching...
+
No Matches
+- ++ +
+ + +diff -Naur third-party-libevdev-bak/doc/html/search/all_1.html third-party-new/doc/html/search/all_1.html +--- third-party-libevdev-bak/doc/html/search/all_1.html 2023-03-28 10:49:53.380511700 +0800 ++++ third-party-new/doc/html/search/all_1.html 2023-04-01 15:29:16.503763700 +0800 +@@ -1,7 +1,8 @@ + +- ++ ++ + +- ++ + + + +@@ -10,14 +11,14 @@ +
+
Loading...
+
+- ++ +
Searching...
+
No Matches
+- ++ +
+ + +diff -Naur third-party-libevdev-bak/doc/html/search/all_2.html third-party-new/doc/html/search/all_2.html +--- third-party-libevdev-bak/doc/html/search/all_2.html 2023-03-28 10:49:53.380511700 +0800 ++++ third-party-new/doc/html/search/all_2.html 2023-04-01 15:29:31.940338000 +0800 +@@ -1,7 +1,8 @@ + +- ++ ++ + +- ++ + + + +@@ -10,14 +11,14 @@ +
+
Loading...
+
+- ++ +
Searching...
+
No Matches
+- ++ +
+ + +diff -Naur third-party-libevdev-bak/doc/html/search/all_2.js third-party-new/doc/html/search/all_2.js +--- third-party-libevdev-bak/doc/html/search/all_2.js 2023-03-28 10:49:53.380511700 +0800 ++++ third-party-new/doc/html/search/all_2.js 2023-04-01 15:30:08.670223600 +0800 +@@ -1,5 +1,5 @@ + var searchData= + [ +- ['event_20handling_2',['Event handling',['../group__events.html',1,'']]], +- ['evdev_20ioctls_3',['evdev ioctls',['../ioctls.html',1,'']]] ++ ['evdev_20ioctls_2',['evdev ioctls',['../ioctls.html',1,'']]], ++ ['event_20handling_3',['Event handling',['../group__events.html',1,'']]] + ]; +diff -Naur third-party-libevdev-bak/doc/html/search/all_3.html third-party-new/doc/html/search/all_3.html +--- third-party-libevdev-bak/doc/html/search/all_3.html 2023-03-28 10:49:53.380511700 +0800 ++++ third-party-new/doc/html/search/all_3.html 2023-04-01 15:30:20.097653000 +0800 +@@ -1,7 +1,8 @@ + +- ++ ++ + +- ++ + + + +@@ -10,14 +11,14 @@ +
+
Loading...
+
+- ++ +
Searching...
+
No Matches
+- ++ +
+ + +diff -Naur third-party-libevdev-bak/doc/html/search/all_4.html third-party-new/doc/html/search/all_4.html +--- third-party-libevdev-bak/doc/html/search/all_4.html 2023-03-28 10:49:53.380511700 +0800 ++++ third-party-new/doc/html/search/all_4.html 2023-04-01 15:30:33.994637700 +0800 +@@ -1,7 +1,8 @@ + +- ++ ++ + +- ++ + + + +@@ -10,14 +11,14 @@ +
+
Loading...
+
+- ++ +
Searching...
+
No Matches
+- ++ +
+ + +diff -Naur third-party-libevdev-bak/doc/html/search/all_5.html third-party-new/doc/html/search/all_5.html +--- third-party-libevdev-bak/doc/html/search/all_5.html 2023-03-28 10:49:53.380511700 +0800 ++++ third-party-new/doc/html/search/all_5.html 2023-04-01 15:30:46.610374600 +0800 +@@ -1,7 +1,8 @@ + +- ++ ++ + +- ++ + + + +@@ -10,14 +11,14 @@ +
+
Loading...
+
+- ++ +
Searching...
+
No Matches
+- ++ +
+ + +diff -Naur third-party-libevdev-bak/doc/html/search/all_5.js third-party-new/doc/html/search/all_5.js +--- third-party-libevdev-bak/doc/html/search/all_5.js 2023-03-28 10:49:53.380511700 +0800 ++++ third-party-new/doc/html/search/all_5.js 2023-04-01 15:31:04.034005000 +0800 +@@ -1,117 +1,118 @@ + var searchData= + [ +- ['libevdev_2duinput_2eh_6',['libevdev-uinput.h',['../libevdev-uinput_8h.html',1,'']]], +- ['libevdev_2eh_7',['libevdev.h',['../libevdev_8h.html',1,'']]], +- ['libevdev_5fattribute_5fprintf_8',['LIBEVDEV_ATTRIBUTE_PRINTF',['../libevdev_8h.html#a64a0f325e88e1be50eb806e1ff75aec8',1,'libevdev.h']]], +- ['libevdev_5fchange_5ffd_9',['libevdev_change_fd',['../group__init.html#gac71c9cca4c572ed1b1a8c233be70a17c',1,'libevdev.h']]], +- ['libevdev_5fdeprecated_10',['LIBEVDEV_DEPRECATED',['../libevdev_8h.html#aa136bf4638abda28de7cd9f48af534ae',1,'libevdev.h']]], +- ['libevdev_5fdevice_5flog_5ffunc_5ft_11',['libevdev_device_log_func_t',['../group__logging.html#gab7eb997be2b701cc6f42e7b4c3478269',1,'libevdev.h']]], +- ['libevdev_5fdisable_5fevent_5fcode_12',['libevdev_disable_event_code',['../group__kernel.html#ga6199a7c8144f54e092e913c2d2df16de',1,'libevdev.h']]], +- ['libevdev_5fdisable_5fevent_5ftype_13',['libevdev_disable_event_type',['../group__kernel.html#gabbacb53b66882b5335055c0fd1f40d9a',1,'libevdev.h']]], +- ['libevdev_5fdisable_5fproperty_14',['libevdev_disable_property',['../group__kernel.html#ga8f6367c36331c803ad69b2591e210019',1,'libevdev.h']]], +- ['libevdev_5fenable_5fevent_5fcode_15',['libevdev_enable_event_code',['../group__kernel.html#ga51cfda33fd526549046399aadd764fca',1,'libevdev.h']]], +- ['libevdev_5fenable_5fevent_5ftype_16',['libevdev_enable_event_type',['../group__kernel.html#ga59ef78b1557f9543d0060ab25b0167ca',1,'libevdev.h']]], +- ['libevdev_5fenable_5fproperty_17',['libevdev_enable_property',['../group__kernel.html#gafc552080520c9d886452b05f3a1d75b6',1,'libevdev.h']]], +- ['libevdev_5fevent_5fcode_5ffrom_5fcode_5fname_18',['libevdev_event_code_from_code_name',['../group__misc.html#gabad00f68481d83747a134c0a37aca003',1,'libevdev.h']]], +- ['libevdev_5fevent_5fcode_5ffrom_5fcode_5fname_5fn_19',['libevdev_event_code_from_code_name_n',['../group__misc.html#ga5bf9af4b8c372d87793e8a3c2dbeb466',1,'libevdev.h']]], +- ['libevdev_5fevent_5fcode_5ffrom_5fname_20',['libevdev_event_code_from_name',['../group__misc.html#ga6620301a67f467489e4a7f93afe81621',1,'libevdev.h']]], +- ['libevdev_5fevent_5fcode_5ffrom_5fname_5fn_21',['libevdev_event_code_from_name_n',['../group__misc.html#ga17a760a9eea9dc25011f39e1d5c282a0',1,'libevdev.h']]], +- ['libevdev_5fevent_5fcode_5fget_5fname_22',['libevdev_event_code_get_name',['../group__misc.html#gab407b3c2caaae502859c28460cad17bb',1,'libevdev.h']]], +- ['libevdev_5fevent_5fis_5fcode_23',['libevdev_event_is_code',['../group__misc.html#ga37766a6a498fef3294d589abcce688bb',1,'libevdev.h']]], +- ['libevdev_5fevent_5fis_5ftype_24',['libevdev_event_is_type',['../group__misc.html#gab8b6b80740e028261300b8952b61a596',1,'libevdev.h']]], +- ['libevdev_5fevent_5ftype_5ffrom_5fcode_5fname_25',['libevdev_event_type_from_code_name',['../group__misc.html#gadd41b7514cca16c8b8920f16e562e08a',1,'libevdev.h']]], +- ['libevdev_5fevent_5ftype_5ffrom_5fcode_5fname_5fn_26',['libevdev_event_type_from_code_name_n',['../group__misc.html#gab214498fca7a328f8a712ce15bf21982',1,'libevdev.h']]], +- ['libevdev_5fevent_5ftype_5ffrom_5fname_27',['libevdev_event_type_from_name',['../group__misc.html#ga61ce3bf1e66bd172e583b86a11fc41f1',1,'libevdev.h']]], +- ['libevdev_5fevent_5ftype_5ffrom_5fname_5fn_28',['libevdev_event_type_from_name_n',['../group__misc.html#ga4ee03d650200bb04a23233570667fa84',1,'libevdev.h']]], +- ['libevdev_5fevent_5ftype_5fget_5fmax_29',['libevdev_event_type_get_max',['../group__misc.html#gabfad87ea78d034631cf3e5322ac383a1',1,'libevdev.h']]], +- ['libevdev_5fevent_5ftype_5fget_5fname_30',['libevdev_event_type_get_name',['../group__misc.html#gac99720fd926bf288764f9a81bf37ed09',1,'libevdev.h']]], +- ['libevdev_5fevent_5fvalue_5ffrom_5fname_31',['libevdev_event_value_from_name',['../group__misc.html#ga314903beeafedabe45f879637e7254b0',1,'libevdev.h']]], +- ['libevdev_5fevent_5fvalue_5ffrom_5fname_5fn_32',['libevdev_event_value_from_name_n',['../group__misc.html#gaebfc6b0ebb70169c9fec61620f1ea85f',1,'libevdev.h']]], +- ['libevdev_5fevent_5fvalue_5fget_5fname_33',['libevdev_event_value_get_name',['../group__misc.html#gabcd45c5e963cba245e944ea66e72fcc3',1,'libevdev.h']]], +- ['libevdev_5ffetch_5fevent_5fvalue_34',['libevdev_fetch_event_value',['../group__bits.html#ga0a7be80d769294bf9758adf79c3c7147',1,'libevdev.h']]], +- ['libevdev_5ffetch_5fslot_5fvalue_35',['libevdev_fetch_slot_value',['../group__mt.html#gaca19dca5aa8f0ea3b210f3fc670384ec',1,'libevdev.h']]], +- ['libevdev_5ffree_36',['libevdev_free',['../group__init.html#gacd9fe760d15be25fc99ce469034bd78c',1,'libevdev.h']]], +- ['libevdev_5fget_5fabs_5fflat_37',['libevdev_get_abs_flat',['../group__bits.html#ga6b3f7ebae2324524dc41384acd724b92',1,'libevdev.h']]], +- ['libevdev_5fget_5fabs_5ffuzz_38',['libevdev_get_abs_fuzz',['../group__bits.html#ga1a3dfeb3bb2db0b4323c836c7ab10f1a',1,'libevdev.h']]], +- ['libevdev_5fget_5fabs_5finfo_39',['libevdev_get_abs_info',['../group__bits.html#ga6d8e2caf87fa536fad979346671838d7',1,'libevdev.h']]], +- ['libevdev_5fget_5fabs_5fmaximum_40',['libevdev_get_abs_maximum',['../group__bits.html#ga97a3411ae85f1f3b5c5eb1d5351b11ca',1,'libevdev.h']]], +- ['libevdev_5fget_5fabs_5fminimum_41',['libevdev_get_abs_minimum',['../group__bits.html#ga482ce989a3f62f7e67e4ea7ad534189e',1,'libevdev.h']]], +- ['libevdev_5fget_5fabs_5fresolution_42',['libevdev_get_abs_resolution',['../group__bits.html#ga75751e637a845201b6d1c419ecfa6ba4',1,'libevdev.h']]], +- ['libevdev_5fget_5fcurrent_5fslot_43',['libevdev_get_current_slot',['../group__mt.html#gad22e2420be668b56ef486cde2e98c5dd',1,'libevdev.h']]], +- ['libevdev_5fget_5fdriver_5fversion_44',['libevdev_get_driver_version',['../group__bits.html#ga31e9e7a99215a03bcdc339b53e1be2fa',1,'libevdev.h']]], +- ['libevdev_5fget_5fevent_5fvalue_45',['libevdev_get_event_value',['../group__bits.html#ga6259f4c6bdba950329ff9cd48c2ef8a3',1,'libevdev.h']]], +- ['libevdev_5fget_5ffd_46',['libevdev_get_fd',['../group__init.html#gab9bfc800859ac3aa63f41d58ec4b616c',1,'libevdev.h']]], +- ['libevdev_5fget_5fid_5fbustype_47',['libevdev_get_id_bustype',['../group__bits.html#ga9bf55d416401642bad0c435735682308',1,'libevdev.h']]], +- ['libevdev_5fget_5fid_5fproduct_48',['libevdev_get_id_product',['../group__bits.html#ga1dc66cfef646878d58be72f8902a6bac',1,'libevdev.h']]], +- ['libevdev_5fget_5fid_5fvendor_49',['libevdev_get_id_vendor',['../group__bits.html#ga08891c3285da5b8d26769c9a34f063f3',1,'libevdev.h']]], +- ['libevdev_5fget_5fid_5fversion_50',['libevdev_get_id_version',['../group__bits.html#ga75a07d0c96dfe09d2194c104c429d0ae',1,'libevdev.h']]], +- ['libevdev_5fget_5flog_5fpriority_51',['libevdev_get_log_priority',['../group__logging.html#ga1da07493a798595cf85c127490b98ee8',1,'libevdev.h']]], +- ['libevdev_5fget_5fname_52',['libevdev_get_name',['../group__bits.html#gaed0328c67b7a78422636d9fe09a73f12',1,'libevdev.h']]], +- ['libevdev_5fget_5fnum_5fslots_53',['libevdev_get_num_slots',['../group__mt.html#gaf272526f0a59d2f61ef7389046cd4088',1,'libevdev.h']]], +- ['libevdev_5fget_5fphys_54',['libevdev_get_phys',['../group__bits.html#ga5df483b0b24d7b96ea1181808fab851d',1,'libevdev.h']]], +- ['libevdev_5fget_5frepeat_55',['libevdev_get_repeat',['../group__bits.html#gaf12fa199bb9497b38358d72e7505d770',1,'libevdev.h']]], +- ['libevdev_5fget_5fslot_5fvalue_56',['libevdev_get_slot_value',['../group__mt.html#ga8c6303391cb4f90b2d46763cf4eb8bc8',1,'libevdev.h']]], +- ['libevdev_5fget_5funiq_57',['libevdev_get_uniq',['../group__bits.html#ga6d9f7d44bff8828ead3d251177035ca4',1,'libevdev.h']]], +- ['libevdev_5fgrab_58',['LIBEVDEV_GRAB',['../group__init.html#ggaa282ec9badaa6bc11b1dc5bb124dbd5bad3ac6f5f3ebf7d38a6aad74a88396c88',1,'LIBEVDEV_GRAB(): libevdev.h'],['../group__init.html#ga5d434af74fee20f273db568e2cbbd13f',1,'libevdev_grab(struct libevdev *dev, enum libevdev_grab_mode grab): libevdev.h']]], +- ['libevdev_5fgrab_5fmode_59',['libevdev_grab_mode',['../group__init.html#gaa282ec9badaa6bc11b1dc5bb124dbd5b',1,'libevdev.h']]], +- ['libevdev_5fhas_5fevent_5fcode_60',['libevdev_has_event_code',['../group__bits.html#gab2ab9dad417f33daa79fa0c3d682df0b',1,'libevdev.h']]], +- ['libevdev_5fhas_5fevent_5fpending_61',['libevdev_has_event_pending',['../group__events.html#gae18fbfb59064c9c4b9d5db2d8cb23784',1,'libevdev.h']]], +- ['libevdev_5fhas_5fevent_5ftype_62',['libevdev_has_event_type',['../group__bits.html#ga398bef155fa4a0cfb832de30723ebd14',1,'libevdev.h']]], +- ['libevdev_5fhas_5fproperty_63',['libevdev_has_property',['../group__bits.html#ga36d529ea53f4522004bc7d16c051464b',1,'libevdev.h']]], +- ['libevdev_5fkernel_5fset_5fabs_5finfo_64',['libevdev_kernel_set_abs_info',['../group__kernel.html#ga41c0321b93349d0ddd1f1c007ccf7de9',1,'libevdev.h']]], +- ['libevdev_5fkernel_5fset_5fled_5fvalue_65',['libevdev_kernel_set_led_value',['../group__kernel.html#gaa7d13aeac3c40e16f296467780e67c01',1,'libevdev.h']]], +- ['libevdev_5fkernel_5fset_5fled_5fvalues_66',['libevdev_kernel_set_led_values',['../group__kernel.html#ga93a19fa6e5be57903aff7c4a60af2a00',1,'libevdev.h']]], +- ['libevdev_5fled_5foff_67',['LIBEVDEV_LED_OFF',['../group__kernel.html#gga8cddf7779debef0067665671e911ec41a23e508440306c387ddf89acd2db9e065',1,'libevdev.h']]], +- ['libevdev_5fled_5fon_68',['LIBEVDEV_LED_ON',['../group__kernel.html#gga8cddf7779debef0067665671e911ec41a69d5a4cdf2a9357915fff0251a61d2ab',1,'libevdev.h']]], +- ['libevdev_5fled_5fvalue_69',['libevdev_led_value',['../group__kernel.html#ga8cddf7779debef0067665671e911ec41',1,'libevdev.h']]], +- ['libevdev_5flog_5fdebug_70',['LIBEVDEV_LOG_DEBUG',['../group__logging.html#gga0b798d0864f2b1b10e4603f9431b3364a760d66d422ffcf89b0f1ddb529b95793',1,'libevdev.h']]], +- ['libevdev_5flog_5ferror_71',['LIBEVDEV_LOG_ERROR',['../group__logging.html#gga0b798d0864f2b1b10e4603f9431b3364a21fd1083f2ebd0a25f09ee982e365d5f',1,'libevdev.h']]], +- ['libevdev_5flog_5ffunc_5ft_72',['libevdev_log_func_t',['../group__logging.html#gaf36c721d273c0794251eb7dacea2f0a4',1,'libevdev.h']]], +- ['libevdev_5flog_5finfo_73',['LIBEVDEV_LOG_INFO',['../group__logging.html#gga0b798d0864f2b1b10e4603f9431b3364a4d13a031b112292ca3e7bab8c6d76abc',1,'libevdev.h']]], +- ['libevdev_5flog_5fpriority_74',['libevdev_log_priority',['../group__logging.html#ga0b798d0864f2b1b10e4603f9431b3364',1,'libevdev.h']]], +- ['libevdev_5fnew_75',['libevdev_new',['../group__init.html#ga332c8ee260b4ef864345abe5d04e820c',1,'libevdev.h']]], +- ['libevdev_5fnew_5ffrom_5ffd_76',['libevdev_new_from_fd',['../group__init.html#ga89bb5bce1c23e293293484b05b12aaf4',1,'libevdev.h']]], +- ['libevdev_5fnext_5fevent_77',['libevdev_next_event',['../group__events.html#gabb96c864e836c0b98788f4ab771c3a76',1,'libevdev.h']]], +- ['libevdev_5fproperty_5ffrom_5fname_78',['libevdev_property_from_name',['../group__misc.html#ga6f4418c98aa475a2fc34d58a197f7edd',1,'libevdev.h']]], +- ['libevdev_5fproperty_5ffrom_5fname_5fn_79',['libevdev_property_from_name_n',['../group__misc.html#gaaa0bc4c7d0d2aedc84c7dcffee9ce29b',1,'libevdev.h']]], +- ['libevdev_5fproperty_5fget_5fname_80',['libevdev_property_get_name',['../group__misc.html#gacc12bdb7b912070ac9c375428f2c9892',1,'libevdev.h']]], +- ['libevdev_5fread_5fflag_81',['libevdev_read_flag',['../group__events.html#ga56c288d9f2e4c1632986c4e218c494e9',1,'libevdev.h']]], +- ['libevdev_5fread_5fflag_5fblocking_82',['LIBEVDEV_READ_FLAG_BLOCKING',['../group__events.html#gga56c288d9f2e4c1632986c4e218c494e9a0a348d44362a7e515b40a4ed4d528e19',1,'libevdev.h']]], +- ['libevdev_5fread_5fflag_5fforce_5fsync_83',['LIBEVDEV_READ_FLAG_FORCE_SYNC',['../group__events.html#gga56c288d9f2e4c1632986c4e218c494e9a5198e5c9cc98b75f73f61b104d6a674c',1,'libevdev.h']]], +- ['libevdev_5fread_5fflag_5fnormal_84',['LIBEVDEV_READ_FLAG_NORMAL',['../group__events.html#gga56c288d9f2e4c1632986c4e218c494e9ac0d6ee19551eecf76f1ede4f36252418',1,'libevdev.h']]], +- ['libevdev_5fread_5fflag_5fsync_85',['LIBEVDEV_READ_FLAG_SYNC',['../group__events.html#gga56c288d9f2e4c1632986c4e218c494e9a1f13a19641d6dafcf01a86a6389800f8',1,'libevdev.h']]], +- ['libevdev_5fread_5fstatus_86',['libevdev_read_status',['../group__events.html#ga4a96221b3c7f54dfb86035d952154e3a',1,'libevdev.h']]], +- ['libevdev_5fread_5fstatus_5fsuccess_87',['LIBEVDEV_READ_STATUS_SUCCESS',['../group__events.html#gga4a96221b3c7f54dfb86035d952154e3aab053221fc1c9630eee7111b75aa0aec7',1,'libevdev.h']]], +- ['libevdev_5fread_5fstatus_5fsync_88',['LIBEVDEV_READ_STATUS_SYNC',['../group__events.html#gga4a96221b3c7f54dfb86035d952154e3aa8d70b14a38204fde4ad433023baa545a',1,'libevdev.h']]], +- ['libevdev_5fset_5fabs_5fflat_89',['libevdev_set_abs_flat',['../group__kernel.html#gabd309f30744a49e9391250b00ba2d67a',1,'libevdev.h']]], +- ['libevdev_5fset_5fabs_5ffuzz_90',['libevdev_set_abs_fuzz',['../group__kernel.html#gaa192bf0c68620be819337da6ec361c21',1,'libevdev.h']]], +- ['libevdev_5fset_5fabs_5finfo_91',['libevdev_set_abs_info',['../group__kernel.html#gafc7a4f5308e2dbf55f875630b8dca049',1,'libevdev.h']]], +- ['libevdev_5fset_5fabs_5fmaximum_92',['libevdev_set_abs_maximum',['../group__kernel.html#ga2302fd9a491d8e27280157d67a703af6',1,'libevdev.h']]], +- ['libevdev_5fset_5fabs_5fminimum_93',['libevdev_set_abs_minimum',['../group__kernel.html#gaca62172c2a823cd02eacf0d2292d917a',1,'libevdev.h']]], +- ['libevdev_5fset_5fabs_5fresolution_94',['libevdev_set_abs_resolution',['../group__kernel.html#ga2266b59711cdaa4fc12fa56c9313a038',1,'libevdev.h']]], +- ['libevdev_5fset_5fclock_5fid_95',['libevdev_set_clock_id',['../group__kernel.html#ga2925b6fbf8c7991ff2164424b840b82d',1,'libevdev.h']]], +- ['libevdev_5fset_5fdevice_5flog_5ffunction_96',['libevdev_set_device_log_function',['../group__logging.html#ga2830ff0aa391d8d1111682d3e762091b',1,'libevdev.h']]], +- ['libevdev_5fset_5fevent_5fvalue_97',['libevdev_set_event_value',['../group__kernel.html#ga79e82ee2a95cb08adb4172aabe0c7184',1,'libevdev.h']]], +- ['libevdev_5fset_5ffd_98',['libevdev_set_fd',['../group__init.html#ga6658ac490d68c307ff8b8d1536c12b44',1,'libevdev.h']]], +- ['libevdev_5fset_5fid_5fbustype_99',['libevdev_set_id_bustype',['../group__kernel.html#gaf99139c728ba1bd4b37ede612780b6b0',1,'libevdev.h']]], +- ['libevdev_5fset_5fid_5fproduct_100',['libevdev_set_id_product',['../group__kernel.html#ga62fbdaac056ab5c3db154a9eeaf33799',1,'libevdev.h']]], +- ['libevdev_5fset_5fid_5fvendor_101',['libevdev_set_id_vendor',['../group__kernel.html#ga8ce28051ebbb73de1d04d782f4d0d6fe',1,'libevdev.h']]], +- ['libevdev_5fset_5fid_5fversion_102',['libevdev_set_id_version',['../group__kernel.html#gaee1d2db88b191ec21d5bf22dd4fe3055',1,'libevdev.h']]], +- ['libevdev_5fset_5flog_5ffunction_103',['libevdev_set_log_function',['../group__logging.html#gaa60be86b83b3a6c82d8e536ba89ff955',1,'libevdev.h']]], +- ['libevdev_5fset_5flog_5fpriority_104',['libevdev_set_log_priority',['../group__logging.html#gaf6b6842a9ed98b61d0abb421e853fd89',1,'libevdev.h']]], +- ['libevdev_5fset_5fname_105',['libevdev_set_name',['../group__kernel.html#gae5dcdb7678cdc9be4ab1989725b4ed32',1,'libevdev.h']]], +- ['libevdev_5fset_5fphys_106',['libevdev_set_phys',['../group__kernel.html#gacd57c8d6ace8e0b1417809a9c1c67af3',1,'libevdev.h']]], +- ['libevdev_5fset_5fslot_5fvalue_107',['libevdev_set_slot_value',['../group__kernel.html#ga0c61f4919b03b0850529a50c37a20333',1,'libevdev.h']]], +- ['libevdev_5fset_5funiq_108',['libevdev_set_uniq',['../group__kernel.html#ga4e4fd2627744fd5811c50c7403f27ad7',1,'libevdev.h']]], +- ['libevdev_5fuinput_5fcreate_5ffrom_5fdevice_109',['libevdev_uinput_create_from_device',['../group__uinput.html#gaf14b21301bac9d79c20e890172873b96',1,'libevdev-uinput.h']]], +- ['libevdev_5fuinput_5fdestroy_110',['libevdev_uinput_destroy',['../group__uinput.html#ga9dfa58a84eb4c6b97107dcf3fa621329',1,'libevdev-uinput.h']]], +- ['libevdev_5fuinput_5fget_5fdevnode_111',['libevdev_uinput_get_devnode',['../group__uinput.html#ga4c595bcda748b08561e2819fe9b7c2d2',1,'libevdev-uinput.h']]], +- ['libevdev_5fuinput_5fget_5ffd_112',['libevdev_uinput_get_fd',['../group__uinput.html#ga9cd7fb14a96d4cc14d3dffdcead84c5d',1,'libevdev-uinput.h']]], +- ['libevdev_5fuinput_5fget_5fsyspath_113',['libevdev_uinput_get_syspath',['../group__uinput.html#gaacca93061fce57cec0ce3c52e443a427',1,'libevdev-uinput.h']]], +- ['libevdev_5fuinput_5fopen_5fmanaged_114',['LIBEVDEV_UINPUT_OPEN_MANAGED',['../libevdev-uinput_8h.html#a6546acd3e4fe75a74d91eebf9bbd3d03adcf2d4de38844ee3a8c830bc3285afad',1,'libevdev-uinput.h']]], +- ['libevdev_5fuinput_5fopen_5fmode_115',['libevdev_uinput_open_mode',['../libevdev-uinput_8h.html#a6546acd3e4fe75a74d91eebf9bbd3d03',1,'libevdev-uinput.h']]], +- ['libevdev_5fuinput_5fwrite_5fevent_116',['libevdev_uinput_write_event',['../group__uinput.html#ga4c3c2f5fcd315a28a067f53b9f855fe7',1,'libevdev-uinput.h']]], +- ['libevdev_5fungrab_117',['LIBEVDEV_UNGRAB',['../group__init.html#ggaa282ec9badaa6bc11b1dc5bb124dbd5ba6c0930d0c280753504cd05ebdcda09eb',1,'libevdev.h']]], +- ['library_20logging_20facilities_118',['Library logging facilities',['../group__logging.html',1,'']]], +- ['libevdev_2dinternal_20test_20suite_119',['libevdev-internal test suite',['../testing.html',1,'']]] ++ ['libevdev_2dinternal_20test_20suite_6',['libevdev-internal test suite',['../testing.html',1,'']]], ++ ['libevdev_2duinput_2eh_7',['libevdev-uinput.h',['../libevdev-uinput_8h.html',1,'']]], ++ ['libevdev_2eh_8',['libevdev.h',['../libevdev_8h.html',1,'']]], ++ ['libevdev_5fattribute_5fprintf_9',['LIBEVDEV_ATTRIBUTE_PRINTF',['../libevdev_8h.html#a64a0f325e88e1be50eb806e1ff75aec8',1,'libevdev.h']]], ++ ['libevdev_5fchange_5ffd_10',['libevdev_change_fd',['../group__init.html#gac71c9cca4c572ed1b1a8c233be70a17c',1,'libevdev.h']]], ++ ['libevdev_5fdeprecated_11',['LIBEVDEV_DEPRECATED',['../libevdev_8h.html#aa136bf4638abda28de7cd9f48af534ae',1,'libevdev.h']]], ++ ['libevdev_5fdevice_5flog_5ffunc_5ft_12',['libevdev_device_log_func_t',['../group__logging.html#gab7eb997be2b701cc6f42e7b4c3478269',1,'libevdev.h']]], ++ ['libevdev_5fdisable_5fevent_5fcode_13',['libevdev_disable_event_code',['../group__kernel.html#ga6199a7c8144f54e092e913c2d2df16de',1,'libevdev.h']]], ++ ['libevdev_5fdisable_5fevent_5ftype_14',['libevdev_disable_event_type',['../group__kernel.html#gabbacb53b66882b5335055c0fd1f40d9a',1,'libevdev.h']]], ++ ['libevdev_5fdisable_5fproperty_15',['libevdev_disable_property',['../group__kernel.html#ga8f6367c36331c803ad69b2591e210019',1,'libevdev.h']]], ++ ['libevdev_5fenable_5fevent_5fcode_16',['libevdev_enable_event_code',['../group__kernel.html#ga51cfda33fd526549046399aadd764fca',1,'libevdev.h']]], ++ ['libevdev_5fenable_5fevent_5ftype_17',['libevdev_enable_event_type',['../group__kernel.html#ga59ef78b1557f9543d0060ab25b0167ca',1,'libevdev.h']]], ++ ['libevdev_5fenable_5fproperty_18',['libevdev_enable_property',['../group__kernel.html#gafc552080520c9d886452b05f3a1d75b6',1,'libevdev.h']]], ++ ['libevdev_5fevent_5fcode_5ffrom_5fcode_5fname_19',['libevdev_event_code_from_code_name',['../group__misc.html#gabad00f68481d83747a134c0a37aca003',1,'libevdev.h']]], ++ ['libevdev_5fevent_5fcode_5ffrom_5fcode_5fname_5fn_20',['libevdev_event_code_from_code_name_n',['../group__misc.html#ga5bf9af4b8c372d87793e8a3c2dbeb466',1,'libevdev.h']]], ++ ['libevdev_5fevent_5fcode_5ffrom_5fname_21',['libevdev_event_code_from_name',['../group__misc.html#ga6620301a67f467489e4a7f93afe81621',1,'libevdev.h']]], ++ ['libevdev_5fevent_5fcode_5ffrom_5fname_5fn_22',['libevdev_event_code_from_name_n',['../group__misc.html#ga17a760a9eea9dc25011f39e1d5c282a0',1,'libevdev.h']]], ++ ['libevdev_5fevent_5fcode_5fget_5fname_23',['libevdev_event_code_get_name',['../group__misc.html#gab407b3c2caaae502859c28460cad17bb',1,'libevdev.h']]], ++ ['libevdev_5fevent_5fis_5fcode_24',['libevdev_event_is_code',['../group__misc.html#ga37766a6a498fef3294d589abcce688bb',1,'libevdev.h']]], ++ ['libevdev_5fevent_5fis_5ftype_25',['libevdev_event_is_type',['../group__misc.html#gab8b6b80740e028261300b8952b61a596',1,'libevdev.h']]], ++ ['libevdev_5fevent_5ftype_5ffrom_5fcode_5fname_26',['libevdev_event_type_from_code_name',['../group__misc.html#gadd41b7514cca16c8b8920f16e562e08a',1,'libevdev.h']]], ++ ['libevdev_5fevent_5ftype_5ffrom_5fcode_5fname_5fn_27',['libevdev_event_type_from_code_name_n',['../group__misc.html#gab214498fca7a328f8a712ce15bf21982',1,'libevdev.h']]], ++ ['libevdev_5fevent_5ftype_5ffrom_5fname_28',['libevdev_event_type_from_name',['../group__misc.html#ga61ce3bf1e66bd172e583b86a11fc41f1',1,'libevdev.h']]], ++ ['libevdev_5fevent_5ftype_5ffrom_5fname_5fn_29',['libevdev_event_type_from_name_n',['../group__misc.html#ga4ee03d650200bb04a23233570667fa84',1,'libevdev.h']]], ++ ['libevdev_5fevent_5ftype_5fget_5fmax_30',['libevdev_event_type_get_max',['../group__misc.html#gabfad87ea78d034631cf3e5322ac383a1',1,'libevdev.h']]], ++ ['libevdev_5fevent_5ftype_5fget_5fname_31',['libevdev_event_type_get_name',['../group__misc.html#gac99720fd926bf288764f9a81bf37ed09',1,'libevdev.h']]], ++ ['libevdev_5fevent_5fvalue_5ffrom_5fname_32',['libevdev_event_value_from_name',['../group__misc.html#ga314903beeafedabe45f879637e7254b0',1,'libevdev.h']]], ++ ['libevdev_5fevent_5fvalue_5ffrom_5fname_5fn_33',['libevdev_event_value_from_name_n',['../group__misc.html#gaebfc6b0ebb70169c9fec61620f1ea85f',1,'libevdev.h']]], ++ ['libevdev_5fevent_5fvalue_5fget_5fname_34',['libevdev_event_value_get_name',['../group__misc.html#gabcd45c5e963cba245e944ea66e72fcc3',1,'libevdev.h']]], ++ ['libevdev_5ffetch_5fevent_5fvalue_35',['libevdev_fetch_event_value',['../group__bits.html#ga0a7be80d769294bf9758adf79c3c7147',1,'libevdev.h']]], ++ ['libevdev_5ffetch_5fslot_5fvalue_36',['libevdev_fetch_slot_value',['../group__mt.html#gaca19dca5aa8f0ea3b210f3fc670384ec',1,'libevdev.h']]], ++ ['libevdev_5ffree_37',['libevdev_free',['../group__init.html#gacd9fe760d15be25fc99ce469034bd78c',1,'libevdev.h']]], ++ ['libevdev_5fget_5fabs_5fflat_38',['libevdev_get_abs_flat',['../group__bits.html#ga6b3f7ebae2324524dc41384acd724b92',1,'libevdev.h']]], ++ ['libevdev_5fget_5fabs_5ffuzz_39',['libevdev_get_abs_fuzz',['../group__bits.html#ga1a3dfeb3bb2db0b4323c836c7ab10f1a',1,'libevdev.h']]], ++ ['libevdev_5fget_5fabs_5finfo_40',['libevdev_get_abs_info',['../group__bits.html#ga6d8e2caf87fa536fad979346671838d7',1,'libevdev.h']]], ++ ['libevdev_5fget_5fabs_5fmaximum_41',['libevdev_get_abs_maximum',['../group__bits.html#ga97a3411ae85f1f3b5c5eb1d5351b11ca',1,'libevdev.h']]], ++ ['libevdev_5fget_5fabs_5fminimum_42',['libevdev_get_abs_minimum',['../group__bits.html#ga482ce989a3f62f7e67e4ea7ad534189e',1,'libevdev.h']]], ++ ['libevdev_5fget_5fabs_5fresolution_43',['libevdev_get_abs_resolution',['../group__bits.html#ga75751e637a845201b6d1c419ecfa6ba4',1,'libevdev.h']]], ++ ['libevdev_5fget_5fcurrent_5fslot_44',['libevdev_get_current_slot',['../group__mt.html#gad22e2420be668b56ef486cde2e98c5dd',1,'libevdev.h']]], ++ ['libevdev_5fget_5fdriver_5fversion_45',['libevdev_get_driver_version',['../group__bits.html#ga31e9e7a99215a03bcdc339b53e1be2fa',1,'libevdev.h']]], ++ ['libevdev_5fget_5fevent_5fvalue_46',['libevdev_get_event_value',['../group__bits.html#ga6259f4c6bdba950329ff9cd48c2ef8a3',1,'libevdev.h']]], ++ ['libevdev_5fget_5ffd_47',['libevdev_get_fd',['../group__init.html#gab9bfc800859ac3aa63f41d58ec4b616c',1,'libevdev.h']]], ++ ['libevdev_5fget_5fid_5fbustype_48',['libevdev_get_id_bustype',['../group__bits.html#ga9bf55d416401642bad0c435735682308',1,'libevdev.h']]], ++ ['libevdev_5fget_5fid_5fproduct_49',['libevdev_get_id_product',['../group__bits.html#ga1dc66cfef646878d58be72f8902a6bac',1,'libevdev.h']]], ++ ['libevdev_5fget_5fid_5fvendor_50',['libevdev_get_id_vendor',['../group__bits.html#ga08891c3285da5b8d26769c9a34f063f3',1,'libevdev.h']]], ++ ['libevdev_5fget_5fid_5fversion_51',['libevdev_get_id_version',['../group__bits.html#ga75a07d0c96dfe09d2194c104c429d0ae',1,'libevdev.h']]], ++ ['libevdev_5fget_5flog_5fpriority_52',['libevdev_get_log_priority',['../group__logging.html#ga1da07493a798595cf85c127490b98ee8',1,'libevdev.h']]], ++ ['libevdev_5fget_5fname_53',['libevdev_get_name',['../group__bits.html#gaed0328c67b7a78422636d9fe09a73f12',1,'libevdev.h']]], ++ ['libevdev_5fget_5fnum_5fslots_54',['libevdev_get_num_slots',['../group__mt.html#gaf272526f0a59d2f61ef7389046cd4088',1,'libevdev.h']]], ++ ['libevdev_5fget_5fphys_55',['libevdev_get_phys',['../group__bits.html#ga5df483b0b24d7b96ea1181808fab851d',1,'libevdev.h']]], ++ ['libevdev_5fget_5frepeat_56',['libevdev_get_repeat',['../group__bits.html#gaf12fa199bb9497b38358d72e7505d770',1,'libevdev.h']]], ++ ['libevdev_5fget_5fslot_5fvalue_57',['libevdev_get_slot_value',['../group__mt.html#ga8c6303391cb4f90b2d46763cf4eb8bc8',1,'libevdev.h']]], ++ ['libevdev_5fget_5funiq_58',['libevdev_get_uniq',['../group__bits.html#ga6d9f7d44bff8828ead3d251177035ca4',1,'libevdev.h']]], ++ ['libevdev_5fgrab_59',['LIBEVDEV_GRAB',['../group__init.html#ggaa282ec9badaa6bc11b1dc5bb124dbd5bad3ac6f5f3ebf7d38a6aad74a88396c88',1,'libevdev.h']]], ++ ['libevdev_5fgrab_60',['libevdev_grab',['../group__init.html#ga5d434af74fee20f273db568e2cbbd13f',1,'libevdev.h']]], ++ ['libevdev_5fgrab_5fmode_61',['libevdev_grab_mode',['../group__init.html#gaa282ec9badaa6bc11b1dc5bb124dbd5b',1,'libevdev.h']]], ++ ['libevdev_5fhas_5fevent_5fcode_62',['libevdev_has_event_code',['../group__bits.html#gab2ab9dad417f33daa79fa0c3d682df0b',1,'libevdev.h']]], ++ ['libevdev_5fhas_5fevent_5fpending_63',['libevdev_has_event_pending',['../group__events.html#gae18fbfb59064c9c4b9d5db2d8cb23784',1,'libevdev.h']]], ++ ['libevdev_5fhas_5fevent_5ftype_64',['libevdev_has_event_type',['../group__bits.html#ga398bef155fa4a0cfb832de30723ebd14',1,'libevdev.h']]], ++ ['libevdev_5fhas_5fproperty_65',['libevdev_has_property',['../group__bits.html#ga36d529ea53f4522004bc7d16c051464b',1,'libevdev.h']]], ++ ['libevdev_5fkernel_5fset_5fabs_5finfo_66',['libevdev_kernel_set_abs_info',['../group__kernel.html#ga41c0321b93349d0ddd1f1c007ccf7de9',1,'libevdev.h']]], ++ ['libevdev_5fkernel_5fset_5fled_5fvalue_67',['libevdev_kernel_set_led_value',['../group__kernel.html#gaa7d13aeac3c40e16f296467780e67c01',1,'libevdev.h']]], ++ ['libevdev_5fkernel_5fset_5fled_5fvalues_68',['libevdev_kernel_set_led_values',['../group__kernel.html#ga93a19fa6e5be57903aff7c4a60af2a00',1,'libevdev.h']]], ++ ['libevdev_5fled_5foff_69',['LIBEVDEV_LED_OFF',['../group__kernel.html#gga8cddf7779debef0067665671e911ec41a23e508440306c387ddf89acd2db9e065',1,'libevdev.h']]], ++ ['libevdev_5fled_5fon_70',['LIBEVDEV_LED_ON',['../group__kernel.html#gga8cddf7779debef0067665671e911ec41a69d5a4cdf2a9357915fff0251a61d2ab',1,'libevdev.h']]], ++ ['libevdev_5fled_5fvalue_71',['libevdev_led_value',['../group__kernel.html#ga8cddf7779debef0067665671e911ec41',1,'libevdev.h']]], ++ ['libevdev_5flog_5fdebug_72',['LIBEVDEV_LOG_DEBUG',['../group__logging.html#gga0b798d0864f2b1b10e4603f9431b3364a760d66d422ffcf89b0f1ddb529b95793',1,'libevdev.h']]], ++ ['libevdev_5flog_5ferror_73',['LIBEVDEV_LOG_ERROR',['../group__logging.html#gga0b798d0864f2b1b10e4603f9431b3364a21fd1083f2ebd0a25f09ee982e365d5f',1,'libevdev.h']]], ++ ['libevdev_5flog_5ffunc_5ft_74',['libevdev_log_func_t',['../group__logging.html#gaf36c721d273c0794251eb7dacea2f0a4',1,'libevdev.h']]], ++ ['libevdev_5flog_5finfo_75',['LIBEVDEV_LOG_INFO',['../group__logging.html#gga0b798d0864f2b1b10e4603f9431b3364a4d13a031b112292ca3e7bab8c6d76abc',1,'libevdev.h']]], ++ ['libevdev_5flog_5fpriority_76',['libevdev_log_priority',['../group__logging.html#ga0b798d0864f2b1b10e4603f9431b3364',1,'libevdev.h']]], ++ ['libevdev_5fnew_77',['libevdev_new',['../group__init.html#ga332c8ee260b4ef864345abe5d04e820c',1,'libevdev.h']]], ++ ['libevdev_5fnew_5ffrom_5ffd_78',['libevdev_new_from_fd',['../group__init.html#ga89bb5bce1c23e293293484b05b12aaf4',1,'libevdev.h']]], ++ ['libevdev_5fnext_5fevent_79',['libevdev_next_event',['../group__events.html#gabb96c864e836c0b98788f4ab771c3a76',1,'libevdev.h']]], ++ ['libevdev_5fproperty_5ffrom_5fname_80',['libevdev_property_from_name',['../group__misc.html#ga6f4418c98aa475a2fc34d58a197f7edd',1,'libevdev.h']]], ++ ['libevdev_5fproperty_5ffrom_5fname_5fn_81',['libevdev_property_from_name_n',['../group__misc.html#gaaa0bc4c7d0d2aedc84c7dcffee9ce29b',1,'libevdev.h']]], ++ ['libevdev_5fproperty_5fget_5fname_82',['libevdev_property_get_name',['../group__misc.html#gacc12bdb7b912070ac9c375428f2c9892',1,'libevdev.h']]], ++ ['libevdev_5fread_5fflag_83',['libevdev_read_flag',['../group__events.html#ga56c288d9f2e4c1632986c4e218c494e9',1,'libevdev.h']]], ++ ['libevdev_5fread_5fflag_5fblocking_84',['LIBEVDEV_READ_FLAG_BLOCKING',['../group__events.html#gga56c288d9f2e4c1632986c4e218c494e9a0a348d44362a7e515b40a4ed4d528e19',1,'libevdev.h']]], ++ ['libevdev_5fread_5fflag_5fforce_5fsync_85',['LIBEVDEV_READ_FLAG_FORCE_SYNC',['../group__events.html#gga56c288d9f2e4c1632986c4e218c494e9a5198e5c9cc98b75f73f61b104d6a674c',1,'libevdev.h']]], ++ ['libevdev_5fread_5fflag_5fnormal_86',['LIBEVDEV_READ_FLAG_NORMAL',['../group__events.html#gga56c288d9f2e4c1632986c4e218c494e9ac0d6ee19551eecf76f1ede4f36252418',1,'libevdev.h']]], ++ ['libevdev_5fread_5fflag_5fsync_87',['LIBEVDEV_READ_FLAG_SYNC',['../group__events.html#gga56c288d9f2e4c1632986c4e218c494e9a1f13a19641d6dafcf01a86a6389800f8',1,'libevdev.h']]], ++ ['libevdev_5fread_5fstatus_88',['libevdev_read_status',['../group__events.html#ga4a96221b3c7f54dfb86035d952154e3a',1,'libevdev.h']]], ++ ['libevdev_5fread_5fstatus_5fsuccess_89',['LIBEVDEV_READ_STATUS_SUCCESS',['../group__events.html#gga4a96221b3c7f54dfb86035d952154e3aab053221fc1c9630eee7111b75aa0aec7',1,'libevdev.h']]], ++ ['libevdev_5fread_5fstatus_5fsync_90',['LIBEVDEV_READ_STATUS_SYNC',['../group__events.html#gga4a96221b3c7f54dfb86035d952154e3aa8d70b14a38204fde4ad433023baa545a',1,'libevdev.h']]], ++ ['libevdev_5fset_5fabs_5fflat_91',['libevdev_set_abs_flat',['../group__kernel.html#gabd309f30744a49e9391250b00ba2d67a',1,'libevdev.h']]], ++ ['libevdev_5fset_5fabs_5ffuzz_92',['libevdev_set_abs_fuzz',['../group__kernel.html#gaa192bf0c68620be819337da6ec361c21',1,'libevdev.h']]], ++ ['libevdev_5fset_5fabs_5finfo_93',['libevdev_set_abs_info',['../group__kernel.html#gafc7a4f5308e2dbf55f875630b8dca049',1,'libevdev.h']]], ++ ['libevdev_5fset_5fabs_5fmaximum_94',['libevdev_set_abs_maximum',['../group__kernel.html#ga2302fd9a491d8e27280157d67a703af6',1,'libevdev.h']]], ++ ['libevdev_5fset_5fabs_5fminimum_95',['libevdev_set_abs_minimum',['../group__kernel.html#gaca62172c2a823cd02eacf0d2292d917a',1,'libevdev.h']]], ++ ['libevdev_5fset_5fabs_5fresolution_96',['libevdev_set_abs_resolution',['../group__kernel.html#ga2266b59711cdaa4fc12fa56c9313a038',1,'libevdev.h']]], ++ ['libevdev_5fset_5fclock_5fid_97',['libevdev_set_clock_id',['../group__kernel.html#ga2925b6fbf8c7991ff2164424b840b82d',1,'libevdev.h']]], ++ ['libevdev_5fset_5fdevice_5flog_5ffunction_98',['libevdev_set_device_log_function',['../group__logging.html#ga2830ff0aa391d8d1111682d3e762091b',1,'libevdev.h']]], ++ ['libevdev_5fset_5fevent_5fvalue_99',['libevdev_set_event_value',['../group__kernel.html#ga79e82ee2a95cb08adb4172aabe0c7184',1,'libevdev.h']]], ++ ['libevdev_5fset_5ffd_100',['libevdev_set_fd',['../group__init.html#ga6658ac490d68c307ff8b8d1536c12b44',1,'libevdev.h']]], ++ ['libevdev_5fset_5fid_5fbustype_101',['libevdev_set_id_bustype',['../group__kernel.html#gaf99139c728ba1bd4b37ede612780b6b0',1,'libevdev.h']]], ++ ['libevdev_5fset_5fid_5fproduct_102',['libevdev_set_id_product',['../group__kernel.html#ga62fbdaac056ab5c3db154a9eeaf33799',1,'libevdev.h']]], ++ ['libevdev_5fset_5fid_5fvendor_103',['libevdev_set_id_vendor',['../group__kernel.html#ga8ce28051ebbb73de1d04d782f4d0d6fe',1,'libevdev.h']]], ++ ['libevdev_5fset_5fid_5fversion_104',['libevdev_set_id_version',['../group__kernel.html#gaee1d2db88b191ec21d5bf22dd4fe3055',1,'libevdev.h']]], ++ ['libevdev_5fset_5flog_5ffunction_105',['libevdev_set_log_function',['../group__logging.html#gaa60be86b83b3a6c82d8e536ba89ff955',1,'libevdev.h']]], ++ ['libevdev_5fset_5flog_5fpriority_106',['libevdev_set_log_priority',['../group__logging.html#gaf6b6842a9ed98b61d0abb421e853fd89',1,'libevdev.h']]], ++ ['libevdev_5fset_5fname_107',['libevdev_set_name',['../group__kernel.html#gae5dcdb7678cdc9be4ab1989725b4ed32',1,'libevdev.h']]], ++ ['libevdev_5fset_5fphys_108',['libevdev_set_phys',['../group__kernel.html#gacd57c8d6ace8e0b1417809a9c1c67af3',1,'libevdev.h']]], ++ ['libevdev_5fset_5fslot_5fvalue_109',['libevdev_set_slot_value',['../group__kernel.html#ga0c61f4919b03b0850529a50c37a20333',1,'libevdev.h']]], ++ ['libevdev_5fset_5funiq_110',['libevdev_set_uniq',['../group__kernel.html#ga4e4fd2627744fd5811c50c7403f27ad7',1,'libevdev.h']]], ++ ['libevdev_5fuinput_5fcreate_5ffrom_5fdevice_111',['libevdev_uinput_create_from_device',['../group__uinput.html#gaf14b21301bac9d79c20e890172873b96',1,'libevdev-uinput.h']]], ++ ['libevdev_5fuinput_5fdestroy_112',['libevdev_uinput_destroy',['../group__uinput.html#ga9dfa58a84eb4c6b97107dcf3fa621329',1,'libevdev-uinput.h']]], ++ ['libevdev_5fuinput_5fget_5fdevnode_113',['libevdev_uinput_get_devnode',['../group__uinput.html#ga4c595bcda748b08561e2819fe9b7c2d2',1,'libevdev-uinput.h']]], ++ ['libevdev_5fuinput_5fget_5ffd_114',['libevdev_uinput_get_fd',['../group__uinput.html#ga9cd7fb14a96d4cc14d3dffdcead84c5d',1,'libevdev-uinput.h']]], ++ ['libevdev_5fuinput_5fget_5fsyspath_115',['libevdev_uinput_get_syspath',['../group__uinput.html#gaacca93061fce57cec0ce3c52e443a427',1,'libevdev-uinput.h']]], ++ ['libevdev_5fuinput_5fopen_5fmanaged_116',['LIBEVDEV_UINPUT_OPEN_MANAGED',['../libevdev-uinput_8h.html#a6546acd3e4fe75a74d91eebf9bbd3d03adcf2d4de38844ee3a8c830bc3285afad',1,'libevdev-uinput.h']]], ++ ['libevdev_5fuinput_5fopen_5fmode_117',['libevdev_uinput_open_mode',['../libevdev-uinput_8h.html#a6546acd3e4fe75a74d91eebf9bbd3d03',1,'libevdev-uinput.h']]], ++ ['libevdev_5fuinput_5fwrite_5fevent_118',['libevdev_uinput_write_event',['../group__uinput.html#ga4c3c2f5fcd315a28a067f53b9f855fe7',1,'libevdev-uinput.h']]], ++ ['libevdev_5fungrab_119',['LIBEVDEV_UNGRAB',['../group__init.html#ggaa282ec9badaa6bc11b1dc5bb124dbd5ba6c0930d0c280753504cd05ebdcda09eb',1,'libevdev.h']]], ++ ['library_20logging_20facilities_120',['Library logging facilities',['../group__logging.html',1,'']]] + ]; +diff -Naur third-party-libevdev-bak/doc/html/search/all_6.html third-party-new/doc/html/search/all_6.html +--- third-party-libevdev-bak/doc/html/search/all_6.html 2023-03-28 10:49:53.380511700 +0800 ++++ third-party-new/doc/html/search/all_6.html 2023-04-01 15:31:16.478114500 +0800 +@@ -1,7 +1,8 @@ + +- ++ ++ + +- ++ + + + +@@ -10,14 +11,14 @@ +
+
Loading...
+
+- ++ +
Searching...
+
No Matches
+- ++ +
+ + +diff -Naur third-party-libevdev-bak/doc/html/search/all_6.js third-party-new/doc/html/search/all_6.js +--- third-party-libevdev-bak/doc/html/search/all_6.js 2023-03-28 10:49:53.380511700 +0800 ++++ third-party-new/doc/html/search/all_6.js 2023-04-01 15:32:09.994225500 +0800 +@@ -1,6 +1,6 @@ + var searchData= + [ +- ['modifying_20the_20appearance_20or_20capabilities_20of_20the_20device_120',['Modifying the appearance or capabilities of the device',['../group__kernel.html',1,'']]], + ['miscellaneous_20helper_20functions_121',['Miscellaneous helper functions',['../group__misc.html',1,'']]], +- ['multi_2dtouch_20related_20functions_122',['Multi-touch related functions',['../group__mt.html',1,'']]] ++ ['modifying_20the_20appearance_20or_20capabilities_20of_20the_20device_122',['Modifying the appearance or capabilities of the device',['../group__kernel.html',1,'']]], ++ ['multi_2dtouch_20related_20functions_123',['Multi-touch related functions',['../group__mt.html',1,'']]] + ]; +diff -Naur third-party-libevdev-bak/doc/html/search/all_7.html third-party-new/doc/html/search/all_7.html +--- third-party-libevdev-bak/doc/html/search/all_7.html 2023-03-28 10:49:53.380511700 +0800 ++++ third-party-new/doc/html/search/all_7.html 2023-04-01 15:32:18.878297000 +0800 +@@ -1,7 +1,8 @@ + +- ++ ++ + +- ++ + + + +@@ -10,14 +11,14 @@ +
+
Loading...
+
+- ++ +
Searching...
+
No Matches
+- ++ +
+ + +diff -Naur third-party-libevdev-bak/doc/html/search/all_7.js third-party-new/doc/html/search/all_7.js +--- third-party-libevdev-bak/doc/html/search/all_7.js 2023-03-28 10:49:53.380511700 +0800 ++++ third-party-new/doc/html/search/all_7.js 2023-04-01 15:32:26.253499200 +0800 +@@ -1,4 +1,4 @@ + var searchData= + [ +- ['querying_20device_20capabilities_123',['Querying device capabilities',['../group__bits.html',1,'']]] ++ ['querying_20device_20capabilities_124',['Querying device capabilities',['../group__bits.html',1,'']]] + ]; +diff -Naur third-party-libevdev-bak/doc/html/search/all_8.html third-party-new/doc/html/search/all_8.html +--- third-party-libevdev-bak/doc/html/search/all_8.html 2023-03-28 10:49:53.380511700 +0800 ++++ third-party-new/doc/html/search/all_8.html 2023-04-01 15:32:39.466172800 +0800 +@@ -1,7 +1,8 @@ + +- ++ ++ + +- ++ + + + +@@ -10,14 +11,14 @@ +
+
Loading...
+
+- ++ +
Searching...
+
No Matches
+- ++ +
+ + +diff -Naur third-party-libevdev-bak/doc/html/search/all_8.js third-party-new/doc/html/search/all_8.js +--- third-party-libevdev-bak/doc/html/search/all_8.js 2023-03-28 10:49:53.380511700 +0800 ++++ third-party-new/doc/html/search/all_8.js 2023-04-01 15:33:13.706101600 +0800 +@@ -1,5 +1,5 @@ + var searchData= + [ +- ['statically_20linking_20libevdev_124',['Statically linking libevdev',['../static_linking.html',1,'']]], +- ['syn_5fdropped_20handling_125',['SYN_DROPPED handling',['../syn_dropped.html',1,'']]] ++ ['statically_20linking_20libevdev_125',['Statically linking libevdev',['../static_linking.html',1,'']]], ++ ['syn_5fdropped_20handling_126',['SYN_DROPPED handling',['../syn_dropped.html',1,'']]] + ]; +diff -Naur third-party-libevdev-bak/doc/html/search/all_9.html third-party-new/doc/html/search/all_9.html +--- third-party-libevdev-bak/doc/html/search/all_9.html 2023-03-28 10:49:53.380511700 +0800 ++++ third-party-new/doc/html/search/all_9.html 2023-04-01 15:33:28.510781400 +0800 +@@ -1,7 +1,8 @@ + +- ++ ++ + +- ++ + + + +@@ -10,14 +11,14 @@ +
+
Loading...
+
+- ++ +
Searching...
+
No Matches
+- ++ +
+ + +diff -Naur third-party-libevdev-bak/doc/html/search/all_9.js third-party-new/doc/html/search/all_9.js +--- third-party-libevdev-bak/doc/html/search/all_9.js 2023-03-28 10:49:53.380511700 +0800 ++++ third-party-new/doc/html/search/all_9.js 2023-04-01 15:34:22.031122000 +0800 +@@ -1,4 +1,4 @@ + var searchData= + [ +- ['uinput_20device_20creation_126',['uinput device creation',['../group__uinput.html',1,'']]] ++ ['uinput_20device_20creation_127',['uinput device creation',['../group__uinput.html',1,'']]] + ]; +diff -Naur third-party-libevdev-bak/doc/html/search/defines_0.html third-party-new/doc/html/search/defines_0.html +--- third-party-libevdev-bak/doc/html/search/defines_0.html 2023-03-28 10:49:53.380511700 +0800 ++++ third-party-new/doc/html/search/defines_0.html 2023-04-01 15:34:45.107059600 +0800 +@@ -1,7 +1,8 @@ + +- ++ ++ + +- ++ + + + +@@ -10,14 +11,14 @@ +
+
Loading...
+
+- ++ +
Searching...
+
No Matches
+- ++ +
+ + +diff -Naur third-party-libevdev-bak/doc/html/search/defines_0.js third-party-new/doc/html/search/defines_0.js +--- third-party-libevdev-bak/doc/html/search/defines_0.js 2023-03-28 10:49:53.380511700 +0800 ++++ third-party-new/doc/html/search/defines_0.js 2023-04-01 15:35:14.026840800 +0800 +@@ -1,5 +1,5 @@ + var searchData= + [ +- ['libevdev_5fattribute_5fprintf_238',['LIBEVDEV_ATTRIBUTE_PRINTF',['../libevdev_8h.html#a64a0f325e88e1be50eb806e1ff75aec8',1,'libevdev.h']]], +- ['libevdev_5fdeprecated_239',['LIBEVDEV_DEPRECATED',['../libevdev_8h.html#aa136bf4638abda28de7cd9f48af534ae',1,'libevdev.h']]] ++ ['libevdev_5fattribute_5fprintf_239',['LIBEVDEV_ATTRIBUTE_PRINTF',['../libevdev_8h.html#a64a0f325e88e1be50eb806e1ff75aec8',1,'libevdev.h']]], ++ ['libevdev_5fdeprecated_240',['LIBEVDEV_DEPRECATED',['../libevdev_8h.html#aa136bf4638abda28de7cd9f48af534ae',1,'libevdev.h']]] + ]; +diff -Naur third-party-libevdev-bak/doc/html/search/enums_0.html third-party-new/doc/html/search/enums_0.html +--- third-party-libevdev-bak/doc/html/search/enums_0.html 2023-03-28 10:49:53.380511700 +0800 ++++ third-party-new/doc/html/search/enums_0.html 2023-04-01 15:35:30.484303500 +0800 +@@ -1,7 +1,8 @@ + +- ++ ++ + +- ++ + + + +@@ -10,14 +11,14 @@ +
+
Loading...
+
+- ++ +
Searching...
+
No Matches
+- ++ +
+ + +diff -Naur third-party-libevdev-bak/doc/html/search/enums_0.js third-party-new/doc/html/search/enums_0.js +--- third-party-libevdev-bak/doc/html/search/enums_0.js 2023-03-28 10:49:53.380511700 +0800 ++++ third-party-new/doc/html/search/enums_0.js 2023-04-01 15:35:37.093037800 +0800 +@@ -1,9 +1,9 @@ + var searchData= + [ +- ['libevdev_5fgrab_5fmode_218',['libevdev_grab_mode',['../group__init.html#gaa282ec9badaa6bc11b1dc5bb124dbd5b',1,'libevdev.h']]], +- ['libevdev_5fled_5fvalue_219',['libevdev_led_value',['../group__kernel.html#ga8cddf7779debef0067665671e911ec41',1,'libevdev.h']]], +- ['libevdev_5flog_5fpriority_220',['libevdev_log_priority',['../group__logging.html#ga0b798d0864f2b1b10e4603f9431b3364',1,'libevdev.h']]], +- ['libevdev_5fread_5fflag_221',['libevdev_read_flag',['../group__events.html#ga56c288d9f2e4c1632986c4e218c494e9',1,'libevdev.h']]], +- ['libevdev_5fread_5fstatus_222',['libevdev_read_status',['../group__events.html#ga4a96221b3c7f54dfb86035d952154e3a',1,'libevdev.h']]], +- ['libevdev_5fuinput_5fopen_5fmode_223',['libevdev_uinput_open_mode',['../libevdev-uinput_8h.html#a6546acd3e4fe75a74d91eebf9bbd3d03',1,'libevdev-uinput.h']]] ++ ['libevdev_5fgrab_5fmode_219',['libevdev_grab_mode',['../group__init.html#gaa282ec9badaa6bc11b1dc5bb124dbd5b',1,'libevdev.h']]], ++ ['libevdev_5fled_5fvalue_220',['libevdev_led_value',['../group__kernel.html#ga8cddf7779debef0067665671e911ec41',1,'libevdev.h']]], ++ ['libevdev_5flog_5fpriority_221',['libevdev_log_priority',['../group__logging.html#ga0b798d0864f2b1b10e4603f9431b3364',1,'libevdev.h']]], ++ ['libevdev_5fread_5fflag_222',['libevdev_read_flag',['../group__events.html#ga56c288d9f2e4c1632986c4e218c494e9',1,'libevdev.h']]], ++ ['libevdev_5fread_5fstatus_223',['libevdev_read_status',['../group__events.html#ga4a96221b3c7f54dfb86035d952154e3a',1,'libevdev.h']]], ++ ['libevdev_5fuinput_5fopen_5fmode_224',['libevdev_uinput_open_mode',['../libevdev-uinput_8h.html#a6546acd3e4fe75a74d91eebf9bbd3d03',1,'libevdev-uinput.h']]] + ]; +diff -Naur third-party-libevdev-bak/doc/html/search/enumvalues_0.html third-party-new/doc/html/search/enumvalues_0.html +--- third-party-libevdev-bak/doc/html/search/enumvalues_0.html 2023-03-28 10:49:53.380511700 +0800 ++++ third-party-new/doc/html/search/enumvalues_0.html 2023-04-01 15:35:47.907023100 +0800 +@@ -1,7 +1,8 @@ + +- ++ ++ + +- ++ + + + +@@ -10,14 +11,14 @@ +
+
Loading...
+
+- ++ +
Searching...
+
No Matches
+- ++ +
+ + +diff -Naur third-party-libevdev-bak/doc/html/search/enumvalues_0.js third-party-new/doc/html/search/enumvalues_0.js +--- third-party-libevdev-bak/doc/html/search/enumvalues_0.js 2023-03-28 10:49:53.380511700 +0800 ++++ third-party-new/doc/html/search/enumvalues_0.js 2023-04-01 15:36:18.438425700 +0800 +@@ -1,17 +1,17 @@ + var searchData= + [ +- ['libevdev_5fgrab_224',['LIBEVDEV_GRAB',['../group__init.html#ggaa282ec9badaa6bc11b1dc5bb124dbd5bad3ac6f5f3ebf7d38a6aad74a88396c88',1,'libevdev.h']]], +- ['libevdev_5fled_5foff_225',['LIBEVDEV_LED_OFF',['../group__kernel.html#gga8cddf7779debef0067665671e911ec41a23e508440306c387ddf89acd2db9e065',1,'libevdev.h']]], +- ['libevdev_5fled_5fon_226',['LIBEVDEV_LED_ON',['../group__kernel.html#gga8cddf7779debef0067665671e911ec41a69d5a4cdf2a9357915fff0251a61d2ab',1,'libevdev.h']]], +- ['libevdev_5flog_5fdebug_227',['LIBEVDEV_LOG_DEBUG',['../group__logging.html#gga0b798d0864f2b1b10e4603f9431b3364a760d66d422ffcf89b0f1ddb529b95793',1,'libevdev.h']]], +- ['libevdev_5flog_5ferror_228',['LIBEVDEV_LOG_ERROR',['../group__logging.html#gga0b798d0864f2b1b10e4603f9431b3364a21fd1083f2ebd0a25f09ee982e365d5f',1,'libevdev.h']]], +- ['libevdev_5flog_5finfo_229',['LIBEVDEV_LOG_INFO',['../group__logging.html#gga0b798d0864f2b1b10e4603f9431b3364a4d13a031b112292ca3e7bab8c6d76abc',1,'libevdev.h']]], +- ['libevdev_5fread_5fflag_5fblocking_230',['LIBEVDEV_READ_FLAG_BLOCKING',['../group__events.html#gga56c288d9f2e4c1632986c4e218c494e9a0a348d44362a7e515b40a4ed4d528e19',1,'libevdev.h']]], +- ['libevdev_5fread_5fflag_5fforce_5fsync_231',['LIBEVDEV_READ_FLAG_FORCE_SYNC',['../group__events.html#gga56c288d9f2e4c1632986c4e218c494e9a5198e5c9cc98b75f73f61b104d6a674c',1,'libevdev.h']]], +- ['libevdev_5fread_5fflag_5fnormal_232',['LIBEVDEV_READ_FLAG_NORMAL',['../group__events.html#gga56c288d9f2e4c1632986c4e218c494e9ac0d6ee19551eecf76f1ede4f36252418',1,'libevdev.h']]], +- ['libevdev_5fread_5fflag_5fsync_233',['LIBEVDEV_READ_FLAG_SYNC',['../group__events.html#gga56c288d9f2e4c1632986c4e218c494e9a1f13a19641d6dafcf01a86a6389800f8',1,'libevdev.h']]], +- ['libevdev_5fread_5fstatus_5fsuccess_234',['LIBEVDEV_READ_STATUS_SUCCESS',['../group__events.html#gga4a96221b3c7f54dfb86035d952154e3aab053221fc1c9630eee7111b75aa0aec7',1,'libevdev.h']]], +- ['libevdev_5fread_5fstatus_5fsync_235',['LIBEVDEV_READ_STATUS_SYNC',['../group__events.html#gga4a96221b3c7f54dfb86035d952154e3aa8d70b14a38204fde4ad433023baa545a',1,'libevdev.h']]], +- ['libevdev_5fuinput_5fopen_5fmanaged_236',['LIBEVDEV_UINPUT_OPEN_MANAGED',['../libevdev-uinput_8h.html#a6546acd3e4fe75a74d91eebf9bbd3d03adcf2d4de38844ee3a8c830bc3285afad',1,'libevdev-uinput.h']]], +- ['libevdev_5fungrab_237',['LIBEVDEV_UNGRAB',['../group__init.html#ggaa282ec9badaa6bc11b1dc5bb124dbd5ba6c0930d0c280753504cd05ebdcda09eb',1,'libevdev.h']]] ++ ['libevdev_5fgrab_225',['LIBEVDEV_GRAB',['../group__init.html#ggaa282ec9badaa6bc11b1dc5bb124dbd5bad3ac6f5f3ebf7d38a6aad74a88396c88',1,'libevdev.h']]], ++ ['libevdev_5fled_5foff_226',['LIBEVDEV_LED_OFF',['../group__kernel.html#gga8cddf7779debef0067665671e911ec41a23e508440306c387ddf89acd2db9e065',1,'libevdev.h']]], ++ ['libevdev_5fled_5fon_227',['LIBEVDEV_LED_ON',['../group__kernel.html#gga8cddf7779debef0067665671e911ec41a69d5a4cdf2a9357915fff0251a61d2ab',1,'libevdev.h']]], ++ ['libevdev_5flog_5fdebug_228',['LIBEVDEV_LOG_DEBUG',['../group__logging.html#gga0b798d0864f2b1b10e4603f9431b3364a760d66d422ffcf89b0f1ddb529b95793',1,'libevdev.h']]], ++ ['libevdev_5flog_5ferror_229',['LIBEVDEV_LOG_ERROR',['../group__logging.html#gga0b798d0864f2b1b10e4603f9431b3364a21fd1083f2ebd0a25f09ee982e365d5f',1,'libevdev.h']]], ++ ['libevdev_5flog_5finfo_230',['LIBEVDEV_LOG_INFO',['../group__logging.html#gga0b798d0864f2b1b10e4603f9431b3364a4d13a031b112292ca3e7bab8c6d76abc',1,'libevdev.h']]], ++ ['libevdev_5fread_5fflag_5fblocking_231',['LIBEVDEV_READ_FLAG_BLOCKING',['../group__events.html#gga56c288d9f2e4c1632986c4e218c494e9a0a348d44362a7e515b40a4ed4d528e19',1,'libevdev.h']]], ++ ['libevdev_5fread_5fflag_5fforce_5fsync_232',['LIBEVDEV_READ_FLAG_FORCE_SYNC',['../group__events.html#gga56c288d9f2e4c1632986c4e218c494e9a5198e5c9cc98b75f73f61b104d6a674c',1,'libevdev.h']]], ++ ['libevdev_5fread_5fflag_5fnormal_233',['LIBEVDEV_READ_FLAG_NORMAL',['../group__events.html#gga56c288d9f2e4c1632986c4e218c494e9ac0d6ee19551eecf76f1ede4f36252418',1,'libevdev.h']]], ++ ['libevdev_5fread_5fflag_5fsync_234',['LIBEVDEV_READ_FLAG_SYNC',['../group__events.html#gga56c288d9f2e4c1632986c4e218c494e9a1f13a19641d6dafcf01a86a6389800f8',1,'libevdev.h']]], ++ ['libevdev_5fread_5fstatus_5fsuccess_235',['LIBEVDEV_READ_STATUS_SUCCESS',['../group__events.html#gga4a96221b3c7f54dfb86035d952154e3aab053221fc1c9630eee7111b75aa0aec7',1,'libevdev.h']]], ++ ['libevdev_5fread_5fstatus_5fsync_236',['LIBEVDEV_READ_STATUS_SYNC',['../group__events.html#gga4a96221b3c7f54dfb86035d952154e3aa8d70b14a38204fde4ad433023baa545a',1,'libevdev.h']]], ++ ['libevdev_5fuinput_5fopen_5fmanaged_237',['LIBEVDEV_UINPUT_OPEN_MANAGED',['../libevdev-uinput_8h.html#a6546acd3e4fe75a74d91eebf9bbd3d03adcf2d4de38844ee3a8c830bc3285afad',1,'libevdev-uinput.h']]], ++ ['libevdev_5fungrab_238',['LIBEVDEV_UNGRAB',['../group__init.html#ggaa282ec9badaa6bc11b1dc5bb124dbd5ba6c0930d0c280753504cd05ebdcda09eb',1,'libevdev.h']]] + ]; +diff -Naur third-party-libevdev-bak/doc/html/search/files_0.html third-party-new/doc/html/search/files_0.html +--- third-party-libevdev-bak/doc/html/search/files_0.html 2023-03-28 10:49:53.380511700 +0800 ++++ third-party-new/doc/html/search/files_0.html 2023-04-01 15:36:36.394843100 +0800 +@@ -1,7 +1,8 @@ + +- ++ ++ + +- ++ + + + +@@ -10,14 +11,14 @@ +
+
Loading...
+
+- ++ +
Searching...
+
No Matches
+- ++ +
+ + +diff -Naur third-party-libevdev-bak/doc/html/search/files_0.js third-party-new/doc/html/search/files_0.js +--- third-party-libevdev-bak/doc/html/search/files_0.js 2023-03-28 10:49:53.380511700 +0800 ++++ third-party-new/doc/html/search/files_0.js 2023-04-01 15:36:46.743227100 +0800 +@@ -1,5 +1,5 @@ + var searchData= + [ +- ['libevdev_2duinput_2eh_127',['libevdev-uinput.h',['../libevdev-uinput_8h.html',1,'']]], +- ['libevdev_2eh_128',['libevdev.h',['../libevdev_8h.html',1,'']]] ++ ['libevdev_2duinput_2eh_128',['libevdev-uinput.h',['../libevdev-uinput_8h.html',1,'']]], ++ ['libevdev_2eh_129',['libevdev.h',['../libevdev_8h.html',1,'']]] + ]; +diff -Naur third-party-libevdev-bak/doc/html/search/functions_0.html third-party-new/doc/html/search/functions_0.html +--- third-party-libevdev-bak/doc/html/search/functions_0.html 2023-03-28 10:49:53.380511700 +0800 ++++ third-party-new/doc/html/search/functions_0.html 2023-04-01 15:36:56.210338900 +0800 +@@ -1,7 +1,8 @@ + +- ++ ++ + +- ++ + + + +@@ -10,14 +11,14 @@ +
+
Loading...
+
+- ++ +
Searching...
+
No Matches
+- ++ +
+ + +diff -Naur third-party-libevdev-bak/doc/html/search/functions_0.js third-party-new/doc/html/search/functions_0.js +--- third-party-libevdev-bak/doc/html/search/functions_0.js 2023-03-28 10:49:53.380511700 +0800 ++++ third-party-new/doc/html/search/functions_0.js 2023-04-01 15:37:12.417086900 +0800 +@@ -1,90 +1,90 @@ + var searchData= + [ +- ['libevdev_5fchange_5ffd_129',['libevdev_change_fd',['../group__init.html#gac71c9cca4c572ed1b1a8c233be70a17c',1,'libevdev.h']]], +- ['libevdev_5fdisable_5fevent_5fcode_130',['libevdev_disable_event_code',['../group__kernel.html#ga6199a7c8144f54e092e913c2d2df16de',1,'libevdev.h']]], +- ['libevdev_5fdisable_5fevent_5ftype_131',['libevdev_disable_event_type',['../group__kernel.html#gabbacb53b66882b5335055c0fd1f40d9a',1,'libevdev.h']]], +- ['libevdev_5fdisable_5fproperty_132',['libevdev_disable_property',['../group__kernel.html#ga8f6367c36331c803ad69b2591e210019',1,'libevdev.h']]], +- ['libevdev_5fenable_5fevent_5fcode_133',['libevdev_enable_event_code',['../group__kernel.html#ga51cfda33fd526549046399aadd764fca',1,'libevdev.h']]], +- ['libevdev_5fenable_5fevent_5ftype_134',['libevdev_enable_event_type',['../group__kernel.html#ga59ef78b1557f9543d0060ab25b0167ca',1,'libevdev.h']]], +- ['libevdev_5fenable_5fproperty_135',['libevdev_enable_property',['../group__kernel.html#gafc552080520c9d886452b05f3a1d75b6',1,'libevdev.h']]], +- ['libevdev_5fevent_5fcode_5ffrom_5fcode_5fname_136',['libevdev_event_code_from_code_name',['../group__misc.html#gabad00f68481d83747a134c0a37aca003',1,'libevdev.h']]], +- ['libevdev_5fevent_5fcode_5ffrom_5fcode_5fname_5fn_137',['libevdev_event_code_from_code_name_n',['../group__misc.html#ga5bf9af4b8c372d87793e8a3c2dbeb466',1,'libevdev.h']]], +- ['libevdev_5fevent_5fcode_5ffrom_5fname_138',['libevdev_event_code_from_name',['../group__misc.html#ga6620301a67f467489e4a7f93afe81621',1,'libevdev.h']]], +- ['libevdev_5fevent_5fcode_5ffrom_5fname_5fn_139',['libevdev_event_code_from_name_n',['../group__misc.html#ga17a760a9eea9dc25011f39e1d5c282a0',1,'libevdev.h']]], +- ['libevdev_5fevent_5fcode_5fget_5fname_140',['libevdev_event_code_get_name',['../group__misc.html#gab407b3c2caaae502859c28460cad17bb',1,'libevdev.h']]], +- ['libevdev_5fevent_5fis_5fcode_141',['libevdev_event_is_code',['../group__misc.html#ga37766a6a498fef3294d589abcce688bb',1,'libevdev.h']]], +- ['libevdev_5fevent_5fis_5ftype_142',['libevdev_event_is_type',['../group__misc.html#gab8b6b80740e028261300b8952b61a596',1,'libevdev.h']]], +- ['libevdev_5fevent_5ftype_5ffrom_5fcode_5fname_143',['libevdev_event_type_from_code_name',['../group__misc.html#gadd41b7514cca16c8b8920f16e562e08a',1,'libevdev.h']]], +- ['libevdev_5fevent_5ftype_5ffrom_5fcode_5fname_5fn_144',['libevdev_event_type_from_code_name_n',['../group__misc.html#gab214498fca7a328f8a712ce15bf21982',1,'libevdev.h']]], +- ['libevdev_5fevent_5ftype_5ffrom_5fname_145',['libevdev_event_type_from_name',['../group__misc.html#ga61ce3bf1e66bd172e583b86a11fc41f1',1,'libevdev.h']]], +- ['libevdev_5fevent_5ftype_5ffrom_5fname_5fn_146',['libevdev_event_type_from_name_n',['../group__misc.html#ga4ee03d650200bb04a23233570667fa84',1,'libevdev.h']]], +- ['libevdev_5fevent_5ftype_5fget_5fmax_147',['libevdev_event_type_get_max',['../group__misc.html#gabfad87ea78d034631cf3e5322ac383a1',1,'libevdev.h']]], +- ['libevdev_5fevent_5ftype_5fget_5fname_148',['libevdev_event_type_get_name',['../group__misc.html#gac99720fd926bf288764f9a81bf37ed09',1,'libevdev.h']]], +- ['libevdev_5fevent_5fvalue_5ffrom_5fname_149',['libevdev_event_value_from_name',['../group__misc.html#ga314903beeafedabe45f879637e7254b0',1,'libevdev.h']]], +- ['libevdev_5fevent_5fvalue_5ffrom_5fname_5fn_150',['libevdev_event_value_from_name_n',['../group__misc.html#gaebfc6b0ebb70169c9fec61620f1ea85f',1,'libevdev.h']]], +- ['libevdev_5fevent_5fvalue_5fget_5fname_151',['libevdev_event_value_get_name',['../group__misc.html#gabcd45c5e963cba245e944ea66e72fcc3',1,'libevdev.h']]], +- ['libevdev_5ffetch_5fevent_5fvalue_152',['libevdev_fetch_event_value',['../group__bits.html#ga0a7be80d769294bf9758adf79c3c7147',1,'libevdev.h']]], +- ['libevdev_5ffetch_5fslot_5fvalue_153',['libevdev_fetch_slot_value',['../group__mt.html#gaca19dca5aa8f0ea3b210f3fc670384ec',1,'libevdev.h']]], +- ['libevdev_5ffree_154',['libevdev_free',['../group__init.html#gacd9fe760d15be25fc99ce469034bd78c',1,'libevdev.h']]], +- ['libevdev_5fget_5fabs_5fflat_155',['libevdev_get_abs_flat',['../group__bits.html#ga6b3f7ebae2324524dc41384acd724b92',1,'libevdev.h']]], +- ['libevdev_5fget_5fabs_5ffuzz_156',['libevdev_get_abs_fuzz',['../group__bits.html#ga1a3dfeb3bb2db0b4323c836c7ab10f1a',1,'libevdev.h']]], +- ['libevdev_5fget_5fabs_5finfo_157',['libevdev_get_abs_info',['../group__bits.html#ga6d8e2caf87fa536fad979346671838d7',1,'libevdev.h']]], +- ['libevdev_5fget_5fabs_5fmaximum_158',['libevdev_get_abs_maximum',['../group__bits.html#ga97a3411ae85f1f3b5c5eb1d5351b11ca',1,'libevdev.h']]], +- ['libevdev_5fget_5fabs_5fminimum_159',['libevdev_get_abs_minimum',['../group__bits.html#ga482ce989a3f62f7e67e4ea7ad534189e',1,'libevdev.h']]], +- ['libevdev_5fget_5fabs_5fresolution_160',['libevdev_get_abs_resolution',['../group__bits.html#ga75751e637a845201b6d1c419ecfa6ba4',1,'libevdev.h']]], +- ['libevdev_5fget_5fcurrent_5fslot_161',['libevdev_get_current_slot',['../group__mt.html#gad22e2420be668b56ef486cde2e98c5dd',1,'libevdev.h']]], +- ['libevdev_5fget_5fdriver_5fversion_162',['libevdev_get_driver_version',['../group__bits.html#ga31e9e7a99215a03bcdc339b53e1be2fa',1,'libevdev.h']]], +- ['libevdev_5fget_5fevent_5fvalue_163',['libevdev_get_event_value',['../group__bits.html#ga6259f4c6bdba950329ff9cd48c2ef8a3',1,'libevdev.h']]], +- ['libevdev_5fget_5ffd_164',['libevdev_get_fd',['../group__init.html#gab9bfc800859ac3aa63f41d58ec4b616c',1,'libevdev.h']]], +- ['libevdev_5fget_5fid_5fbustype_165',['libevdev_get_id_bustype',['../group__bits.html#ga9bf55d416401642bad0c435735682308',1,'libevdev.h']]], +- ['libevdev_5fget_5fid_5fproduct_166',['libevdev_get_id_product',['../group__bits.html#ga1dc66cfef646878d58be72f8902a6bac',1,'libevdev.h']]], +- ['libevdev_5fget_5fid_5fvendor_167',['libevdev_get_id_vendor',['../group__bits.html#ga08891c3285da5b8d26769c9a34f063f3',1,'libevdev.h']]], +- ['libevdev_5fget_5fid_5fversion_168',['libevdev_get_id_version',['../group__bits.html#ga75a07d0c96dfe09d2194c104c429d0ae',1,'libevdev.h']]], +- ['libevdev_5fget_5flog_5fpriority_169',['libevdev_get_log_priority',['../group__logging.html#ga1da07493a798595cf85c127490b98ee8',1,'libevdev.h']]], +- ['libevdev_5fget_5fname_170',['libevdev_get_name',['../group__bits.html#gaed0328c67b7a78422636d9fe09a73f12',1,'libevdev.h']]], +- ['libevdev_5fget_5fnum_5fslots_171',['libevdev_get_num_slots',['../group__mt.html#gaf272526f0a59d2f61ef7389046cd4088',1,'libevdev.h']]], +- ['libevdev_5fget_5fphys_172',['libevdev_get_phys',['../group__bits.html#ga5df483b0b24d7b96ea1181808fab851d',1,'libevdev.h']]], +- ['libevdev_5fget_5frepeat_173',['libevdev_get_repeat',['../group__bits.html#gaf12fa199bb9497b38358d72e7505d770',1,'libevdev.h']]], +- ['libevdev_5fget_5fslot_5fvalue_174',['libevdev_get_slot_value',['../group__mt.html#ga8c6303391cb4f90b2d46763cf4eb8bc8',1,'libevdev.h']]], +- ['libevdev_5fget_5funiq_175',['libevdev_get_uniq',['../group__bits.html#ga6d9f7d44bff8828ead3d251177035ca4',1,'libevdev.h']]], +- ['libevdev_5fgrab_176',['libevdev_grab',['../group__init.html#ga5d434af74fee20f273db568e2cbbd13f',1,'libevdev.h']]], +- ['libevdev_5fhas_5fevent_5fcode_177',['libevdev_has_event_code',['../group__bits.html#gab2ab9dad417f33daa79fa0c3d682df0b',1,'libevdev.h']]], +- ['libevdev_5fhas_5fevent_5fpending_178',['libevdev_has_event_pending',['../group__events.html#gae18fbfb59064c9c4b9d5db2d8cb23784',1,'libevdev.h']]], +- ['libevdev_5fhas_5fevent_5ftype_179',['libevdev_has_event_type',['../group__bits.html#ga398bef155fa4a0cfb832de30723ebd14',1,'libevdev.h']]], +- ['libevdev_5fhas_5fproperty_180',['libevdev_has_property',['../group__bits.html#ga36d529ea53f4522004bc7d16c051464b',1,'libevdev.h']]], +- ['libevdev_5fkernel_5fset_5fabs_5finfo_181',['libevdev_kernel_set_abs_info',['../group__kernel.html#ga41c0321b93349d0ddd1f1c007ccf7de9',1,'libevdev.h']]], +- ['libevdev_5fkernel_5fset_5fled_5fvalue_182',['libevdev_kernel_set_led_value',['../group__kernel.html#gaa7d13aeac3c40e16f296467780e67c01',1,'libevdev.h']]], +- ['libevdev_5fkernel_5fset_5fled_5fvalues_183',['libevdev_kernel_set_led_values',['../group__kernel.html#ga93a19fa6e5be57903aff7c4a60af2a00',1,'libevdev.h']]], +- ['libevdev_5fnew_184',['libevdev_new',['../group__init.html#ga332c8ee260b4ef864345abe5d04e820c',1,'libevdev.h']]], +- ['libevdev_5fnew_5ffrom_5ffd_185',['libevdev_new_from_fd',['../group__init.html#ga89bb5bce1c23e293293484b05b12aaf4',1,'libevdev.h']]], +- ['libevdev_5fnext_5fevent_186',['libevdev_next_event',['../group__events.html#gabb96c864e836c0b98788f4ab771c3a76',1,'libevdev.h']]], +- ['libevdev_5fproperty_5ffrom_5fname_187',['libevdev_property_from_name',['../group__misc.html#ga6f4418c98aa475a2fc34d58a197f7edd',1,'libevdev.h']]], +- ['libevdev_5fproperty_5ffrom_5fname_5fn_188',['libevdev_property_from_name_n',['../group__misc.html#gaaa0bc4c7d0d2aedc84c7dcffee9ce29b',1,'libevdev.h']]], +- ['libevdev_5fproperty_5fget_5fname_189',['libevdev_property_get_name',['../group__misc.html#gacc12bdb7b912070ac9c375428f2c9892',1,'libevdev.h']]], +- ['libevdev_5fset_5fabs_5fflat_190',['libevdev_set_abs_flat',['../group__kernel.html#gabd309f30744a49e9391250b00ba2d67a',1,'libevdev.h']]], +- ['libevdev_5fset_5fabs_5ffuzz_191',['libevdev_set_abs_fuzz',['../group__kernel.html#gaa192bf0c68620be819337da6ec361c21',1,'libevdev.h']]], +- ['libevdev_5fset_5fabs_5finfo_192',['libevdev_set_abs_info',['../group__kernel.html#gafc7a4f5308e2dbf55f875630b8dca049',1,'libevdev.h']]], +- ['libevdev_5fset_5fabs_5fmaximum_193',['libevdev_set_abs_maximum',['../group__kernel.html#ga2302fd9a491d8e27280157d67a703af6',1,'libevdev.h']]], +- ['libevdev_5fset_5fabs_5fminimum_194',['libevdev_set_abs_minimum',['../group__kernel.html#gaca62172c2a823cd02eacf0d2292d917a',1,'libevdev.h']]], +- ['libevdev_5fset_5fabs_5fresolution_195',['libevdev_set_abs_resolution',['../group__kernel.html#ga2266b59711cdaa4fc12fa56c9313a038',1,'libevdev.h']]], +- ['libevdev_5fset_5fclock_5fid_196',['libevdev_set_clock_id',['../group__kernel.html#ga2925b6fbf8c7991ff2164424b840b82d',1,'libevdev.h']]], +- ['libevdev_5fset_5fdevice_5flog_5ffunction_197',['libevdev_set_device_log_function',['../group__logging.html#ga2830ff0aa391d8d1111682d3e762091b',1,'libevdev.h']]], +- ['libevdev_5fset_5fevent_5fvalue_198',['libevdev_set_event_value',['../group__kernel.html#ga79e82ee2a95cb08adb4172aabe0c7184',1,'libevdev.h']]], +- ['libevdev_5fset_5ffd_199',['libevdev_set_fd',['../group__init.html#ga6658ac490d68c307ff8b8d1536c12b44',1,'libevdev.h']]], +- ['libevdev_5fset_5fid_5fbustype_200',['libevdev_set_id_bustype',['../group__kernel.html#gaf99139c728ba1bd4b37ede612780b6b0',1,'libevdev.h']]], +- ['libevdev_5fset_5fid_5fproduct_201',['libevdev_set_id_product',['../group__kernel.html#ga62fbdaac056ab5c3db154a9eeaf33799',1,'libevdev.h']]], +- ['libevdev_5fset_5fid_5fvendor_202',['libevdev_set_id_vendor',['../group__kernel.html#ga8ce28051ebbb73de1d04d782f4d0d6fe',1,'libevdev.h']]], +- ['libevdev_5fset_5fid_5fversion_203',['libevdev_set_id_version',['../group__kernel.html#gaee1d2db88b191ec21d5bf22dd4fe3055',1,'libevdev.h']]], +- ['libevdev_5fset_5flog_5ffunction_204',['libevdev_set_log_function',['../group__logging.html#gaa60be86b83b3a6c82d8e536ba89ff955',1,'libevdev.h']]], +- ['libevdev_5fset_5flog_5fpriority_205',['libevdev_set_log_priority',['../group__logging.html#gaf6b6842a9ed98b61d0abb421e853fd89',1,'libevdev.h']]], +- ['libevdev_5fset_5fname_206',['libevdev_set_name',['../group__kernel.html#gae5dcdb7678cdc9be4ab1989725b4ed32',1,'libevdev.h']]], +- ['libevdev_5fset_5fphys_207',['libevdev_set_phys',['../group__kernel.html#gacd57c8d6ace8e0b1417809a9c1c67af3',1,'libevdev.h']]], +- ['libevdev_5fset_5fslot_5fvalue_208',['libevdev_set_slot_value',['../group__kernel.html#ga0c61f4919b03b0850529a50c37a20333',1,'libevdev.h']]], +- ['libevdev_5fset_5funiq_209',['libevdev_set_uniq',['../group__kernel.html#ga4e4fd2627744fd5811c50c7403f27ad7',1,'libevdev.h']]], +- ['libevdev_5fuinput_5fcreate_5ffrom_5fdevice_210',['libevdev_uinput_create_from_device',['../group__uinput.html#gaf14b21301bac9d79c20e890172873b96',1,'libevdev-uinput.h']]], +- ['libevdev_5fuinput_5fdestroy_211',['libevdev_uinput_destroy',['../group__uinput.html#ga9dfa58a84eb4c6b97107dcf3fa621329',1,'libevdev-uinput.h']]], +- ['libevdev_5fuinput_5fget_5fdevnode_212',['libevdev_uinput_get_devnode',['../group__uinput.html#ga4c595bcda748b08561e2819fe9b7c2d2',1,'libevdev-uinput.h']]], +- ['libevdev_5fuinput_5fget_5ffd_213',['libevdev_uinput_get_fd',['../group__uinput.html#ga9cd7fb14a96d4cc14d3dffdcead84c5d',1,'libevdev-uinput.h']]], +- ['libevdev_5fuinput_5fget_5fsyspath_214',['libevdev_uinput_get_syspath',['../group__uinput.html#gaacca93061fce57cec0ce3c52e443a427',1,'libevdev-uinput.h']]], +- ['libevdev_5fuinput_5fwrite_5fevent_215',['libevdev_uinput_write_event',['../group__uinput.html#ga4c3c2f5fcd315a28a067f53b9f855fe7',1,'libevdev-uinput.h']]] ++ ['libevdev_5fchange_5ffd_130',['libevdev_change_fd',['../group__init.html#gac71c9cca4c572ed1b1a8c233be70a17c',1,'libevdev.h']]], ++ ['libevdev_5fdisable_5fevent_5fcode_131',['libevdev_disable_event_code',['../group__kernel.html#ga6199a7c8144f54e092e913c2d2df16de',1,'libevdev.h']]], ++ ['libevdev_5fdisable_5fevent_5ftype_132',['libevdev_disable_event_type',['../group__kernel.html#gabbacb53b66882b5335055c0fd1f40d9a',1,'libevdev.h']]], ++ ['libevdev_5fdisable_5fproperty_133',['libevdev_disable_property',['../group__kernel.html#ga8f6367c36331c803ad69b2591e210019',1,'libevdev.h']]], ++ ['libevdev_5fenable_5fevent_5fcode_134',['libevdev_enable_event_code',['../group__kernel.html#ga51cfda33fd526549046399aadd764fca',1,'libevdev.h']]], ++ ['libevdev_5fenable_5fevent_5ftype_135',['libevdev_enable_event_type',['../group__kernel.html#ga59ef78b1557f9543d0060ab25b0167ca',1,'libevdev.h']]], ++ ['libevdev_5fenable_5fproperty_136',['libevdev_enable_property',['../group__kernel.html#gafc552080520c9d886452b05f3a1d75b6',1,'libevdev.h']]], ++ ['libevdev_5fevent_5fcode_5ffrom_5fcode_5fname_137',['libevdev_event_code_from_code_name',['../group__misc.html#gabad00f68481d83747a134c0a37aca003',1,'libevdev.h']]], ++ ['libevdev_5fevent_5fcode_5ffrom_5fcode_5fname_5fn_138',['libevdev_event_code_from_code_name_n',['../group__misc.html#ga5bf9af4b8c372d87793e8a3c2dbeb466',1,'libevdev.h']]], ++ ['libevdev_5fevent_5fcode_5ffrom_5fname_139',['libevdev_event_code_from_name',['../group__misc.html#ga6620301a67f467489e4a7f93afe81621',1,'libevdev.h']]], ++ ['libevdev_5fevent_5fcode_5ffrom_5fname_5fn_140',['libevdev_event_code_from_name_n',['../group__misc.html#ga17a760a9eea9dc25011f39e1d5c282a0',1,'libevdev.h']]], ++ ['libevdev_5fevent_5fcode_5fget_5fname_141',['libevdev_event_code_get_name',['../group__misc.html#gab407b3c2caaae502859c28460cad17bb',1,'libevdev.h']]], ++ ['libevdev_5fevent_5fis_5fcode_142',['libevdev_event_is_code',['../group__misc.html#ga37766a6a498fef3294d589abcce688bb',1,'libevdev.h']]], ++ ['libevdev_5fevent_5fis_5ftype_143',['libevdev_event_is_type',['../group__misc.html#gab8b6b80740e028261300b8952b61a596',1,'libevdev.h']]], ++ ['libevdev_5fevent_5ftype_5ffrom_5fcode_5fname_144',['libevdev_event_type_from_code_name',['../group__misc.html#gadd41b7514cca16c8b8920f16e562e08a',1,'libevdev.h']]], ++ ['libevdev_5fevent_5ftype_5ffrom_5fcode_5fname_5fn_145',['libevdev_event_type_from_code_name_n',['../group__misc.html#gab214498fca7a328f8a712ce15bf21982',1,'libevdev.h']]], ++ ['libevdev_5fevent_5ftype_5ffrom_5fname_146',['libevdev_event_type_from_name',['../group__misc.html#ga61ce3bf1e66bd172e583b86a11fc41f1',1,'libevdev.h']]], ++ ['libevdev_5fevent_5ftype_5ffrom_5fname_5fn_147',['libevdev_event_type_from_name_n',['../group__misc.html#ga4ee03d650200bb04a23233570667fa84',1,'libevdev.h']]], ++ ['libevdev_5fevent_5ftype_5fget_5fmax_148',['libevdev_event_type_get_max',['../group__misc.html#gabfad87ea78d034631cf3e5322ac383a1',1,'libevdev.h']]], ++ ['libevdev_5fevent_5ftype_5fget_5fname_149',['libevdev_event_type_get_name',['../group__misc.html#gac99720fd926bf288764f9a81bf37ed09',1,'libevdev.h']]], ++ ['libevdev_5fevent_5fvalue_5ffrom_5fname_150',['libevdev_event_value_from_name',['../group__misc.html#ga314903beeafedabe45f879637e7254b0',1,'libevdev.h']]], ++ ['libevdev_5fevent_5fvalue_5ffrom_5fname_5fn_151',['libevdev_event_value_from_name_n',['../group__misc.html#gaebfc6b0ebb70169c9fec61620f1ea85f',1,'libevdev.h']]], ++ ['libevdev_5fevent_5fvalue_5fget_5fname_152',['libevdev_event_value_get_name',['../group__misc.html#gabcd45c5e963cba245e944ea66e72fcc3',1,'libevdev.h']]], ++ ['libevdev_5ffetch_5fevent_5fvalue_153',['libevdev_fetch_event_value',['../group__bits.html#ga0a7be80d769294bf9758adf79c3c7147',1,'libevdev.h']]], ++ ['libevdev_5ffetch_5fslot_5fvalue_154',['libevdev_fetch_slot_value',['../group__mt.html#gaca19dca5aa8f0ea3b210f3fc670384ec',1,'libevdev.h']]], ++ ['libevdev_5ffree_155',['libevdev_free',['../group__init.html#gacd9fe760d15be25fc99ce469034bd78c',1,'libevdev.h']]], ++ ['libevdev_5fget_5fabs_5fflat_156',['libevdev_get_abs_flat',['../group__bits.html#ga6b3f7ebae2324524dc41384acd724b92',1,'libevdev.h']]], ++ ['libevdev_5fget_5fabs_5ffuzz_157',['libevdev_get_abs_fuzz',['../group__bits.html#ga1a3dfeb3bb2db0b4323c836c7ab10f1a',1,'libevdev.h']]], ++ ['libevdev_5fget_5fabs_5finfo_158',['libevdev_get_abs_info',['../group__bits.html#ga6d8e2caf87fa536fad979346671838d7',1,'libevdev.h']]], ++ ['libevdev_5fget_5fabs_5fmaximum_159',['libevdev_get_abs_maximum',['../group__bits.html#ga97a3411ae85f1f3b5c5eb1d5351b11ca',1,'libevdev.h']]], ++ ['libevdev_5fget_5fabs_5fminimum_160',['libevdev_get_abs_minimum',['../group__bits.html#ga482ce989a3f62f7e67e4ea7ad534189e',1,'libevdev.h']]], ++ ['libevdev_5fget_5fabs_5fresolution_161',['libevdev_get_abs_resolution',['../group__bits.html#ga75751e637a845201b6d1c419ecfa6ba4',1,'libevdev.h']]], ++ ['libevdev_5fget_5fcurrent_5fslot_162',['libevdev_get_current_slot',['../group__mt.html#gad22e2420be668b56ef486cde2e98c5dd',1,'libevdev.h']]], ++ ['libevdev_5fget_5fdriver_5fversion_163',['libevdev_get_driver_version',['../group__bits.html#ga31e9e7a99215a03bcdc339b53e1be2fa',1,'libevdev.h']]], ++ ['libevdev_5fget_5fevent_5fvalue_164',['libevdev_get_event_value',['../group__bits.html#ga6259f4c6bdba950329ff9cd48c2ef8a3',1,'libevdev.h']]], ++ ['libevdev_5fget_5ffd_165',['libevdev_get_fd',['../group__init.html#gab9bfc800859ac3aa63f41d58ec4b616c',1,'libevdev.h']]], ++ ['libevdev_5fget_5fid_5fbustype_166',['libevdev_get_id_bustype',['../group__bits.html#ga9bf55d416401642bad0c435735682308',1,'libevdev.h']]], ++ ['libevdev_5fget_5fid_5fproduct_167',['libevdev_get_id_product',['../group__bits.html#ga1dc66cfef646878d58be72f8902a6bac',1,'libevdev.h']]], ++ ['libevdev_5fget_5fid_5fvendor_168',['libevdev_get_id_vendor',['../group__bits.html#ga08891c3285da5b8d26769c9a34f063f3',1,'libevdev.h']]], ++ ['libevdev_5fget_5fid_5fversion_169',['libevdev_get_id_version',['../group__bits.html#ga75a07d0c96dfe09d2194c104c429d0ae',1,'libevdev.h']]], ++ ['libevdev_5fget_5flog_5fpriority_170',['libevdev_get_log_priority',['../group__logging.html#ga1da07493a798595cf85c127490b98ee8',1,'libevdev.h']]], ++ ['libevdev_5fget_5fname_171',['libevdev_get_name',['../group__bits.html#gaed0328c67b7a78422636d9fe09a73f12',1,'libevdev.h']]], ++ ['libevdev_5fget_5fnum_5fslots_172',['libevdev_get_num_slots',['../group__mt.html#gaf272526f0a59d2f61ef7389046cd4088',1,'libevdev.h']]], ++ ['libevdev_5fget_5fphys_173',['libevdev_get_phys',['../group__bits.html#ga5df483b0b24d7b96ea1181808fab851d',1,'libevdev.h']]], ++ ['libevdev_5fget_5frepeat_174',['libevdev_get_repeat',['../group__bits.html#gaf12fa199bb9497b38358d72e7505d770',1,'libevdev.h']]], ++ ['libevdev_5fget_5fslot_5fvalue_175',['libevdev_get_slot_value',['../group__mt.html#ga8c6303391cb4f90b2d46763cf4eb8bc8',1,'libevdev.h']]], ++ ['libevdev_5fget_5funiq_176',['libevdev_get_uniq',['../group__bits.html#ga6d9f7d44bff8828ead3d251177035ca4',1,'libevdev.h']]], ++ ['libevdev_5fgrab_177',['libevdev_grab',['../group__init.html#ga5d434af74fee20f273db568e2cbbd13f',1,'libevdev.h']]], ++ ['libevdev_5fhas_5fevent_5fcode_178',['libevdev_has_event_code',['../group__bits.html#gab2ab9dad417f33daa79fa0c3d682df0b',1,'libevdev.h']]], ++ ['libevdev_5fhas_5fevent_5fpending_179',['libevdev_has_event_pending',['../group__events.html#gae18fbfb59064c9c4b9d5db2d8cb23784',1,'libevdev.h']]], ++ ['libevdev_5fhas_5fevent_5ftype_180',['libevdev_has_event_type',['../group__bits.html#ga398bef155fa4a0cfb832de30723ebd14',1,'libevdev.h']]], ++ ['libevdev_5fhas_5fproperty_181',['libevdev_has_property',['../group__bits.html#ga36d529ea53f4522004bc7d16c051464b',1,'libevdev.h']]], ++ ['libevdev_5fkernel_5fset_5fabs_5finfo_182',['libevdev_kernel_set_abs_info',['../group__kernel.html#ga41c0321b93349d0ddd1f1c007ccf7de9',1,'libevdev.h']]], ++ ['libevdev_5fkernel_5fset_5fled_5fvalue_183',['libevdev_kernel_set_led_value',['../group__kernel.html#gaa7d13aeac3c40e16f296467780e67c01',1,'libevdev.h']]], ++ ['libevdev_5fkernel_5fset_5fled_5fvalues_184',['libevdev_kernel_set_led_values',['../group__kernel.html#ga93a19fa6e5be57903aff7c4a60af2a00',1,'libevdev.h']]], ++ ['libevdev_5fnew_185',['libevdev_new',['../group__init.html#ga332c8ee260b4ef864345abe5d04e820c',1,'libevdev.h']]], ++ ['libevdev_5fnew_5ffrom_5ffd_186',['libevdev_new_from_fd',['../group__init.html#ga89bb5bce1c23e293293484b05b12aaf4',1,'libevdev.h']]], ++ ['libevdev_5fnext_5fevent_187',['libevdev_next_event',['../group__events.html#gabb96c864e836c0b98788f4ab771c3a76',1,'libevdev.h']]], ++ ['libevdev_5fproperty_5ffrom_5fname_188',['libevdev_property_from_name',['../group__misc.html#ga6f4418c98aa475a2fc34d58a197f7edd',1,'libevdev.h']]], ++ ['libevdev_5fproperty_5ffrom_5fname_5fn_189',['libevdev_property_from_name_n',['../group__misc.html#gaaa0bc4c7d0d2aedc84c7dcffee9ce29b',1,'libevdev.h']]], ++ ['libevdev_5fproperty_5fget_5fname_190',['libevdev_property_get_name',['../group__misc.html#gacc12bdb7b912070ac9c375428f2c9892',1,'libevdev.h']]], ++ ['libevdev_5fset_5fabs_5fflat_191',['libevdev_set_abs_flat',['../group__kernel.html#gabd309f30744a49e9391250b00ba2d67a',1,'libevdev.h']]], ++ ['libevdev_5fset_5fabs_5ffuzz_192',['libevdev_set_abs_fuzz',['../group__kernel.html#gaa192bf0c68620be819337da6ec361c21',1,'libevdev.h']]], ++ ['libevdev_5fset_5fabs_5finfo_193',['libevdev_set_abs_info',['../group__kernel.html#gafc7a4f5308e2dbf55f875630b8dca049',1,'libevdev.h']]], ++ ['libevdev_5fset_5fabs_5fmaximum_194',['libevdev_set_abs_maximum',['../group__kernel.html#ga2302fd9a491d8e27280157d67a703af6',1,'libevdev.h']]], ++ ['libevdev_5fset_5fabs_5fminimum_195',['libevdev_set_abs_minimum',['../group__kernel.html#gaca62172c2a823cd02eacf0d2292d917a',1,'libevdev.h']]], ++ ['libevdev_5fset_5fabs_5fresolution_196',['libevdev_set_abs_resolution',['../group__kernel.html#ga2266b59711cdaa4fc12fa56c9313a038',1,'libevdev.h']]], ++ ['libevdev_5fset_5fclock_5fid_197',['libevdev_set_clock_id',['../group__kernel.html#ga2925b6fbf8c7991ff2164424b840b82d',1,'libevdev.h']]], ++ ['libevdev_5fset_5fdevice_5flog_5ffunction_198',['libevdev_set_device_log_function',['../group__logging.html#ga2830ff0aa391d8d1111682d3e762091b',1,'libevdev.h']]], ++ ['libevdev_5fset_5fevent_5fvalue_199',['libevdev_set_event_value',['../group__kernel.html#ga79e82ee2a95cb08adb4172aabe0c7184',1,'libevdev.h']]], ++ ['libevdev_5fset_5ffd_200',['libevdev_set_fd',['../group__init.html#ga6658ac490d68c307ff8b8d1536c12b44',1,'libevdev.h']]], ++ ['libevdev_5fset_5fid_5fbustype_201',['libevdev_set_id_bustype',['../group__kernel.html#gaf99139c728ba1bd4b37ede612780b6b0',1,'libevdev.h']]], ++ ['libevdev_5fset_5fid_5fproduct_202',['libevdev_set_id_product',['../group__kernel.html#ga62fbdaac056ab5c3db154a9eeaf33799',1,'libevdev.h']]], ++ ['libevdev_5fset_5fid_5fvendor_203',['libevdev_set_id_vendor',['../group__kernel.html#ga8ce28051ebbb73de1d04d782f4d0d6fe',1,'libevdev.h']]], ++ ['libevdev_5fset_5fid_5fversion_204',['libevdev_set_id_version',['../group__kernel.html#gaee1d2db88b191ec21d5bf22dd4fe3055',1,'libevdev.h']]], ++ ['libevdev_5fset_5flog_5ffunction_205',['libevdev_set_log_function',['../group__logging.html#gaa60be86b83b3a6c82d8e536ba89ff955',1,'libevdev.h']]], ++ ['libevdev_5fset_5flog_5fpriority_206',['libevdev_set_log_priority',['../group__logging.html#gaf6b6842a9ed98b61d0abb421e853fd89',1,'libevdev.h']]], ++ ['libevdev_5fset_5fname_207',['libevdev_set_name',['../group__kernel.html#gae5dcdb7678cdc9be4ab1989725b4ed32',1,'libevdev.h']]], ++ ['libevdev_5fset_5fphys_208',['libevdev_set_phys',['../group__kernel.html#gacd57c8d6ace8e0b1417809a9c1c67af3',1,'libevdev.h']]], ++ ['libevdev_5fset_5fslot_5fvalue_209',['libevdev_set_slot_value',['../group__kernel.html#ga0c61f4919b03b0850529a50c37a20333',1,'libevdev.h']]], ++ ['libevdev_5fset_5funiq_210',['libevdev_set_uniq',['../group__kernel.html#ga4e4fd2627744fd5811c50c7403f27ad7',1,'libevdev.h']]], ++ ['libevdev_5fuinput_5fcreate_5ffrom_5fdevice_211',['libevdev_uinput_create_from_device',['../group__uinput.html#gaf14b21301bac9d79c20e890172873b96',1,'libevdev-uinput.h']]], ++ ['libevdev_5fuinput_5fdestroy_212',['libevdev_uinput_destroy',['../group__uinput.html#ga9dfa58a84eb4c6b97107dcf3fa621329',1,'libevdev-uinput.h']]], ++ ['libevdev_5fuinput_5fget_5fdevnode_213',['libevdev_uinput_get_devnode',['../group__uinput.html#ga4c595bcda748b08561e2819fe9b7c2d2',1,'libevdev-uinput.h']]], ++ ['libevdev_5fuinput_5fget_5ffd_214',['libevdev_uinput_get_fd',['../group__uinput.html#ga9cd7fb14a96d4cc14d3dffdcead84c5d',1,'libevdev-uinput.h']]], ++ ['libevdev_5fuinput_5fget_5fsyspath_215',['libevdev_uinput_get_syspath',['../group__uinput.html#gaacca93061fce57cec0ce3c52e443a427',1,'libevdev-uinput.h']]], ++ ['libevdev_5fuinput_5fwrite_5fevent_216',['libevdev_uinput_write_event',['../group__uinput.html#ga4c3c2f5fcd315a28a067f53b9f855fe7',1,'libevdev-uinput.h']]] + ]; +diff -Naur third-party-libevdev-bak/doc/html/search/groups_0.html third-party-new/doc/html/search/groups_0.html +--- third-party-libevdev-bak/doc/html/search/groups_0.html 2023-03-28 10:49:53.380511700 +0800 ++++ third-party-new/doc/html/search/groups_0.html 2023-04-01 15:37:22.852030700 +0800 +@@ -1,7 +1,8 @@ + +- ++ ++ + +- ++ + + + +@@ -10,14 +11,14 @@ +
+
Loading...
+
+- ++ +
Searching...
+
No Matches
+- ++ +
+ + +diff -Naur third-party-libevdev-bak/doc/html/search/groups_0.js third-party-new/doc/html/search/groups_0.js +--- third-party-libevdev-bak/doc/html/search/groups_0.js 2023-03-28 10:49:53.380511700 +0800 ++++ third-party-new/doc/html/search/groups_0.js 2023-04-01 15:37:57.952960100 +0800 +@@ -1,4 +1,4 @@ + var searchData= + [ +- ['event_20handling_240',['Event handling',['../group__events.html',1,'']]] ++ ['event_20handling_241',['Event handling',['../group__events.html',1,'']]] + ]; +diff -Naur third-party-libevdev-bak/doc/html/search/groups_1.html third-party-new/doc/html/search/groups_1.html +--- third-party-libevdev-bak/doc/html/search/groups_1.html 2023-03-28 10:49:53.380511700 +0800 ++++ third-party-new/doc/html/search/groups_1.html 2023-04-01 15:38:06.712734500 +0800 +@@ -1,7 +1,8 @@ + +- ++ ++ + +- ++ + + + +@@ -10,14 +11,14 @@ +
+
Loading...
+
+- ++ +
Searching...
+
No Matches
+- ++ +
+ + +diff -Naur third-party-libevdev-bak/doc/html/search/groups_1.js third-party-new/doc/html/search/groups_1.js +--- third-party-libevdev-bak/doc/html/search/groups_1.js 2023-03-28 10:49:53.380511700 +0800 ++++ third-party-new/doc/html/search/groups_1.js 2023-04-01 15:38:33.084187700 +0800 +@@ -1,4 +1,4 @@ + var searchData= + [ +- ['initialization_20and_20setup_241',['Initialization and setup',['../group__init.html',1,'']]] ++ ['initialization_20and_20setup_242',['Initialization and setup',['../group__init.html',1,'']]] + ]; +diff -Naur third-party-libevdev-bak/doc/html/search/groups_2.html third-party-new/doc/html/search/groups_2.html +--- third-party-libevdev-bak/doc/html/search/groups_2.html 2023-03-28 10:49:53.380511700 +0800 ++++ third-party-new/doc/html/search/groups_2.html 2023-04-01 15:39:09.984504000 +0800 +@@ -1,7 +1,8 @@ + +- ++ ++ + +- ++ + + + +@@ -10,14 +11,14 @@ +
+
Loading...
+
+- ++ +
Searching...
+
No Matches
+- ++ +
+ + +diff -Naur third-party-libevdev-bak/doc/html/search/groups_2.js third-party-new/doc/html/search/groups_2.js +--- third-party-libevdev-bak/doc/html/search/groups_2.js 2023-03-28 10:49:53.380511700 +0800 ++++ third-party-new/doc/html/search/groups_2.js 2023-04-01 15:39:16.356257600 +0800 +@@ -1,4 +1,4 @@ + var searchData= + [ +- ['library_20logging_20facilities_242',['Library logging facilities',['../group__logging.html',1,'']]] ++ ['library_20logging_20facilities_243',['Library logging facilities',['../group__logging.html',1,'']]] + ]; +diff -Naur third-party-libevdev-bak/doc/html/search/groups_3.html third-party-new/doc/html/search/groups_3.html +--- third-party-libevdev-bak/doc/html/search/groups_3.html 2023-03-28 10:49:53.380511700 +0800 ++++ third-party-new/doc/html/search/groups_3.html 2023-04-01 15:39:50.436242300 +0800 +@@ -1,7 +1,8 @@ + +- ++ ++ + +- ++ + + + +@@ -10,14 +11,14 @@ +
+
Loading...
+
+- ++ +
Searching...
+
No Matches
+- ++ +
+ + +diff -Naur third-party-libevdev-bak/doc/html/search/groups_3.js third-party-new/doc/html/search/groups_3.js +--- third-party-libevdev-bak/doc/html/search/groups_3.js 2023-03-28 10:49:53.380511700 +0800 ++++ third-party-new/doc/html/search/groups_3.js 2023-04-01 15:41:15.124700200 +0800 +@@ -1,6 +1,6 @@ + var searchData= + [ +- ['modifying_20the_20appearance_20or_20capabilities_20of_20the_20device_243',['Modifying the appearance or capabilities of the device',['../group__kernel.html',1,'']]], + ['miscellaneous_20helper_20functions_244',['Miscellaneous helper functions',['../group__misc.html',1,'']]], +- ['multi_2dtouch_20related_20functions_245',['Multi-touch related functions',['../group__mt.html',1,'']]] ++ ['modifying_20the_20appearance_20or_20capabilities_20of_20the_20device_245',['Modifying the appearance or capabilities of the device',['../group__kernel.html',1,'']]], ++ ['multi_2dtouch_20related_20functions_246',['Multi-touch related functions',['../group__mt.html',1,'']]] + ]; +diff -Naur third-party-libevdev-bak/doc/html/search/groups_4.html third-party-new/doc/html/search/groups_4.html +--- third-party-libevdev-bak/doc/html/search/groups_4.html 2023-03-28 10:49:53.380511700 +0800 ++++ third-party-new/doc/html/search/groups_4.html 2023-04-01 15:41:26.515764300 +0800 +@@ -1,7 +1,8 @@ + +- ++ ++ + +- ++ + + + +@@ -10,14 +11,14 @@ +
+
Loading...
+
+- ++ +
Searching...
+
No Matches
+- ++ +
+ + +diff -Naur third-party-libevdev-bak/doc/html/search/groups_4.js third-party-new/doc/html/search/groups_4.js +--- third-party-libevdev-bak/doc/html/search/groups_4.js 2023-03-28 10:49:53.380511700 +0800 ++++ third-party-new/doc/html/search/groups_4.js 2023-04-01 15:41:39.190840500 +0800 +@@ -1,4 +1,4 @@ + var searchData= + [ +- ['querying_20device_20capabilities_246',['Querying device capabilities',['../group__bits.html',1,'']]] ++ ['querying_20device_20capabilities_247',['Querying device capabilities',['../group__bits.html',1,'']]] + ]; +diff -Naur third-party-libevdev-bak/doc/html/search/groups_5.html third-party-new/doc/html/search/groups_5.html +--- third-party-libevdev-bak/doc/html/search/groups_5.html 2023-03-28 10:49:53.380511700 +0800 ++++ third-party-new/doc/html/search/groups_5.html 2023-04-01 15:43:50.131466200 +0800 +@@ -1,7 +1,8 @@ + +- ++ ++ + +- ++ + + + +@@ -10,14 +11,14 @@ +
+
Loading...
+
+- ++ +
Searching...
+
No Matches
+- ++ +
+ + +diff -Naur third-party-libevdev-bak/doc/html/search/groups_5.js third-party-new/doc/html/search/groups_5.js +--- third-party-libevdev-bak/doc/html/search/groups_5.js 2023-03-28 10:49:53.380511700 +0800 ++++ third-party-new/doc/html/search/groups_5.js 2023-04-01 15:44:07.553194200 +0800 +@@ -1,4 +1,4 @@ + var searchData= + [ +- ['uinput_20device_20creation_247',['uinput device creation',['../group__uinput.html',1,'']]] ++ ['uinput_20device_20creation_248',['uinput device creation',['../group__uinput.html',1,'']]] + ]; +diff -Naur third-party-libevdev-bak/doc/html/search/nomatches.html third-party-new/doc/html/search/nomatches.html +--- third-party-libevdev-bak/doc/html/search/nomatches.html 2023-03-28 10:49:53.380511700 +0800 ++++ third-party-new/doc/html/search/nomatches.html 2023-04-01 15:45:22.889226400 +0800 +@@ -1,5 +1,6 @@ + +- ++ ++ + + + +diff -Naur third-party-libevdev-bak/doc/html/search/pages_0.html third-party-new/doc/html/search/pages_0.html +--- third-party-libevdev-bak/doc/html/search/pages_0.html 2023-03-28 10:49:53.380511700 +0800 ++++ third-party-new/doc/html/search/pages_0.html 2023-04-01 15:46:15.618387500 +0800 +@@ -1,7 +1,8 @@ + +- ++ ++ + +- ++ + + + +@@ -10,14 +11,14 @@ +
+
Loading...
+
+- ++ +
Searching...
+
No Matches
+- ++ +
+ + +diff -Naur third-party-libevdev-bak/doc/html/search/pages_0.js third-party-new/doc/html/search/pages_0.js +--- third-party-libevdev-bak/doc/html/search/pages_0.js 2023-03-28 10:49:53.384511800 +0800 ++++ third-party-new/doc/html/search/pages_0.js 2023-04-01 15:49:32.539324100 +0800 +@@ -1,4 +1,4 @@ + var searchData= + [ +- ['compatibility_20and_20behavior_20across_20kernel_20versions_248',['Compatibility and Behavior across kernel versions',['../backwardscompatibility.html',1,'']]] ++ ['compatibility_20and_20behavior_20across_20kernel_20versions_249',['Compatibility and Behavior across kernel versions',['../backwardscompatibility.html',1,'']]] + ]; +diff -Naur third-party-libevdev-bak/doc/html/search/pages_1.html third-party-new/doc/html/search/pages_1.html +--- third-party-libevdev-bak/doc/html/search/pages_1.html 2023-03-28 10:49:53.384511800 +0800 ++++ third-party-new/doc/html/search/pages_1.html 2023-04-01 15:49:43.025097100 +0800 +@@ -1,7 +1,8 @@ + +- ++ ++ + +- ++ + + + +@@ -10,14 +11,14 @@ +
+
Loading...
+
+- ++ +
Searching...
+
No Matches
+- ++ +
+ + +diff -Naur third-party-libevdev-bak/doc/html/search/pages_1.js third-party-new/doc/html/search/pages_1.js +--- third-party-libevdev-bak/doc/html/search/pages_1.js 2023-03-28 10:49:53.384511800 +0800 ++++ third-party-new/doc/html/search/pages_1.js 2023-04-01 15:50:13.734641400 +0800 +@@ -1,4 +1,4 @@ + var searchData= + [ +- ['deprecated_20list_249',['Deprecated List',['../deprecated.html',1,'']]] ++ ['deprecated_20list_250',['Deprecated List',['../deprecated.html',1,'']]] + ]; +diff -Naur third-party-libevdev-bak/doc/html/search/pages_2.html third-party-new/doc/html/search/pages_2.html +--- third-party-libevdev-bak/doc/html/search/pages_2.html 2023-03-28 10:49:53.384511800 +0800 ++++ third-party-new/doc/html/search/pages_2.html 2023-04-01 15:50:24.890090300 +0800 +@@ -1,7 +1,8 @@ + +- ++ ++ + +- ++ + + + +@@ -10,14 +11,14 @@ +
+
Loading...
+
+- ++ +
Searching...
+
No Matches
+- ++ +
+ + +diff -Naur third-party-libevdev-bak/doc/html/search/pages_2.js third-party-new/doc/html/search/pages_2.js +--- third-party-libevdev-bak/doc/html/search/pages_2.js 2023-03-28 10:49:53.384511800 +0800 ++++ third-party-new/doc/html/search/pages_2.js 2023-04-01 15:50:37.732190100 +0800 +@@ -1,4 +1,4 @@ + var searchData= + [ +- ['evdev_20ioctls_250',['evdev ioctls',['../ioctls.html',1,'']]] ++ ['evdev_20ioctls_251',['evdev ioctls',['../ioctls.html',1,'']]] + ]; +diff -Naur third-party-libevdev-bak/doc/html/search/pages_3.html third-party-new/doc/html/search/pages_3.html +--- third-party-libevdev-bak/doc/html/search/pages_3.html 2023-03-28 10:49:53.384511800 +0800 ++++ third-party-new/doc/html/search/pages_3.html 2023-04-01 15:50:47.836288700 +0800 +@@ -1,7 +1,8 @@ + +- ++ ++ + +- ++ + + + +@@ -10,14 +11,14 @@ +
+
Loading...
+
+- ++ +
Searching...
+
No Matches
+- ++ +
+ + +diff -Naur third-party-libevdev-bak/doc/html/search/pages_3.js third-party-new/doc/html/search/pages_3.js +--- third-party-libevdev-bak/doc/html/search/pages_3.js 2023-03-28 10:49:53.384511800 +0800 ++++ third-party-new/doc/html/search/pages_3.js 2023-04-01 15:50:56.221896100 +0800 +@@ -1,4 +1,4 @@ + var searchData= + [ +- ['kernel_20header_251',['Kernel header',['../kernel_header.html',1,'']]] ++ ['kernel_20header_252',['Kernel header',['../kernel_header.html',1,'']]] + ]; +diff -Naur third-party-libevdev-bak/doc/html/search/pages_4.html third-party-new/doc/html/search/pages_4.html +--- third-party-libevdev-bak/doc/html/search/pages_4.html 2023-03-28 10:49:53.384511800 +0800 ++++ third-party-new/doc/html/search/pages_4.html 2023-04-01 15:51:04.995238600 +0800 +@@ -1,7 +1,8 @@ + +- ++ ++ + +- ++ + + + +@@ -10,14 +11,14 @@ +
+
Loading...
+
+- ++ +
Searching...
+
No Matches
+- ++ +
+ + +diff -Naur third-party-libevdev-bak/doc/html/search/pages_4.js third-party-new/doc/html/search/pages_4.js +--- third-party-libevdev-bak/doc/html/search/pages_4.js 2023-03-28 10:49:53.384511800 +0800 ++++ third-party-new/doc/html/search/pages_4.js 2023-04-01 15:51:18.476565200 +0800 +@@ -1,4 +1,4 @@ + var searchData= + [ +- ['libevdev_2dinternal_20test_20suite_252',['libevdev-internal test suite',['../testing.html',1,'']]] ++ ['libevdev_2dinternal_20test_20suite_253',['libevdev-internal test suite',['../testing.html',1,'']]] + ]; +diff -Naur third-party-libevdev-bak/doc/html/search/pages_5.html third-party-new/doc/html/search/pages_5.html +--- third-party-libevdev-bak/doc/html/search/pages_5.html 2023-03-28 10:49:53.384511800 +0800 ++++ third-party-new/doc/html/search/pages_5.html 2023-04-01 15:51:35.170111200 +0800 +@@ -1,7 +1,8 @@ + +- ++ ++ + +- ++ + + + +@@ -10,14 +11,14 @@ +
+
Loading...
+
+- ++ +
Searching...
+
No Matches
+- ++ +
+ + +diff -Naur third-party-libevdev-bak/doc/html/search/pages_5.js third-party-new/doc/html/search/pages_5.js +--- third-party-libevdev-bak/doc/html/search/pages_5.js 2023-03-28 10:49:53.384511800 +0800 ++++ third-party-new/doc/html/search/pages_5.js 2023-04-01 15:51:41.455294000 +0800 +@@ -1,5 +1,5 @@ + var searchData= + [ +- ['statically_20linking_20libevdev_253',['Statically linking libevdev',['../static_linking.html',1,'']]], +- ['syn_5fdropped_20handling_254',['SYN_DROPPED handling',['../syn_dropped.html',1,'']]] ++ ['statically_20linking_20libevdev_254',['Statically linking libevdev',['../static_linking.html',1,'']]], ++ ['syn_5fdropped_20handling_255',['SYN_DROPPED handling',['../syn_dropped.html',1,'']]] + ]; +diff -Naur third-party-libevdev-bak/doc/html/search/search.css third-party-new/doc/html/search/search.css +--- third-party-libevdev-bak/doc/html/search/search.css 2023-03-28 10:49:53.384511800 +0800 ++++ third-party-new/doc/html/search/search.css 2023-04-01 15:51:53.793569800 +0800 +@@ -204,19 +204,21 @@ + + span.SRScope { + padding-left: 4px; ++ font-family: Arial, Verdana, sans-serif; + } + + .SRPage .SRStatus { + padding: 2px 5px; + font-size: 8pt; + font-style: italic; ++ font-family: Arial, Verdana, sans-serif; + } + + .SRResult { + display: none; + } + +-DIV.searchresults { ++div.searchresults { + margin-left: 10px; + margin-right: 10px; + } +diff -Naur third-party-libevdev-bak/doc/html/search/search.js third-party-new/doc/html/search/search.js +--- third-party-libevdev-bak/doc/html/search/search.js 2023-03-28 10:49:53.384511800 +0800 ++++ third-party-new/doc/html/search/search.js 2023-04-01 15:52:03.869932900 +0800 +@@ -80,9 +80,10 @@ + storing this instance. Is needed to be able to set timeouts. + resultPath - path to use for external files + */ +-function SearchBox(name, resultsPath, inFrame, label) ++function SearchBox(name, resultsPath, inFrame, label, extension) + { + if (!name || !resultsPath) { alert("Missing parameters to SearchBox."); } ++ if (!extension || extension == "") { extension = ".html"; } + + // ---------- Instance variables + this.name = name; +@@ -97,6 +98,7 @@ + this.searchActive = false; + this.insideFrame = inFrame; + this.searchLabel = label; ++ this.extension = extension; + + // ----------- DOM Elements + +@@ -347,13 +349,13 @@ + if (idx!=-1) + { + var hexCode=idx.toString(16); +- resultsPage = this.resultsPath + '/' + indexSectionNames[this.searchIndex] + '_' + hexCode + '.html'; ++ resultsPage = this.resultsPath + '/' + indexSectionNames[this.searchIndex] + '_' + hexCode + this.extension; + resultsPageWithSearch = resultsPage+'?'+escape(searchValue); + hasResultsPage = true; + } + else // nothing available for this search term + { +- resultsPage = this.resultsPath + '/nomatches.html'; ++ resultsPage = this.resultsPath + '/nomatches' + this.extension; + resultsPageWithSearch = resultsPage; + hasResultsPage = false; + } +@@ -439,12 +441,12 @@ + + while (element && element!=parentElement) + { +- if (element.nodeName == 'DIV' && element.className == 'SRChildren') ++ if (element.nodeName.toLowerCase() == 'div' && element.className == 'SRChildren') + { + return element; + } + +- if (element.nodeName == 'DIV' && element.hasChildNodes()) ++ if (element.nodeName.toLowerCase() == 'div' && element.hasChildNodes()) + { + element = element.firstChild; + } +diff -Naur third-party-libevdev-bak/doc/html/search/typedefs_0.html third-party-new/doc/html/search/typedefs_0.html +--- third-party-libevdev-bak/doc/html/search/typedefs_0.html 2023-03-28 10:49:53.384511800 +0800 ++++ third-party-new/doc/html/search/typedefs_0.html 2023-04-01 15:52:33.109118000 +0800 +@@ -1,7 +1,8 @@ + +- ++ ++ + +- ++ + + + +@@ -10,14 +11,14 @@ +
+
Loading...
+
+- ++ +
Searching...
+
No Matches
+- ++ +
+ + +diff -Naur third-party-libevdev-bak/doc/html/search/typedefs_0.js third-party-new/doc/html/search/typedefs_0.js +--- third-party-libevdev-bak/doc/html/search/typedefs_0.js 2023-03-28 10:49:53.384511800 +0800 ++++ third-party-new/doc/html/search/typedefs_0.js 2023-04-01 15:52:40.243913400 +0800 +@@ -1,5 +1,5 @@ + var searchData= + [ +- ['libevdev_5fdevice_5flog_5ffunc_5ft_216',['libevdev_device_log_func_t',['../group__logging.html#gab7eb997be2b701cc6f42e7b4c3478269',1,'libevdev.h']]], +- ['libevdev_5flog_5ffunc_5ft_217',['libevdev_log_func_t',['../group__logging.html#gaf36c721d273c0794251eb7dacea2f0a4',1,'libevdev.h']]] ++ ['libevdev_5fdevice_5flog_5ffunc_5ft_217',['libevdev_device_log_func_t',['../group__logging.html#gab7eb997be2b701cc6f42e7b4c3478269',1,'libevdev.h']]], ++ ['libevdev_5flog_5ffunc_5ft_218',['libevdev_log_func_t',['../group__logging.html#gaf36c721d273c0794251eb7dacea2f0a4',1,'libevdev.h']]] + ]; +diff -Naur third-party-libevdev-bak/doc/html/static_linking.html third-party-new/doc/html/static_linking.html +--- third-party-libevdev-bak/doc/html/static_linking.html 2023-03-28 10:49:53.384511800 +0800 ++++ third-party-new/doc/html/static_linking.html 2023-04-03 10:51:28.904735900 +0800 +@@ -6,7 +6,7 @@ + + + +- ++ + + libevdev: Statically linking libevdev + +@@ -25,7 +25,7 @@ + +@@ -36,10 +36,10 @@ +
+
+ +- ++ + + +@@ -87,7 +87,7 @@ + + + +diff -Naur third-party-libevdev-bak/doc/html/syn_dropped.html third-party-new/doc/html/syn_dropped.html +--- third-party-libevdev-bak/doc/html/syn_dropped.html 2023-03-28 10:49:53.384511800 +0800 ++++ third-party-new/doc/html/syn_dropped.html 2023-04-03 10:51:40.301674000 +0800 +@@ -6,7 +6,7 @@ + + + +- ++ + + libevdev: SYN_DROPPED handling + +@@ -25,7 +25,7 @@ + +@@ -36,10 +36,10 @@ +
+
+ +- ++ + + +@@ -185,6 +185,9 @@ +
EV_ABS ABS_MT_POSITION_Y 10
+
EV_SYN SYN_REPORT 0
+
-------------------
++
@ LIBEVDEV_READ_STATUS_SYNC
Depending on the libevdev_next_event() read flag:
Definition: libevdev.h:1090
++
@ LIBEVDEV_READ_FLAG_SYNC
Process data in sync mode.
Definition: libevdev.h:761
++
@ LIBEVDEV_READ_FLAG_NORMAL
Process data in normal mode.
Definition: libevdev.h:762
+

The axis events do not reflect the position of a current touch point, a client must take care not to generate a new touch point based on those updates.

+

+ Discarding events before synchronizing

+@@ -209,9 +212,6 @@ +
EV_SYN SYN_REPORT 0
+
+
+-
@ LIBEVDEV_READ_STATUS_SYNC
Depending on the libevdev_next_event() read flag:
Definition: libevdev.h:1087
+-
@ LIBEVDEV_READ_FLAG_NORMAL
Process data in normal mode.
Definition: libevdev.h:759
+-
@ LIBEVDEV_READ_FLAG_SYNC
Process data in sync mode.
Definition: libevdev.h:758
+ + +
+@@ -222,7 +222,7 @@ + + + +diff -Naur third-party-libevdev-bak/doc/html/testing.html third-party-new/doc/html/testing.html +--- third-party-libevdev-bak/doc/html/testing.html 2023-03-28 10:49:53.384511800 +0800 ++++ third-party-new/doc/html/testing.html 2023-04-03 10:52:14.250526200 +0800 +@@ -6,7 +6,7 @@ + + + +- ++ + + libevdev: libevdev-internal test suite + +@@ -25,7 +25,7 @@ + +@@ -36,10 +36,10 @@ +
+
+ +- ++ + + +@@ -75,11 +75,11 @@ +

libevdev's internal test suite uses the Check unit testing framework.

+

Tests are divided into test suites and test cases. Most tests create a uinput device, so you'll need to run as root, and your kernel must have CONFIG_INPUT_UINPUT enabled.

+

To run a specific suite only:

export CK_RUN_SUITE="suite name"
+-

To run a specific test case only:

export CK_RUN_TEST="test case name"
+-

To get a list of all suites or tests:

git grep "suite_create"
++

To run a specific test case only:

export CK_RUN_TEST="test case name"
++

To get a list of all suites or tests:

git grep "suite_create"
+ git grep "tcase_create"
+-

By default, Check forks, making debugging harder. The test suite tries to detect if it is running inside gdb and disable forking. If that doesn't work for some reason, run gdb as below to avoid forking.

sudo CK_FORK=no CK_RUN_TEST="test case name" gdb ./test/test-libevdev
+-

A special target make gcov-report.txt exists that runs gcov and leaves a libevdev.c.gcov file. Check that for test coverage.

++

By default, Check forks, making debugging harder. The test suite tries to detect if it is running inside gdb and disable forking. If that doesn't work for some reason, run gdb as below to avoid forking.

sudo CK_FORK=no CK_RUN_TEST="test case name" gdb ./test/test-libevdev
++

A special target make gcov-report.txt exists that runs gcov and leaves a libevdev.c.gcov file. Check that for test coverage.

+

make check is hooked up to run the test and gcov (again, needs root).

+

The test suite creates a lot of devices, very quickly. Add the following xorg.conf.d snippet to avoid the devices being added as X devices (at the time of writing, mutter can't handle these devices and exits after getting a BadDevice error).

$ cat /etc/X11/xorg.conf.d/99-ignore-libevdev-devices.conf
+ Section "InputClass"
+@@ -99,7 +99,7 @@
+ 
+ 
+ 
+diff -Naur third-party-libevdev-bak/export_include/libevdev/libevdev.h third-party-new/export_include/libevdev/libevdev.h
+--- third-party-libevdev-bak/export_include/libevdev/libevdev.h	2023-03-28 10:49:53.388511800 +0800
++++ third-party-new/export_include/libevdev/libevdev.h	2023-04-03 10:54:02.032303600 +0800
+@@ -1,23 +1,26 @@
++/* SPDX-License-Identifier: MIT */
+ /*
+  * Copyright © 2013 Red Hat, Inc.
+  *
+- * Permission to use, copy, modify, distribute, and sell this software and its
+- * documentation for any purpose is hereby granted without fee, provided that
+- * the above copyright notice appear in all copies and that both that copyright
+- * notice and this permission notice appear in supporting documentation, and
+- * that the name of the copyright holders not be used in advertising or
+- * publicity pertaining to distribution of the software without specific,
+- * written prior permission.  The copyright holders make no representations
+- * about the suitability of this software for any purpose.  It is provided "as
+- * is" without express or implied warranty.
+- *
+- * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+- * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+- * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+- * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+- * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+- * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+- * OF THIS SOFTWARE.
++ * Permission is hereby granted, free of charge, to any person obtaining a copy
++ * of this software and associated documentation files (the "Software"), to
++ * deal in the Software without restriction, including without limitation the
++ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
++ * sell copies of the Software, and to permit persons to whom the Software is
++ * furnished to do so, subject to the following conditions:
++ *
++ * The above copyright notice and this permission notice (including the next
++ * paragraph) shall be included in all copies or substantial portions of the
++ * Software.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
++ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
++ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
++ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
++ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
++ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
++ * IN THE SOFTWARE.
++ *
+  */
+ 
+ #ifndef LIBEVDEV_H
+@@ -631,7 +634,7 @@
+  *         return ENOMEM;
+  *
+  * err = libevdev_set_fd(dev, fd);
+- * if (err < 0) {
++ * if (err < 0)
+  *         printf("Failed (errno %d): %s\n", -err, strerror(-err));
+  *
+  * libevdev_free(dev);
+@@ -1515,8 +1518,7 @@
+  * the event.
+  *
+  * If the device supports ABS_MT_SLOT, the value returned for any ABS_MT_*
+- * event code is the value of the currently active slot. You should use
+- * libevdev_get_slot_value() instead.
++ * event code is undefined. Use libevdev_get_slot_value() instead.
+  *
+  * @param dev The evdev device, already initialized with libevdev_set_fd()
+  * @param type The event type for the code to query (EV_SYN, EV_REL, etc.)
+diff -Naur third-party-libevdev-bak/include/config.h third-party-new/include/config.h
+--- third-party-libevdev-bak/include/config.h	2023-03-28 10:49:53.388511800 +0800
++++ third-party-new/include/config.h	2023-04-03 10:54:49.836630400 +0800
+@@ -0,0 +1,9 @@
++/*
++ * Autogenerated by the Meson build system.
++ * Do not edit, your changes will be lost.
++ */
++
++#pragma once
++
++#define _GNU_SOURCE 1
++
+diff -Naur third-party-libevdev-bak/include/event-names.h third-party-new/include/event-names.h
+--- third-party-libevdev-bak/include/event-names.h	2023-03-28 10:49:53.388511800 +0800
++++ third-party-new/include/event-names.h	2023-04-03 10:55:34.844073900 +0800
+@@ -281,7 +281,7 @@
+     [KEY_PAUSECD] = "KEY_PAUSECD",
+     [KEY_PROG3] = "KEY_PROG3",
+     [KEY_PROG4] = "KEY_PROG4",
+-    [KEY_DASHBOARD] = "KEY_DASHBOARD",
++    [KEY_ALL_APPLICATIONS] = "KEY_ALL_APPLICATIONS",
+     [KEY_SUSPEND] = "KEY_SUSPEND",
+     [KEY_CLOSE] = "KEY_CLOSE",
+     [KEY_PLAY] = "KEY_PLAY",
+@@ -417,6 +417,9 @@
+     [KEY_10CHANNELSUP] = "KEY_10CHANNELSUP",
+     [KEY_10CHANNELSDOWN] = "KEY_10CHANNELSDOWN",
+     [KEY_IMAGES] = "KEY_IMAGES",
++    [KEY_NOTIFICATION_CENTER] = "KEY_NOTIFICATION_CENTER",
++    [KEY_PICKUP_PHONE] = "KEY_PICKUP_PHONE",
++    [KEY_HANGUP_PHONE] = "KEY_HANGUP_PHONE",
+     [KEY_DEL_EOL] = "KEY_DEL_EOL",
+     [KEY_DEL_EOS] = "KEY_DEL_EOS",
+     [KEY_INS_LINE] = "KEY_INS_LINE",
+@@ -442,6 +445,7 @@
+     [KEY_FN_F] = "KEY_FN_F",
+     [KEY_FN_S] = "KEY_FN_S",
+     [KEY_FN_B] = "KEY_FN_B",
++    [KEY_FN_RIGHT_SHIFT] = "KEY_FN_RIGHT_SHIFT",
+     [KEY_BRL_DOT1] = "KEY_BRL_DOT1",
+     [KEY_BRL_DOT2] = "KEY_BRL_DOT2",
+     [KEY_BRL_DOT3] = "KEY_BRL_DOT3",
+@@ -494,6 +498,8 @@
+     [KEY_VOICECOMMAND] = "KEY_VOICECOMMAND",
+     [KEY_ASSISTANT] = "KEY_ASSISTANT",
+     [KEY_KBD_LAYOUT_NEXT] = "KEY_KBD_LAYOUT_NEXT",
++    [KEY_EMOJI_PICKER] = "KEY_EMOJI_PICKER",
++    [KEY_DICTATE] = "KEY_DICTATE",
+     [KEY_BRIGHTNESS_MIN] = "KEY_BRIGHTNESS_MIN",
+     [KEY_BRIGHTNESS_MAX] = "KEY_BRIGHTNESS_MAX",
+     [KEY_KBDINPUTASSIST_PREV] = "KEY_KBDINPUTASSIST_PREV",
+@@ -1063,6 +1069,7 @@
+     { .name = "KEY_AB", .value = KEY_AB },
+     { .name = "KEY_ADDRESSBOOK", .value = KEY_ADDRESSBOOK },
+     { .name = "KEY_AGAIN", .value = KEY_AGAIN },
++    { .name = "KEY_ALL_APPLICATIONS", .value = KEY_ALL_APPLICATIONS },
+     { .name = "KEY_ALS_TOGGLE", .value = KEY_ALS_TOGGLE },
+     { .name = "KEY_ALTERASE", .value = KEY_ALTERASE },
+     { .name = "KEY_ANGLE", .value = KEY_ANGLE },
+@@ -1137,7 +1144,6 @@
+     { .name = "KEY_CUT", .value = KEY_CUT },
+     { .name = "KEY_CYCLEWINDOWS", .value = KEY_CYCLEWINDOWS },
+     { .name = "KEY_D", .value = KEY_D },
+-    { .name = "KEY_DASHBOARD", .value = KEY_DASHBOARD },
+     { .name = "KEY_DATA", .value = KEY_DATA },
+     { .name = "KEY_DATABASE", .value = KEY_DATABASE },
+     { .name = "KEY_DELETE", .value = KEY_DELETE },
+@@ -1145,6 +1151,7 @@
+     { .name = "KEY_DEL_EOL", .value = KEY_DEL_EOL },
+     { .name = "KEY_DEL_EOS", .value = KEY_DEL_EOS },
+     { .name = "KEY_DEL_LINE", .value = KEY_DEL_LINE },
++    { .name = "KEY_DICTATE", .value = KEY_DICTATE },
+     { .name = "KEY_DIGITS", .value = KEY_DIGITS },
+     { .name = "KEY_DIRECTORY", .value = KEY_DIRECTORY },
+     { .name = "KEY_DISPLAYTOGGLE", .value = KEY_DISPLAYTOGGLE },
+@@ -1160,6 +1167,7 @@
+     { .name = "KEY_EJECTCD", .value = KEY_EJECTCD },
+     { .name = "KEY_EJECTCLOSECD", .value = KEY_EJECTCLOSECD },
+     { .name = "KEY_EMAIL", .value = KEY_EMAIL },
++    { .name = "KEY_EMOJI_PICKER", .value = KEY_EMOJI_PICKER },
+     { .name = "KEY_END", .value = KEY_END },
+     { .name = "KEY_ENTER", .value = KEY_ENTER },
+     { .name = "KEY_EPG", .value = KEY_EPG },
+@@ -1219,6 +1227,7 @@
+     { .name = "KEY_FN_F7", .value = KEY_FN_F7 },
+     { .name = "KEY_FN_F8", .value = KEY_FN_F8 },
+     { .name = "KEY_FN_F9", .value = KEY_FN_F9 },
++    { .name = "KEY_FN_RIGHT_SHIFT", .value = KEY_FN_RIGHT_SHIFT },
+     { .name = "KEY_FN_S", .value = KEY_FN_S },
+     { .name = "KEY_FORWARD", .value = KEY_FORWARD },
+     { .name = "KEY_FORWARDMAIL", .value = KEY_FORWARDMAIL },
+@@ -1234,6 +1243,7 @@
+     { .name = "KEY_GREEN", .value = KEY_GREEN },
+     { .name = "KEY_H", .value = KEY_H },
+     { .name = "KEY_HANGEUL", .value = KEY_HANGEUL },
++    { .name = "KEY_HANGUP_PHONE", .value = KEY_HANGUP_PHONE },
+     { .name = "KEY_HANJA", .value = KEY_HANJA },
+     { .name = "KEY_HELP", .value = KEY_HELP },
+     { .name = "KEY_HENKAN", .value = KEY_HENKAN },
+@@ -1366,6 +1376,7 @@
+     { .name = "KEY_NEXT", .value = KEY_NEXT },
+     { .name = "KEY_NEXTSONG", .value = KEY_NEXTSONG },
+     { .name = "KEY_NEXT_FAVORITE", .value = KEY_NEXT_FAVORITE },
++    { .name = "KEY_NOTIFICATION_CENTER", .value = KEY_NOTIFICATION_CENTER },
+     { .name = "KEY_NUMERIC_0", .value = KEY_NUMERIC_0 },
+     { .name = "KEY_NUMERIC_1", .value = KEY_NUMERIC_1 },
+     { .name = "KEY_NUMERIC_11", .value = KEY_NUMERIC_11 },
+@@ -1399,6 +1410,7 @@
+     { .name = "KEY_PAUSE_RECORD", .value = KEY_PAUSE_RECORD },
+     { .name = "KEY_PC", .value = KEY_PC },
+     { .name = "KEY_PHONE", .value = KEY_PHONE },
++    { .name = "KEY_PICKUP_PHONE", .value = KEY_PICKUP_PHONE },
+     { .name = "KEY_PLAY", .value = KEY_PLAY },
+     { .name = "KEY_PLAYCD", .value = KEY_PLAYCD },
+     { .name = "KEY_PLAYER", .value = KEY_PLAYER },
+diff -Naur third-party-libevdev-bak/include/linux/input.h third-party-new/include/linux/input.h
+--- third-party-libevdev-bak/include/linux/input.h	2023-03-28 10:49:53.388511800 +0800
++++ third-party-new/include/linux/input.h	2023-04-03 10:54:25.334322800 +0800
+@@ -1,5 +1,5 @@
+-//#ifdef __linux__
++#ifdef __linux__
+ #include "linux/input.h"
+-//#elif __FreeBSD__
+-//#include "freebsd/input.h"
+-//#endif
++#elif __FreeBSD__
++#include "freebsd/input.h"
++#endif
+diff -Naur third-party-libevdev-bak/include/linux/linux/input-event-codes.h third-party-new/include/linux/linux/input-event-codes.h
+--- third-party-libevdev-bak/include/linux/linux/input-event-codes.h	2023-03-28 10:49:53.388511800 +0800
++++ third-party-new/include/linux/linux/input-event-codes.h	2023-04-03 14:59:14.990160600 +0800
+@@ -278,7 +278,8 @@
+ #define KEY_PAUSECD		201
+ #define KEY_PROG3		202
+ #define KEY_PROG4		203
+-#define KEY_DASHBOARD		204	/* AL Dashboard */
++#define KEY_ALL_APPLICATIONS	204	/* AC Desktop Show All Applications */
++#define KEY_DASHBOARD		KEY_ALL_APPLICATIONS
+ #define KEY_SUSPEND		205
+ #define KEY_CLOSE		206	/* AC Close */
+ #define KEY_PLAY		207
+@@ -515,6 +516,9 @@
+ #define KEY_10CHANNELSUP	0x1b8	/* 10 channels up (10+) */
+ #define KEY_10CHANNELSDOWN	0x1b9	/* 10 channels down (10-) */
+ #define KEY_IMAGES		0x1ba	/* AL Image Browser */
++#define KEY_NOTIFICATION_CENTER	0x1bc	/* Show/hide the notification center */
++#define KEY_PICKUP_PHONE	0x1bd	/* Answer incoming call */
++#define KEY_HANGUP_PHONE	0x1be	/* Decline incoming call */
+ 
+ #define KEY_DEL_EOL		0x1c0
+ #define KEY_DEL_EOS		0x1c1
+@@ -542,6 +546,7 @@
+ #define KEY_FN_F		0x1e2
+ #define KEY_FN_S		0x1e3
+ #define KEY_FN_B		0x1e4
++#define KEY_FN_RIGHT_SHIFT	0x1e5
+ 
+ #define KEY_BRL_DOT1		0x1f1
+ #define KEY_BRL_DOT2		0x1f2
+@@ -607,6 +612,8 @@
+ #define KEY_VOICECOMMAND		0x246	/* Listening Voice Command */
+ #define KEY_ASSISTANT		0x247	/* AL Context-aware desktop assistant */
+ #define KEY_KBD_LAYOUT_NEXT	0x248	/* AC Next Keyboard Layout Select */
++#define KEY_EMOJI_PICKER	0x249	/* Show/hide emoji picker (HUTRR101) */
++#define KEY_DICTATE		0x24a	/* Start or Stop Voice Dictation Session (HUTRR99) */
+ 
+ #define KEY_BRIGHTNESS_MIN		0x250	/* Set Brightness to Minimum */
+ #define KEY_BRIGHTNESS_MAX		0x251	/* Set Brightness to Maximum */
+diff -Naur third-party-libevdev-bak/include/linux/linux/input.h third-party-new/include/linux/linux/input.h
+--- third-party-libevdev-bak/include/linux/linux/input.h	2023-03-28 10:49:53.388511800 +0800
++++ third-party-new/include/linux/linux/input.h	2023-04-03 14:59:02.390820400 +0800
+@@ -82,7 +82,7 @@
+  * in units per radian.
+  * When INPUT_PROP_ACCELEROMETER is set the resolution changes.
+  * The main axes (ABS_X, ABS_Y, ABS_Z) are then reported in
+- * in units per g (units/g) and in units per degree per second
++ * units per g (units/g) and in units per degree per second
+  * (units/deg/s) for rotational axes (ABS_RX, ABS_RY, ABS_RZ).
+  */
+ struct input_absinfo {
+diff -Naur third-party-libevdev-bak/libevdev/Makefile.in third-party-new/libevdev/Makefile.in
+--- third-party-libevdev-bak/libevdev/Makefile.in	1970-01-01 08:00:00.000000000 +0800
++++ third-party-new/libevdev/Makefile.in	2023-04-03 10:58:57.538254500 +0800
+@@ -0,0 +1,750 @@
++# Makefile.in generated by automake 1.16.5 from Makefile.am.
++# @configure_input@
++
++# Copyright (C) 1994-2021 Free Software Foundation, Inc.
++
++# This Makefile.in is free software; the Free Software Foundation
++# gives unlimited permission to copy and/or distribute it,
++# with or without modifications, as long as this notice is preserved.
++
++# This program is distributed in the hope that it will be useful,
++# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
++# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
++# PARTICULAR PURPOSE.
++
++@SET_MAKE@
++
++
++VPATH = @srcdir@
++am__is_gnu_make = { \
++  if test -z '$(MAKELEVEL)'; then \
++    false; \
++  elif test -n '$(MAKE_HOST)'; then \
++    true; \
++  elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
++    true; \
++  else \
++    false; \
++  fi; \
++}
++am__make_running_with_option = \
++  case $${target_option-} in \
++      ?) ;; \
++      *) echo "am__make_running_with_option: internal error: invalid" \
++              "target option '$${target_option-}' specified" >&2; \
++         exit 1;; \
++  esac; \
++  has_opt=no; \
++  sane_makeflags=$$MAKEFLAGS; \
++  if $(am__is_gnu_make); then \
++    sane_makeflags=$$MFLAGS; \
++  else \
++    case $$MAKEFLAGS in \
++      *\\[\ \	]*) \
++        bs=\\; \
++        sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
++          | sed "s/$$bs$$bs[$$bs $$bs	]*//g"`;; \
++    esac; \
++  fi; \
++  skip_next=no; \
++  strip_trailopt () \
++  { \
++    flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
++  }; \
++  for flg in $$sane_makeflags; do \
++    test $$skip_next = yes && { skip_next=no; continue; }; \
++    case $$flg in \
++      *=*|--*) continue;; \
++        -*I) strip_trailopt 'I'; skip_next=yes;; \
++      -*I?*) strip_trailopt 'I';; \
++        -*O) strip_trailopt 'O'; skip_next=yes;; \
++      -*O?*) strip_trailopt 'O';; \
++        -*l) strip_trailopt 'l'; skip_next=yes;; \
++      -*l?*) strip_trailopt 'l';; \
++      -[dEDm]) skip_next=yes;; \
++      -[JT]) skip_next=yes;; \
++    esac; \
++    case $$flg in \
++      *$$target_option*) has_opt=yes; break;; \
++    esac; \
++  done; \
++  test $$has_opt = yes
++am__make_dryrun = (target_option=n; $(am__make_running_with_option))
++am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
++pkgdatadir = $(datadir)/@PACKAGE@
++pkgincludedir = $(includedir)/@PACKAGE@
++pkglibdir = $(libdir)/@PACKAGE@
++pkglibexecdir = $(libexecdir)/@PACKAGE@
++am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
++install_sh_DATA = $(install_sh) -c -m 644
++install_sh_PROGRAM = $(install_sh) -c
++install_sh_SCRIPT = $(install_sh) -c
++INSTALL_HEADER = $(INSTALL_DATA)
++transform = $(program_transform_name)
++NORMAL_INSTALL = :
++PRE_INSTALL = :
++POST_INSTALL = :
++NORMAL_UNINSTALL = :
++PRE_UNINSTALL = :
++POST_UNINSTALL = :
++build_triplet = @build@
++host_triplet = @host@
++@GCOV_ENABLED_TRUE@am__append_1 = *.gcno
++subdir = libevdev
++ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
++am__aclocal_m4_deps = $(top_srcdir)/m4/attributes.m4 \
++	$(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \
++	$(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \
++	$(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac
++am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
++	$(ACLOCAL_M4)
++DIST_COMMON = $(srcdir)/Makefile.am $(libevdevinclude_HEADERS) \
++	$(am__DIST_COMMON)
++mkinstalldirs = $(install_sh) -d
++CONFIG_HEADER = $(top_builddir)/config.h
++CONFIG_CLEAN_FILES =
++CONFIG_CLEAN_VPATH_FILES =
++am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
++am__vpath_adj = case $$p in \
++    $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
++    *) f=$$p;; \
++  esac;
++am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
++am__install_max = 40
++am__nobase_strip_setup = \
++  srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
++am__nobase_strip = \
++  for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
++am__nobase_list = $(am__nobase_strip_setup); \
++  for p in $$list; do echo "$$p $$p"; done | \
++  sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
++  $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
++    if (++n[$$2] == $(am__install_max)) \
++      { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
++    END { for (dir in files) print dir, files[dir] }'
++am__base_list = \
++  sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
++  sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
++am__uninstall_files_from_dir = { \
++  test -z "$$files" \
++    || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
++    || { echo " ( cd '$$dir' && rm -f" $$files ")"; \
++         $(am__cd) "$$dir" && rm -f $$files; }; \
++  }
++am__installdirs = "$(DESTDIR)$(libdir)" \
++	"$(DESTDIR)$(libevdevincludedir)"
++LTLIBRARIES = $(lib_LTLIBRARIES)
++libevdev_la_LIBADD =
++am_libevdev_la_OBJECTS = libevdev-uinput.lo libevdev.lo \
++	libevdev-names.lo
++libevdev_la_OBJECTS = $(am_libevdev_la_OBJECTS)
++AM_V_lt = $(am__v_lt_@AM_V@)
++am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
++am__v_lt_0 = --silent
++am__v_lt_1 = 
++libevdev_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
++	$(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
++	$(libevdev_la_LDFLAGS) $(LDFLAGS) -o $@
++AM_V_P = $(am__v_P_@AM_V@)
++am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
++am__v_P_0 = false
++am__v_P_1 = :
++AM_V_GEN = $(am__v_GEN_@AM_V@)
++am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
++am__v_GEN_0 = @echo "  GEN     " $@;
++am__v_GEN_1 = 
++AM_V_at = $(am__v_at_@AM_V@)
++am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
++am__v_at_0 = @
++am__v_at_1 = 
++DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
++depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp
++am__maybe_remake_depfiles = depfiles
++am__depfiles_remade = ./$(DEPDIR)/libevdev-names.Plo \
++	./$(DEPDIR)/libevdev-uinput.Plo ./$(DEPDIR)/libevdev.Plo
++am__mv = mv -f
++COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
++	$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
++LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
++	$(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \
++	$(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
++	$(AM_CFLAGS) $(CFLAGS)
++AM_V_CC = $(am__v_CC_@AM_V@)
++am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@)
++am__v_CC_0 = @echo "  CC      " $@;
++am__v_CC_1 = 
++CCLD = $(CC)
++LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
++	$(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
++	$(AM_LDFLAGS) $(LDFLAGS) -o $@
++AM_V_CCLD = $(am__v_CCLD_@AM_V@)
++am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@)
++am__v_CCLD_0 = @echo "  CCLD    " $@;
++am__v_CCLD_1 = 
++SOURCES = $(libevdev_la_SOURCES)
++DIST_SOURCES = $(libevdev_la_SOURCES)
++am__can_run_installinfo = \
++  case $$AM_UPDATE_INFO_DIR in \
++    n|no|NO) false;; \
++    *) (install-info --version) >/dev/null 2>&1;; \
++  esac
++HEADERS = $(libevdevinclude_HEADERS)
++am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
++# Read a list of newline-separated strings from the standard input,
++# and print each of them once, without duplicates.  Input order is
++# *not* preserved.
++am__uniquify_input = $(AWK) '\
++  BEGIN { nonempty = 0; } \
++  { items[$$0] = 1; nonempty = 1; } \
++  END { if (nonempty) { for (i in items) print i; }; } \
++'
++# Make sure the list of sources is unique.  This is necessary because,
++# e.g., the same source file might be shared among _SOURCES variables
++# for different programs/libraries.
++am__define_uniq_tagged_files = \
++  list='$(am__tagged_files)'; \
++  unique=`for i in $$list; do \
++    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
++  done | $(am__uniquify_input)`
++am__DIST_COMMON = $(srcdir)/Makefile.in \
++	$(top_srcdir)/build-aux/depcomp
++DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
++ACLOCAL = @ACLOCAL@
++AMTAR = @AMTAR@
++AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
++AR = @AR@
++AUTOCONF = @AUTOCONF@
++AUTOHEADER = @AUTOHEADER@
++AUTOMAKE = @AUTOMAKE@
++AWK = @AWK@
++CC = @CC@
++CCDEPMODE = @CCDEPMODE@
++CFLAGS = @CFLAGS@
++CHECK_CFLAGS = @CHECK_CFLAGS@
++CHECK_LIBS = @CHECK_LIBS@
++CPPFLAGS = @CPPFLAGS@
++CSCOPE = @CSCOPE@
++CTAGS = @CTAGS@
++CYGPATH_W = @CYGPATH_W@
++DEFS = @DEFS@
++DEPDIR = @DEPDIR@
++DLLTOOL = @DLLTOOL@
++DOXYGEN = @DOXYGEN@
++DSYMUTIL = @DSYMUTIL@
++DUMPBIN = @DUMPBIN@
++ECHO_C = @ECHO_C@
++ECHO_N = @ECHO_N@
++ECHO_T = @ECHO_T@
++EGREP = @EGREP@
++ETAGS = @ETAGS@
++EXEEXT = @EXEEXT@
++FGREP = @FGREP@
++GCC_CFLAGS = @GCC_CFLAGS@
++GCOV_CFLAGS = @GCOV_CFLAGS@
++GCOV_LDFLAGS = @GCOV_LDFLAGS@
++GNU_LD_FLAGS = @GNU_LD_FLAGS@
++GREP = @GREP@
++INSTALL = @INSTALL@
++INSTALL_DATA = @INSTALL_DATA@
++INSTALL_PROGRAM = @INSTALL_PROGRAM@
++INSTALL_SCRIPT = @INSTALL_SCRIPT@
++INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
++LD = @LD@
++LDFLAGS = @LDFLAGS@
++LIBEVDEV_LT_VERSION = @LIBEVDEV_LT_VERSION@
++LIBOBJS = @LIBOBJS@
++LIBS = @LIBS@
++LIBTOOL = @LIBTOOL@
++LIPO = @LIPO@
++LN_S = @LN_S@
++LTLIBOBJS = @LTLIBOBJS@
++LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
++MAKEINFO = @MAKEINFO@
++MANIFEST_TOOL = @MANIFEST_TOOL@
++MKDIR_P = @MKDIR_P@
++NM = @NM@
++NMEDIT = @NMEDIT@
++OBJDUMP = @OBJDUMP@
++OBJEXT = @OBJEXT@
++OS = @OS@
++OTOOL = @OTOOL@
++OTOOL64 = @OTOOL64@
++PACKAGE = @PACKAGE@
++PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
++PACKAGE_NAME = @PACKAGE_NAME@
++PACKAGE_STRING = @PACKAGE_STRING@
++PACKAGE_TARNAME = @PACKAGE_TARNAME@
++PACKAGE_URL = @PACKAGE_URL@
++PACKAGE_VERSION = @PACKAGE_VERSION@
++PATH_SEPARATOR = @PATH_SEPARATOR@
++PKG_CONFIG = @PKG_CONFIG@
++PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
++PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
++PYTHON = @PYTHON@
++PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
++PYTHON_PLATFORM = @PYTHON_PLATFORM@
++PYTHON_PREFIX = @PYTHON_PREFIX@
++PYTHON_VERSION = @PYTHON_VERSION@
++RANLIB = @RANLIB@
++SED = @SED@
++SET_MAKE = @SET_MAKE@
++SHELL = @SHELL@
++STRIP = @STRIP@
++VALGRIND = @VALGRIND@
++VERSION = @VERSION@
++abs_builddir = @abs_builddir@
++abs_srcdir = @abs_srcdir@
++abs_top_builddir = @abs_top_builddir@
++abs_top_srcdir = @abs_top_srcdir@
++ac_ct_AR = @ac_ct_AR@
++ac_ct_CC = @ac_ct_CC@
++ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
++am__include = @am__include@
++am__leading_dot = @am__leading_dot@
++am__quote = @am__quote@
++am__tar = @am__tar@
++am__untar = @am__untar@
++bindir = @bindir@
++build = @build@
++build_alias = @build_alias@
++build_cpu = @build_cpu@
++build_os = @build_os@
++build_vendor = @build_vendor@
++builddir = @builddir@
++datadir = @datadir@
++datarootdir = @datarootdir@
++docdir = @docdir@
++dvidir = @dvidir@
++exec_prefix = @exec_prefix@
++host = @host@
++host_alias = @host_alias@
++host_cpu = @host_cpu@
++host_os = @host_os@
++host_vendor = @host_vendor@
++htmldir = @htmldir@
++includedir = @includedir@
++infodir = @infodir@
++install_sh = @install_sh@
++libdir = @libdir@
++libexecdir = @libexecdir@
++localedir = @localedir@
++localstatedir = @localstatedir@
++mandir = @mandir@
++mkdir_p = @mkdir_p@
++oldincludedir = @oldincludedir@
++pdfdir = @pdfdir@
++pkgpyexecdir = @pkgpyexecdir@
++pkgpythondir = @pkgpythondir@
++prefix = @prefix@
++program_transform_name = @program_transform_name@
++psdir = @psdir@
++pyexecdir = @pyexecdir@
++pythondir = @pythondir@
++runstatedir = @runstatedir@
++sbindir = @sbindir@
++sharedstatedir = @sharedstatedir@
++srcdir = @srcdir@
++sysconfdir = @sysconfdir@
++target_alias = @target_alias@
++top_build_prefix = @top_build_prefix@
++top_builddir = @top_builddir@
++top_srcdir = @top_srcdir@
++lib_LTLIBRARIES = libevdev.la
++AM_CPPFLAGS = $(GCC_CFLAGS) $(GCOV_CFLAGS) -I$(top_srcdir)/include -I$(top_srcdir)
++AM_LDFLAGS = $(GCOV_LDFLAGS)
++libevdev_la_SOURCES = \
++                   libevdev.h \
++                   libevdev-int.h \
++                   libevdev-util.h \
++                   libevdev-uinput.c \
++                   libevdev-uinput.h \
++                   libevdev-uinput-int.h \
++                   libevdev.c \
++                   libevdev-names.c \
++		   ../include/linux/input.h \
++		   ../include/linux/uinput.h \
++		   ../include/linux/@OS@/input-event-codes.h \
++		   ../include/linux/@OS@/input.h \
++		   ../include/linux/@OS@/uinput.h
++
++libevdev_la_LDFLAGS = \
++        $(AM_LDFLAGS) \
++	-version-info $(LIBEVDEV_LT_VERSION) \
++	-Wl,--version-script="$(srcdir)/libevdev.sym" \
++	$(GNU_LD_FLAGS)
++
++EXTRA_libevdev_la_DEPENDENCIES = $(srcdir)/libevdev.sym
++libevdevincludedir = $(includedir)/libevdev-1.0/libevdev
++libevdevinclude_HEADERS = libevdev.h libevdev-uinput.h
++EXTRA_DIST = make-event-names.py libevdev.sym
++CLEANFILES = event-names.h $(am__append_1)
++BUILT_SOURCES = event-names.h
++all: $(BUILT_SOURCES)
++	$(MAKE) $(AM_MAKEFLAGS) all-am
++
++.SUFFIXES:
++.SUFFIXES: .c .lo .o .obj
++$(srcdir)/Makefile.in:  $(srcdir)/Makefile.am  $(am__configure_deps)
++	@for dep in $?; do \
++	  case '$(am__configure_deps)' in \
++	    *$$dep*) \
++	      ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
++	        && { if test -f $@; then exit 0; else break; fi; }; \
++	      exit 1;; \
++	  esac; \
++	done; \
++	echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign libevdev/Makefile'; \
++	$(am__cd) $(top_srcdir) && \
++	  $(AUTOMAKE) --foreign libevdev/Makefile
++Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
++	@case '$?' in \
++	  *config.status*) \
++	    cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
++	  *) \
++	    echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \
++	    cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \
++	esac;
++
++$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
++	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
++
++$(top_srcdir)/configure:  $(am__configure_deps)
++	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
++$(ACLOCAL_M4):  $(am__aclocal_m4_deps)
++	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
++$(am__aclocal_m4_deps):
++
++install-libLTLIBRARIES: $(lib_LTLIBRARIES)
++	@$(NORMAL_INSTALL)
++	@list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \
++	list2=; for p in $$list; do \
++	  if test -f $$p; then \
++	    list2="$$list2 $$p"; \
++	  else :; fi; \
++	done; \
++	test -z "$$list2" || { \
++	  echo " $(MKDIR_P) '$(DESTDIR)$(libdir)'"; \
++	  $(MKDIR_P) "$(DESTDIR)$(libdir)" || exit 1; \
++	  echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(libdir)'"; \
++	  $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(libdir)"; \
++	}
++
++uninstall-libLTLIBRARIES:
++	@$(NORMAL_UNINSTALL)
++	@list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \
++	for p in $$list; do \
++	  $(am__strip_dir) \
++	  echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$f'"; \
++	  $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$f"; \
++	done
++
++clean-libLTLIBRARIES:
++	-test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES)
++	@list='$(lib_LTLIBRARIES)'; \
++	locs=`for p in $$list; do echo $$p; done | \
++	      sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \
++	      sort -u`; \
++	test -z "$$locs" || { \
++	  echo rm -f $${locs}; \
++	  rm -f $${locs}; \
++	}
++
++libevdev.la: $(libevdev_la_OBJECTS) $(libevdev_la_DEPENDENCIES) $(EXTRA_libevdev_la_DEPENDENCIES) 
++	$(AM_V_CCLD)$(libevdev_la_LINK) -rpath $(libdir) $(libevdev_la_OBJECTS) $(libevdev_la_LIBADD) $(LIBS)
++
++mostlyclean-compile:
++	-rm -f *.$(OBJEXT)
++
++distclean-compile:
++	-rm -f *.tab.c
++
++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libevdev-names.Plo@am__quote@ # am--include-marker
++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libevdev-uinput.Plo@am__quote@ # am--include-marker
++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libevdev.Plo@am__quote@ # am--include-marker
++
++$(am__depfiles_remade):
++	@$(MKDIR_P) $(@D)
++	@echo '# dummy' >$@-t && $(am__mv) $@-t $@
++
++am--depfiles: $(am__depfiles_remade)
++
++.c.o:
++@am__fastdepCC_TRUE@	$(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\
++@am__fastdepCC_TRUE@	$(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
++@am__fastdepCC_TRUE@	$(am__mv) $$depbase.Tpo $$depbase.Po
++@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
++@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
++@am__fastdepCC_FALSE@	$(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $<
++
++.c.obj:
++@am__fastdepCC_TRUE@	$(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\
++@am__fastdepCC_TRUE@	$(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\
++@am__fastdepCC_TRUE@	$(am__mv) $$depbase.Tpo $$depbase.Po
++@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
++@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
++@am__fastdepCC_FALSE@	$(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
++
++.c.lo:
++@am__fastdepCC_TRUE@	$(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\
++@am__fastdepCC_TRUE@	$(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
++@am__fastdepCC_TRUE@	$(am__mv) $$depbase.Tpo $$depbase.Plo
++@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
++@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
++@am__fastdepCC_FALSE@	$(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $<
++
++mostlyclean-libtool:
++	-rm -f *.lo
++
++clean-libtool:
++	-rm -rf .libs _libs
++install-libevdevincludeHEADERS: $(libevdevinclude_HEADERS)
++	@$(NORMAL_INSTALL)
++	@list='$(libevdevinclude_HEADERS)'; test -n "$(libevdevincludedir)" || list=; \
++	if test -n "$$list"; then \
++	  echo " $(MKDIR_P) '$(DESTDIR)$(libevdevincludedir)'"; \
++	  $(MKDIR_P) "$(DESTDIR)$(libevdevincludedir)" || exit 1; \
++	fi; \
++	for p in $$list; do \
++	  if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
++	  echo "$$d$$p"; \
++	done | $(am__base_list) | \
++	while read files; do \
++	  echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(libevdevincludedir)'"; \
++	  $(INSTALL_HEADER) $$files "$(DESTDIR)$(libevdevincludedir)" || exit $$?; \
++	done
++
++uninstall-libevdevincludeHEADERS:
++	@$(NORMAL_UNINSTALL)
++	@list='$(libevdevinclude_HEADERS)'; test -n "$(libevdevincludedir)" || list=; \
++	files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
++	dir='$(DESTDIR)$(libevdevincludedir)'; $(am__uninstall_files_from_dir)
++
++ID: $(am__tagged_files)
++	$(am__define_uniq_tagged_files); mkid -fID $$unique
++tags: tags-am
++TAGS: tags
++
++tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
++	set x; \
++	here=`pwd`; \
++	$(am__define_uniq_tagged_files); \
++	shift; \
++	if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
++	  test -n "$$unique" || unique=$$empty_fix; \
++	  if test $$# -gt 0; then \
++	    $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
++	      "$$@" $$unique; \
++	  else \
++	    $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
++	      $$unique; \
++	  fi; \
++	fi
++ctags: ctags-am
++
++CTAGS: ctags
++ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
++	$(am__define_uniq_tagged_files); \
++	test -z "$(CTAGS_ARGS)$$unique" \
++	  || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
++	     $$unique
++
++GTAGS:
++	here=`$(am__cd) $(top_builddir) && pwd` \
++	  && $(am__cd) $(top_srcdir) \
++	  && gtags -i $(GTAGS_ARGS) "$$here"
++cscopelist: cscopelist-am
++
++cscopelist-am: $(am__tagged_files)
++	list='$(am__tagged_files)'; \
++	case "$(srcdir)" in \
++	  [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
++	  *) sdir=$(subdir)/$(srcdir) ;; \
++	esac; \
++	for i in $$list; do \
++	  if test -f "$$i"; then \
++	    echo "$(subdir)/$$i"; \
++	  else \
++	    echo "$$sdir/$$i"; \
++	  fi; \
++	done >> $(top_builddir)/cscope.files
++
++distclean-tags:
++	-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
++distdir: $(BUILT_SOURCES)
++	$(MAKE) $(AM_MAKEFLAGS) distdir-am
++
++distdir-am: $(DISTFILES)
++	@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
++	topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
++	list='$(DISTFILES)'; \
++	  dist_files=`for file in $$list; do echo $$file; done | \
++	  sed -e "s|^$$srcdirstrip/||;t" \
++	      -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
++	case $$dist_files in \
++	  */*) $(MKDIR_P) `echo "$$dist_files" | \
++			   sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
++			   sort -u` ;; \
++	esac; \
++	for file in $$dist_files; do \
++	  if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
++	  if test -d $$d/$$file; then \
++	    dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
++	    if test -d "$(distdir)/$$file"; then \
++	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
++	    fi; \
++	    if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
++	      cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
++	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
++	    fi; \
++	    cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
++	  else \
++	    test -f "$(distdir)/$$file" \
++	    || cp -p $$d/$$file "$(distdir)/$$file" \
++	    || exit 1; \
++	  fi; \
++	done
++check-am: all-am
++check: $(BUILT_SOURCES)
++	$(MAKE) $(AM_MAKEFLAGS) check-am
++all-am: Makefile $(LTLIBRARIES) $(HEADERS)
++installdirs:
++	for dir in "$(DESTDIR)$(libdir)" "$(DESTDIR)$(libevdevincludedir)"; do \
++	  test -z "$$dir" || $(MKDIR_P) "$$dir"; \
++	done
++install: $(BUILT_SOURCES)
++	$(MAKE) $(AM_MAKEFLAGS) install-am
++install-exec: $(BUILT_SOURCES)
++	$(MAKE) $(AM_MAKEFLAGS) install-exec-am
++install-data: install-data-am
++uninstall: uninstall-am
++
++install-am: all-am
++	@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
++
++installcheck: installcheck-am
++install-strip:
++	if test -z '$(STRIP)'; then \
++	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
++	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
++	      install; \
++	else \
++	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
++	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
++	    "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
++	fi
++mostlyclean-generic:
++
++clean-generic:
++	-test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
++
++distclean-generic:
++	-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
++	-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
++
++maintainer-clean-generic:
++	@echo "This command is intended for maintainers to use"
++	@echo "it deletes files that may require special tools to rebuild."
++	-test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES)
++clean: clean-am
++
++clean-am: clean-generic clean-libLTLIBRARIES clean-libtool \
++	mostlyclean-am
++
++distclean: distclean-am
++		-rm -f ./$(DEPDIR)/libevdev-names.Plo
++	-rm -f ./$(DEPDIR)/libevdev-uinput.Plo
++	-rm -f ./$(DEPDIR)/libevdev.Plo
++	-rm -f Makefile
++distclean-am: clean-am distclean-compile distclean-generic \
++	distclean-tags
++
++dvi: dvi-am
++
++dvi-am:
++
++html: html-am
++
++html-am:
++
++info: info-am
++
++info-am:
++
++install-data-am: install-libevdevincludeHEADERS
++
++install-dvi: install-dvi-am
++
++install-dvi-am:
++
++install-exec-am: install-libLTLIBRARIES
++
++install-html: install-html-am
++
++install-html-am:
++
++install-info: install-info-am
++
++install-info-am:
++
++install-man:
++
++install-pdf: install-pdf-am
++
++install-pdf-am:
++
++install-ps: install-ps-am
++
++install-ps-am:
++
++installcheck-am:
++
++maintainer-clean: maintainer-clean-am
++		-rm -f ./$(DEPDIR)/libevdev-names.Plo
++	-rm -f ./$(DEPDIR)/libevdev-uinput.Plo
++	-rm -f ./$(DEPDIR)/libevdev.Plo
++	-rm -f Makefile
++maintainer-clean-am: distclean-am maintainer-clean-generic
++
++mostlyclean: mostlyclean-am
++
++mostlyclean-am: mostlyclean-compile mostlyclean-generic \
++	mostlyclean-libtool
++
++pdf: pdf-am
++
++pdf-am:
++
++ps: ps-am
++
++ps-am:
++
++uninstall-am: uninstall-libLTLIBRARIES \
++	uninstall-libevdevincludeHEADERS
++
++.MAKE: all check install install-am install-exec install-strip
++
++.PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \
++	clean-generic clean-libLTLIBRARIES clean-libtool cscopelist-am \
++	ctags ctags-am distclean distclean-compile distclean-generic \
++	distclean-libtool distclean-tags distdir dvi dvi-am html \
++	html-am info info-am install install-am install-data \
++	install-data-am install-dvi install-dvi-am install-exec \
++	install-exec-am install-html install-html-am install-info \
++	install-info-am install-libLTLIBRARIES \
++	install-libevdevincludeHEADERS install-man install-pdf \
++	install-pdf-am install-ps install-ps-am install-strip \
++	installcheck installcheck-am installdirs maintainer-clean \
++	maintainer-clean-generic mostlyclean mostlyclean-compile \
++	mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
++	tags tags-am uninstall uninstall-am uninstall-libLTLIBRARIES \
++	uninstall-libevdevincludeHEADERS
++
++.PRECIOUS: Makefile
++
++
++event-names.h: Makefile make-event-names.py
++	$(PYTHON) $(srcdir)/make-event-names.py $(top_srcdir)/include/linux/@OS@/input.h $(top_srcdir)/include/linux/@OS@/input-event-codes.h  > $@
++
++# Tell versions [3.59,3.63) of GNU make to not export all variables.
++# Otherwise a system limit (for SysV at least) may be exceeded.
++.NOEXPORT:
+diff -Naur third-party-libevdev-bak/libevdev/libevdev-int.h third-party-new/libevdev/libevdev-int.h
+--- third-party-libevdev-bak/libevdev/libevdev-int.h	2023-03-28 10:49:53.388511800 +0800
++++ third-party-new/libevdev/libevdev-int.h	2023-04-03 10:56:27.930339900 +0800
+@@ -1,23 +1,6 @@
++// SPDX-License-Identifier: MIT
+ /*
+  * Copyright © 2013 Red Hat, Inc.
+- *
+- * Permission to use, copy, modify, distribute, and sell this software and its
+- * documentation for any purpose is hereby granted without fee, provided that
+- * the above copyright notice appear in all copies and that both that copyright
+- * notice and this permission notice appear in supporting documentation, and
+- * that the name of the copyright holders not be used in advertising or
+- * publicity pertaining to distribution of the software without specific,
+- * written prior permission.  The copyright holders make no representations
+- * about the suitability of this software for any purpose.  It is provided "as
+- * is" without express or implied warranty.
+- *
+- * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+- * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+- * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+- * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+- * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+- * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+- * OF THIS SOFTWARE.
+  */
+ 
+ #ifndef LIBEVDEV_INT_H
+diff -Naur third-party-libevdev-bak/libevdev/libevdev-names.c third-party-new/libevdev/libevdev-names.c
+--- third-party-libevdev-bak/libevdev/libevdev-names.c	2023-03-28 10:49:53.388511800 +0800
++++ third-party-new/libevdev/libevdev-names.c	2023-04-03 10:56:35.702547900 +0800
+@@ -1,23 +1,6 @@
++// SPDX-License-Identifier: MIT
+ /*
+  * Copyright © 2013 David Herrmann 
+- *
+- * Permission to use, copy, modify, distribute, and sell this software and its
+- * documentation for any purpose is hereby granted without fee, provided that
+- * the above copyright notice appear in all copies and that both that copyright
+- * notice and this permission notice appear in supporting documentation, and
+- * that the name of the copyright holders not be used in advertising or
+- * publicity pertaining to distribution of the software without specific,
+- * written prior permission.  The copyright holders make no representations
+- * about the suitability of this software for any purpose.  It is provided "as
+- * is" without express or implied warranty.
+- *
+- * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+- * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+- * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+- * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+- * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+- * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+- * OF THIS SOFTWARE.
+  */
+ 
+ #include "config.h"
+diff -Naur third-party-libevdev-bak/libevdev/libevdev-uinput-int.h third-party-new/libevdev/libevdev-uinput-int.h
+--- third-party-libevdev-bak/libevdev/libevdev-uinput-int.h	2023-03-28 10:49:53.388511800 +0800
++++ third-party-new/libevdev/libevdev-uinput-int.h	2023-04-03 10:57:19.761681900 +0800
+@@ -1,23 +1,6 @@
++// SPDX-License-Identifier: MIT
+ /*
+  * Copyright © 2013 Red Hat, Inc.
+- *
+- * Permission to use, copy, modify, distribute, and sell this software and its
+- * documentation for any purpose is hereby granted without fee, provided that
+- * the above copyright notice appear in all copies and that both that copyright
+- * notice and this permission notice appear in supporting documentation, and
+- * that the name of the copyright holders not be used in advertising or
+- * publicity pertaining to distribution of the software without specific,
+- * written prior permission.  The copyright holders make no representations
+- * about the suitability of this software for any purpose.  It is provided "as
+- * is" without express or implied warranty.
+- *
+- * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+- * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+- * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+- * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+- * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+- * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+- * OF THIS SOFTWARE.
+  */
+ 
+ struct libevdev_uinput {
+diff -Naur third-party-libevdev-bak/libevdev/libevdev-uinput.c third-party-new/libevdev/libevdev-uinput.c
+--- third-party-libevdev-bak/libevdev/libevdev-uinput.c	2023-03-28 10:49:53.388511800 +0800
++++ third-party-new/libevdev/libevdev-uinput.c	2023-04-03 10:56:54.433613900 +0800
+@@ -1,23 +1,6 @@
++// SPDX-License-Identifier: MIT
+ /*
+  * Copyright © 2013 Red Hat, Inc.
+- *
+- * Permission to use, copy, modify, distribute, and sell this software and its
+- * documentation for any purpose is hereby granted without fee, provided that
+- * the above copyright notice appear in all copies and that both that copyright
+- * notice and this permission notice appear in supporting documentation, and
+- * that the name of the copyright holders not be used in advertising or
+- * publicity pertaining to distribution of the software without specific,
+- * written prior permission.  The copyright holders make no representations
+- * about the suitability of this software for any purpose.  It is provided "as
+- * is" without express or implied warranty.
+- *
+- * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+- * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+- * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+- * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+- * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+- * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+- * OF THIS SOFTWARE.
+  */
+ 
+ #include "config.h"
+@@ -185,7 +168,7 @@
+  * FreeBSD does not have anything similar to sysfs.
+  * Set libevdev_uinput->syspath to NULL unconditionally.
+  * Look up the device nodes directly instead of via sysfs, as this matches what
+- * is returned by the UI_GET_SYSNAME ioctl() on FreeBSD.  
++ * is returned by the UI_GET_SYSNAME ioctl() on FreeBSD.
+  */
+ static int
+ fetch_syspath_and_devnode(struct libevdev_uinput *uinput_dev)
+@@ -485,11 +468,7 @@
+ 			    unsigned int code,
+ 			    int value)
+ {
+-#ifndef __MUSL__
+ 	struct input_event ev = { {0,0}, type, code, value };
+-#else
+-	struct input_event ev = { type, code, value };
+-#endif
+ 	int fd = libevdev_uinput_get_fd(uinput_dev);
+ 	int rc, max;
+ 
+diff -Naur third-party-libevdev-bak/libevdev/libevdev-uinput.h third-party-new/libevdev/libevdev-uinput.h
+--- third-party-libevdev-bak/libevdev/libevdev-uinput.h	2023-03-28 10:49:53.388511800 +0800
++++ third-party-new/libevdev/libevdev-uinput.h	2023-04-03 10:57:12.546311000 +0800
+@@ -1,23 +1,25 @@
++/* SPDX-License-Identifier: MIT */
+ /*
+  * Copyright © 2013 Red Hat, Inc.
+  *
+- * Permission to use, copy, modify, distribute, and sell this software and its
+- * documentation for any purpose is hereby granted without fee, provided that
+- * the above copyright notice appear in all copies and that both that copyright
+- * notice and this permission notice appear in supporting documentation, and
+- * that the name of the copyright holders not be used in advertising or
+- * publicity pertaining to distribution of the software without specific,
+- * written prior permission.  The copyright holders make no representations
+- * about the suitability of this software for any purpose.  It is provided "as
+- * is" without express or implied warranty.
+- *
+- * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+- * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+- * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+- * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+- * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+- * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+- * OF THIS SOFTWARE.
++ * Permission is hereby granted, free of charge, to any person obtaining a copy
++ * of this software and associated documentation files (the "Software"), to
++ * deal in the Software without restriction, including without limitation the
++ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
++ * sell copies of the Software, and to permit persons to whom the Software is
++ * furnished to do so, subject to the following conditions:
++ *
++ * The above copyright notice and this permission notice (including the next
++ * paragraph) shall be included in all copies or substantial portions of the
++ * Software.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
++ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
++ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
++ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
++ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
++ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
++ * IN THE SOFTWARE.
+  */
+ 
+ #ifndef LIBEVDEV_UINPUT_H
+@@ -40,14 +42,13 @@
+  *
+  * @code
+  * int err;
+- * int fd, new_fd, uifd;
++ * int fd, uifd;
+  * struct libevdev *dev;
+  * struct libevdev_uinput *uidev;
+- * struct input_event ev[2];
+  *
+  * fd = open("/dev/input/event0", O_RDONLY);
+  * if (fd < 0)
+- *     return err;
++ *     return -errno;
+  *
+  * err = libevdev_new_from_fd(fd, &dev);
+  * if (err != 0)
+@@ -65,7 +66,7 @@
+  * err = libevdev_uinput_write_event(uidev, EV_REL, REL_X, -1);
+  * if (err != 0)
+  *     return err;
+- * libevdev_uinput_write_event(uidev, EV_SYN, SYN_REPORT, 0);
++ * err = libevdev_uinput_write_event(uidev, EV_SYN, SYN_REPORT, 0);
+  * if (err != 0)
+  *     return err;
+  *
+@@ -107,7 +108,7 @@
+  */
+ 
+ enum libevdev_uinput_open_mode {
+-	/* intentionally -2 to avoid to avoid code like the below from accidentally working:
++	/* intentionally -2 to avoid code like below from accidentally working:
+ 		fd = open("/dev/uinput", O_RDWR); // fails, fd is -1
+ 		libevdev_uinput_create_from_device(dev, fd, &uidev); // may hide the error */
+ 	LIBEVDEV_UINPUT_OPEN_MANAGED = -2  /**< let libevdev open and close @c /dev/uinput */
+@@ -186,7 +187,7 @@
+  * @ingroup uinput
+  *
+  * Return the syspath representing this uinput device. If the UI_GET_SYSNAME
+- * ioctl not available, libevdev makes an educated guess.
++ * ioctl is not available, libevdev makes an educated guess.
+  * The UI_GET_SYSNAME ioctl is available since Linux 3.15.
+  *
+  * The syspath returned is the one of the input node itself
+@@ -195,8 +196,8 @@
+  *
+  * @note This function may return NULL if UI_GET_SYSNAME is not available.
+  * In that case, libevdev uses ctime and the device name to guess devices.
+- * To avoid false positives, wait at least wait at least 1.5s between
+- * creating devices that have the same name.
++ * To avoid false positives, wait at least 1.5s between creating devices that
++ * have the same name.
+  *
+  * @note FreeBSD does not have sysfs, on FreeBSD this function always returns
+  * NULL.
+@@ -219,7 +220,7 @@
+  * @note This function may return NULL. libevdev may have to guess the
+  * syspath and the device node. See libevdev_uinput_get_syspath() for details.
+  *
+- * @note On FreeBSD, this function can not return NULL.  libudev uses the
++ * @note On FreeBSD, this function can not return NULL. libudev uses the
+  * UI_GET_SYSNAME ioctl to get the device node on this platform and if that
+  * fails, the call to libevdev_uinput_create_from_device() fails.
+  *
+diff -Naur third-party-libevdev-bak/libevdev/libevdev-util.h third-party-new/libevdev/libevdev-util.h
+--- third-party-libevdev-bak/libevdev/libevdev-util.h	2023-03-28 10:49:53.388511800 +0800
++++ third-party-new/libevdev/libevdev-util.h	2023-04-03 10:57:26.584450200 +0800
+@@ -1,23 +1,6 @@
++// SPDX-License-Identifier: MIT
+ /*
+  * Copyright © 2013 Red Hat, Inc.
+- *
+- * Permission to use, copy, modify, distribute, and sell this software and its
+- * documentation for any purpose is hereby granted without fee, provided that
+- * the above copyright notice appear in all copies and that both that copyright
+- * notice and this permission notice appear in supporting documentation, and
+- * that the name of the copyright holders not be used in advertising or
+- * publicity pertaining to distribution of the software without specific,
+- * written prior permission.  The copyright holders make no representations
+- * about the suitability of this software for any purpose.  It is provided "as
+- * is" without express or implied warranty.
+- *
+- * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+- * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+- * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+- * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+- * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+- * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+- * OF THIS SOFTWARE.
+  */
+ 
+ #ifndef _UTIL_H_
+diff -Naur third-party-libevdev-bak/libevdev/libevdev.c third-party-new/libevdev/libevdev.c
+--- third-party-libevdev-bak/libevdev/libevdev.c	2023-03-28 10:49:53.388511800 +0800
++++ third-party-new/libevdev/libevdev.c	2023-04-03 10:55:59.815147300 +0800
+@@ -1,23 +1,6 @@
++// SPDX-License-Identifier: MIT
+ /*
+  * Copyright © 2013 Red Hat, Inc.
+- *
+- * Permission to use, copy, modify, distribute, and sell this software and its
+- * documentation for any purpose is hereby granted without fee, provided that
+- * the above copyright notice appear in all copies and that both that copyright
+- * notice and this permission notice appear in supporting documentation, and
+- * that the name of the copyright holders not be used in advertising or
+- * publicity pertaining to distribution of the software without specific,
+- * written prior permission.  The copyright holders make no representations
+- * about the suitability of this software for any purpose.  It is provided "as
+- * is" without express or implied warranty.
+- *
+- * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+- * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+- * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+- * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+- * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+- * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+- * OF THIS SOFTWARE.
+  */
+ 
+ #include "config.h"
+diff -Naur third-party-libevdev-bak/libevdev/libevdev.h third-party-new/libevdev/libevdev.h
+--- third-party-libevdev-bak/libevdev/libevdev.h	2023-03-28 10:49:53.392511900 +0800
++++ third-party-new/libevdev/libevdev.h	2023-04-03 10:56:13.042137200 +0800
+@@ -1,23 +1,26 @@
++/* SPDX-License-Identifier: MIT */
+ /*
+  * Copyright © 2013 Red Hat, Inc.
+  *
+- * Permission to use, copy, modify, distribute, and sell this software and its
+- * documentation for any purpose is hereby granted without fee, provided that
+- * the above copyright notice appear in all copies and that both that copyright
+- * notice and this permission notice appear in supporting documentation, and
+- * that the name of the copyright holders not be used in advertising or
+- * publicity pertaining to distribution of the software without specific,
+- * written prior permission.  The copyright holders make no representations
+- * about the suitability of this software for any purpose.  It is provided "as
+- * is" without express or implied warranty.
+- *
+- * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+- * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+- * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+- * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+- * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+- * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+- * OF THIS SOFTWARE.
++ * Permission is hereby granted, free of charge, to any person obtaining a copy
++ * of this software and associated documentation files (the "Software"), to
++ * deal in the Software without restriction, including without limitation the
++ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
++ * sell copies of the Software, and to permit persons to whom the Software is
++ * furnished to do so, subject to the following conditions:
++ *
++ * The above copyright notice and this permission notice (including the next
++ * paragraph) shall be included in all copies or substantial portions of the
++ * Software.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
++ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
++ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
++ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
++ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
++ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
++ * IN THE SOFTWARE.
++ *
+  */
+ 
+ #ifndef LIBEVDEV_H
+@@ -631,7 +634,7 @@
+  *         return ENOMEM;
+  *
+  * err = libevdev_set_fd(dev, fd);
+- * if (err < 0) {
++ * if (err < 0)
+  *         printf("Failed (errno %d): %s\n", -err, strerror(-err));
+  *
+  * libevdev_free(dev);
+@@ -1515,8 +1518,7 @@
+  * the event.
+  *
+  * If the device supports ABS_MT_SLOT, the value returned for any ABS_MT_*
+- * event code is the value of the currently active slot. You should use
+- * libevdev_get_slot_value() instead.
++ * event code is undefined. Use libevdev_get_slot_value() instead.
+  *
+  * @param dev The evdev device, already initialized with libevdev_set_fd()
+  * @param type The event type for the code to query (EV_SYN, EV_REL, etc.)
+diff -Naur third-party-libevdev-bak/libevdev/libevdev.sym third-party-new/libevdev/libevdev.sym
+--- third-party-libevdev-bak/libevdev/libevdev.sym	2023-03-28 10:49:53.392511900 +0800
++++ third-party-new/libevdev/libevdev.sym	2023-04-03 10:56:20.288783100 +0800
+@@ -1,23 +1,6 @@
++/* SPDX-License-Identifier: MIT */
+ /*
+  * Copyright (c) 2013 David Herrmann 
+- *
+- * Permission to use, copy, modify, distribute, and sell this software and its
+- * documentation for any purpose is hereby granted without fee, provided that
+- * the above copyright notice appear in all copies and that both that copyright
+- * notice and this permission notice appear in supporting documentation, and
+- * that the name of the copyright holders not be used in advertising or
+- * publicity pertaining to distribution of the software without specific,
+- * written prior permission.  The copyright holders make no representations
+- * about the suitability of this software for any purpose.  It is provided "as
+- * is" without express or implied warranty.
+- *
+- * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+- * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+- * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+- * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+- * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+- * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+- * OF THIS SOFTWARE.
+  */
+ 
+ LIBEVDEV_1 {
+diff -Naur third-party-libevdev-bak/libevdev/make-event-names.py third-party-new/libevdev/make-event-names.py
+--- third-party-libevdev-bak/libevdev/make-event-names.py	2023-03-28 10:49:53.392511900 +0800
++++ third-party-new/libevdev/make-event-names.py	2023-04-03 10:57:38.511272000 +0800
+@@ -70,10 +70,10 @@
+     if not hasattr(bits, prefix):
+         return
+     print("static const char * const %s_map[%s_MAX + 1] = {" % (prefix, prefix.upper()))
+-    for val, name in list(getattr(bits, prefix).items()):
++    for val, name in sorted(list(getattr(bits, prefix).items())):
+         print("    [%s] = \"%s\"," % (name, name))
+     if prefix == "key":
+-        for val, name in list(getattr(bits, "btn").items()):
++        for val, name in sorted(list(getattr(bits, "btn").items())):
+             print("    [%s] = \"%s\"," % (name, name))
+     print("};")
+     print("")
+@@ -118,7 +118,7 @@
+     if not hasattr(bits, prefix):
+         return
+ 
+-    names = list(getattr(bits, prefix).items())
++    names = sorted(list(getattr(bits, prefix).items()))
+     if prefix == "btn":
+         names = names + btn_additional
+ 
+diff -Naur third-party-libevdev-bak/meson.build third-party-new/meson.build
+--- third-party-libevdev-bak/meson.build	2023-03-28 10:49:53.392511900 +0800
++++ third-party-new/meson.build	2023-04-03 14:17:28.310190000 +0800
+@@ -1,5 +1,5 @@
+ project('libevdev', 'c',
+-	version: '1.10.0', # change autotools version too
++	version: '1.12.1', # change autotools version too
+ 	license: 'MIT/Expat',
+ 	default_options: [ 'c_std=gnu99', 'warning_level=2' ],
+ 	meson_version: '>= 0.47.0')
+@@ -37,6 +37,7 @@
+ # Dependencies
+ pkgconfig = import('pkgconfig')
+ dep_lm = cc.find_library('m')
++dep_rt = cc.find_library('rt')
+ 
+ input_h = join_paths(meson.source_root(), 'include', 'linux', host_machine.system(), 'input.h')
+ uinput_h = join_paths(meson.source_root(), 'include', 'linux', host_machine.system(), 'uinput.h')
+@@ -76,7 +77,7 @@
+ lib_libevdev = library('evdev',
+ 	src_libevdev,
+ 	include_directories: [includes_include],
+-	dependencies: [],
++	dependencies: [dep_rt],
+ 	version: libevdev_so_version,
+ 	link_args: version_flag,
+ 	link_depends: mapfile,
+@@ -108,6 +109,11 @@
+ 	   include_directories: [includes_include],
+ 	   dependencies: dep_libevdev,
+ 	   install: false)
++executable('libevdev-list-codes',
++	   sources: ['tools/libevdev-list-codes.c'],
++	   include_directories: [includes_include],
++	   dependencies: dep_libevdev,
++	   install: false)
+ executable('touchpad-edge-detector',
+ 	   sources: ['tools/touchpad-edge-detector.c'],
+ 	   include_directories: [includes_include],
+diff -Naur third-party-libevdev-bak/test/Makefile.am third-party-new/test/Makefile.am
+--- third-party-libevdev-bak/test/Makefile.am	1970-01-01 08:00:00.000000000 +0800
++++ third-party-new/test/Makefile.am	2022-03-25 12:33:26.000000000 +0800
+@@ -0,0 +1,143 @@
++build_tests = test-compile-pedantic test-link
++
++if ENABLE_STATIC_LINK_TEST
++build_tests += test-static-link
++endif
++
++noinst_PROGRAMS = $(build_tests)
++
++AM_CPPFLAGS = -I$(top_srcdir) -I$(top_srcdir)/include -I$(top_builddir)/libevdev
++AM_LDFLAGS =
++
++test_compile_pedantic_SOURCES = test-compile-pedantic.c
++test_compile_pedantic_CFLAGS = $(AM_CPPFLAGS) -pedantic -Werror -std=c89
++
++test_link_SOURCES = test-link.c
++test_link_CFLAGS = -I$(top_srcdir)
++test_link_LDADD = $(top_builddir)/libevdev/libevdev.la
++
++test_static_link_SOURCES = test-link.c
++test_static_link_CFLAGS = -I$(top_srcdir)
++test_static_link_LDADD = $(top_builddir)/libevdev/libevdev.la
++test_static_link_LDFLAGS = $(AM_LDFLAGS) -static
++
++check_local_deps =
++
++if ENABLE_RUNTIME_TESTS
++run_tests = \
++	    test-libevdev \
++	    test-kernel \
++	    test-uinput \
++	    test-event-codes \
++	    test-libevdev-internals \
++	    $(NULL)
++
++.NOTPARALLEL:
++
++noinst_PROGRAMS += $(run_tests)
++
++TESTS = $(run_tests)
++
++common_sources = \
++		 test-common-uinput.c \
++		 test-common-uinput.h \
++		 test-common.c \
++		 test-common.h
++
++# include builddir for event-names.h
++AM_CPPFLAGS += $(CHECK_CFLAGS) $(GCOV_CFLAGS)
++AM_LDFLAGS += $(GCOV_LDFLAGS)
++
++test_event_codes_SOURCES = \
++			test-main.c \
++			test-event-codes.c \
++			test-event-names.c \
++			test-context.c \
++			$(common_sources)
++test_event_codes_LDADD = $(CHECK_LIBS) $(top_builddir)/libevdev/libevdev.la
++test_event_codes_LDFLAGS = -no-install
++
++test_libevdev_internals_SOURCES = \
++			test-main.c \
++			test-int-queue.c \
++			$(common_sources)
++test_libevdev_internals_LDADD = $(CHECK_LIBS) $(top_builddir)/libevdev/libevdev.la
++test_libevdev_internals_LDFLAGS = -no-install
++
++test_uinput_SOURCES = \
++			test-main.c \
++			test-uinput.c \
++			$(common_sources)
++test_uinput_LDADD = $(CHECK_LIBS) $(top_builddir)/libevdev/libevdev.la
++test_uinput_LDFLAGS = -no-install
++
++test_libevdev_SOURCES = \
++			test-main.c \
++			test-libevdev-init.c \
++			test-libevdev-has-event.c \
++			test-libevdev-events.c \
++			$(common_sources)
++
++test_libevdev_LDADD = $(CHECK_LIBS) $(top_builddir)/libevdev/libevdev.la
++test_libevdev_LDFLAGS = -no-install
++
++test_kernel_SOURCES = \
++		      test-main.c \
++		      test-kernel.c \
++		      $(common_sources)
++
++test_kernel_CFLAGS = -I$(top_srcdir)
++test_kernel_LDADD = $(CHECK_LIBS) $(top_builddir)/libevdev/libevdev.la
++
++if HAVE_VALGRIND
++VALGRIND_FLAGS=--leak-check=full \
++		--quiet \
++		--error-exitcode=3 \
++		--suppressions=$(srcdir)/valgrind.suppressions
++
++valgrind:
++	        $(MAKE) check-TESTS CK_TIMEOUT_MULTIPLIER=10 LOG_COMPILER="$(VALGRIND)" LOG_FLAGS="$(VALGRIND_FLAGS)"
++
++check_local_deps += valgrind
++
++endif
++
++if GCOV_ENABLED
++
++CLEANFILES = gcov-reports/*.gcov gcov-reports/summary.txt *.gcno *.gcda
++
++gcov-report: generate-gcov-report.sh check-TESTS
++	$(AM_V_GEN)$(srcdir)/generate-gcov-report.sh gcov-reports $(top_builddir)/libevdev $(builddir)
++
++gcov: gcov-report
++	@cat gcov-reports/summary.txt
++
++check_local_deps += gcov
++
++else
++
++gcov-report.txt:
++	@true
++
++gcov:
++	@true
++
++
++endif # GCOV_ENABLED
++
++.PHONY: gcov gcov-clean gcov-report
++
++endif # ENABLE_RUNTIME_TESTS
++
++if ENABLE_STATIC_SYMBOL_LEAKS_TEST
++static-symbol-leaks: test-static-link test-static-symbols-leak.sh
++	$(AM_V_GEN) $(srcdir)/test-static-symbols-leak.sh $(builddir)
++
++check_local_deps += static-symbol-leaks
++
++endif # HAVE_NM
++
++EXTRA_DIST = valgrind.suppressions  generate-gcov-report.sh test-static-symbols-leak.sh
++
++check-local: $(check_local_deps)
++
+diff -Naur third-party-libevdev-bak/test/Makefile.in third-party-new/test/Makefile.in
+--- third-party-libevdev-bak/test/Makefile.in	1970-01-01 08:00:00.000000000 +0800
++++ third-party-new/test/Makefile.in	2022-03-25 12:33:32.000000000 +0800
+@@ -0,0 +1,1439 @@
++# Makefile.in generated by automake 1.16.5 from Makefile.am.
++# @configure_input@
++
++# Copyright (C) 1994-2021 Free Software Foundation, Inc.
++
++# This Makefile.in is free software; the Free Software Foundation
++# gives unlimited permission to copy and/or distribute it,
++# with or without modifications, as long as this notice is preserved.
++
++# This program is distributed in the hope that it will be useful,
++# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
++# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
++# PARTICULAR PURPOSE.
++
++@SET_MAKE@
++
++VPATH = @srcdir@
++am__is_gnu_make = { \
++  if test -z '$(MAKELEVEL)'; then \
++    false; \
++  elif test -n '$(MAKE_HOST)'; then \
++    true; \
++  elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
++    true; \
++  else \
++    false; \
++  fi; \
++}
++am__make_running_with_option = \
++  case $${target_option-} in \
++      ?) ;; \
++      *) echo "am__make_running_with_option: internal error: invalid" \
++              "target option '$${target_option-}' specified" >&2; \
++         exit 1;; \
++  esac; \
++  has_opt=no; \
++  sane_makeflags=$$MAKEFLAGS; \
++  if $(am__is_gnu_make); then \
++    sane_makeflags=$$MFLAGS; \
++  else \
++    case $$MAKEFLAGS in \
++      *\\[\ \	]*) \
++        bs=\\; \
++        sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
++          | sed "s/$$bs$$bs[$$bs $$bs	]*//g"`;; \
++    esac; \
++  fi; \
++  skip_next=no; \
++  strip_trailopt () \
++  { \
++    flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
++  }; \
++  for flg in $$sane_makeflags; do \
++    test $$skip_next = yes && { skip_next=no; continue; }; \
++    case $$flg in \
++      *=*|--*) continue;; \
++        -*I) strip_trailopt 'I'; skip_next=yes;; \
++      -*I?*) strip_trailopt 'I';; \
++        -*O) strip_trailopt 'O'; skip_next=yes;; \
++      -*O?*) strip_trailopt 'O';; \
++        -*l) strip_trailopt 'l'; skip_next=yes;; \
++      -*l?*) strip_trailopt 'l';; \
++      -[dEDm]) skip_next=yes;; \
++      -[JT]) skip_next=yes;; \
++    esac; \
++    case $$flg in \
++      *$$target_option*) has_opt=yes; break;; \
++    esac; \
++  done; \
++  test $$has_opt = yes
++am__make_dryrun = (target_option=n; $(am__make_running_with_option))
++am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
++pkgdatadir = $(datadir)/@PACKAGE@
++pkgincludedir = $(includedir)/@PACKAGE@
++pkglibdir = $(libdir)/@PACKAGE@
++pkglibexecdir = $(libexecdir)/@PACKAGE@
++am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
++install_sh_DATA = $(install_sh) -c -m 644
++install_sh_PROGRAM = $(install_sh) -c
++install_sh_SCRIPT = $(install_sh) -c
++INSTALL_HEADER = $(INSTALL_DATA)
++transform = $(program_transform_name)
++NORMAL_INSTALL = :
++PRE_INSTALL = :
++POST_INSTALL = :
++NORMAL_UNINSTALL = :
++PRE_UNINSTALL = :
++POST_UNINSTALL = :
++build_triplet = @build@
++host_triplet = @host@
++@ENABLE_STATIC_LINK_TEST_TRUE@am__append_1 = test-static-link
++noinst_PROGRAMS = $(am__EXEEXT_2) $(am__EXEEXT_4)
++@ENABLE_RUNTIME_TESTS_TRUE@am__append_2 = $(run_tests)
++@ENABLE_RUNTIME_TESTS_TRUE@TESTS = $(am__EXEEXT_3)
++
++# include builddir for event-names.h
++@ENABLE_RUNTIME_TESTS_TRUE@am__append_3 = $(CHECK_CFLAGS) $(GCOV_CFLAGS)
++@ENABLE_RUNTIME_TESTS_TRUE@am__append_4 = $(GCOV_LDFLAGS)
++@ENABLE_RUNTIME_TESTS_TRUE@@HAVE_VALGRIND_TRUE@am__append_5 = valgrind
++@ENABLE_RUNTIME_TESTS_TRUE@@GCOV_ENABLED_TRUE@am__append_6 = gcov
++@ENABLE_STATIC_SYMBOL_LEAKS_TEST_TRUE@am__append_7 = static-symbol-leaks
++subdir = test
++ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
++am__aclocal_m4_deps = $(top_srcdir)/m4/attributes.m4 \
++	$(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \
++	$(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \
++	$(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac
++am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
++	$(ACLOCAL_M4)
++DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON)
++mkinstalldirs = $(install_sh) -d
++CONFIG_HEADER = $(top_builddir)/config.h
++CONFIG_CLEAN_FILES =
++CONFIG_CLEAN_VPATH_FILES =
++@ENABLE_STATIC_LINK_TEST_TRUE@am__EXEEXT_1 =  \
++@ENABLE_STATIC_LINK_TEST_TRUE@	test-static-link$(EXEEXT)
++am__EXEEXT_2 = test-compile-pedantic$(EXEEXT) test-link$(EXEEXT) \
++	$(am__EXEEXT_1)
++@ENABLE_RUNTIME_TESTS_TRUE@am__EXEEXT_3 = test-libevdev$(EXEEXT) \
++@ENABLE_RUNTIME_TESTS_TRUE@	test-kernel$(EXEEXT) \
++@ENABLE_RUNTIME_TESTS_TRUE@	test-uinput$(EXEEXT) \
++@ENABLE_RUNTIME_TESTS_TRUE@	test-event-codes$(EXEEXT) \
++@ENABLE_RUNTIME_TESTS_TRUE@	test-libevdev-internals$(EXEEXT)
++@ENABLE_RUNTIME_TESTS_TRUE@am__EXEEXT_4 = $(am__EXEEXT_3)
++PROGRAMS = $(noinst_PROGRAMS)
++am_test_compile_pedantic_OBJECTS =  \
++	test_compile_pedantic-test-compile-pedantic.$(OBJEXT)
++test_compile_pedantic_OBJECTS = $(am_test_compile_pedantic_OBJECTS)
++test_compile_pedantic_LDADD = $(LDADD)
++AM_V_lt = $(am__v_lt_@AM_V@)
++am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
++am__v_lt_0 = --silent
++am__v_lt_1 = 
++test_compile_pedantic_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \
++	$(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \
++	$(test_compile_pedantic_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
++	$(LDFLAGS) -o $@
++am__test_event_codes_SOURCES_DIST = test-main.c test-event-codes.c \
++	test-event-names.c test-context.c test-common-uinput.c \
++	test-common-uinput.h test-common.c test-common.h
++@ENABLE_RUNTIME_TESTS_TRUE@am__objects_1 =  \
++@ENABLE_RUNTIME_TESTS_TRUE@	test-common-uinput.$(OBJEXT) \
++@ENABLE_RUNTIME_TESTS_TRUE@	test-common.$(OBJEXT)
++@ENABLE_RUNTIME_TESTS_TRUE@am_test_event_codes_OBJECTS =  \
++@ENABLE_RUNTIME_TESTS_TRUE@	test-main.$(OBJEXT) \
++@ENABLE_RUNTIME_TESTS_TRUE@	test-event-codes.$(OBJEXT) \
++@ENABLE_RUNTIME_TESTS_TRUE@	test-event-names.$(OBJEXT) \
++@ENABLE_RUNTIME_TESTS_TRUE@	test-context.$(OBJEXT) \
++@ENABLE_RUNTIME_TESTS_TRUE@	$(am__objects_1)
++test_event_codes_OBJECTS = $(am_test_event_codes_OBJECTS)
++am__DEPENDENCIES_1 =
++@ENABLE_RUNTIME_TESTS_TRUE@test_event_codes_DEPENDENCIES =  \
++@ENABLE_RUNTIME_TESTS_TRUE@	$(am__DEPENDENCIES_1) \
++@ENABLE_RUNTIME_TESTS_TRUE@	$(top_builddir)/libevdev/libevdev.la
++test_event_codes_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \
++	$(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \
++	$(AM_CFLAGS) $(CFLAGS) $(test_event_codes_LDFLAGS) $(LDFLAGS) \
++	-o $@
++am__test_kernel_SOURCES_DIST = test-main.c test-kernel.c \
++	test-common-uinput.c test-common-uinput.h test-common.c \
++	test-common.h
++@ENABLE_RUNTIME_TESTS_TRUE@am__objects_2 = test_kernel-test-common-uinput.$(OBJEXT) \
++@ENABLE_RUNTIME_TESTS_TRUE@	test_kernel-test-common.$(OBJEXT)
++@ENABLE_RUNTIME_TESTS_TRUE@am_test_kernel_OBJECTS =  \
++@ENABLE_RUNTIME_TESTS_TRUE@	test_kernel-test-main.$(OBJEXT) \
++@ENABLE_RUNTIME_TESTS_TRUE@	test_kernel-test-kernel.$(OBJEXT) \
++@ENABLE_RUNTIME_TESTS_TRUE@	$(am__objects_2)
++test_kernel_OBJECTS = $(am_test_kernel_OBJECTS)
++@ENABLE_RUNTIME_TESTS_TRUE@test_kernel_DEPENDENCIES =  \
++@ENABLE_RUNTIME_TESTS_TRUE@	$(am__DEPENDENCIES_1) \
++@ENABLE_RUNTIME_TESTS_TRUE@	$(top_builddir)/libevdev/libevdev.la
++test_kernel_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
++	$(LIBTOOLFLAGS) --mode=link $(CCLD) $(test_kernel_CFLAGS) \
++	$(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
++am__test_libevdev_SOURCES_DIST = test-main.c test-libevdev-init.c \
++	test-libevdev-has-event.c test-libevdev-events.c \
++	test-common-uinput.c test-common-uinput.h test-common.c \
++	test-common.h
++@ENABLE_RUNTIME_TESTS_TRUE@am_test_libevdev_OBJECTS =  \
++@ENABLE_RUNTIME_TESTS_TRUE@	test-main.$(OBJEXT) \
++@ENABLE_RUNTIME_TESTS_TRUE@	test-libevdev-init.$(OBJEXT) \
++@ENABLE_RUNTIME_TESTS_TRUE@	test-libevdev-has-event.$(OBJEXT) \
++@ENABLE_RUNTIME_TESTS_TRUE@	test-libevdev-events.$(OBJEXT) \
++@ENABLE_RUNTIME_TESTS_TRUE@	$(am__objects_1)
++test_libevdev_OBJECTS = $(am_test_libevdev_OBJECTS)
++@ENABLE_RUNTIME_TESTS_TRUE@test_libevdev_DEPENDENCIES =  \
++@ENABLE_RUNTIME_TESTS_TRUE@	$(am__DEPENDENCIES_1) \
++@ENABLE_RUNTIME_TESTS_TRUE@	$(top_builddir)/libevdev/libevdev.la
++test_libevdev_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
++	$(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
++	$(test_libevdev_LDFLAGS) $(LDFLAGS) -o $@
++am__test_libevdev_internals_SOURCES_DIST = test-main.c \
++	test-int-queue.c test-common-uinput.c test-common-uinput.h \
++	test-common.c test-common.h
++@ENABLE_RUNTIME_TESTS_TRUE@am_test_libevdev_internals_OBJECTS =  \
++@ENABLE_RUNTIME_TESTS_TRUE@	test-main.$(OBJEXT) \
++@ENABLE_RUNTIME_TESTS_TRUE@	test-int-queue.$(OBJEXT) \
++@ENABLE_RUNTIME_TESTS_TRUE@	$(am__objects_1)
++test_libevdev_internals_OBJECTS =  \
++	$(am_test_libevdev_internals_OBJECTS)
++@ENABLE_RUNTIME_TESTS_TRUE@test_libevdev_internals_DEPENDENCIES =  \
++@ENABLE_RUNTIME_TESTS_TRUE@	$(am__DEPENDENCIES_1) \
++@ENABLE_RUNTIME_TESTS_TRUE@	$(top_builddir)/libevdev/libevdev.la
++test_libevdev_internals_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \
++	$(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \
++	$(AM_CFLAGS) $(CFLAGS) $(test_libevdev_internals_LDFLAGS) \
++	$(LDFLAGS) -o $@
++am_test_link_OBJECTS = test_link-test-link.$(OBJEXT)
++test_link_OBJECTS = $(am_test_link_OBJECTS)
++test_link_DEPENDENCIES = $(top_builddir)/libevdev/libevdev.la
++test_link_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
++	$(LIBTOOLFLAGS) --mode=link $(CCLD) $(test_link_CFLAGS) \
++	$(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
++am_test_static_link_OBJECTS = test_static_link-test-link.$(OBJEXT)
++test_static_link_OBJECTS = $(am_test_static_link_OBJECTS)
++test_static_link_DEPENDENCIES = $(top_builddir)/libevdev/libevdev.la
++test_static_link_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \
++	$(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \
++	$(test_static_link_CFLAGS) $(CFLAGS) \
++	$(test_static_link_LDFLAGS) $(LDFLAGS) -o $@
++am__test_uinput_SOURCES_DIST = test-main.c test-uinput.c \
++	test-common-uinput.c test-common-uinput.h test-common.c \
++	test-common.h
++@ENABLE_RUNTIME_TESTS_TRUE@am_test_uinput_OBJECTS =  \
++@ENABLE_RUNTIME_TESTS_TRUE@	test-main.$(OBJEXT) \
++@ENABLE_RUNTIME_TESTS_TRUE@	test-uinput.$(OBJEXT) \
++@ENABLE_RUNTIME_TESTS_TRUE@	$(am__objects_1)
++test_uinput_OBJECTS = $(am_test_uinput_OBJECTS)
++@ENABLE_RUNTIME_TESTS_TRUE@test_uinput_DEPENDENCIES =  \
++@ENABLE_RUNTIME_TESTS_TRUE@	$(am__DEPENDENCIES_1) \
++@ENABLE_RUNTIME_TESTS_TRUE@	$(top_builddir)/libevdev/libevdev.la
++test_uinput_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
++	$(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
++	$(test_uinput_LDFLAGS) $(LDFLAGS) -o $@
++AM_V_P = $(am__v_P_@AM_V@)
++am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
++am__v_P_0 = false
++am__v_P_1 = :
++AM_V_GEN = $(am__v_GEN_@AM_V@)
++am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
++am__v_GEN_0 = @echo "  GEN     " $@;
++am__v_GEN_1 = 
++AM_V_at = $(am__v_at_@AM_V@)
++am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
++am__v_at_0 = @
++am__v_at_1 = 
++DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
++depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp
++am__maybe_remake_depfiles = depfiles
++am__depfiles_remade = ./$(DEPDIR)/test-common-uinput.Po \
++	./$(DEPDIR)/test-common.Po ./$(DEPDIR)/test-context.Po \
++	./$(DEPDIR)/test-event-codes.Po \
++	./$(DEPDIR)/test-event-names.Po ./$(DEPDIR)/test-int-queue.Po \
++	./$(DEPDIR)/test-libevdev-events.Po \
++	./$(DEPDIR)/test-libevdev-has-event.Po \
++	./$(DEPDIR)/test-libevdev-init.Po ./$(DEPDIR)/test-main.Po \
++	./$(DEPDIR)/test-uinput.Po \
++	./$(DEPDIR)/test_compile_pedantic-test-compile-pedantic.Po \
++	./$(DEPDIR)/test_kernel-test-common-uinput.Po \
++	./$(DEPDIR)/test_kernel-test-common.Po \
++	./$(DEPDIR)/test_kernel-test-kernel.Po \
++	./$(DEPDIR)/test_kernel-test-main.Po \
++	./$(DEPDIR)/test_link-test-link.Po \
++	./$(DEPDIR)/test_static_link-test-link.Po
++am__mv = mv -f
++COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
++	$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
++LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
++	$(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \
++	$(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
++	$(AM_CFLAGS) $(CFLAGS)
++AM_V_CC = $(am__v_CC_@AM_V@)
++am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@)
++am__v_CC_0 = @echo "  CC      " $@;
++am__v_CC_1 = 
++CCLD = $(CC)
++LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
++	$(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
++	$(AM_LDFLAGS) $(LDFLAGS) -o $@
++AM_V_CCLD = $(am__v_CCLD_@AM_V@)
++am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@)
++am__v_CCLD_0 = @echo "  CCLD    " $@;
++am__v_CCLD_1 = 
++SOURCES = $(test_compile_pedantic_SOURCES) $(test_event_codes_SOURCES) \
++	$(test_kernel_SOURCES) $(test_libevdev_SOURCES) \
++	$(test_libevdev_internals_SOURCES) $(test_link_SOURCES) \
++	$(test_static_link_SOURCES) $(test_uinput_SOURCES)
++DIST_SOURCES = $(test_compile_pedantic_SOURCES) \
++	$(am__test_event_codes_SOURCES_DIST) \
++	$(am__test_kernel_SOURCES_DIST) \
++	$(am__test_libevdev_SOURCES_DIST) \
++	$(am__test_libevdev_internals_SOURCES_DIST) \
++	$(test_link_SOURCES) $(test_static_link_SOURCES) \
++	$(am__test_uinput_SOURCES_DIST)
++am__can_run_installinfo = \
++  case $$AM_UPDATE_INFO_DIR in \
++    n|no|NO) false;; \
++    *) (install-info --version) >/dev/null 2>&1;; \
++  esac
++am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
++# Read a list of newline-separated strings from the standard input,
++# and print each of them once, without duplicates.  Input order is
++# *not* preserved.
++am__uniquify_input = $(AWK) '\
++  BEGIN { nonempty = 0; } \
++  { items[$$0] = 1; nonempty = 1; } \
++  END { if (nonempty) { for (i in items) print i; }; } \
++'
++# Make sure the list of sources is unique.  This is necessary because,
++# e.g., the same source file might be shared among _SOURCES variables
++# for different programs/libraries.
++am__define_uniq_tagged_files = \
++  list='$(am__tagged_files)'; \
++  unique=`for i in $$list; do \
++    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
++  done | $(am__uniquify_input)`
++am__tty_colors_dummy = \
++  mgn= red= grn= lgn= blu= brg= std=; \
++  am__color_tests=no
++am__tty_colors = { \
++  $(am__tty_colors_dummy); \
++  if test "X$(AM_COLOR_TESTS)" = Xno; then \
++    am__color_tests=no; \
++  elif test "X$(AM_COLOR_TESTS)" = Xalways; then \
++    am__color_tests=yes; \
++  elif test "X$$TERM" != Xdumb && { test -t 1; } 2>/dev/null; then \
++    am__color_tests=yes; \
++  fi; \
++  if test $$am__color_tests = yes; then \
++    red=''; \
++    grn=''; \
++    lgn=''; \
++    blu=''; \
++    mgn=''; \
++    brg=''; \
++    std=''; \
++  fi; \
++}
++am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
++am__vpath_adj = case $$p in \
++    $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
++    *) f=$$p;; \
++  esac;
++am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
++am__install_max = 40
++am__nobase_strip_setup = \
++  srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
++am__nobase_strip = \
++  for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
++am__nobase_list = $(am__nobase_strip_setup); \
++  for p in $$list; do echo "$$p $$p"; done | \
++  sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
++  $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
++    if (++n[$$2] == $(am__install_max)) \
++      { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
++    END { for (dir in files) print dir, files[dir] }'
++am__base_list = \
++  sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
++  sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
++am__uninstall_files_from_dir = { \
++  test -z "$$files" \
++    || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
++    || { echo " ( cd '$$dir' && rm -f" $$files ")"; \
++         $(am__cd) "$$dir" && rm -f $$files; }; \
++  }
++am__recheck_rx = ^[ 	]*:recheck:[ 	]*
++am__global_test_result_rx = ^[ 	]*:global-test-result:[ 	]*
++am__copy_in_global_log_rx = ^[ 	]*:copy-in-global-log:[ 	]*
++# A command that, given a newline-separated list of test names on the
++# standard input, print the name of the tests that are to be re-run
++# upon "make recheck".
++am__list_recheck_tests = $(AWK) '{ \
++  recheck = 1; \
++  while ((rc = (getline line < ($$0 ".trs"))) != 0) \
++    { \
++      if (rc < 0) \
++        { \
++          if ((getline line2 < ($$0 ".log")) < 0) \
++	    recheck = 0; \
++          break; \
++        } \
++      else if (line ~ /$(am__recheck_rx)[nN][Oo]/) \
++        { \
++          recheck = 0; \
++          break; \
++        } \
++      else if (line ~ /$(am__recheck_rx)[yY][eE][sS]/) \
++        { \
++          break; \
++        } \
++    }; \
++  if (recheck) \
++    print $$0; \
++  close ($$0 ".trs"); \
++  close ($$0 ".log"); \
++}'
++# A command that, given a newline-separated list of test names on the
++# standard input, create the global log from their .trs and .log files.
++am__create_global_log = $(AWK) ' \
++function fatal(msg) \
++{ \
++  print "fatal: making $@: " msg | "cat >&2"; \
++  exit 1; \
++} \
++function rst_section(header) \
++{ \
++  print header; \
++  len = length(header); \
++  for (i = 1; i <= len; i = i + 1) \
++    printf "="; \
++  printf "\n\n"; \
++} \
++{ \
++  copy_in_global_log = 1; \
++  global_test_result = "RUN"; \
++  while ((rc = (getline line < ($$0 ".trs"))) != 0) \
++    { \
++      if (rc < 0) \
++         fatal("failed to read from " $$0 ".trs"); \
++      if (line ~ /$(am__global_test_result_rx)/) \
++        { \
++          sub("$(am__global_test_result_rx)", "", line); \
++          sub("[ 	]*$$", "", line); \
++          global_test_result = line; \
++        } \
++      else if (line ~ /$(am__copy_in_global_log_rx)[nN][oO]/) \
++        copy_in_global_log = 0; \
++    }; \
++  if (copy_in_global_log) \
++    { \
++      rst_section(global_test_result ": " $$0); \
++      while ((rc = (getline line < ($$0 ".log"))) != 0) \
++      { \
++        if (rc < 0) \
++          fatal("failed to read from " $$0 ".log"); \
++        print line; \
++      }; \
++      printf "\n"; \
++    }; \
++  close ($$0 ".trs"); \
++  close ($$0 ".log"); \
++}'
++# Restructured Text title.
++am__rst_title = { sed 's/.*/   &   /;h;s/./=/g;p;x;s/ *$$//;p;g' && echo; }
++# Solaris 10 'make', and several other traditional 'make' implementations,
++# pass "-e" to $(SHELL), and POSIX 2008 even requires this.  Work around it
++# by disabling -e (using the XSI extension "set +e") if it's set.
++am__sh_e_setup = case $$- in *e*) set +e;; esac
++# Default flags passed to test drivers.
++am__common_driver_flags = \
++  --color-tests "$$am__color_tests" \
++  --enable-hard-errors "$$am__enable_hard_errors" \
++  --expect-failure "$$am__expect_failure"
++# To be inserted before the command running the test.  Creates the
++# directory for the log if needed.  Stores in $dir the directory
++# containing $f, in $tst the test, in $log the log.  Executes the
++# developer- defined test setup AM_TESTS_ENVIRONMENT (if any), and
++# passes TESTS_ENVIRONMENT.  Set up options for the wrapper that
++# will run the test scripts (or their associated LOG_COMPILER, if
++# thy have one).
++am__check_pre = \
++$(am__sh_e_setup);					\
++$(am__vpath_adj_setup) $(am__vpath_adj)			\
++$(am__tty_colors);					\
++srcdir=$(srcdir); export srcdir;			\
++case "$@" in						\
++  */*) am__odir=`echo "./$@" | sed 's|/[^/]*$$||'`;;	\
++    *) am__odir=.;; 					\
++esac;							\
++test "x$$am__odir" = x"." || test -d "$$am__odir" 	\
++  || $(MKDIR_P) "$$am__odir" || exit $$?;		\
++if test -f "./$$f"; then dir=./;			\
++elif test -f "$$f"; then dir=;				\
++else dir="$(srcdir)/"; fi;				\
++tst=$$dir$$f; log='$@'; 				\
++if test -n '$(DISABLE_HARD_ERRORS)'; then		\
++  am__enable_hard_errors=no; 				\
++else							\
++  am__enable_hard_errors=yes; 				\
++fi; 							\
++case " $(XFAIL_TESTS) " in				\
++  *[\ \	]$$f[\ \	]* | *[\ \	]$$dir$$f[\ \	]*) \
++    am__expect_failure=yes;;				\
++  *)							\
++    am__expect_failure=no;;				\
++esac; 							\
++$(AM_TESTS_ENVIRONMENT) $(TESTS_ENVIRONMENT)
++# A shell command to get the names of the tests scripts with any registered
++# extension removed (i.e., equivalently, the names of the test logs, with
++# the '.log' extension removed).  The result is saved in the shell variable
++# '$bases'.  This honors runtime overriding of TESTS and TEST_LOGS.  Sadly,
++# we cannot use something simpler, involving e.g., "$(TEST_LOGS:.log=)",
++# since that might cause problem with VPATH rewrites for suffix-less tests.
++# See also 'test-harness-vpath-rewrite.sh' and 'test-trs-basic.sh'.
++am__set_TESTS_bases = \
++  bases='$(TEST_LOGS)'; \
++  bases=`for i in $$bases; do echo $$i; done | sed 's/\.log$$//'`; \
++  bases=`echo $$bases`
++AM_TESTSUITE_SUMMARY_HEADER = ' for $(PACKAGE_STRING)'
++RECHECK_LOGS = $(TEST_LOGS)
++AM_RECURSIVE_TARGETS = check recheck
++TEST_SUITE_LOG = test-suite.log
++TEST_EXTENSIONS = @EXEEXT@ .test
++LOG_DRIVER = $(SHELL) $(top_srcdir)/build-aux/test-driver
++LOG_COMPILE = $(LOG_COMPILER) $(AM_LOG_FLAGS) $(LOG_FLAGS)
++am__set_b = \
++  case '$@' in \
++    */*) \
++      case '$*' in \
++        */*) b='$*';; \
++          *) b=`echo '$@' | sed 's/\.log$$//'`; \
++       esac;; \
++    *) \
++      b='$*';; \
++  esac
++am__test_logs1 = $(TESTS:=.log)
++am__test_logs2 = $(am__test_logs1:@EXEEXT@.log=.log)
++TEST_LOGS = $(am__test_logs2:.test.log=.log)
++TEST_LOG_DRIVER = $(SHELL) $(top_srcdir)/build-aux/test-driver
++TEST_LOG_COMPILE = $(TEST_LOG_COMPILER) $(AM_TEST_LOG_FLAGS) \
++	$(TEST_LOG_FLAGS)
++am__DIST_COMMON = $(srcdir)/Makefile.in \
++	$(top_srcdir)/build-aux/depcomp \
++	$(top_srcdir)/build-aux/test-driver
++DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
++ACLOCAL = @ACLOCAL@
++AMTAR = @AMTAR@
++AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
++AR = @AR@
++AUTOCONF = @AUTOCONF@
++AUTOHEADER = @AUTOHEADER@
++AUTOMAKE = @AUTOMAKE@
++AWK = @AWK@
++CC = @CC@
++CCDEPMODE = @CCDEPMODE@
++CFLAGS = @CFLAGS@
++CHECK_CFLAGS = @CHECK_CFLAGS@
++CHECK_LIBS = @CHECK_LIBS@
++CPPFLAGS = @CPPFLAGS@
++CSCOPE = @CSCOPE@
++CTAGS = @CTAGS@
++CYGPATH_W = @CYGPATH_W@
++DEFS = @DEFS@
++DEPDIR = @DEPDIR@
++DLLTOOL = @DLLTOOL@
++DOXYGEN = @DOXYGEN@
++DSYMUTIL = @DSYMUTIL@
++DUMPBIN = @DUMPBIN@
++ECHO_C = @ECHO_C@
++ECHO_N = @ECHO_N@
++ECHO_T = @ECHO_T@
++EGREP = @EGREP@
++ETAGS = @ETAGS@
++EXEEXT = @EXEEXT@
++FGREP = @FGREP@
++GCC_CFLAGS = @GCC_CFLAGS@
++GCOV_CFLAGS = @GCOV_CFLAGS@
++GCOV_LDFLAGS = @GCOV_LDFLAGS@
++GNU_LD_FLAGS = @GNU_LD_FLAGS@
++GREP = @GREP@
++INSTALL = @INSTALL@
++INSTALL_DATA = @INSTALL_DATA@
++INSTALL_PROGRAM = @INSTALL_PROGRAM@
++INSTALL_SCRIPT = @INSTALL_SCRIPT@
++INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
++LD = @LD@
++LDFLAGS = @LDFLAGS@
++LIBEVDEV_LT_VERSION = @LIBEVDEV_LT_VERSION@
++LIBOBJS = @LIBOBJS@
++LIBS = @LIBS@
++LIBTOOL = @LIBTOOL@
++LIPO = @LIPO@
++LN_S = @LN_S@
++LTLIBOBJS = @LTLIBOBJS@
++LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
++MAKEINFO = @MAKEINFO@
++MANIFEST_TOOL = @MANIFEST_TOOL@
++MKDIR_P = @MKDIR_P@
++NM = @NM@
++NMEDIT = @NMEDIT@
++OBJDUMP = @OBJDUMP@
++OBJEXT = @OBJEXT@
++OS = @OS@
++OTOOL = @OTOOL@
++OTOOL64 = @OTOOL64@
++PACKAGE = @PACKAGE@
++PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
++PACKAGE_NAME = @PACKAGE_NAME@
++PACKAGE_STRING = @PACKAGE_STRING@
++PACKAGE_TARNAME = @PACKAGE_TARNAME@
++PACKAGE_URL = @PACKAGE_URL@
++PACKAGE_VERSION = @PACKAGE_VERSION@
++PATH_SEPARATOR = @PATH_SEPARATOR@
++PKG_CONFIG = @PKG_CONFIG@
++PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
++PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
++PYTHON = @PYTHON@
++PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
++PYTHON_PLATFORM = @PYTHON_PLATFORM@
++PYTHON_PREFIX = @PYTHON_PREFIX@
++PYTHON_VERSION = @PYTHON_VERSION@
++RANLIB = @RANLIB@
++SED = @SED@
++SET_MAKE = @SET_MAKE@
++SHELL = @SHELL@
++STRIP = @STRIP@
++VALGRIND = @VALGRIND@
++VERSION = @VERSION@
++abs_builddir = @abs_builddir@
++abs_srcdir = @abs_srcdir@
++abs_top_builddir = @abs_top_builddir@
++abs_top_srcdir = @abs_top_srcdir@
++ac_ct_AR = @ac_ct_AR@
++ac_ct_CC = @ac_ct_CC@
++ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
++am__include = @am__include@
++am__leading_dot = @am__leading_dot@
++am__quote = @am__quote@
++am__tar = @am__tar@
++am__untar = @am__untar@
++bindir = @bindir@
++build = @build@
++build_alias = @build_alias@
++build_cpu = @build_cpu@
++build_os = @build_os@
++build_vendor = @build_vendor@
++builddir = @builddir@
++datadir = @datadir@
++datarootdir = @datarootdir@
++docdir = @docdir@
++dvidir = @dvidir@
++exec_prefix = @exec_prefix@
++host = @host@
++host_alias = @host_alias@
++host_cpu = @host_cpu@
++host_os = @host_os@
++host_vendor = @host_vendor@
++htmldir = @htmldir@
++includedir = @includedir@
++infodir = @infodir@
++install_sh = @install_sh@
++libdir = @libdir@
++libexecdir = @libexecdir@
++localedir = @localedir@
++localstatedir = @localstatedir@
++mandir = @mandir@
++mkdir_p = @mkdir_p@
++oldincludedir = @oldincludedir@
++pdfdir = @pdfdir@
++pkgpyexecdir = @pkgpyexecdir@
++pkgpythondir = @pkgpythondir@
++prefix = @prefix@
++program_transform_name = @program_transform_name@
++psdir = @psdir@
++pyexecdir = @pyexecdir@
++pythondir = @pythondir@
++runstatedir = @runstatedir@
++sbindir = @sbindir@
++sharedstatedir = @sharedstatedir@
++srcdir = @srcdir@
++sysconfdir = @sysconfdir@
++target_alias = @target_alias@
++top_build_prefix = @top_build_prefix@
++top_builddir = @top_builddir@
++top_srcdir = @top_srcdir@
++build_tests = test-compile-pedantic test-link $(am__append_1)
++AM_CPPFLAGS = -I$(top_srcdir) -I$(top_srcdir)/include \
++	-I$(top_builddir)/libevdev $(am__append_3)
++AM_LDFLAGS = $(am__append_4)
++test_compile_pedantic_SOURCES = test-compile-pedantic.c
++test_compile_pedantic_CFLAGS = $(AM_CPPFLAGS) -pedantic -Werror -std=c89
++test_link_SOURCES = test-link.c
++test_link_CFLAGS = -I$(top_srcdir)
++test_link_LDADD = $(top_builddir)/libevdev/libevdev.la
++test_static_link_SOURCES = test-link.c
++test_static_link_CFLAGS = -I$(top_srcdir)
++test_static_link_LDADD = $(top_builddir)/libevdev/libevdev.la
++test_static_link_LDFLAGS = $(AM_LDFLAGS) -static
++check_local_deps = $(am__append_5) $(am__append_6) $(am__append_7)
++@ENABLE_RUNTIME_TESTS_TRUE@run_tests = \
++@ENABLE_RUNTIME_TESTS_TRUE@	    test-libevdev \
++@ENABLE_RUNTIME_TESTS_TRUE@	    test-kernel \
++@ENABLE_RUNTIME_TESTS_TRUE@	    test-uinput \
++@ENABLE_RUNTIME_TESTS_TRUE@	    test-event-codes \
++@ENABLE_RUNTIME_TESTS_TRUE@	    test-libevdev-internals \
++@ENABLE_RUNTIME_TESTS_TRUE@	    $(NULL)
++
++@ENABLE_RUNTIME_TESTS_TRUE@common_sources = \
++@ENABLE_RUNTIME_TESTS_TRUE@		 test-common-uinput.c \
++@ENABLE_RUNTIME_TESTS_TRUE@		 test-common-uinput.h \
++@ENABLE_RUNTIME_TESTS_TRUE@		 test-common.c \
++@ENABLE_RUNTIME_TESTS_TRUE@		 test-common.h
++
++@ENABLE_RUNTIME_TESTS_TRUE@test_event_codes_SOURCES = \
++@ENABLE_RUNTIME_TESTS_TRUE@			test-main.c \
++@ENABLE_RUNTIME_TESTS_TRUE@			test-event-codes.c \
++@ENABLE_RUNTIME_TESTS_TRUE@			test-event-names.c \
++@ENABLE_RUNTIME_TESTS_TRUE@			test-context.c \
++@ENABLE_RUNTIME_TESTS_TRUE@			$(common_sources)
++
++@ENABLE_RUNTIME_TESTS_TRUE@test_event_codes_LDADD = $(CHECK_LIBS) $(top_builddir)/libevdev/libevdev.la
++@ENABLE_RUNTIME_TESTS_TRUE@test_event_codes_LDFLAGS = -no-install
++@ENABLE_RUNTIME_TESTS_TRUE@test_libevdev_internals_SOURCES = \
++@ENABLE_RUNTIME_TESTS_TRUE@			test-main.c \
++@ENABLE_RUNTIME_TESTS_TRUE@			test-int-queue.c \
++@ENABLE_RUNTIME_TESTS_TRUE@			$(common_sources)
++
++@ENABLE_RUNTIME_TESTS_TRUE@test_libevdev_internals_LDADD = $(CHECK_LIBS) $(top_builddir)/libevdev/libevdev.la
++@ENABLE_RUNTIME_TESTS_TRUE@test_libevdev_internals_LDFLAGS = -no-install
++@ENABLE_RUNTIME_TESTS_TRUE@test_uinput_SOURCES = \
++@ENABLE_RUNTIME_TESTS_TRUE@			test-main.c \
++@ENABLE_RUNTIME_TESTS_TRUE@			test-uinput.c \
++@ENABLE_RUNTIME_TESTS_TRUE@			$(common_sources)
++
++@ENABLE_RUNTIME_TESTS_TRUE@test_uinput_LDADD = $(CHECK_LIBS) $(top_builddir)/libevdev/libevdev.la
++@ENABLE_RUNTIME_TESTS_TRUE@test_uinput_LDFLAGS = -no-install
++@ENABLE_RUNTIME_TESTS_TRUE@test_libevdev_SOURCES = \
++@ENABLE_RUNTIME_TESTS_TRUE@			test-main.c \
++@ENABLE_RUNTIME_TESTS_TRUE@			test-libevdev-init.c \
++@ENABLE_RUNTIME_TESTS_TRUE@			test-libevdev-has-event.c \
++@ENABLE_RUNTIME_TESTS_TRUE@			test-libevdev-events.c \
++@ENABLE_RUNTIME_TESTS_TRUE@			$(common_sources)
++
++@ENABLE_RUNTIME_TESTS_TRUE@test_libevdev_LDADD = $(CHECK_LIBS) $(top_builddir)/libevdev/libevdev.la
++@ENABLE_RUNTIME_TESTS_TRUE@test_libevdev_LDFLAGS = -no-install
++@ENABLE_RUNTIME_TESTS_TRUE@test_kernel_SOURCES = \
++@ENABLE_RUNTIME_TESTS_TRUE@		      test-main.c \
++@ENABLE_RUNTIME_TESTS_TRUE@		      test-kernel.c \
++@ENABLE_RUNTIME_TESTS_TRUE@		      $(common_sources)
++
++@ENABLE_RUNTIME_TESTS_TRUE@test_kernel_CFLAGS = -I$(top_srcdir)
++@ENABLE_RUNTIME_TESTS_TRUE@test_kernel_LDADD = $(CHECK_LIBS) $(top_builddir)/libevdev/libevdev.la
++@ENABLE_RUNTIME_TESTS_TRUE@@HAVE_VALGRIND_TRUE@VALGRIND_FLAGS = --leak-check=full \
++@ENABLE_RUNTIME_TESTS_TRUE@@HAVE_VALGRIND_TRUE@		--quiet \
++@ENABLE_RUNTIME_TESTS_TRUE@@HAVE_VALGRIND_TRUE@		--error-exitcode=3 \
++@ENABLE_RUNTIME_TESTS_TRUE@@HAVE_VALGRIND_TRUE@		--suppressions=$(srcdir)/valgrind.suppressions
++
++@ENABLE_RUNTIME_TESTS_TRUE@@GCOV_ENABLED_TRUE@CLEANFILES = gcov-reports/*.gcov gcov-reports/summary.txt *.gcno *.gcda
++EXTRA_DIST = valgrind.suppressions  generate-gcov-report.sh test-static-symbols-leak.sh
++all: all-am
++
++.SUFFIXES:
++.SUFFIXES: .c .lo .log .o .obj .test .test$(EXEEXT) .trs
++$(srcdir)/Makefile.in:  $(srcdir)/Makefile.am  $(am__configure_deps)
++	@for dep in $?; do \
++	  case '$(am__configure_deps)' in \
++	    *$$dep*) \
++	      ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
++	        && { if test -f $@; then exit 0; else break; fi; }; \
++	      exit 1;; \
++	  esac; \
++	done; \
++	echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign test/Makefile'; \
++	$(am__cd) $(top_srcdir) && \
++	  $(AUTOMAKE) --foreign test/Makefile
++Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
++	@case '$?' in \
++	  *config.status*) \
++	    cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
++	  *) \
++	    echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \
++	    cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \
++	esac;
++
++$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
++	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
++
++$(top_srcdir)/configure:  $(am__configure_deps)
++	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
++$(ACLOCAL_M4):  $(am__aclocal_m4_deps)
++	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
++$(am__aclocal_m4_deps):
++
++clean-noinstPROGRAMS:
++	@list='$(noinst_PROGRAMS)'; test -n "$$list" || exit 0; \
++	echo " rm -f" $$list; \
++	rm -f $$list || exit $$?; \
++	test -n "$(EXEEXT)" || exit 0; \
++	list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \
++	echo " rm -f" $$list; \
++	rm -f $$list
++
++test-compile-pedantic$(EXEEXT): $(test_compile_pedantic_OBJECTS) $(test_compile_pedantic_DEPENDENCIES) $(EXTRA_test_compile_pedantic_DEPENDENCIES) 
++	@rm -f test-compile-pedantic$(EXEEXT)
++	$(AM_V_CCLD)$(test_compile_pedantic_LINK) $(test_compile_pedantic_OBJECTS) $(test_compile_pedantic_LDADD) $(LIBS)
++
++test-event-codes$(EXEEXT): $(test_event_codes_OBJECTS) $(test_event_codes_DEPENDENCIES) $(EXTRA_test_event_codes_DEPENDENCIES) 
++	@rm -f test-event-codes$(EXEEXT)
++	$(AM_V_CCLD)$(test_event_codes_LINK) $(test_event_codes_OBJECTS) $(test_event_codes_LDADD) $(LIBS)
++
++test-kernel$(EXEEXT): $(test_kernel_OBJECTS) $(test_kernel_DEPENDENCIES) $(EXTRA_test_kernel_DEPENDENCIES) 
++	@rm -f test-kernel$(EXEEXT)
++	$(AM_V_CCLD)$(test_kernel_LINK) $(test_kernel_OBJECTS) $(test_kernel_LDADD) $(LIBS)
++
++test-libevdev$(EXEEXT): $(test_libevdev_OBJECTS) $(test_libevdev_DEPENDENCIES) $(EXTRA_test_libevdev_DEPENDENCIES) 
++	@rm -f test-libevdev$(EXEEXT)
++	$(AM_V_CCLD)$(test_libevdev_LINK) $(test_libevdev_OBJECTS) $(test_libevdev_LDADD) $(LIBS)
++
++test-libevdev-internals$(EXEEXT): $(test_libevdev_internals_OBJECTS) $(test_libevdev_internals_DEPENDENCIES) $(EXTRA_test_libevdev_internals_DEPENDENCIES) 
++	@rm -f test-libevdev-internals$(EXEEXT)
++	$(AM_V_CCLD)$(test_libevdev_internals_LINK) $(test_libevdev_internals_OBJECTS) $(test_libevdev_internals_LDADD) $(LIBS)
++
++test-link$(EXEEXT): $(test_link_OBJECTS) $(test_link_DEPENDENCIES) $(EXTRA_test_link_DEPENDENCIES) 
++	@rm -f test-link$(EXEEXT)
++	$(AM_V_CCLD)$(test_link_LINK) $(test_link_OBJECTS) $(test_link_LDADD) $(LIBS)
++
++test-static-link$(EXEEXT): $(test_static_link_OBJECTS) $(test_static_link_DEPENDENCIES) $(EXTRA_test_static_link_DEPENDENCIES) 
++	@rm -f test-static-link$(EXEEXT)
++	$(AM_V_CCLD)$(test_static_link_LINK) $(test_static_link_OBJECTS) $(test_static_link_LDADD) $(LIBS)
++
++test-uinput$(EXEEXT): $(test_uinput_OBJECTS) $(test_uinput_DEPENDENCIES) $(EXTRA_test_uinput_DEPENDENCIES) 
++	@rm -f test-uinput$(EXEEXT)
++	$(AM_V_CCLD)$(test_uinput_LINK) $(test_uinput_OBJECTS) $(test_uinput_LDADD) $(LIBS)
++
++mostlyclean-compile:
++	-rm -f *.$(OBJEXT)
++
++distclean-compile:
++	-rm -f *.tab.c
++
++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-common-uinput.Po@am__quote@ # am--include-marker
++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-common.Po@am__quote@ # am--include-marker
++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-context.Po@am__quote@ # am--include-marker
++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-event-codes.Po@am__quote@ # am--include-marker
++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-event-names.Po@am__quote@ # am--include-marker
++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-int-queue.Po@am__quote@ # am--include-marker
++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-libevdev-events.Po@am__quote@ # am--include-marker
++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-libevdev-has-event.Po@am__quote@ # am--include-marker
++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-libevdev-init.Po@am__quote@ # am--include-marker
++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-main.Po@am__quote@ # am--include-marker
++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-uinput.Po@am__quote@ # am--include-marker
++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_compile_pedantic-test-compile-pedantic.Po@am__quote@ # am--include-marker
++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_kernel-test-common-uinput.Po@am__quote@ # am--include-marker
++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_kernel-test-common.Po@am__quote@ # am--include-marker
++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_kernel-test-kernel.Po@am__quote@ # am--include-marker
++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_kernel-test-main.Po@am__quote@ # am--include-marker
++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_link-test-link.Po@am__quote@ # am--include-marker
++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_static_link-test-link.Po@am__quote@ # am--include-marker
++
++$(am__depfiles_remade):
++	@$(MKDIR_P) $(@D)
++	@echo '# dummy' >$@-t && $(am__mv) $@-t $@
++
++am--depfiles: $(am__depfiles_remade)
++
++.c.o:
++@am__fastdepCC_TRUE@	$(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\
++@am__fastdepCC_TRUE@	$(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
++@am__fastdepCC_TRUE@	$(am__mv) $$depbase.Tpo $$depbase.Po
++@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
++@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
++@am__fastdepCC_FALSE@	$(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $<
++
++.c.obj:
++@am__fastdepCC_TRUE@	$(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\
++@am__fastdepCC_TRUE@	$(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\
++@am__fastdepCC_TRUE@	$(am__mv) $$depbase.Tpo $$depbase.Po
++@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
++@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
++@am__fastdepCC_FALSE@	$(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
++
++.c.lo:
++@am__fastdepCC_TRUE@	$(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\
++@am__fastdepCC_TRUE@	$(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
++@am__fastdepCC_TRUE@	$(am__mv) $$depbase.Tpo $$depbase.Plo
++@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
++@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
++@am__fastdepCC_FALSE@	$(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $<
++
++test_compile_pedantic-test-compile-pedantic.o: test-compile-pedantic.c
++@am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_compile_pedantic_CFLAGS) $(CFLAGS) -MT test_compile_pedantic-test-compile-pedantic.o -MD -MP -MF $(DEPDIR)/test_compile_pedantic-test-compile-pedantic.Tpo -c -o test_compile_pedantic-test-compile-pedantic.o `test -f 'test-compile-pedantic.c' || echo '$(srcdir)/'`test-compile-pedantic.c
++@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/test_compile_pedantic-test-compile-pedantic.Tpo $(DEPDIR)/test_compile_pedantic-test-compile-pedantic.Po
++@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='test-compile-pedantic.c' object='test_compile_pedantic-test-compile-pedantic.o' libtool=no @AMDEPBACKSLASH@
++@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
++@am__fastdepCC_FALSE@	$(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_compile_pedantic_CFLAGS) $(CFLAGS) -c -o test_compile_pedantic-test-compile-pedantic.o `test -f 'test-compile-pedantic.c' || echo '$(srcdir)/'`test-compile-pedantic.c
++
++test_compile_pedantic-test-compile-pedantic.obj: test-compile-pedantic.c
++@am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_compile_pedantic_CFLAGS) $(CFLAGS) -MT test_compile_pedantic-test-compile-pedantic.obj -MD -MP -MF $(DEPDIR)/test_compile_pedantic-test-compile-pedantic.Tpo -c -o test_compile_pedantic-test-compile-pedantic.obj `if test -f 'test-compile-pedantic.c'; then $(CYGPATH_W) 'test-compile-pedantic.c'; else $(CYGPATH_W) '$(srcdir)/test-compile-pedantic.c'; fi`
++@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/test_compile_pedantic-test-compile-pedantic.Tpo $(DEPDIR)/test_compile_pedantic-test-compile-pedantic.Po
++@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='test-compile-pedantic.c' object='test_compile_pedantic-test-compile-pedantic.obj' libtool=no @AMDEPBACKSLASH@
++@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
++@am__fastdepCC_FALSE@	$(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_compile_pedantic_CFLAGS) $(CFLAGS) -c -o test_compile_pedantic-test-compile-pedantic.obj `if test -f 'test-compile-pedantic.c'; then $(CYGPATH_W) 'test-compile-pedantic.c'; else $(CYGPATH_W) '$(srcdir)/test-compile-pedantic.c'; fi`
++
++test_kernel-test-main.o: test-main.c
++@am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_kernel_CFLAGS) $(CFLAGS) -MT test_kernel-test-main.o -MD -MP -MF $(DEPDIR)/test_kernel-test-main.Tpo -c -o test_kernel-test-main.o `test -f 'test-main.c' || echo '$(srcdir)/'`test-main.c
++@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/test_kernel-test-main.Tpo $(DEPDIR)/test_kernel-test-main.Po
++@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='test-main.c' object='test_kernel-test-main.o' libtool=no @AMDEPBACKSLASH@
++@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
++@am__fastdepCC_FALSE@	$(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_kernel_CFLAGS) $(CFLAGS) -c -o test_kernel-test-main.o `test -f 'test-main.c' || echo '$(srcdir)/'`test-main.c
++
++test_kernel-test-main.obj: test-main.c
++@am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_kernel_CFLAGS) $(CFLAGS) -MT test_kernel-test-main.obj -MD -MP -MF $(DEPDIR)/test_kernel-test-main.Tpo -c -o test_kernel-test-main.obj `if test -f 'test-main.c'; then $(CYGPATH_W) 'test-main.c'; else $(CYGPATH_W) '$(srcdir)/test-main.c'; fi`
++@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/test_kernel-test-main.Tpo $(DEPDIR)/test_kernel-test-main.Po
++@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='test-main.c' object='test_kernel-test-main.obj' libtool=no @AMDEPBACKSLASH@
++@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
++@am__fastdepCC_FALSE@	$(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_kernel_CFLAGS) $(CFLAGS) -c -o test_kernel-test-main.obj `if test -f 'test-main.c'; then $(CYGPATH_W) 'test-main.c'; else $(CYGPATH_W) '$(srcdir)/test-main.c'; fi`
++
++test_kernel-test-kernel.o: test-kernel.c
++@am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_kernel_CFLAGS) $(CFLAGS) -MT test_kernel-test-kernel.o -MD -MP -MF $(DEPDIR)/test_kernel-test-kernel.Tpo -c -o test_kernel-test-kernel.o `test -f 'test-kernel.c' || echo '$(srcdir)/'`test-kernel.c
++@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/test_kernel-test-kernel.Tpo $(DEPDIR)/test_kernel-test-kernel.Po
++@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='test-kernel.c' object='test_kernel-test-kernel.o' libtool=no @AMDEPBACKSLASH@
++@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
++@am__fastdepCC_FALSE@	$(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_kernel_CFLAGS) $(CFLAGS) -c -o test_kernel-test-kernel.o `test -f 'test-kernel.c' || echo '$(srcdir)/'`test-kernel.c
++
++test_kernel-test-kernel.obj: test-kernel.c
++@am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_kernel_CFLAGS) $(CFLAGS) -MT test_kernel-test-kernel.obj -MD -MP -MF $(DEPDIR)/test_kernel-test-kernel.Tpo -c -o test_kernel-test-kernel.obj `if test -f 'test-kernel.c'; then $(CYGPATH_W) 'test-kernel.c'; else $(CYGPATH_W) '$(srcdir)/test-kernel.c'; fi`
++@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/test_kernel-test-kernel.Tpo $(DEPDIR)/test_kernel-test-kernel.Po
++@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='test-kernel.c' object='test_kernel-test-kernel.obj' libtool=no @AMDEPBACKSLASH@
++@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
++@am__fastdepCC_FALSE@	$(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_kernel_CFLAGS) $(CFLAGS) -c -o test_kernel-test-kernel.obj `if test -f 'test-kernel.c'; then $(CYGPATH_W) 'test-kernel.c'; else $(CYGPATH_W) '$(srcdir)/test-kernel.c'; fi`
++
++test_kernel-test-common-uinput.o: test-common-uinput.c
++@am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_kernel_CFLAGS) $(CFLAGS) -MT test_kernel-test-common-uinput.o -MD -MP -MF $(DEPDIR)/test_kernel-test-common-uinput.Tpo -c -o test_kernel-test-common-uinput.o `test -f 'test-common-uinput.c' || echo '$(srcdir)/'`test-common-uinput.c
++@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/test_kernel-test-common-uinput.Tpo $(DEPDIR)/test_kernel-test-common-uinput.Po
++@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='test-common-uinput.c' object='test_kernel-test-common-uinput.o' libtool=no @AMDEPBACKSLASH@
++@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
++@am__fastdepCC_FALSE@	$(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_kernel_CFLAGS) $(CFLAGS) -c -o test_kernel-test-common-uinput.o `test -f 'test-common-uinput.c' || echo '$(srcdir)/'`test-common-uinput.c
++
++test_kernel-test-common-uinput.obj: test-common-uinput.c
++@am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_kernel_CFLAGS) $(CFLAGS) -MT test_kernel-test-common-uinput.obj -MD -MP -MF $(DEPDIR)/test_kernel-test-common-uinput.Tpo -c -o test_kernel-test-common-uinput.obj `if test -f 'test-common-uinput.c'; then $(CYGPATH_W) 'test-common-uinput.c'; else $(CYGPATH_W) '$(srcdir)/test-common-uinput.c'; fi`
++@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/test_kernel-test-common-uinput.Tpo $(DEPDIR)/test_kernel-test-common-uinput.Po
++@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='test-common-uinput.c' object='test_kernel-test-common-uinput.obj' libtool=no @AMDEPBACKSLASH@
++@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
++@am__fastdepCC_FALSE@	$(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_kernel_CFLAGS) $(CFLAGS) -c -o test_kernel-test-common-uinput.obj `if test -f 'test-common-uinput.c'; then $(CYGPATH_W) 'test-common-uinput.c'; else $(CYGPATH_W) '$(srcdir)/test-common-uinput.c'; fi`
++
++test_kernel-test-common.o: test-common.c
++@am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_kernel_CFLAGS) $(CFLAGS) -MT test_kernel-test-common.o -MD -MP -MF $(DEPDIR)/test_kernel-test-common.Tpo -c -o test_kernel-test-common.o `test -f 'test-common.c' || echo '$(srcdir)/'`test-common.c
++@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/test_kernel-test-common.Tpo $(DEPDIR)/test_kernel-test-common.Po
++@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='test-common.c' object='test_kernel-test-common.o' libtool=no @AMDEPBACKSLASH@
++@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
++@am__fastdepCC_FALSE@	$(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_kernel_CFLAGS) $(CFLAGS) -c -o test_kernel-test-common.o `test -f 'test-common.c' || echo '$(srcdir)/'`test-common.c
++
++test_kernel-test-common.obj: test-common.c
++@am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_kernel_CFLAGS) $(CFLAGS) -MT test_kernel-test-common.obj -MD -MP -MF $(DEPDIR)/test_kernel-test-common.Tpo -c -o test_kernel-test-common.obj `if test -f 'test-common.c'; then $(CYGPATH_W) 'test-common.c'; else $(CYGPATH_W) '$(srcdir)/test-common.c'; fi`
++@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/test_kernel-test-common.Tpo $(DEPDIR)/test_kernel-test-common.Po
++@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='test-common.c' object='test_kernel-test-common.obj' libtool=no @AMDEPBACKSLASH@
++@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
++@am__fastdepCC_FALSE@	$(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_kernel_CFLAGS) $(CFLAGS) -c -o test_kernel-test-common.obj `if test -f 'test-common.c'; then $(CYGPATH_W) 'test-common.c'; else $(CYGPATH_W) '$(srcdir)/test-common.c'; fi`
++
++test_link-test-link.o: test-link.c
++@am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_link_CFLAGS) $(CFLAGS) -MT test_link-test-link.o -MD -MP -MF $(DEPDIR)/test_link-test-link.Tpo -c -o test_link-test-link.o `test -f 'test-link.c' || echo '$(srcdir)/'`test-link.c
++@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/test_link-test-link.Tpo $(DEPDIR)/test_link-test-link.Po
++@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='test-link.c' object='test_link-test-link.o' libtool=no @AMDEPBACKSLASH@
++@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
++@am__fastdepCC_FALSE@	$(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_link_CFLAGS) $(CFLAGS) -c -o test_link-test-link.o `test -f 'test-link.c' || echo '$(srcdir)/'`test-link.c
++
++test_link-test-link.obj: test-link.c
++@am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_link_CFLAGS) $(CFLAGS) -MT test_link-test-link.obj -MD -MP -MF $(DEPDIR)/test_link-test-link.Tpo -c -o test_link-test-link.obj `if test -f 'test-link.c'; then $(CYGPATH_W) 'test-link.c'; else $(CYGPATH_W) '$(srcdir)/test-link.c'; fi`
++@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/test_link-test-link.Tpo $(DEPDIR)/test_link-test-link.Po
++@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='test-link.c' object='test_link-test-link.obj' libtool=no @AMDEPBACKSLASH@
++@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
++@am__fastdepCC_FALSE@	$(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_link_CFLAGS) $(CFLAGS) -c -o test_link-test-link.obj `if test -f 'test-link.c'; then $(CYGPATH_W) 'test-link.c'; else $(CYGPATH_W) '$(srcdir)/test-link.c'; fi`
++
++test_static_link-test-link.o: test-link.c
++@am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_static_link_CFLAGS) $(CFLAGS) -MT test_static_link-test-link.o -MD -MP -MF $(DEPDIR)/test_static_link-test-link.Tpo -c -o test_static_link-test-link.o `test -f 'test-link.c' || echo '$(srcdir)/'`test-link.c
++@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/test_static_link-test-link.Tpo $(DEPDIR)/test_static_link-test-link.Po
++@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='test-link.c' object='test_static_link-test-link.o' libtool=no @AMDEPBACKSLASH@
++@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
++@am__fastdepCC_FALSE@	$(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_static_link_CFLAGS) $(CFLAGS) -c -o test_static_link-test-link.o `test -f 'test-link.c' || echo '$(srcdir)/'`test-link.c
++
++test_static_link-test-link.obj: test-link.c
++@am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_static_link_CFLAGS) $(CFLAGS) -MT test_static_link-test-link.obj -MD -MP -MF $(DEPDIR)/test_static_link-test-link.Tpo -c -o test_static_link-test-link.obj `if test -f 'test-link.c'; then $(CYGPATH_W) 'test-link.c'; else $(CYGPATH_W) '$(srcdir)/test-link.c'; fi`
++@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/test_static_link-test-link.Tpo $(DEPDIR)/test_static_link-test-link.Po
++@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='test-link.c' object='test_static_link-test-link.obj' libtool=no @AMDEPBACKSLASH@
++@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
++@am__fastdepCC_FALSE@	$(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_static_link_CFLAGS) $(CFLAGS) -c -o test_static_link-test-link.obj `if test -f 'test-link.c'; then $(CYGPATH_W) 'test-link.c'; else $(CYGPATH_W) '$(srcdir)/test-link.c'; fi`
++
++mostlyclean-libtool:
++	-rm -f *.lo
++
++clean-libtool:
++	-rm -rf .libs _libs
++
++ID: $(am__tagged_files)
++	$(am__define_uniq_tagged_files); mkid -fID $$unique
++tags: tags-am
++TAGS: tags
++
++tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
++	set x; \
++	here=`pwd`; \
++	$(am__define_uniq_tagged_files); \
++	shift; \
++	if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
++	  test -n "$$unique" || unique=$$empty_fix; \
++	  if test $$# -gt 0; then \
++	    $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
++	      "$$@" $$unique; \
++	  else \
++	    $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
++	      $$unique; \
++	  fi; \
++	fi
++ctags: ctags-am
++
++CTAGS: ctags
++ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
++	$(am__define_uniq_tagged_files); \
++	test -z "$(CTAGS_ARGS)$$unique" \
++	  || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
++	     $$unique
++
++GTAGS:
++	here=`$(am__cd) $(top_builddir) && pwd` \
++	  && $(am__cd) $(top_srcdir) \
++	  && gtags -i $(GTAGS_ARGS) "$$here"
++cscopelist: cscopelist-am
++
++cscopelist-am: $(am__tagged_files)
++	list='$(am__tagged_files)'; \
++	case "$(srcdir)" in \
++	  [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
++	  *) sdir=$(subdir)/$(srcdir) ;; \
++	esac; \
++	for i in $$list; do \
++	  if test -f "$$i"; then \
++	    echo "$(subdir)/$$i"; \
++	  else \
++	    echo "$$sdir/$$i"; \
++	  fi; \
++	done >> $(top_builddir)/cscope.files
++
++distclean-tags:
++	-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
++
++# Recover from deleted '.trs' file; this should ensure that
++# "rm -f foo.log; make foo.trs" re-run 'foo.test', and re-create
++# both 'foo.log' and 'foo.trs'.  Break the recipe in two subshells
++# to avoid problems with "make -n".
++.log.trs:
++	rm -f $< $@
++	$(MAKE) $(AM_MAKEFLAGS) $<
++
++# Leading 'am--fnord' is there to ensure the list of targets does not
++# expand to empty, as could happen e.g. with make check TESTS=''.
++am--fnord $(TEST_LOGS) $(TEST_LOGS:.log=.trs): $(am__force_recheck)
++am--force-recheck:
++	@:
++
++$(TEST_SUITE_LOG): $(TEST_LOGS)
++	@$(am__set_TESTS_bases); \
++	am__f_ok () { test -f "$$1" && test -r "$$1"; }; \
++	redo_bases=`for i in $$bases; do \
++	              am__f_ok $$i.trs && am__f_ok $$i.log || echo $$i; \
++	            done`; \
++	if test -n "$$redo_bases"; then \
++	  redo_logs=`for i in $$redo_bases; do echo $$i.log; done`; \
++	  redo_results=`for i in $$redo_bases; do echo $$i.trs; done`; \
++	  if $(am__make_dryrun); then :; else \
++	    rm -f $$redo_logs && rm -f $$redo_results || exit 1; \
++	  fi; \
++	fi; \
++	if test -n "$$am__remaking_logs"; then \
++	  echo "fatal: making $(TEST_SUITE_LOG): possible infinite" \
++	       "recursion detected" >&2; \
++	elif test -n "$$redo_logs"; then \
++	  am__remaking_logs=yes $(MAKE) $(AM_MAKEFLAGS) $$redo_logs; \
++	fi; \
++	if $(am__make_dryrun); then :; else \
++	  st=0;  \
++	  errmsg="fatal: making $(TEST_SUITE_LOG): failed to create"; \
++	  for i in $$redo_bases; do \
++	    test -f $$i.trs && test -r $$i.trs \
++	      || { echo "$$errmsg $$i.trs" >&2; st=1; }; \
++	    test -f $$i.log && test -r $$i.log \
++	      || { echo "$$errmsg $$i.log" >&2; st=1; }; \
++	  done; \
++	  test $$st -eq 0 || exit 1; \
++	fi
++	@$(am__sh_e_setup); $(am__tty_colors); $(am__set_TESTS_bases); \
++	ws='[ 	]'; \
++	results=`for b in $$bases; do echo $$b.trs; done`; \
++	test -n "$$results" || results=/dev/null; \
++	all=`  grep "^$$ws*:test-result:"           $$results | wc -l`; \
++	pass=` grep "^$$ws*:test-result:$$ws*PASS"  $$results | wc -l`; \
++	fail=` grep "^$$ws*:test-result:$$ws*FAIL"  $$results | wc -l`; \
++	skip=` grep "^$$ws*:test-result:$$ws*SKIP"  $$results | wc -l`; \
++	xfail=`grep "^$$ws*:test-result:$$ws*XFAIL" $$results | wc -l`; \
++	xpass=`grep "^$$ws*:test-result:$$ws*XPASS" $$results | wc -l`; \
++	error=`grep "^$$ws*:test-result:$$ws*ERROR" $$results | wc -l`; \
++	if test `expr $$fail + $$xpass + $$error` -eq 0; then \
++	  success=true; \
++	else \
++	  success=false; \
++	fi; \
++	br='==================='; br=$$br$$br$$br$$br; \
++	result_count () \
++	{ \
++	    if test x"$$1" = x"--maybe-color"; then \
++	      maybe_colorize=yes; \
++	    elif test x"$$1" = x"--no-color"; then \
++	      maybe_colorize=no; \
++	    else \
++	      echo "$@: invalid 'result_count' usage" >&2; exit 4; \
++	    fi; \
++	    shift; \
++	    desc=$$1 count=$$2; \
++	    if test $$maybe_colorize = yes && test $$count -gt 0; then \
++	      color_start=$$3 color_end=$$std; \
++	    else \
++	      color_start= color_end=; \
++	    fi; \
++	    echo "$${color_start}# $$desc $$count$${color_end}"; \
++	}; \
++	create_testsuite_report () \
++	{ \
++	  result_count $$1 "TOTAL:" $$all   "$$brg"; \
++	  result_count $$1 "PASS: " $$pass  "$$grn"; \
++	  result_count $$1 "SKIP: " $$skip  "$$blu"; \
++	  result_count $$1 "XFAIL:" $$xfail "$$lgn"; \
++	  result_count $$1 "FAIL: " $$fail  "$$red"; \
++	  result_count $$1 "XPASS:" $$xpass "$$red"; \
++	  result_count $$1 "ERROR:" $$error "$$mgn"; \
++	}; \
++	{								\
++	  echo "$(PACKAGE_STRING): $(subdir)/$(TEST_SUITE_LOG)" |	\
++	    $(am__rst_title);						\
++	  create_testsuite_report --no-color;				\
++	  echo;								\
++	  echo ".. contents:: :depth: 2";				\
++	  echo;								\
++	  for b in $$bases; do echo $$b; done				\
++	    | $(am__create_global_log);					\
++	} >$(TEST_SUITE_LOG).tmp || exit 1;				\
++	mv $(TEST_SUITE_LOG).tmp $(TEST_SUITE_LOG);			\
++	if $$success; then						\
++	  col="$$grn";							\
++	 else								\
++	  col="$$red";							\
++	  test x"$$VERBOSE" = x || cat $(TEST_SUITE_LOG);		\
++	fi;								\
++	echo "$${col}$$br$${std}"; 					\
++	echo "$${col}Testsuite summary"$(AM_TESTSUITE_SUMMARY_HEADER)"$${std}";	\
++	echo "$${col}$$br$${std}"; 					\
++	create_testsuite_report --maybe-color;				\
++	echo "$$col$$br$$std";						\
++	if $$success; then :; else					\
++	  echo "$${col}See $(subdir)/$(TEST_SUITE_LOG)$${std}";		\
++	  if test -n "$(PACKAGE_BUGREPORT)"; then			\
++	    echo "$${col}Please report to $(PACKAGE_BUGREPORT)$${std}";	\
++	  fi;								\
++	  echo "$$col$$br$$std";					\
++	fi;								\
++	$$success || exit 1
++
++check-TESTS: 
++	@list='$(RECHECK_LOGS)';           test -z "$$list" || rm -f $$list
++	@list='$(RECHECK_LOGS:.log=.trs)'; test -z "$$list" || rm -f $$list
++	@test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
++	@set +e; $(am__set_TESTS_bases); \
++	log_list=`for i in $$bases; do echo $$i.log; done`; \
++	trs_list=`for i in $$bases; do echo $$i.trs; done`; \
++	log_list=`echo $$log_list`; trs_list=`echo $$trs_list`; \
++	$(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) TEST_LOGS="$$log_list"; \
++	exit $$?;
++recheck: all 
++	@test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
++	@set +e; $(am__set_TESTS_bases); \
++	bases=`for i in $$bases; do echo $$i; done \
++	         | $(am__list_recheck_tests)` || exit 1; \
++	log_list=`for i in $$bases; do echo $$i.log; done`; \
++	log_list=`echo $$log_list`; \
++	$(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) \
++	        am__force_recheck=am--force-recheck \
++	        TEST_LOGS="$$log_list"; \
++	exit $$?
++test-libevdev.log: test-libevdev$(EXEEXT)
++	@p='test-libevdev$(EXEEXT)'; \
++	b='test-libevdev'; \
++	$(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
++	--log-file $$b.log --trs-file $$b.trs \
++	$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
++	"$$tst" $(AM_TESTS_FD_REDIRECT)
++test-kernel.log: test-kernel$(EXEEXT)
++	@p='test-kernel$(EXEEXT)'; \
++	b='test-kernel'; \
++	$(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
++	--log-file $$b.log --trs-file $$b.trs \
++	$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
++	"$$tst" $(AM_TESTS_FD_REDIRECT)
++test-uinput.log: test-uinput$(EXEEXT)
++	@p='test-uinput$(EXEEXT)'; \
++	b='test-uinput'; \
++	$(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
++	--log-file $$b.log --trs-file $$b.trs \
++	$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
++	"$$tst" $(AM_TESTS_FD_REDIRECT)
++test-event-codes.log: test-event-codes$(EXEEXT)
++	@p='test-event-codes$(EXEEXT)'; \
++	b='test-event-codes'; \
++	$(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
++	--log-file $$b.log --trs-file $$b.trs \
++	$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
++	"$$tst" $(AM_TESTS_FD_REDIRECT)
++test-libevdev-internals.log: test-libevdev-internals$(EXEEXT)
++	@p='test-libevdev-internals$(EXEEXT)'; \
++	b='test-libevdev-internals'; \
++	$(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
++	--log-file $$b.log --trs-file $$b.trs \
++	$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
++	"$$tst" $(AM_TESTS_FD_REDIRECT)
++.test.log:
++	@p='$<'; \
++	$(am__set_b); \
++	$(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \
++	--log-file $$b.log --trs-file $$b.trs \
++	$(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \
++	"$$tst" $(AM_TESTS_FD_REDIRECT)
++@am__EXEEXT_TRUE@.test$(EXEEXT).log:
++@am__EXEEXT_TRUE@	@p='$<'; \
++@am__EXEEXT_TRUE@	$(am__set_b); \
++@am__EXEEXT_TRUE@	$(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \
++@am__EXEEXT_TRUE@	--log-file $$b.log --trs-file $$b.trs \
++@am__EXEEXT_TRUE@	$(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \
++@am__EXEEXT_TRUE@	"$$tst" $(AM_TESTS_FD_REDIRECT)
++distdir: $(BUILT_SOURCES)
++	$(MAKE) $(AM_MAKEFLAGS) distdir-am
++
++distdir-am: $(DISTFILES)
++	@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
++	topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
++	list='$(DISTFILES)'; \
++	  dist_files=`for file in $$list; do echo $$file; done | \
++	  sed -e "s|^$$srcdirstrip/||;t" \
++	      -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
++	case $$dist_files in \
++	  */*) $(MKDIR_P) `echo "$$dist_files" | \
++			   sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
++			   sort -u` ;; \
++	esac; \
++	for file in $$dist_files; do \
++	  if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
++	  if test -d $$d/$$file; then \
++	    dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
++	    if test -d "$(distdir)/$$file"; then \
++	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
++	    fi; \
++	    if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
++	      cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
++	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
++	    fi; \
++	    cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
++	  else \
++	    test -f "$(distdir)/$$file" \
++	    || cp -p $$d/$$file "$(distdir)/$$file" \
++	    || exit 1; \
++	  fi; \
++	done
++check-am: all-am
++	$(MAKE) $(AM_MAKEFLAGS) check-TESTS check-local
++check: check-am
++all-am: Makefile $(PROGRAMS)
++installdirs:
++install: install-am
++install-exec: install-exec-am
++install-data: install-data-am
++uninstall: uninstall-am
++
++install-am: all-am
++	@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
++
++installcheck: installcheck-am
++install-strip:
++	if test -z '$(STRIP)'; then \
++	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
++	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
++	      install; \
++	else \
++	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
++	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
++	    "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
++	fi
++mostlyclean-generic:
++	-test -z "$(TEST_LOGS)" || rm -f $(TEST_LOGS)
++	-test -z "$(TEST_LOGS:.log=.trs)" || rm -f $(TEST_LOGS:.log=.trs)
++	-test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
++
++clean-generic:
++	-test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
++
++distclean-generic:
++	-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
++	-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
++
++maintainer-clean-generic:
++	@echo "This command is intended for maintainers to use"
++	@echo "it deletes files that may require special tools to rebuild."
++clean: clean-am
++
++clean-am: clean-generic clean-libtool clean-noinstPROGRAMS \
++	mostlyclean-am
++
++distclean: distclean-am
++		-rm -f ./$(DEPDIR)/test-common-uinput.Po
++	-rm -f ./$(DEPDIR)/test-common.Po
++	-rm -f ./$(DEPDIR)/test-context.Po
++	-rm -f ./$(DEPDIR)/test-event-codes.Po
++	-rm -f ./$(DEPDIR)/test-event-names.Po
++	-rm -f ./$(DEPDIR)/test-int-queue.Po
++	-rm -f ./$(DEPDIR)/test-libevdev-events.Po
++	-rm -f ./$(DEPDIR)/test-libevdev-has-event.Po
++	-rm -f ./$(DEPDIR)/test-libevdev-init.Po
++	-rm -f ./$(DEPDIR)/test-main.Po
++	-rm -f ./$(DEPDIR)/test-uinput.Po
++	-rm -f ./$(DEPDIR)/test_compile_pedantic-test-compile-pedantic.Po
++	-rm -f ./$(DEPDIR)/test_kernel-test-common-uinput.Po
++	-rm -f ./$(DEPDIR)/test_kernel-test-common.Po
++	-rm -f ./$(DEPDIR)/test_kernel-test-kernel.Po
++	-rm -f ./$(DEPDIR)/test_kernel-test-main.Po
++	-rm -f ./$(DEPDIR)/test_link-test-link.Po
++	-rm -f ./$(DEPDIR)/test_static_link-test-link.Po
++	-rm -f Makefile
++distclean-am: clean-am distclean-compile distclean-generic \
++	distclean-tags
++
++dvi: dvi-am
++
++dvi-am:
++
++html: html-am
++
++html-am:
++
++info: info-am
++
++info-am:
++
++install-data-am:
++
++install-dvi: install-dvi-am
++
++install-dvi-am:
++
++install-exec-am:
++
++install-html: install-html-am
++
++install-html-am:
++
++install-info: install-info-am
++
++install-info-am:
++
++install-man:
++
++install-pdf: install-pdf-am
++
++install-pdf-am:
++
++install-ps: install-ps-am
++
++install-ps-am:
++
++installcheck-am:
++
++maintainer-clean: maintainer-clean-am
++		-rm -f ./$(DEPDIR)/test-common-uinput.Po
++	-rm -f ./$(DEPDIR)/test-common.Po
++	-rm -f ./$(DEPDIR)/test-context.Po
++	-rm -f ./$(DEPDIR)/test-event-codes.Po
++	-rm -f ./$(DEPDIR)/test-event-names.Po
++	-rm -f ./$(DEPDIR)/test-int-queue.Po
++	-rm -f ./$(DEPDIR)/test-libevdev-events.Po
++	-rm -f ./$(DEPDIR)/test-libevdev-has-event.Po
++	-rm -f ./$(DEPDIR)/test-libevdev-init.Po
++	-rm -f ./$(DEPDIR)/test-main.Po
++	-rm -f ./$(DEPDIR)/test-uinput.Po
++	-rm -f ./$(DEPDIR)/test_compile_pedantic-test-compile-pedantic.Po
++	-rm -f ./$(DEPDIR)/test_kernel-test-common-uinput.Po
++	-rm -f ./$(DEPDIR)/test_kernel-test-common.Po
++	-rm -f ./$(DEPDIR)/test_kernel-test-kernel.Po
++	-rm -f ./$(DEPDIR)/test_kernel-test-main.Po
++	-rm -f ./$(DEPDIR)/test_link-test-link.Po
++	-rm -f ./$(DEPDIR)/test_static_link-test-link.Po
++	-rm -f Makefile
++maintainer-clean-am: distclean-am maintainer-clean-generic
++
++mostlyclean: mostlyclean-am
++
++mostlyclean-am: mostlyclean-compile mostlyclean-generic \
++	mostlyclean-libtool
++
++pdf: pdf-am
++
++pdf-am:
++
++ps: ps-am
++
++ps-am:
++
++uninstall-am:
++
++.MAKE: check-am install-am install-strip
++
++.PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-TESTS \
++	check-am check-local clean clean-generic clean-libtool \
++	clean-noinstPROGRAMS cscopelist-am ctags ctags-am distclean \
++	distclean-compile distclean-generic distclean-libtool \
++	distclean-tags distdir dvi dvi-am html html-am info info-am \
++	install install-am install-data install-data-am install-dvi \
++	install-dvi-am install-exec install-exec-am install-html \
++	install-html-am install-info install-info-am install-man \
++	install-pdf install-pdf-am install-ps install-ps-am \
++	install-strip installcheck installcheck-am installdirs \
++	maintainer-clean maintainer-clean-generic mostlyclean \
++	mostlyclean-compile mostlyclean-generic mostlyclean-libtool \
++	pdf pdf-am ps ps-am recheck tags tags-am uninstall \
++	uninstall-am
++
++.PRECIOUS: Makefile
++
++
++@ENABLE_RUNTIME_TESTS_TRUE@.NOTPARALLEL:
++
++@ENABLE_RUNTIME_TESTS_TRUE@@HAVE_VALGRIND_TRUE@valgrind:
++@ENABLE_RUNTIME_TESTS_TRUE@@HAVE_VALGRIND_TRUE@	        $(MAKE) check-TESTS CK_TIMEOUT_MULTIPLIER=10 LOG_COMPILER="$(VALGRIND)" LOG_FLAGS="$(VALGRIND_FLAGS)"
++
++@ENABLE_RUNTIME_TESTS_TRUE@@GCOV_ENABLED_TRUE@gcov-report: generate-gcov-report.sh check-TESTS
++@ENABLE_RUNTIME_TESTS_TRUE@@GCOV_ENABLED_TRUE@	$(AM_V_GEN)$(srcdir)/generate-gcov-report.sh gcov-reports $(top_builddir)/libevdev $(builddir)
++
++@ENABLE_RUNTIME_TESTS_TRUE@@GCOV_ENABLED_TRUE@gcov: gcov-report
++@ENABLE_RUNTIME_TESTS_TRUE@@GCOV_ENABLED_TRUE@	@cat gcov-reports/summary.txt
++
++@ENABLE_RUNTIME_TESTS_TRUE@@GCOV_ENABLED_FALSE@gcov-report.txt:
++@ENABLE_RUNTIME_TESTS_TRUE@@GCOV_ENABLED_FALSE@	@true
++
++@ENABLE_RUNTIME_TESTS_TRUE@@GCOV_ENABLED_FALSE@gcov:
++@ENABLE_RUNTIME_TESTS_TRUE@@GCOV_ENABLED_FALSE@	@true
++
++@ENABLE_RUNTIME_TESTS_TRUE@.PHONY: gcov gcov-clean gcov-report
++
++@ENABLE_STATIC_SYMBOL_LEAKS_TEST_TRUE@static-symbol-leaks: test-static-link test-static-symbols-leak.sh
++@ENABLE_STATIC_SYMBOL_LEAKS_TEST_TRUE@	$(AM_V_GEN) $(srcdir)/test-static-symbols-leak.sh $(builddir)
++
++check-local: $(check_local_deps)
++
++# Tell versions [3.59,3.63) of GNU make to not export all variables.
++# Otherwise a system limit (for SysV at least) may be exceeded.
++.NOEXPORT:
+diff -Naur third-party-libevdev-bak/test/generate-gcov-report.sh third-party-new/test/generate-gcov-report.sh
+--- third-party-libevdev-bak/test/generate-gcov-report.sh	1970-01-01 08:00:00.000000000 +0800
++++ third-party-new/test/generate-gcov-report.sh	2022-03-25 12:33:26.000000000 +0800
+@@ -0,0 +1,40 @@
++#!/usr/bin/env bash
++
++set -e
++
++if [[ $# -lt 2 ]]; then
++    echo "Usage: ./generate-gcov-report.sh   [ ... ]"
++    exit 1
++fi
++
++target_dir=$1
++shift
++source_dirs=$*
++
++if [[ "${target_dir:0:1}" != '/' ]]; then
++    target_dir="$PWD/$target_dir"
++fi
++summary_file="$target_dir/summary.txt"
++
++mkdir -p "$target_dir"
++rm -f "$target_dir"/*.gcov
++
++for dir in $source_dirs; do
++	pushd "$dir" > /dev/null
++	for file in *.c; do
++		find ./ -name "*${file/\.c/.gcda}" -exec gcov {} \; > /dev/null
++	done
++	find ./ -name "*.gcov" \! -path "*/`basename "$target_dir"`/*" -exec mv {} "$target_dir" \;
++	popd > /dev/null
++done
++
++echo "========== coverage report ========" > "$summary_file"
++for file in "$target_dir"/*.gcov; do
++	total=`grep -v " -:" "$file" | wc -l`
++	missing=`grep "#####" "$file" | wc -l`
++	hit=$((total - missing));
++	percent=$((($hit * 100)/$total))
++	fname=`basename "$file"`
++	printf "%-32s total lines: %4s not tested: %4s (%3s%%)\n" "$fname" "$total" "$missing" "$percent">> "$summary_file"
++done
++echo "========== =============== ========" >> "$summary_file"
+diff -Naur third-party-libevdev-bak/test/test-common-uinput.c third-party-new/test/test-common-uinput.c
+--- third-party-libevdev-bak/test/test-common-uinput.c	1970-01-01 08:00:00.000000000 +0800
++++ third-party-new/test/test-common-uinput.c	2022-03-25 12:33:26.000000000 +0800
+@@ -0,0 +1,282 @@
++// SPDX-License-Identifier: MIT
++/*
++ * Copyright © 2013 Red Hat, Inc.
++ */
++
++#include "config.h"
++#include 
++#include 
++#include 
++#include 
++#include 
++#include 
++#include 
++#include 
++
++#include 
++#include 
++#include 
++#include 
++
++#include "test-common-uinput.h"
++
++#define SYS_INPUT_DIR "/sys/class/input"
++#define DEV_INPUT_DIR "/dev/input/"
++
++struct uinput_device
++{
++	struct libevdev *d; /* lazy, it has all the accessors */
++	struct libevdev_uinput *uidev;
++	int dev_fd; /* open fd to the devnode */
++	int uinput_fd;
++};
++
++struct uinput_device*
++uinput_device_new(const char *name)
++{
++	struct uinput_device *dev;
++
++	dev = calloc(1, sizeof(*dev));
++	if (!dev)
++		return NULL;
++
++	dev->d = libevdev_new();
++	dev->dev_fd = -1;
++	dev->uinput_fd = -1;
++
++	if (name)
++		libevdev_set_name(dev->d, name);
++
++	return dev;
++}
++
++int
++uinput_device_new_with_events_v(struct uinput_device **d, const char *name, const struct input_id *id, va_list args)
++{
++	int rc;
++	struct uinput_device *dev;
++
++	dev = uinput_device_new(name);
++	if (!dev)
++		return -ENOMEM;
++	if (id != DEFAULT_IDS)
++		uinput_device_set_ids(dev, id);
++
++	rc = uinput_device_set_event_bits_v(dev, args);
++
++	if (rc == 0)
++		rc = uinput_device_create(dev);
++
++	if (rc != 0) {
++		uinput_device_free(dev);
++		dev = NULL;
++	} else
++		*d = dev;
++
++	return rc;
++}
++
++int
++uinput_device_new_with_events(struct uinput_device **d, const char *name, const struct input_id *id, ...)
++{
++	int rc;
++	va_list args;
++
++	va_start(args, id);
++	rc = uinput_device_new_with_events_v(d, name, id, args);
++	va_end(args);
++
++	return rc;
++}
++
++void
++uinput_device_free(struct uinput_device *dev)
++{
++	if (!dev)
++		return;
++
++	if (dev->uinput_fd != -1) {
++		(void)ioctl(dev->uinput_fd, UI_DEV_DESTROY, NULL);
++		close(dev->uinput_fd);
++	}
++	if (dev->dev_fd != -1)
++		close(dev->dev_fd);
++	libevdev_free(dev->d);
++	libevdev_uinput_destroy(dev->uidev);
++	free(dev);
++}
++
++int
++uinput_device_get_fd(const struct uinput_device *dev)
++{
++	return dev->dev_fd;
++}
++
++const char*
++uinput_device_get_devnode(const struct uinput_device *dev)
++{
++	return libevdev_uinput_get_devnode(dev->uidev);
++}
++
++int
++uinput_device_create(struct uinput_device* d)
++{
++	int rc;
++	int fd;
++	const char *devnode;
++
++	fd = open("/dev/uinput", O_RDWR);
++	if (fd < 0)
++		goto error;
++
++	d->uinput_fd = fd;
++
++	rc = libevdev_uinput_create_from_device(d->d, fd, &d->uidev);
++	if (rc != 0)
++		goto error;
++
++	devnode = libevdev_uinput_get_devnode(d->uidev);
++	if (devnode == NULL)
++		goto error;
++
++	d->dev_fd = open(devnode, O_RDWR);
++	if (d->dev_fd == -1)
++		goto error;
++
++	/* write abs resolution now */
++	if (libevdev_has_event_type(d->d, EV_ABS)) {
++		int  code;
++		for (code = 0; code < ABS_CNT; code++) {
++			const struct input_absinfo *abs;
++
++			/* can't change slots */
++			if (code == ABS_MT_SLOT)
++				continue;
++
++			abs = libevdev_get_abs_info(d->d, code);
++			if (!abs)
++				continue;
++
++			rc = ioctl(d->dev_fd, EVIOCSABS(code), abs);
++			if (rc < 0) {
++				printf("error %s for code %d\n", strerror(-rc), code);
++				goto error;
++			}
++		}
++	}
++
++	return 0;
++
++error:
++	if (d->dev_fd != -1)
++		close(d->dev_fd);
++	if (d->uinput_fd != -1)
++		close(d->uinput_fd);
++	return -errno;
++
++}
++
++int uinput_device_set_name(struct uinput_device *dev, const char *name)
++{
++	libevdev_set_name(dev->d, name);
++	return 0;
++}
++
++int uinput_device_set_ids(struct uinput_device *dev, const struct input_id *ids)
++{
++	libevdev_set_id_product(dev->d, ids->product);
++	libevdev_set_id_vendor(dev->d, ids->vendor);
++	libevdev_set_id_bustype(dev->d, ids->bustype);
++	libevdev_set_id_version(dev->d, ids->version);
++	return 0;
++}
++
++int
++uinput_device_set_bit(struct uinput_device* dev, unsigned int bit)
++{
++	return libevdev_enable_event_type(dev->d, bit);
++}
++
++int
++uinput_device_set_prop(struct uinput_device *dev, unsigned int prop)
++{
++	return libevdev_enable_property(dev->d, prop);
++}
++
++int
++uinput_device_set_event_bit(struct uinput_device* dev, unsigned int type, unsigned int code)
++{
++	return libevdev_enable_event_code(dev->d, type, code, NULL);
++}
++
++int
++uinput_device_set_event_bits_v(struct uinput_device *dev, va_list args)
++{
++	int type, code;
++	int rc = 0;
++
++	do {
++		type = va_arg(args, int);
++		if (type == -1)
++			break;
++		code = va_arg(args, int);
++		if (code == -1)
++			break;
++		rc = libevdev_enable_event_code(dev->d, type, code, NULL);
++	} while (rc == 0);
++
++	return rc;
++}
++
++int
++uinput_device_set_event_bits(struct uinput_device *dev, ...)
++{
++	int rc;
++	va_list args;
++	va_start(args, dev);
++	rc = uinput_device_set_event_bits_v(dev, args);
++	va_end(args);
++
++	return rc;
++}
++
++int
++uinput_device_set_abs_bit(struct uinput_device* dev, unsigned int code, const struct input_absinfo *absinfo)
++{
++	return libevdev_enable_event_code(dev->d, EV_ABS, code, absinfo);
++}
++
++int
++uinput_device_event(const struct uinput_device *dev, unsigned int type, unsigned int code, int value)
++{
++	return libevdev_uinput_write_event(dev->uidev, type, code, value);
++}
++
++int uinput_device_event_multiple_v(const struct uinput_device* dev, va_list args)
++{
++	int type, code, value;
++	int rc = 0;
++
++	do {
++		type = va_arg(args, int);
++		if (type == -1)
++			break;
++		code = va_arg(args, int);
++		if (code == -1)
++			break;
++		value = va_arg(args, int);
++		rc = uinput_device_event(dev, type, code, value);
++	} while (rc == 0);
++
++	return rc;
++}
++
++int uinput_device_event_multiple(const struct uinput_device* dev, ...)
++{
++	int rc;
++	va_list args;
++	va_start(args, dev);
++	rc = uinput_device_event_multiple_v(dev, args);
++	va_end(args);
++	return rc;
++}
+diff -Naur third-party-libevdev-bak/test/test-common-uinput.h third-party-new/test/test-common-uinput.h
+--- third-party-libevdev-bak/test/test-common-uinput.h	1970-01-01 08:00:00.000000000 +0800
++++ third-party-new/test/test-common-uinput.h	2022-03-25 12:33:26.000000000 +0800
+@@ -0,0 +1,31 @@
++// SPDX-License-Identifier: MIT
++/*
++ * Copyright © 2013 Red Hat, Inc.
++ */
++
++#include "config.h"
++#include 
++
++#define DEFAULT_IDS NULL
++
++struct uinput_device* uinput_device_new(const char *name);
++int uinput_device_new_with_events(struct uinput_device **dev, const char *name, const struct input_id *ids, ...);
++int uinput_device_new_with_events_v(struct uinput_device **dev, const char *name, const struct input_id *ids, va_list args);
++void uinput_device_free(struct uinput_device *dev);
++
++int uinput_device_create(struct uinput_device* dev);
++int uinput_device_set_name(struct uinput_device* dev, const char *name);
++int uinput_device_set_ids(struct uinput_device* dev, const struct input_id *ids);
++int uinput_device_set_bit(struct uinput_device* dev, unsigned int bit);
++int uinput_device_set_prop(struct uinput_device *dev, unsigned int prop);
++int uinput_device_set_event_bit(struct uinput_device* dev, unsigned int type, unsigned int code);
++int uinput_device_set_event_bits(struct uinput_device* dev, ...);
++int uinput_device_set_event_bits_v(struct uinput_device* dev, va_list args);
++int uinput_device_set_abs_bit(struct uinput_device* dev, unsigned int code, const struct input_absinfo *absinfo);
++int uinput_device_event(const struct uinput_device* dev, unsigned int type, unsigned int code, int value);
++int uinput_device_event_multiple(const struct uinput_device* dev, ...);
++int uinput_device_event_multiple_v(const struct uinput_device* dev, va_list args);
++int uinput_device_get_fd(const struct uinput_device *dev);
++const char* uinput_device_get_devnode(const struct uinput_device *dev);
++
++char *uinput_devnode_from_syspath(const char *syspath);
+diff -Naur third-party-libevdev-bak/test/test-common.c third-party-new/test/test-common.c
+--- third-party-libevdev-bak/test/test-common.c	1970-01-01 08:00:00.000000000 +0800
++++ third-party-new/test/test-common.c	2022-03-25 12:33:26.000000000 +0800
+@@ -0,0 +1,102 @@
++// SPDX-License-Identifier: MIT
++/*
++ * Copyright © 2013 Red Hat, Inc.
++ */
++
++#include "config.h"
++#include 
++#include 
++#include 
++#include 
++
++#include "test-common.h"
++
++void test_logfunc_abort_on_error(enum libevdev_log_priority priority,
++				 void *data,
++				 const char *file, int line,
++				 const char *func,
++				 const char *format, va_list args)
++{
++	vprintf(format, args);
++	ck_abort();
++}
++
++void test_logfunc_ignore_error(enum libevdev_log_priority priority,
++			       void *data,
++			       const char *file, int line,
++			       const char *func,
++			       const char *format, va_list args)
++{
++}
++
++void test_create_device(struct uinput_device **uidev_return,
++			struct libevdev **dev_return,
++			...)
++{
++	int rc, fd;
++	struct uinput_device *uidev;
++	struct libevdev *dev;
++	va_list args;
++
++	va_start(args, dev_return);
++
++	rc = uinput_device_new_with_events_v(&uidev, TEST_DEVICE_NAME, DEFAULT_IDS, args);
++	va_end(args);
++
++	ck_assert_msg(rc == 0, "Failed to create uinput device: %s", strerror(-rc));
++
++	fd = uinput_device_get_fd(uidev);
++
++	rc = libevdev_new_from_fd(fd, &dev);
++	ck_assert_msg(rc == 0, "Failed to init device device: %s", strerror(-rc));
++	rc = fcntl(fd, F_SETFL, O_NONBLOCK);
++	ck_assert_msg(rc == 0, "fcntl failed: %s", strerror(errno));
++
++	*uidev_return = uidev;
++	*dev_return = dev;
++}
++
++void test_create_abs_device(struct uinput_device **uidev_return,
++			    struct libevdev **dev_return,
++			    int nabs,
++			    const struct input_absinfo *abs,
++			    ...)
++{
++	int rc, fd;
++	struct uinput_device *uidev;
++	struct libevdev *dev;
++	va_list args;
++
++	uidev = uinput_device_new(TEST_DEVICE_NAME);
++	ck_assert(uidev != NULL);
++
++	va_start(args, abs);
++	rc = uinput_device_set_event_bits_v(uidev, args);
++	ck_assert_msg(rc == 0, "Failed to set uinput bits");
++	va_end(args);
++
++	while (--nabs >= 0) {
++		int code;
++		struct input_absinfo a;
++
++		code = abs[nabs].value;
++		a = abs[nabs];
++		a.value = 0;
++
++		rc = uinput_device_set_abs_bit(uidev, code, &a);
++		ck_assert_msg(rc == 0, "for abs field %d\n", nabs);
++	}
++
++	rc = uinput_device_create(uidev);
++	ck_assert_msg(rc == 0, "Failed to create uinput device: %s", strerror(-rc));
++
++	fd = uinput_device_get_fd(uidev);
++
++	rc = libevdev_new_from_fd(fd, &dev);
++	ck_assert_msg(rc == 0, "Failed to init device device: %s", strerror(-rc));
++	rc = fcntl(fd, F_SETFL, O_NONBLOCK);
++	ck_assert_msg(rc == 0, "fcntl failed: %s", strerror(errno));
++
++	*uidev_return = uidev;
++	*dev_return = dev;
++}
+diff -Naur third-party-libevdev-bak/test/test-common.h third-party-new/test/test-common.h
+--- third-party-libevdev-bak/test/test-common.h	1970-01-01 08:00:00.000000000 +0800
++++ third-party-new/test/test-common.h	2022-03-25 12:33:26.000000000 +0800
+@@ -0,0 +1,93 @@
++// SPDX-License-Identifier: MIT
++/*
++ * Copyright © 2013 Red Hat, Inc.
++ */
++
++#include "config.h"
++#include 
++#include 
++#include 
++
++#include 
++
++#ifndef _TEST_COMMON_H_
++#define _TEST_COMMON_H_
++
++struct libevdev_test {
++	const char *name;
++	Suite* (*setup)(void);
++	bool needs_root_privileges;
++} __attribute__((aligned(16)));
++
++#define _TEST_SUITE(name, root_privs) \
++	static Suite* (name##_setup)(void); \
++	static const struct libevdev_test _test \
++	__attribute__((used)) \
++	__attribute__((section ("test_section"))) = { \
++		#name, name##_setup, root_privs \
++	}; \
++	static Suite* (name##_setup)(void)
++
++#define TEST_SUITE(name) \
++	_TEST_SUITE(name, false)
++
++#define TEST_SUITE_ROOT_PRIVILEGES(name) \
++	_TEST_SUITE(name, true)
++
++#define TEST_DEVICE_NAME "libevdev test device"
++
++#define add_test(suite, func) do { \
++	TCase *tc = tcase_create(#func); \
++	tcase_add_test(tc, func); \
++	suite_add_tcase(suite, tc); \
++} while(0)
++
++#include "test-common-uinput.h"
++
++#define assert_event(e_, t, c, v) \
++do { \
++	const struct input_event *e = (e_); \
++	ck_assert_int_eq(e->type, (t)); \
++	ck_assert_int_eq(e->code, (c)); \
++	ck_assert_int_eq(e->value, (v)); \
++} while(0)
++
++void test_create_device(struct uinput_device **uidev,
++			struct libevdev **dev,
++			...);
++void test_create_abs_device(struct uinput_device **uidev,
++			    struct libevdev **dev,
++			    int nabs,
++			    const struct input_absinfo *abs,
++			    ...);
++
++void test_logfunc_abort_on_error(enum libevdev_log_priority priority,
++				 void *data,
++				 const char *file, int line,
++				 const char *func,
++				 const char *format, va_list args);
++void test_logfunc_ignore_error(enum libevdev_log_priority priority,
++			       void *data,
++			       const char *file, int line,
++			       const char *func,
++			       const char *format, va_list args);
++
++static inline void
++print_event(const struct input_event *ev)
++{
++	if (ev->type == EV_SYN)
++		printf("Event: time %ld.%06ld, ++++++++++++++++++++ %s +++++++++++++++\n",
++			ev->input_event_sec,
++			ev->input_event_usec,
++			libevdev_event_type_get_name(ev->type));
++	else
++		printf("Event: time %ld.%06ld, type %d (%s), code %d (%s), value %d\n",
++			ev->input_event_sec,
++			ev->input_event_usec,
++			ev->type,
++			libevdev_event_type_get_name(ev->type),
++			ev->code,
++			libevdev_event_code_get_name(ev->type, ev->code),
++			ev->value);
++}
++#endif /* _TEST_COMMON_H_ */
+diff -Naur third-party-libevdev-bak/test/test-compile-pedantic.c third-party-new/test/test-compile-pedantic.c
+--- third-party-libevdev-bak/test/test-compile-pedantic.c	1970-01-01 08:00:00.000000000 +0800
++++ third-party-new/test/test-compile-pedantic.c	2022-03-25 12:33:26.000000000 +0800
+@@ -0,0 +1,6 @@
++#include 
++#include 
++
++int main(void) {
++	return 0;
++}
+diff -Naur third-party-libevdev-bak/test/test-context.c third-party-new/test/test-context.c
+--- third-party-libevdev-bak/test/test-context.c	1970-01-01 08:00:00.000000000 +0800
++++ third-party-new/test/test-context.c	2022-03-25 12:33:26.000000000 +0800
+@@ -0,0 +1,161 @@
++// SPDX-License-Identifier: MIT
++/*
++ * Copyright © 2019 Red Hat, Inc.
++ */
++
++#include "config.h"
++#include "test-common.h"
++
++START_TEST(test_info)
++{
++	struct libevdev *d = libevdev_new();
++
++	libevdev_set_name(d, "some name");
++	ck_assert_str_eq(libevdev_get_name(d), "some name");
++	libevdev_set_phys(d, "physical");
++	ck_assert_str_eq(libevdev_get_phys(d), "physical");
++	libevdev_set_uniq(d, "very unique");
++	ck_assert_str_eq(libevdev_get_uniq(d), "very unique");
++
++	libevdev_set_id_bustype(d, 1);
++	libevdev_set_id_vendor(d, 2);
++	libevdev_set_id_product(d, 3);
++	libevdev_set_id_version(d, 4);
++	ck_assert_int_eq(libevdev_get_id_bustype(d), 1);
++	ck_assert_int_eq(libevdev_get_id_vendor(d), 2);
++	ck_assert_int_eq(libevdev_get_id_product(d), 3);
++	ck_assert_int_eq(libevdev_get_id_version(d), 4);
++
++	libevdev_free(d);
++}
++END_TEST
++
++START_TEST(test_properties)
++{
++	for (unsigned prop = 0; prop < INPUT_PROP_CNT; prop++) {
++		struct libevdev *d = libevdev_new();
++
++		ck_assert(!libevdev_has_property(d, prop));
++		libevdev_enable_property(d, prop);
++		ck_assert(libevdev_has_property(d, prop));
++		libevdev_free(d);
++	}
++}
++END_TEST
++
++START_TEST(test_bits)
++{
++	for (unsigned type = 1; type < EV_CNT; type++) {
++		unsigned max = libevdev_event_type_get_max(type);
++
++		if((int)max == -1)
++			continue;
++
++		for (unsigned code = 0; code <= max; code++) {
++			struct libevdev *d = libevdev_new();
++			const struct input_absinfo abs = {
++				.minimum = 10,
++				.maximum = 20,
++				.fuzz = 30,
++				.flat = 40,
++				.resolution = 50,
++			};
++			const void *data = NULL;
++
++			if (type == EV_ABS || type == EV_REP)
++				data = &abs;
++
++			ck_assert(!libevdev_has_event_code(d, type, code));
++			libevdev_enable_event_code(d, type, code, data);
++			ck_assert(libevdev_has_event_code(d, type, code));
++			libevdev_free(d);
++		}
++	}
++}
++END_TEST
++
++START_TEST(test_mt_slots_enable_disable)
++{
++	struct libevdev *d = libevdev_new();
++	struct input_absinfo abs = {0};
++
++	abs.maximum = 5;
++	libevdev_enable_event_code(d, EV_ABS, ABS_MT_SLOT, &abs);
++	ck_assert(libevdev_has_event_code(d, EV_ABS, ABS_MT_SLOT));
++	ck_assert_int_eq(libevdev_get_num_slots(d), 6);
++
++	libevdev_disable_event_code(d, EV_ABS, ABS_MT_SLOT);
++	ck_assert(!libevdev_has_event_code(d, EV_ABS, ABS_MT_SLOT));
++	ck_assert_int_eq(libevdev_get_num_slots(d), -1);
++
++	abs.maximum = 2;
++	libevdev_enable_event_code(d, EV_ABS, ABS_MT_SLOT, &abs);
++	ck_assert(libevdev_has_event_code(d, EV_ABS, ABS_MT_SLOT));
++	ck_assert_int_eq(libevdev_get_num_slots(d), 3);
++
++	libevdev_free(d);
++}
++END_TEST
++
++START_TEST(test_mt_slots_increase_decrease)
++{
++	struct libevdev *d = libevdev_new();
++	struct input_absinfo abs = {0};
++
++	abs.maximum = 5;
++	libevdev_enable_event_code(d, EV_ABS, ABS_MT_SLOT, &abs);
++	ck_assert(libevdev_has_event_code(d, EV_ABS, ABS_MT_SLOT));
++	ck_assert_int_eq(libevdev_get_num_slots(d), 6);
++
++	abs.maximum = 2;
++	libevdev_enable_event_code(d, EV_ABS, ABS_MT_SLOT, &abs);
++	ck_assert(libevdev_has_event_code(d, EV_ABS, ABS_MT_SLOT));
++	ck_assert_int_eq(libevdev_get_num_slots(d), 3);
++
++	abs.maximum = 6;
++	libevdev_enable_event_code(d, EV_ABS, ABS_MT_SLOT, &abs);
++	ck_assert(libevdev_has_event_code(d, EV_ABS, ABS_MT_SLOT));
++	ck_assert_int_eq(libevdev_get_num_slots(d), 7);
++
++	abs.maximum = 10;
++	libevdev_enable_event_code(d, EV_ABS, ABS_MT_SLOT, &abs);
++	ck_assert(libevdev_has_event_code(d, EV_ABS, ABS_MT_SLOT));
++	ck_assert_int_eq(libevdev_get_num_slots(d), 11);
++
++	libevdev_free(d);
++}
++END_TEST
++
++START_TEST(test_mt_tracking_id)
++{
++	struct libevdev *d = libevdev_new();
++	struct input_absinfo abs = { .maximum = 5 };
++
++	libevdev_enable_event_code(d, EV_ABS, ABS_MT_SLOT, &abs);
++
++	/* Not yet enabled, so 0. This is technically undefined */
++	for (int slot = 0; slot < 5; slot++)
++		ck_assert_int_eq(libevdev_get_slot_value(d, 0, ABS_MT_TRACKING_ID), 0);
++
++	libevdev_enable_event_code(d, EV_ABS, ABS_MT_TRACKING_ID, &abs);
++
++	for (int slot = 0; slot < 5; slot++)
++		ck_assert_int_eq(libevdev_get_slot_value(d, 0, ABS_MT_TRACKING_ID), -1);
++
++	libevdev_free(d);
++}
++END_TEST
++
++TEST_SUITE(event_name_suite)
++{
++	Suite *s = suite_create("Context manipulation");
++
++	add_test(s, test_info);
++	add_test(s, test_properties);
++	add_test(s, test_bits);
++	add_test(s, test_mt_slots_enable_disable);
++	add_test(s, test_mt_slots_increase_decrease);
++	add_test(s, test_mt_tracking_id);
++
++	return s;
++}
+diff -Naur third-party-libevdev-bak/test/test-event-codes.c third-party-new/test/test-event-codes.c
+--- third-party-libevdev-bak/test/test-event-codes.c	1970-01-01 08:00:00.000000000 +0800
++++ third-party-new/test/test-event-codes.c	2022-03-25 12:33:26.000000000 +0800
+@@ -0,0 +1,268 @@
++// SPDX-License-Identifier: MIT
++/*
++ * Copyright © 2013 David Herrmann 
++ */
++
++#include "config.h"
++#include "test-common.h"
++
++START_TEST(test_type_names)
++{
++	ck_assert_int_eq(libevdev_event_type_from_name("EV_SYN"), EV_SYN);
++	ck_assert_int_eq(libevdev_event_type_from_name("EV_KEY"), EV_KEY);
++	ck_assert_int_eq(libevdev_event_type_from_name("EV_REL"), EV_REL);
++	ck_assert_int_eq(libevdev_event_type_from_name("EV_ABS"), EV_ABS);
++	ck_assert_int_eq(libevdev_event_type_from_name("EV_MSC"), EV_MSC);
++	ck_assert_int_eq(libevdev_event_type_from_name("EV_SND"), EV_SND);
++	ck_assert_int_eq(libevdev_event_type_from_name("EV_SW"), EV_SW);
++	ck_assert_int_eq(libevdev_event_type_from_name("EV_LED"), EV_LED);
++	ck_assert_int_eq(libevdev_event_type_from_name("EV_REP"), EV_REP);
++	ck_assert_int_eq(libevdev_event_type_from_name("EV_FF"), EV_FF);
++	ck_assert_int_eq(libevdev_event_type_from_name("EV_FF_STATUS"), EV_FF_STATUS);
++	ck_assert_int_eq(libevdev_event_type_from_name("EV_MAX"), EV_MAX);
++
++	ck_assert_int_eq(libevdev_event_type_from_name_n("EV_SYNTAX", 6), EV_SYN);
++	ck_assert_int_eq(libevdev_event_type_from_name_n("EV_REPTILE", 6), EV_REP);
++}
++END_TEST
++
++START_TEST(test_type_names_invalid)
++{
++	ck_assert_int_eq(libevdev_event_type_from_name("EV_Syn"), -1);
++	ck_assert_int_eq(libevdev_event_type_from_name("ev_SYN"), -1);
++	ck_assert_int_eq(libevdev_event_type_from_name("SYN"), -1);
++	ck_assert_int_eq(libevdev_event_type_from_name("EV_SYNTAX"), -1);
++
++	ck_assert_int_eq(libevdev_event_type_from_name_n("EV_SYN", 5), -1);
++	ck_assert_int_eq(libevdev_event_type_from_name_n("EV_REPTILE", 7), -1);
++}
++END_TEST
++
++START_TEST(test_type_name_lookup)
++{
++	ck_assert_int_eq(libevdev_event_type_from_code_name("SYN_REPORT"), EV_SYN);
++	ck_assert_int_eq(libevdev_event_type_from_code_name("KEY_A"), EV_KEY);
++	ck_assert_int_eq(libevdev_event_type_from_code_name("REL_Z"), EV_REL);
++	ck_assert_int_eq(libevdev_event_type_from_code_name("ABS_Z"), EV_ABS);
++	ck_assert_int_eq(libevdev_event_type_from_code_name("MSC_SERIAL"), EV_MSC);
++	ck_assert_int_eq(libevdev_event_type_from_code_name("SND_TONE"), EV_SND);
++	ck_assert_int_eq(libevdev_event_type_from_code_name("SW_TABLET_MODE"), EV_SW);
++	ck_assert_int_eq(libevdev_event_type_from_code_name("LED_CHARGING"), EV_LED);
++	ck_assert_int_eq(libevdev_event_type_from_code_name("REP_PERIOD"), EV_REP);
++	ck_assert_int_eq(libevdev_event_type_from_code_name("FF_SPRING"), EV_FF);
++	ck_assert_int_eq(libevdev_event_type_from_code_name("FF_STATUS_STOPPED"), EV_FF_STATUS);
++
++	ck_assert_int_eq(libevdev_event_type_from_code_name_n("KEY_1zzzzz", 5), EV_KEY);
++	ck_assert_int_eq(libevdev_event_type_from_code_name_n("ABS_Zooom", 5), EV_ABS);
++
++	ck_assert_int_eq(libevdev_event_type_from_code_name("KEY_MAX"), EV_KEY);
++	ck_assert_int_eq(libevdev_event_type_from_code_name("REL_MAX"), EV_REL);
++	ck_assert_int_eq(libevdev_event_type_from_code_name("ABS_MAX"), EV_ABS);
++}
++END_TEST
++
++START_TEST(test_type_name_lookup_invalid)
++{
++	ck_assert_int_eq(libevdev_event_type_from_name("SYN_REPORTED"),  -1);
++	ck_assert_int_eq(libevdev_event_type_from_name("syn_blah"), -1);
++	ck_assert_int_eq(libevdev_event_type_from_name("SYN_"), -1);
++	ck_assert_int_eq(libevdev_event_type_from_name("KEY_BANANA"), -1);
++
++	ck_assert_int_eq(libevdev_event_type_from_name_n("KEY_BA", 6), -1);
++	ck_assert_int_eq(libevdev_event_type_from_name_n("KEY_BLAH", 8), -1);
++}
++END_TEST
++
++START_TEST(test_code_names)
++{
++	ck_assert_int_eq(libevdev_event_code_from_name(EV_SYN, "SYN_REPORT"), SYN_REPORT);
++	ck_assert_int_eq(libevdev_event_code_from_name(EV_ABS, "ABS_X"), ABS_X);
++	ck_assert_int_eq(libevdev_event_code_from_name(EV_KEY, "BTN_A"), BTN_A);
++	ck_assert_int_eq(libevdev_event_code_from_name(EV_KEY, "KEY_A"), KEY_A);
++	ck_assert_int_eq(libevdev_event_code_from_name(EV_REL, "REL_X"), REL_X);
++	ck_assert_int_eq(libevdev_event_code_from_name(EV_MSC, "MSC_RAW"), MSC_RAW);
++	ck_assert_int_eq(libevdev_event_code_from_name(EV_LED, "LED_KANA"), LED_KANA);
++	ck_assert_int_eq(libevdev_event_code_from_name(EV_SND, "SND_BELL"), SND_BELL);
++	ck_assert_int_eq(libevdev_event_code_from_name(EV_REP, "REP_DELAY"), REP_DELAY);
++	ck_assert_int_eq(libevdev_event_code_from_name(EV_SYN, "SYN_DROPPED"), SYN_DROPPED);
++	ck_assert_int_eq(libevdev_event_code_from_name(EV_KEY, "KEY_RESERVED"), KEY_RESERVED);
++	ck_assert_int_eq(libevdev_event_code_from_name(EV_KEY, "BTN_0"), BTN_0);
++	ck_assert_int_eq(libevdev_event_code_from_name(EV_KEY, "KEY_0"), KEY_0);
++	ck_assert_int_eq(libevdev_event_code_from_name(EV_FF, "FF_GAIN"), FF_GAIN);
++	ck_assert_int_eq(libevdev_event_code_from_name(EV_FF_STATUS, "FF_STATUS_MAX"), FF_STATUS_MAX);
++	ck_assert_int_eq(libevdev_event_code_from_name(EV_SW, "SW_PEN_INSERTED"), SW_PEN_INSERTED);
++
++	ck_assert_int_eq(libevdev_event_code_from_name_n(EV_ABS, "ABS_YXZ", 5), ABS_Y);
++}
++END_TEST
++
++START_TEST(test_code_name_lookup)
++{
++	/* Same as test_code_names() but without the type */
++	ck_assert_int_eq(libevdev_event_code_from_code_name("SYN_REPORT"), SYN_REPORT);
++	ck_assert_int_eq(libevdev_event_code_from_code_name("ABS_X"), ABS_X);
++	ck_assert_int_eq(libevdev_event_code_from_code_name("BTN_A"), BTN_A);
++	ck_assert_int_eq(libevdev_event_code_from_code_name("KEY_A"), KEY_A);
++	ck_assert_int_eq(libevdev_event_code_from_code_name("REL_X"), REL_X);
++	ck_assert_int_eq(libevdev_event_code_from_code_name("MSC_RAW"), MSC_RAW);
++	ck_assert_int_eq(libevdev_event_code_from_code_name("LED_KANA"), LED_KANA);
++	ck_assert_int_eq(libevdev_event_code_from_code_name("SND_BELL"), SND_BELL);
++	ck_assert_int_eq(libevdev_event_code_from_code_name("REP_DELAY"), REP_DELAY);
++	ck_assert_int_eq(libevdev_event_code_from_code_name("SYN_DROPPED"), SYN_DROPPED);
++	ck_assert_int_eq(libevdev_event_code_from_code_name("KEY_RESERVED"), KEY_RESERVED);
++	ck_assert_int_eq(libevdev_event_code_from_code_name("BTN_0"), BTN_0);
++	ck_assert_int_eq(libevdev_event_code_from_code_name("KEY_0"), KEY_0);
++	ck_assert_int_eq(libevdev_event_code_from_code_name("FF_GAIN"), FF_GAIN);
++	ck_assert_int_eq(libevdev_event_code_from_code_name("FF_STATUS_MAX"), FF_STATUS_MAX);
++	ck_assert_int_eq(libevdev_event_code_from_code_name("SW_PEN_INSERTED"), SW_PEN_INSERTED);
++
++	ck_assert_int_eq(libevdev_event_code_from_code_name_n("ABS_YXZ", 5), ABS_Y);
++}
++END_TEST
++
++START_TEST(test_code_names_invalid)
++{
++	ck_assert_int_eq(libevdev_event_code_from_name(EV_MAX, "MAX_FAKE"), -1);
++	ck_assert_int_eq(libevdev_event_code_from_name(EV_CNT, "CNT_FAKE"), -1);
++	ck_assert_int_eq(libevdev_event_code_from_name(EV_PWR, "PWR_SOMETHING"), -1);
++	ck_assert_int_eq(libevdev_event_code_from_name(EV_ABS, "EV_ABS"), -1);
++	ck_assert_int_eq(libevdev_event_code_from_name(EV_ABS, "ABS_XY"), -1);
++	ck_assert_int_eq(libevdev_event_code_from_name(EV_KEY, "BTN_GAMEPAD"), -1);
++	ck_assert_int_eq(libevdev_event_code_from_name(EV_KEY, "BUS_PCI"), -1);
++	ck_assert_int_eq(libevdev_event_code_from_name(EV_FF_STATUS, "FF_STATUS"), -1);
++	ck_assert_int_eq(libevdev_event_code_from_name(EV_FF_STATUS, "FF_STATUS_"), -1);
++	ck_assert_int_eq(libevdev_event_code_from_name(EV_FF, "FF_STATUS"), -1);
++	ck_assert_int_eq(libevdev_event_code_from_name(EV_FF, "FF_STATUS_"), -1);
++	ck_assert_int_eq(libevdev_event_code_from_name(EV_KEY, "ID_BUS"), -1);
++	ck_assert_int_eq(libevdev_event_code_from_name(EV_SND, "SND_CNT"), -1);
++	ck_assert_int_eq(libevdev_event_code_from_name(EV_SW, "SW_CNT"), -1);
++
++	ck_assert_int_eq(libevdev_event_code_from_name_n(EV_ABS, "ABS_X", 4), -1);
++}
++END_TEST
++
++START_TEST(test_code_name_lookup_invalid)
++{
++	/* Same as test_code_names_invalid() but without the type */
++	ck_assert_int_eq(libevdev_event_code_from_code_name("MAX_FAKE"), -1);
++	ck_assert_int_eq(libevdev_event_code_from_code_name("CNT_FAKE"), -1);
++	ck_assert_int_eq(libevdev_event_code_from_code_name("PWR_SOMETHING"), -1);
++	ck_assert_int_eq(libevdev_event_code_from_code_name("EV_ABS"), -1);
++	ck_assert_int_eq(libevdev_event_code_from_code_name("ABS_XY"), -1);
++	ck_assert_int_eq(libevdev_event_code_from_code_name("BTN_GAMEPAD"), -1);
++	ck_assert_int_eq(libevdev_event_code_from_code_name("BUS_PCI"), -1);
++	ck_assert_int_eq(libevdev_event_code_from_code_name("FF_STATUS"), -1);
++	ck_assert_int_eq(libevdev_event_code_from_code_name("FF_STATUS_"), -1);
++	ck_assert_int_eq(libevdev_event_code_from_code_name("FF_STATUS"), -1);
++	ck_assert_int_eq(libevdev_event_code_from_code_name("FF_STATUS_"), -1);
++	ck_assert_int_eq(libevdev_event_code_from_code_name("ID_BUS"), -1);
++	ck_assert_int_eq(libevdev_event_code_from_code_name("SND_CNT"), -1);
++	ck_assert_int_eq(libevdev_event_code_from_code_name("SW_CNT"), -1);
++
++	ck_assert_int_eq(libevdev_event_code_from_code_name_n("ABS_X", 4), -1);
++}
++END_TEST
++
++START_TEST(test_code_names_max)
++{
++	ck_assert_int_eq(libevdev_event_code_from_name(EV_SYN, "SYN_MAX"), SYN_MAX);
++	ck_assert_int_eq(libevdev_event_code_from_name(EV_KEY, "KEY_MAX"), KEY_MAX);
++	ck_assert_int_eq(libevdev_event_code_from_name(EV_REL, "REL_MAX"), REL_MAX);
++	ck_assert_int_eq(libevdev_event_code_from_name(EV_ABS, "ABS_MAX"), ABS_MAX);
++	ck_assert_int_eq(libevdev_event_code_from_name(EV_MSC, "MSC_MAX"), MSC_MAX);
++	ck_assert_int_eq(libevdev_event_code_from_name(EV_SW, "SW_MAX"), SW_MAX);
++	ck_assert_int_eq(libevdev_event_code_from_name(EV_LED, "LED_MAX"), LED_MAX);
++	ck_assert_int_eq(libevdev_event_code_from_name(EV_SND, "SND_MAX"), SND_MAX);
++	ck_assert_int_eq(libevdev_event_code_from_name(EV_REP, "REP_MAX"), REP_MAX);
++	ck_assert_int_eq(libevdev_event_code_from_name(EV_FF, "FF_MAX"), FF_MAX);
++
++	ck_assert_int_eq(libevdev_event_code_from_code_name("SYN_MAX"), SYN_MAX);
++	ck_assert_int_eq(libevdev_event_code_from_code_name("KEY_MAX"), KEY_MAX);
++	ck_assert_int_eq(libevdev_event_code_from_code_name("REL_MAX"), REL_MAX);
++	ck_assert_int_eq(libevdev_event_code_from_code_name("ABS_MAX"), ABS_MAX);
++	ck_assert_int_eq(libevdev_event_code_from_code_name("MSC_MAX"), MSC_MAX);
++	ck_assert_int_eq(libevdev_event_code_from_code_name("SW_MAX"), SW_MAX);
++	ck_assert_int_eq(libevdev_event_code_from_code_name("LED_MAX"), LED_MAX);
++	ck_assert_int_eq(libevdev_event_code_from_code_name("SND_MAX"), SND_MAX);
++	ck_assert_int_eq(libevdev_event_code_from_code_name("REP_MAX"), REP_MAX);
++	ck_assert_int_eq(libevdev_event_code_from_code_name("FF_MAX"), FF_MAX);
++}
++END_TEST
++
++START_TEST(test_value_names)
++{
++	ck_assert_int_eq(libevdev_event_value_from_name(EV_ABS, ABS_MT_TOOL_TYPE, "MT_TOOL_PALM"), MT_TOOL_PALM);
++	ck_assert_int_eq(libevdev_event_value_from_name(EV_ABS, ABS_MT_TOOL_TYPE, "MT_TOOL_FINGER"), MT_TOOL_FINGER);
++	ck_assert_int_eq(libevdev_event_value_from_name(EV_ABS, ABS_MT_TOOL_TYPE, "MT_TOOL_PEN"), MT_TOOL_PEN);
++	ck_assert_int_eq(libevdev_event_value_from_name(EV_ABS, ABS_MT_TOOL_TYPE, "MT_TOOL_MAX"), MT_TOOL_MAX);
++}
++END_TEST
++
++START_TEST(test_value_names_invalid)
++{
++	ck_assert_int_eq(libevdev_event_value_from_name(EV_SYN, REL_X, "MT_TOOL_PALM"), -1);
++	ck_assert_int_eq(libevdev_event_value_from_name(EV_REL, REL_X, "MT_TOOL_PALM"), -1);
++	ck_assert_int_eq(libevdev_event_value_from_name(EV_ABS, ABS_X, "MT_TOOL_PALM"), -1);
++	ck_assert_int_eq(libevdev_event_value_from_name(EV_ABS, ABS_MT_TOOL_TYPE, "MT_TOOL_"), -1);
++	ck_assert_int_eq(libevdev_event_value_from_name(EV_ABS, ABS_MT_TOOL_TYPE, "MT_TOOL_PALMA"), -1);
++	ck_assert_int_eq(libevdev_event_value_from_name(EV_ABS, ABS_MT_TOOL_TYPE, ""), -1);
++	ck_assert_int_eq(libevdev_event_value_from_name(EV_ABS, ABS_MT_TOOL_TYPE, "EV_ABS"), -1);
++	ck_assert_int_eq(libevdev_event_value_from_name(EV_ABS, ABS_MT_TOOL_TYPE, "ABS_X"), -1);
++}
++END_TEST
++
++START_TEST(test_properties)
++{
++	struct prop {
++		int val;
++		const char *name;
++	} lut[] = {
++		{ INPUT_PROP_DIRECT, "INPUT_PROP_DIRECT" },
++		{ INPUT_PROP_POINTER, "INPUT_PROP_POINTER" },
++		{ INPUT_PROP_MAX, "INPUT_PROP_MAX" },
++		{ -1, NULL}
++	};
++	struct prop *p = lut;
++	while (p->val != -1) {
++		ck_assert_int_eq(libevdev_property_from_name(p->name), p->val);
++		p++;
++	}
++}
++END_TEST
++
++START_TEST(test_properties_invalid)
++{
++	ck_assert_int_eq(libevdev_property_from_name("EV_ABS"), -1);
++	ck_assert_int_eq(libevdev_property_from_name("INPUT_PROP"), -1);
++	ck_assert_int_eq(libevdev_property_from_name("INPUT_PROP_"), -1);
++	ck_assert_int_eq(libevdev_property_from_name("INPUT_PROP_FOO"), -1);
++
++	ck_assert_int_eq(libevdev_property_from_name_n("INPUT_PROP_POINTER", 11), -1);
++	ck_assert_int_eq(libevdev_property_from_name_n("INPUT_PROP_POINTER",
++						strlen("INPUT_PROP_POINTER") - 1), -1);
++}
++END_TEST
++
++TEST_SUITE(event_code_suite)
++{
++	Suite *s = suite_create("Event codes");
++
++	add_test(s, test_type_names);
++	add_test(s, test_type_names_invalid);
++	add_test(s, test_type_name_lookup);
++	add_test(s, test_type_name_lookup_invalid);
++
++	add_test(s, test_code_names);
++	add_test(s, test_code_name_lookup);
++	add_test(s, test_code_names_invalid);
++	add_test(s, test_code_name_lookup_invalid);
++	add_test(s, test_code_names_max);
++
++	add_test(s, test_value_names);
++	add_test(s, test_value_names_invalid);
++
++	add_test(s, test_properties);
++	add_test(s, test_properties_invalid);
++
++	return s;
++}
+diff -Naur third-party-libevdev-bak/test/test-event-names.c third-party-new/test/test-event-names.c
+--- third-party-libevdev-bak/test/test-event-names.c	1970-01-01 08:00:00.000000000 +0800
++++ third-party-new/test/test-event-names.c	2022-03-25 12:33:26.000000000 +0800
+@@ -0,0 +1,314 @@
++// SPDX-License-Identifier: MIT
++/*
++ * Copyright © 2013 Red Hat, Inc.
++ */
++
++#include "config.h"
++#include "test-common.h"
++
++START_TEST(test_limits)
++{
++	ck_assert(libevdev_event_type_get_name(EV_MAX + 1) == NULL);
++	ck_assert(libevdev_event_code_get_name(EV_ABS, ABS_MAX + 1) == NULL);
++	ck_assert(libevdev_event_code_get_name(EV_REL, REL_MAX + 1) == NULL);
++	ck_assert(libevdev_event_code_get_name(EV_KEY, KEY_MAX + 1) == NULL);
++	ck_assert(libevdev_event_code_get_name(EV_LED, LED_MAX + 1) == NULL);
++	ck_assert(libevdev_event_code_get_name(EV_SW, SW_MAX + 1) == NULL);
++	ck_assert(libevdev_event_code_get_name(EV_MSC, MSC_MAX + 1) == NULL);
++	ck_assert(libevdev_event_code_get_name(EV_SND, SND_MAX + 1) == NULL);
++	ck_assert(libevdev_event_code_get_name(EV_REP, REP_MAX + 1) == NULL);
++	ck_assert(libevdev_event_code_get_name(EV_FF, FF_MAX + 1) == NULL);
++	ck_assert(libevdev_event_code_get_name(EV_MAX + 1, 0) == NULL);
++	ck_assert(libevdev_event_value_get_name(EV_ABS, ABS_MT_TOOL_TYPE, MT_TOOL_MAX + 1) == NULL);
++}
++END_TEST
++
++START_TEST(test_type_name)
++{
++	ck_assert_str_eq(libevdev_event_type_get_name(EV_SYN), "EV_SYN");
++	ck_assert_str_eq(libevdev_event_type_get_name(EV_REL), "EV_REL");
++	ck_assert_str_eq(libevdev_event_type_get_name(EV_ABS), "EV_ABS");
++	ck_assert_str_eq(libevdev_event_type_get_name(EV_MSC), "EV_MSC");
++	ck_assert_str_eq(libevdev_event_type_get_name(EV_SW),  "EV_SW");
++	ck_assert_str_eq(libevdev_event_type_get_name(EV_LED), "EV_LED");
++	ck_assert_str_eq(libevdev_event_type_get_name(EV_SND), "EV_SND");
++	ck_assert_str_eq(libevdev_event_type_get_name(EV_REP), "EV_REP");
++	ck_assert_str_eq(libevdev_event_type_get_name(EV_FF),  "EV_FF");
++	ck_assert_str_eq(libevdev_event_type_get_name(EV_PWR), "EV_PWR");
++	ck_assert_str_eq(libevdev_event_type_get_name(EV_FF_STATUS), "EV_FF_STATUS");
++	ck_assert_str_eq(libevdev_event_type_get_name(EV_MAX), "EV_MAX");
++}
++END_TEST
++
++START_TEST(test_code_abs_name)
++{
++	/* pick out a few only */
++	ck_assert_str_eq(libevdev_event_code_get_name(EV_ABS, ABS_X), "ABS_X");
++	ck_assert_str_eq(libevdev_event_code_get_name(EV_ABS, ABS_Y), "ABS_Y");
++
++	ck_assert_str_eq(libevdev_event_code_get_name(EV_ABS, ABS_MT_SLOT), "ABS_MT_SLOT");
++	ck_assert_str_eq(libevdev_event_code_get_name(EV_ABS, ABS_MISC), "ABS_MISC");
++	ck_assert_str_eq(libevdev_event_code_get_name(EV_ABS, ABS_MAX), "ABS_MAX");
++
++	ck_assert(libevdev_event_code_get_name(EV_ABS, ABS_MAX - 1) == NULL);
++
++}
++END_TEST
++
++START_TEST(test_code_rel_name)
++{
++	/* pick out a few only */
++	ck_assert_str_eq(libevdev_event_code_get_name(EV_REL, REL_X), "REL_X");
++	ck_assert_str_eq(libevdev_event_code_get_name(EV_REL, REL_Y), "REL_Y");
++	ck_assert_str_eq(libevdev_event_code_get_name(EV_REL, REL_MISC), "REL_MISC");
++	ck_assert_str_eq(libevdev_event_code_get_name(EV_REL, REL_MAX), "REL_MAX");
++
++	ck_assert(libevdev_event_code_get_name(EV_REL, REL_MAX - 1) == NULL);
++
++}
++END_TEST
++
++START_TEST(test_code_key_name)
++{
++	/* pick out a few only */
++	ck_assert_str_eq(libevdev_event_code_get_name(EV_KEY, KEY_RESERVED), "KEY_RESERVED");
++	ck_assert_str_eq(libevdev_event_code_get_name(EV_KEY, KEY_ESC), "KEY_ESC");
++	ck_assert_str_eq(libevdev_event_code_get_name(EV_KEY, KEY_1), "KEY_1");
++	ck_assert_str_eq(libevdev_event_code_get_name(EV_KEY, KEY_2), "KEY_2");
++	ck_assert_str_eq(libevdev_event_code_get_name(EV_KEY, KEY_UNKNOWN), "KEY_UNKNOWN");
++
++	ck_assert_str_eq(libevdev_event_code_get_name(EV_KEY, BTN_0), "BTN_0");
++	ck_assert_str_eq(libevdev_event_code_get_name(EV_KEY, BTN_LEFT), "BTN_LEFT");
++	ck_assert_str_eq(libevdev_event_code_get_name(EV_KEY, BTN_TRIGGER), "BTN_TRIGGER");
++	ck_assert_str_eq(libevdev_event_code_get_name(EV_KEY, BTN_A), "BTN_SOUTH");
++	ck_assert_str_eq(libevdev_event_code_get_name(EV_KEY, BTN_TOOL_PEN), "BTN_TOOL_PEN");
++
++	ck_assert_str_eq(libevdev_event_code_get_name(EV_KEY, KEY_TOUCHPAD_TOGGLE), "KEY_TOUCHPAD_TOGGLE");
++	ck_assert_str_eq(libevdev_event_code_get_name(EV_KEY, BTN_TRIGGER_HAPPY), "BTN_TRIGGER_HAPPY1");
++
++	ck_assert_str_eq(libevdev_event_code_get_name(EV_KEY, KEY_MAX), "KEY_MAX");
++	ck_assert(libevdev_event_code_get_name(EV_KEY, KEY_MAX - 1) == NULL);
++
++	/* special cases that resolve to something else */
++	ck_assert_str_eq(libevdev_event_code_get_name(EV_KEY, KEY_HANGUEL), "KEY_HANGEUL");
++	ck_assert_str_eq(libevdev_event_code_get_name(EV_KEY, KEY_SCREENLOCK), "KEY_COFFEE");
++	ck_assert_str_eq(libevdev_event_code_get_name(EV_KEY, BTN_MISC), "BTN_0");
++	ck_assert_str_eq(libevdev_event_code_get_name(EV_KEY, BTN_MOUSE), "BTN_LEFT");
++	ck_assert_str_eq(libevdev_event_code_get_name(EV_KEY, BTN_JOYSTICK), "BTN_TRIGGER");
++	ck_assert_str_eq(libevdev_event_code_get_name(EV_KEY, BTN_GAMEPAD), "BTN_SOUTH");
++	ck_assert_str_eq(libevdev_event_code_get_name(EV_KEY, BTN_DIGI), "BTN_TOOL_PEN");
++	ck_assert_str_eq(libevdev_event_code_get_name(EV_KEY, BTN_WHEEL), "BTN_GEAR_DOWN");
++	ck_assert_str_eq(libevdev_event_code_get_name(EV_KEY, BTN_TRIGGER_HAPPY), "BTN_TRIGGER_HAPPY1");
++
++}
++END_TEST
++
++START_TEST(test_code_led_name)
++{
++	/* pick out a few only */
++	ck_assert_str_eq(libevdev_event_code_get_name(EV_LED, LED_NUML), "LED_NUML");
++	ck_assert_str_eq(libevdev_event_code_get_name(EV_LED, LED_KANA), "LED_KANA");
++	ck_assert_str_eq(libevdev_event_code_get_name(EV_LED, LED_MAX), "LED_MAX");
++
++	ck_assert(libevdev_event_code_get_name(EV_LED, LED_MAX - 1) == NULL);
++
++}
++END_TEST
++
++START_TEST(test_code_snd_name)
++{
++	/* pick out a few only */
++	ck_assert_str_eq(libevdev_event_code_get_name(EV_SND, SND_CLICK), "SND_CLICK");
++	ck_assert_str_eq(libevdev_event_code_get_name(EV_SND, SND_TONE), "SND_TONE");
++	ck_assert_str_eq(libevdev_event_code_get_name(EV_SND, SND_MAX), "SND_MAX");
++
++	ck_assert(libevdev_event_code_get_name(EV_SND, SND_MAX - 1) == NULL);
++
++}
++END_TEST
++
++START_TEST(test_code_rep_name)
++{
++	ck_assert_str_eq(libevdev_event_code_get_name(EV_REP, REP_DELAY), "REP_DELAY");
++	ck_assert_str_eq(libevdev_event_code_get_name(EV_REP, REP_PERIOD), "REP_PERIOD");
++	ck_assert_str_eq(libevdev_event_code_get_name(EV_REP, REP_MAX), "REP_PERIOD");
++
++}
++END_TEST
++
++START_TEST(test_code_msc_name)
++{
++	/* pick out a few only */
++	ck_assert_str_eq(libevdev_event_code_get_name(EV_MSC, MSC_SERIAL), "MSC_SERIAL");
++	ck_assert_str_eq(libevdev_event_code_get_name(EV_MSC, MSC_RAW), "MSC_RAW");
++#ifdef MSC_TIMESTAMP
++	ck_assert_str_eq(libevdev_event_code_get_name(EV_MSC, MSC_TIMESTAMP), "MSC_TIMESTAMP");
++#endif
++	ck_assert_str_eq(libevdev_event_code_get_name(EV_MSC, MSC_MAX), "MSC_MAX");
++
++	ck_assert(libevdev_event_code_get_name(EV_MSC, MSC_MAX - 1) == NULL);
++
++}
++END_TEST
++
++START_TEST(test_code_sw_name)
++{
++	/* pick out a few only */
++	ck_assert_str_eq(libevdev_event_code_get_name(EV_SW, SW_LID), "SW_LID");
++	ck_assert_str_eq(libevdev_event_code_get_name(EV_SW, SW_RFKILL_ALL), "SW_RFKILL_ALL");
++	ck_assert_str_eq(libevdev_event_code_get_name(EV_SW, SW_LINEIN_INSERT), "SW_LINEIN_INSERT");
++	ck_assert_str_eq(libevdev_event_code_get_name(EV_SW, SW_PEN_INSERTED), "SW_PEN_INSERTED");
++	ck_assert_str_eq(libevdev_event_code_get_name(EV_SW, SW_MAX), "SW_MACHINE_COVER");
++}
++END_TEST
++
++START_TEST(test_code_ff_name)
++{
++	/* pick out a few only */
++	ck_assert_str_eq(libevdev_event_code_get_name(EV_FF, FF_STATUS_STOPPED), "FF_STATUS_STOPPED");
++	ck_assert_str_eq(libevdev_event_code_get_name(EV_FF, FF_FRICTION), "FF_FRICTION");
++	ck_assert_str_eq(libevdev_event_code_get_name(EV_FF, FF_CUSTOM), "FF_CUSTOM");
++	ck_assert_str_eq(libevdev_event_code_get_name(EV_FF, FF_MAX), "FF_MAX");
++
++	ck_assert(libevdev_event_code_get_name(EV_FF, FF_MAX - 1) == NULL);
++
++}
++END_TEST
++
++START_TEST(test_code_syn_name)
++{
++	ck_assert_str_eq(libevdev_event_code_get_name(EV_SYN, SYN_REPORT), "SYN_REPORT");
++	ck_assert_str_eq(libevdev_event_code_get_name(EV_SYN, SYN_CONFIG), "SYN_CONFIG");
++	ck_assert_str_eq(libevdev_event_code_get_name(EV_SYN, SYN_MT_REPORT), "SYN_MT_REPORT");
++	ck_assert_str_eq(libevdev_event_code_get_name(EV_SYN, SYN_DROPPED), "SYN_DROPPED");
++	ck_assert_str_eq(libevdev_event_code_get_name(EV_SYN, SYN_MAX), "SYN_MAX");
++}
++END_TEST
++
++START_TEST(test_value_name)
++{
++	unsigned int type, code;
++	int value;
++
++	for (type = 0; type < EV_MAX; type++) {
++		int max = libevdev_event_type_get_max(type);
++
++		if (max == -1)
++			continue;
++
++		for (code = 0; code < (unsigned int)max; code++) {
++			if (type == EV_ABS && code == ABS_MT_TOOL_TYPE)
++				continue;
++
++			for (value = 0; value < 0xff; value++) {
++				ck_assert(libevdev_event_value_get_name(type, code, value) == NULL);
++			}
++		}
++	}
++
++	ck_assert_str_eq(libevdev_event_value_get_name(EV_ABS, ABS_MT_TOOL_TYPE, MT_TOOL_FINGER), "MT_TOOL_FINGER");
++	ck_assert_str_eq(libevdev_event_value_get_name(EV_ABS, ABS_MT_TOOL_TYPE, MT_TOOL_PALM), "MT_TOOL_PALM");
++	ck_assert_str_eq(libevdev_event_value_get_name(EV_ABS, ABS_MT_TOOL_TYPE, MT_TOOL_PEN), "MT_TOOL_PEN");
++	ck_assert_str_eq(libevdev_event_value_get_name(EV_ABS, ABS_MT_TOOL_TYPE, MT_TOOL_MAX), "MT_TOOL_MAX");
++	ck_assert(libevdev_event_value_get_name(EV_ABS, ABS_MT_TOOL_TYPE, -1) == NULL);
++}
++END_TEST
++
++START_TEST(test_prop_name)
++{
++	ck_assert_str_eq(libevdev_property_get_name(INPUT_PROP_POINTER), "INPUT_PROP_POINTER");
++	ck_assert_str_eq(libevdev_property_get_name(INPUT_PROP_DIRECT), "INPUT_PROP_DIRECT");
++	ck_assert_str_eq(libevdev_property_get_name(INPUT_PROP_BUTTONPAD), "INPUT_PROP_BUTTONPAD");
++	ck_assert_str_eq(libevdev_property_get_name(INPUT_PROP_SEMI_MT), "INPUT_PROP_SEMI_MT");
++	ck_assert_str_eq(libevdev_property_get_name(INPUT_PROP_MAX), "INPUT_PROP_MAX");
++
++	ck_assert(libevdev_property_get_name(INPUT_PROP_MAX - 1) == NULL);
++	ck_assert(libevdev_property_get_name(INPUT_PROP_MAX + 1) == NULL);
++}
++END_TEST
++
++START_TEST(test_event_type_max)
++{
++	ck_assert_int_eq(libevdev_event_type_get_max(EV_ABS), ABS_MAX);
++	ck_assert_int_eq(libevdev_event_type_get_max(EV_REL), REL_MAX);
++	ck_assert_int_eq(libevdev_event_type_get_max(EV_KEY), KEY_MAX);
++
++	ck_assert_int_eq(libevdev_event_type_get_max(EV_MAX - 1), -1);
++	ck_assert_int_eq(libevdev_event_type_get_max(EV_MAX + 1), -1);
++
++}
++END_TEST
++
++START_TEST(test_event_type)
++{
++	struct input_event ev;
++	int i = 0;
++
++	ev.type = EV_REL;
++
++	ck_assert_int_eq(libevdev_event_is_type(&ev, EV_REL), 1);
++	for (i = 0; i < EV_CNT; i++) {
++		if (i == ev.type)
++			continue;
++		ck_assert_int_eq(libevdev_event_is_type(&ev, i), 0);
++	}
++	ck_assert_int_eq(libevdev_event_is_type(&ev, EV_MAX + 1), 0);
++}
++END_TEST
++
++START_TEST(test_event_code)
++{
++	struct input_event ev;
++	int i = 0;
++
++	ev.type = EV_REL;
++	ev.code = REL_Y;
++
++	ck_assert_int_eq(libevdev_event_is_code(&ev, EV_REL, REL_Y), 1);
++	for (i = 0; i < EV_CNT; i++) {
++		int j;
++		if (i == ev.type || i == EV_SYN)
++			continue;
++
++		for (j = 0; j < libevdev_event_type_get_max(i); i++) {
++			ck_assert_int_eq(libevdev_event_is_code(&ev, i, j), 0);
++		}
++	}
++	ck_assert_int_eq(libevdev_event_is_code(&ev, EV_MAX + 1, ev.code), 0);
++	ck_assert_int_eq(libevdev_event_is_code(&ev, EV_REL, REL_MAX + 1), 0);
++
++	ev.type = EV_SYN;
++	ev.code = SYN_REPORT;
++	ck_assert_int_eq(libevdev_event_is_code(&ev, EV_SYN, SYN_REPORT), 1);
++	ck_assert_int_eq(libevdev_event_is_code(&ev, EV_SYN, SYN_DROPPED), 0);
++}
++END_TEST
++
++TEST_SUITE(event_name_suite)
++{
++	Suite *s = suite_create("Event names");
++
++	add_test(s, test_limits);
++	add_test(s, test_event_type_max);
++
++	add_test(s, test_type_name);
++
++	add_test(s, test_code_abs_name);
++	add_test(s, test_code_rel_name);
++	add_test(s, test_code_key_name);
++	add_test(s, test_code_led_name);
++	add_test(s, test_code_snd_name);
++	add_test(s, test_code_rep_name);
++	add_test(s, test_code_msc_name);
++	add_test(s, test_code_sw_name);
++	add_test(s, test_code_ff_name);
++	add_test(s, test_code_syn_name);
++
++	add_test(s, test_value_name);
++	add_test(s, test_prop_name);
++
++	add_test(s, test_event_type);
++	add_test(s, test_event_code);
++
++	return s;
++}
+diff -Naur third-party-libevdev-bak/test/test-int-queue.c third-party-new/test/test-int-queue.c
+--- third-party-libevdev-bak/test/test-int-queue.c	1970-01-01 08:00:00.000000000 +0800
++++ third-party-new/test/test-int-queue.c	2022-03-25 12:33:26.000000000 +0800
+@@ -0,0 +1,338 @@
++// SPDX-License-Identifier: MIT
++/*
++ * Copyright © 2013 Red Hat, Inc.
++ */
++
++#include "config.h"
++#include 
++#include 
++#include "test-common.h"
++
++START_TEST(test_queue_alloc)
++{
++	struct libevdev dev;
++	int rc;
++
++	rc = queue_alloc(&dev, 0);
++	ck_assert_int_eq(rc, -ENOMEM);
++
++	rc = queue_alloc(&dev, 100);
++	ck_assert_int_eq(rc, 0);
++
++	ck_assert_int_eq(dev.queue_size, 100);
++	ck_assert_int_eq(dev.queue_next, 0);
++
++	queue_free(&dev);
++	ck_assert_int_eq(dev.queue_size, 0);
++	ck_assert_int_eq(dev.queue_next, 0);
++
++}
++END_TEST
++
++START_TEST(test_queue_sizes)
++{
++	struct libevdev dev = {0};
++
++	queue_alloc(&dev, 0);
++	ck_assert_int_eq(queue_num_elements(&dev), 0);
++	ck_assert_int_eq(queue_num_free_elements(&dev), 0);
++	ck_assert_int_eq(queue_size(&dev), 0);
++
++	queue_alloc(&dev, 100);
++	ck_assert_int_eq(queue_num_elements(&dev), 0);
++	ck_assert_int_eq(queue_num_free_elements(&dev), 100);
++	ck_assert_int_eq(queue_size(&dev), 100);
++
++	queue_free(&dev);
++
++	ck_assert_int_eq(queue_num_elements(&dev), 0);
++	ck_assert_int_eq(queue_num_free_elements(&dev), 0);
++	ck_assert_int_eq(queue_size(&dev), 0);
++}
++END_TEST
++
++START_TEST(test_queue_push)
++{
++	struct libevdev dev = {0};
++	struct input_event *ev;
++
++	queue_alloc(&dev, 0);
++	ev = queue_push(&dev);
++	ck_assert(ev == NULL);
++
++	queue_alloc(&dev, 2);
++	ev = queue_push(&dev);
++	ck_assert(ev == dev.queue);
++	ck_assert_int_eq(queue_num_elements(&dev), 1);
++	ck_assert_int_eq(queue_num_free_elements(&dev), 1);
++
++	ev = queue_push(&dev);
++	ck_assert(ev == dev.queue + 1);
++
++	ev = queue_push(&dev);
++	ck_assert(ev == NULL);
++
++	queue_free(&dev);
++	ev = queue_push(&dev);
++	ck_assert(ev == NULL);
++
++}
++END_TEST
++
++START_TEST(test_queue_pop)
++{
++	struct libevdev dev = {0};
++	struct input_event ev, *e, tmp;
++	int rc;
++
++	queue_alloc(&dev, 0);
++	rc = queue_pop(&dev, &ev);
++	ck_assert_int_eq(rc, 1);
++
++	queue_alloc(&dev, 2);
++	e = queue_push(&dev);
++	memset(e, 0xab, sizeof(*e));
++	ck_assert_int_eq(queue_num_elements(&dev), 1);
++	ck_assert_int_eq(queue_num_free_elements(&dev), 1);
++
++	rc = queue_pop(&dev, &ev);
++	ck_assert_int_eq(rc, 0);
++	memset(&tmp, 0xab, sizeof(tmp));
++	rc = memcmp(&tmp, &ev, sizeof(tmp));
++	ck_assert_int_eq(rc, 0);
++
++	ck_assert_int_eq(queue_num_elements(&dev), 0);
++	ck_assert_int_eq(queue_num_free_elements(&dev), 2);
++
++	rc = queue_pop(&dev, &ev);
++	ck_assert_int_eq(rc, 1);
++
++	queue_free(&dev);
++}
++END_TEST
++
++START_TEST(test_queue_peek)
++{
++	struct libevdev dev = {0};
++	struct input_event ev, *e, tmp;
++	int rc;
++
++	queue_alloc(&dev, 0);
++	rc = queue_peek(&dev, 0, &ev);
++	ck_assert_int_eq(rc, 1);
++
++	queue_alloc(&dev, 2);
++	e = queue_push(&dev);
++	memset(e, 0xab, sizeof(*e));
++
++	rc = queue_peek(&dev, 0, &ev);
++	ck_assert_int_eq(rc, 0);
++	memset(&tmp, 0xab, sizeof(tmp));
++	rc = memcmp(&tmp, &ev, sizeof(tmp));
++	ck_assert_int_eq(rc, 0);
++
++	ck_assert_int_eq(queue_num_elements(&dev), 1);
++	e = queue_push(&dev);
++	memset(e, 0xbc, sizeof(*e));
++
++	rc = queue_peek(&dev, 1, &ev);
++	ck_assert_int_eq(rc, 0);
++	memset(&tmp, 0xbc, sizeof(tmp));
++	rc = memcmp(&tmp, &ev, sizeof(tmp));
++	ck_assert_int_eq(rc, 0);
++
++	rc = queue_peek(&dev, 0, &ev);
++	ck_assert_int_eq(rc, 0);
++	memset(&tmp, 0xab, sizeof(tmp));
++	rc = memcmp(&tmp, &ev, sizeof(tmp));
++	ck_assert_int_eq(rc, 0);
++
++	ck_assert_int_eq(queue_num_elements(&dev), 2);
++
++	queue_free(&dev);
++}
++END_TEST
++
++START_TEST(test_queue_shift)
++{
++	struct libevdev dev = {0};
++	struct input_event ev, *first, *second, e1, e2;
++	int rc;
++
++	ck_assert_int_eq(queue_shift(&dev, &ev), 1);
++
++	queue_alloc(&dev, 10);
++	ck_assert_int_eq(queue_shift(&dev, &ev), 1);
++
++	first = queue_push(&dev);
++	ck_assert(first != NULL);
++	memset(first, 0xab, sizeof(*first));
++
++	e1 = *first;
++
++	second = queue_push(&dev);
++	ck_assert(second != NULL);
++	memset(second, 0x12, sizeof(*second));
++
++	e2 = *second;
++
++	rc = queue_shift(&dev, &ev);
++	ck_assert_int_eq(rc, 0);
++	rc = memcmp(&ev, &e1, sizeof(ev));
++	ck_assert_int_eq(rc, 0);
++
++	rc = queue_shift(&dev, &ev);
++	ck_assert_int_eq(rc, 0);
++	rc = memcmp(&ev, &e2, sizeof(ev));
++	ck_assert_int_eq(rc, 0);
++
++	ck_assert_int_eq(queue_shift(&dev, &ev), 1);
++
++	queue_free(&dev);
++}
++END_TEST
++
++START_TEST(test_queue_shift_multiple)
++{
++	struct libevdev dev = {0};
++	struct input_event ev, *first, *second, e1, e2;
++	struct input_event events[5];
++	int rc;
++
++	ck_assert_int_eq(queue_shift_multiple(&dev, 1, &ev), 0);
++	ck_assert_int_eq(queue_shift_multiple(&dev, 0, &ev), 0);
++
++	queue_alloc(&dev, 10);
++	ck_assert_int_eq(queue_shift_multiple(&dev, 1, &ev), 0);
++	ck_assert_int_eq(queue_shift_multiple(&dev, 0, &ev), 0);
++
++	first = queue_push(&dev);
++	ck_assert(first != NULL);
++	memset(first, 0xab, sizeof(*first));
++	e1 = *first;
++
++	second = queue_push(&dev);
++	ck_assert(second != NULL);
++	memset(second, 0x12, sizeof(*second));
++	e2 = *second;
++
++	rc = queue_shift_multiple(&dev, 5, events);
++	ck_assert_int_eq(rc, 2);
++	rc = memcmp(&events[0], &e1, sizeof(ev));
++	ck_assert_int_eq(rc, 0);
++	rc = memcmp(&events[1], &e2, sizeof(ev));
++	ck_assert_int_eq(rc, 0);
++
++	first = queue_push(&dev);
++	ck_assert(first != NULL);
++	memset(first, 0xab, sizeof(*first));
++	e1 = *first;
++
++	second = queue_push(&dev);
++	ck_assert(second != NULL);
++	memset(second, 0x12, sizeof(*second));
++	e2 = *second;
++
++	rc = queue_shift_multiple(&dev, 1, events);
++	ck_assert_int_eq(rc, 1);
++	rc = memcmp(&events[0], &e1, sizeof(ev));
++	ck_assert_int_eq(rc, 0);
++
++	rc = queue_shift_multiple(&dev, 1, events);
++	ck_assert_int_eq(rc, 1);
++	rc = memcmp(&events[0], &e2, sizeof(ev));
++	ck_assert_int_eq(rc, 0);
++
++	ck_assert_int_eq(queue_shift_multiple(&dev, 1, events), 0);
++
++	queue_free(&dev);
++}
++END_TEST
++
++START_TEST(test_queue_next_element)
++{
++	struct libevdev dev = {0};
++	struct input_event ev, *first, *second;
++	int rc;
++
++	queue_alloc(&dev, 0);
++	first = queue_next_element(&dev);
++	ck_assert(first == NULL);
++
++	queue_alloc(&dev, 2);
++	first = queue_next_element(&dev);
++	ck_assert(first != NULL);
++	memset(first, 0xab, sizeof(*first));
++
++	second = queue_next_element(&dev);
++	ck_assert(second != NULL);
++	memset(second, 0xbc, sizeof(*second));
++
++	/* queue_next_element does not advance, so we overwrite */
++	memset(&ev, 0xbc, sizeof(ev));
++	rc = memcmp(&ev, first, sizeof(ev));
++	ck_assert_int_eq(rc, 0);
++
++	ck_assert_int_eq(queue_num_elements(&dev), 0);
++
++	first = queue_next_element(&dev);
++	ck_assert(first != NULL);
++	memset(first, 0xab, sizeof(*first));
++
++	queue_set_num_elements(&dev, 1);
++	ck_assert_int_eq(queue_num_elements(&dev), 1);
++
++	second = queue_next_element(&dev);
++	ck_assert(second != NULL);
++	memset(second, 0xbc, sizeof(*second));
++
++	memset(&ev, 0xab, sizeof(ev));
++	rc = memcmp(&ev, first, sizeof(ev));
++	ck_assert_int_eq(rc, 0);
++
++	queue_free(&dev);
++}
++END_TEST
++
++START_TEST(test_queue_set_num_elements)
++{
++	struct libevdev dev = {0};
++
++	queue_alloc(&dev, 0);
++	ck_assert_int_eq(queue_set_num_elements(&dev, 1), 1);
++
++	queue_alloc(&dev, 2);
++	ck_assert_int_eq(queue_set_num_elements(&dev, 3), 1);
++	ck_assert_int_eq(queue_set_num_elements(&dev, 2), 0);
++
++	queue_free(&dev);
++}
++END_TEST
++
++TEST_SUITE(queue_suite)
++{
++	Suite *s = suite_create("Event queue");
++
++	TCase *tc = tcase_create("Queue allocation");
++	tcase_add_test(tc, test_queue_alloc);
++	tcase_add_test(tc, test_queue_sizes);
++	suite_add_tcase(s, tc);
++
++	tc = tcase_create("Queue push/pop/peek");
++	tcase_add_test(tc, test_queue_push);
++	tcase_add_test(tc, test_queue_pop);
++	tcase_add_test(tc, test_queue_peek);
++	suite_add_tcase(s, tc);
++
++	tc = tcase_create("Queue shift");
++	tcase_add_test(tc, test_queue_shift);
++	tcase_add_test(tc, test_queue_shift_multiple);
++	suite_add_tcase(s, tc);
++
++	tc = tcase_create("Queue next elem");
++	tcase_add_test(tc, test_queue_next_element);
++	tcase_add_test(tc, test_queue_set_num_elements);
++	suite_add_tcase(s, tc);
++
++	return s;
++}
+diff -Naur third-party-libevdev-bak/test/test-kernel.c third-party-new/test/test-kernel.c
+--- third-party-libevdev-bak/test/test-kernel.c	1970-01-01 08:00:00.000000000 +0800
++++ third-party-new/test/test-kernel.c	2022-03-25 12:33:26.000000000 +0800
+@@ -0,0 +1,160 @@
++// SPDX-License-Identifier: MIT
++/*
++ * Copyright © 2014 Red Hat, Inc.
++ */
++
++#include "config.h"
++#include 
++#include 
++#include 
++#include 
++#include 
++#include 
++#include 
++#include 
++#include 
++
++#include 
++#include 
++#include "test-common.h"
++
++START_TEST(test_revoke)
++{
++	struct uinput_device* uidev;
++	struct libevdev *dev, *dev2;
++	int rc, fd;
++	struct input_event ev1, ev2;
++	int dev_fd;
++
++	test_create_device(&uidev, &dev,
++			   EV_SYN, SYN_REPORT,
++			   EV_REL, REL_X,
++			   EV_REL, REL_Y,
++			   EV_REL, REL_WHEEL,
++			   EV_KEY, BTN_LEFT,
++			   EV_KEY, BTN_MIDDLE,
++			   EV_KEY, BTN_RIGHT,
++			   -1);
++
++	fd = open(uinput_device_get_devnode(uidev), O_RDONLY|O_NONBLOCK);
++	ck_assert_int_gt(fd, -1);
++	rc = libevdev_new_from_fd(fd, &dev2);
++	ck_assert_msg(rc == 0, "Failed to create second device: %s", strerror(-rc));
++
++	uinput_device_event(uidev, EV_REL, REL_X, 1);
++	uinput_device_event(uidev, EV_SYN, SYN_REPORT, 0);
++
++	for (int i = 0; i < 2; i++) {
++		rc = libevdev_next_event(dev, LIBEVDEV_READ_FLAG_NORMAL, &ev1);
++		ck_assert_int_eq(rc, LIBEVDEV_READ_STATUS_SUCCESS);
++
++		rc = libevdev_next_event(dev2, LIBEVDEV_READ_FLAG_NORMAL, &ev2);
++		ck_assert_int_eq(rc, LIBEVDEV_READ_STATUS_SUCCESS);
++
++		ck_assert_int_eq(ev1.type, ev2.type);
++		ck_assert_int_eq(ev1.code, ev2.code);
++		ck_assert_int_eq(ev1.value, ev2.value);
++	}
++
++	/* revoke first device, expect it closed, second device still open */
++	dev_fd = libevdev_get_fd(dev);
++	ck_assert_int_ge(dev_fd, 0);
++	rc = ioctl(dev_fd, EVIOCREVOKE, NULL);
++	if (rc == -1 && errno == EINVAL) {
++		fprintf(stderr, "WARNING: skipping EVIOCREVOKE test, not suported by current kernel\n");
++		goto out;
++	}
++	ck_assert_msg(rc == 0, "Failed to revoke device: %s", strerror(errno));
++
++	uinput_device_event(uidev, EV_REL, REL_X, 1);
++	uinput_device_event(uidev, EV_SYN, SYN_REPORT, 0);
++
++	rc = libevdev_next_event(dev, LIBEVDEV_READ_FLAG_NORMAL, &ev1);
++	ck_assert_int_eq(rc, -ENODEV);
++
++	rc = libevdev_next_event(dev2, LIBEVDEV_READ_FLAG_NORMAL, &ev2);
++	ck_assert_int_eq(rc, LIBEVDEV_READ_STATUS_SUCCESS);
++
++out:
++	uinput_device_free(uidev);
++	libevdev_free(dev);
++	libevdev_free(dev2);
++	close(fd);
++}
++END_TEST
++
++START_TEST(test_revoke_invalid)
++{
++	struct uinput_device* uidev;
++	struct libevdev *dev;
++	int rc;
++	int dev_fd;
++
++	test_create_device(&uidev, &dev,
++			   EV_SYN, SYN_REPORT,
++			   EV_REL, REL_X,
++			   EV_REL, REL_Y,
++			   EV_REL, REL_WHEEL,
++			   EV_KEY, BTN_LEFT,
++			   EV_KEY, BTN_MIDDLE,
++			   EV_KEY, BTN_RIGHT,
++			   -1);
++
++	dev_fd = libevdev_get_fd(dev);
++	ck_assert_int_ge(dev_fd, 0);
++	/* ioctl requires 0 as value */
++	rc = ioctl(dev_fd, EVIOCREVOKE, 1);
++	ck_assert_int_eq(rc, -1);
++	ck_assert_int_eq(errno, EINVAL);
++
++	uinput_device_free(uidev);
++	libevdev_free(dev);
++}
++END_TEST
++
++START_TEST(test_revoke_fail_after)
++{
++	struct uinput_device* uidev;
++	struct libevdev *dev, *dev2 = NULL;
++	int rc, fd;
++
++	test_create_device(&uidev, &dev,
++			   EV_SYN, SYN_REPORT,
++			   EV_REL, REL_X,
++			   EV_REL, REL_Y,
++			   EV_REL, REL_WHEEL,
++			   EV_KEY, BTN_LEFT,
++			   EV_KEY, BTN_MIDDLE,
++			   EV_KEY, BTN_RIGHT,
++			   -1);
++
++	fd = open(uinput_device_get_devnode(uidev), O_RDONLY|O_NONBLOCK);
++	ck_assert_int_gt(fd, -1);
++
++	rc = ioctl(fd, EVIOCREVOKE, NULL);
++	if (rc == -1 && errno == EINVAL) {
++		fprintf(stderr, "WARNING: skipping EVIOCREVOKE test, not suported by current kernel\n");
++		goto out;
++	}
++	ck_assert_msg(rc == 0, "Failed to revoke device: %s", strerror(errno));
++
++	rc = libevdev_new_from_fd(fd, &dev2);
++	ck_assert_int_eq(rc, -ENODEV);
++
++out:
++	uinput_device_free(uidev);
++	libevdev_free(dev);
++	close(fd);
++}
++END_TEST
++
++TEST_SUITE_ROOT_PRIVILEGES(kernel)
++{
++	Suite *s = suite_create("kernel");
++
++	add_test(s, test_revoke);
++	add_test(s, test_revoke_invalid);
++	add_test(s, test_revoke_fail_after);
++
++	return s;
++}
+diff -Naur third-party-libevdev-bak/test/test-libevdev-events.c third-party-new/test/test-libevdev-events.c
+--- third-party-libevdev-bak/test/test-libevdev-events.c	1970-01-01 08:00:00.000000000 +0800
++++ third-party-new/test/test-libevdev-events.c	2022-03-25 12:33:26.000000000 +0800
+@@ -0,0 +1,2084 @@
++// SPDX-License-Identifier: MIT
++/*
++ * Copyright © 2013 Red Hat, Inc.
++ */
++
++#include "config.h"
++#include 
++#include 
++#include 
++#include 
++#include 
++#include 
++
++#include "test-common.h"
++
++START_TEST(test_next_event)
++{
++	struct uinput_device* uidev;
++	struct libevdev *dev;
++	int rc;
++	struct input_event ev;
++
++	test_create_device(&uidev, &dev,
++			   EV_REL, REL_X,
++			   EV_REL, REL_Y,
++			   EV_KEY, BTN_LEFT,
++			   -1);
++
++	rc = libevdev_next_event(dev, LIBEVDEV_READ_FLAG_NORMAL, &ev);
++	ck_assert_int_eq(rc, -EAGAIN);
++
++	uinput_device_event(uidev, EV_KEY, BTN_LEFT, 1);
++	uinput_device_event(uidev, EV_SYN, SYN_REPORT, 0);
++	rc = libevdev_next_event(dev, LIBEVDEV_READ_FLAG_NORMAL, &ev);
++	ck_assert_int_eq(rc, LIBEVDEV_READ_STATUS_SUCCESS);
++	assert_event(&ev, EV_KEY, BTN_LEFT, 1);
++
++	libevdev_free(dev);
++	uinput_device_free(uidev);
++
++}
++END_TEST
++
++START_TEST(test_next_event_invalid_fd)
++{
++	struct uinput_device* uidev;
++	struct libevdev *dev;
++	int rc;
++	struct input_event ev;
++
++	libevdev_set_log_function(test_logfunc_ignore_error, NULL);
++
++	dev = libevdev_new();
++	rc = libevdev_next_event(dev, LIBEVDEV_READ_FLAG_NORMAL, &ev);
++	ck_assert_int_eq(rc, -EBADF);
++	libevdev_free(dev);
++
++	test_create_device(&uidev, &dev,
++			   EV_REL, REL_X,
++			   EV_REL, REL_Y,
++			   EV_KEY, BTN_LEFT,
++			   -1);
++
++	/* invalid (missing) flag */
++	rc = libevdev_next_event(dev, 0x10, &ev);
++	ck_assert_int_eq(rc, -EINVAL);
++
++	/* set an invalid fd */
++	rc = libevdev_change_fd(dev, -3);
++	ck_assert_int_eq(rc, 0);
++	rc = libevdev_next_event(dev, LIBEVDEV_READ_FLAG_NORMAL, &ev);
++	ck_assert_int_eq(rc, -EBADF);
++
++	libevdev_set_log_function(test_logfunc_abort_on_error, NULL);
++
++	libevdev_free(dev);
++	uinput_device_free(uidev);
++}
++END_TEST
++
++START_TEST(test_next_event_blocking)
++{
++	struct uinput_device* uidev;
++	struct libevdev *dev;
++	int fd, flags;
++	int rc;
++	struct input_event ev;
++
++	test_create_device(&uidev, &dev,
++			   EV_REL, REL_X,
++			   EV_REL, REL_Y,
++			   EV_KEY, BTN_LEFT,
++			   -1);
++
++	fd = libevdev_get_fd(dev);
++	flags = fcntl(fd, F_GETFL) & ~O_NONBLOCK;
++	rc = fcntl(fd, F_SETFL, flags);
++	ck_assert_int_eq(rc, 0);
++
++	uinput_device_event(uidev, EV_KEY, BTN_LEFT, 1);
++	uinput_device_event(uidev, EV_SYN, SYN_REPORT, 0);
++	rc = libevdev_next_event(dev, LIBEVDEV_READ_FLAG_BLOCKING, &ev);
++	ck_assert_int_eq(rc, LIBEVDEV_READ_STATUS_SUCCESS);
++	assert_event(&ev, EV_KEY, BTN_LEFT, 1);
++
++	libevdev_free(dev);
++	uinput_device_free(uidev);
++}
++END_TEST
++
++START_TEST(test_syn_dropped_event)
++{
++	struct uinput_device* uidev;
++	struct libevdev *dev;
++	int rc;
++	struct input_event ev;
++	int pipefd[2];
++
++	test_create_device(&uidev, &dev,
++			   EV_SYN, SYN_REPORT,
++			   EV_SYN, SYN_DROPPED,
++			   EV_REL, REL_X,
++			   EV_REL, REL_Y,
++			   EV_KEY, BTN_LEFT,
++			   -1);
++
++	/* This is a bit complicated:
++	   we can't get SYN_DROPPED through uinput, so we push two events down
++	   uinput, and process those. Then write a SYN_DROPPED on a pipe,
++	   switch the fd and read one event off the wire. Switch back, so
++	   that when we do read off the SYN_DROPPED we have the fd back on
++	   the device and the ioctls work.
++	 */
++	uinput_device_event(uidev, EV_KEY, BTN_LEFT, 1);
++	uinput_device_event(uidev, EV_SYN, SYN_REPORT, 0);
++	rc = libevdev_next_event(dev, LIBEVDEV_READ_FLAG_NORMAL, &ev);
++	ck_assert_int_eq(rc, LIBEVDEV_READ_STATUS_SUCCESS);
++	assert_event(&ev, EV_KEY, BTN_LEFT, 1);
++
++	rc = libevdev_next_event(dev, LIBEVDEV_READ_FLAG_NORMAL, &ev);
++	ck_assert_int_eq(rc, LIBEVDEV_READ_STATUS_SUCCESS);
++	assert_event(&ev, EV_SYN, SYN_REPORT, 0);
++
++	rc = pipe2(pipefd, O_NONBLOCK);
++	ck_assert_int_eq(rc, 0);
++
++	libevdev_change_fd(dev, pipefd[0]);
++	ev.type = EV_SYN;
++	ev.code = SYN_DROPPED;
++	ev.value = 0;
++	rc = write(pipefd[1], &ev, sizeof(ev));
++	ck_assert_int_eq(rc, sizeof(ev));
++
++	rc = libevdev_next_event(dev, LIBEVDEV_READ_FLAG_NORMAL, &ev);
++	ck_assert_int_eq(rc, LIBEVDEV_READ_STATUS_SYNC);
++	assert_event(&ev, EV_SYN, SYN_DROPPED, 0);
++
++	libevdev_change_fd(dev, uinput_device_get_fd(uidev));
++	/* only check for the rc, nothing actually changed on the device */
++
++	libevdev_free(dev);
++	uinput_device_free(uidev);
++
++	close(pipefd[0]);
++	close(pipefd[1]);
++
++}
++END_TEST
++
++START_TEST(test_event_type_filtered)
++{
++	struct uinput_device* uidev;
++	struct libevdev *dev;
++	int rc;
++	struct input_event ev;
++
++	test_create_device(&uidev, &dev,
++			   EV_REL, REL_X,
++			   EV_REL, REL_Y,
++			   EV_KEY, BTN_LEFT,
++			   -1);
++
++	libevdev_disable_event_type(dev, EV_REL);
++
++	rc = libevdev_next_event(dev, LIBEVDEV_READ_FLAG_NORMAL, &ev);
++	ck_assert_int_eq(rc, -EAGAIN);
++
++	uinput_device_event(uidev, EV_REL, REL_X, 1);
++	uinput_device_event(uidev, EV_KEY, REL_Y, 1);
++	uinput_device_event(uidev, EV_SYN, SYN_REPORT, 0);
++	rc = libevdev_next_event(dev, LIBEVDEV_READ_FLAG_NORMAL, &ev);
++	ck_assert_int_eq(rc, LIBEVDEV_READ_STATUS_SUCCESS);
++	assert_event(&ev, EV_SYN, SYN_REPORT, 0);
++
++	rc = libevdev_next_event(dev, LIBEVDEV_READ_FLAG_NORMAL, &ev);
++	ck_assert_int_eq(rc, -EAGAIN);
++
++	libevdev_free(dev);
++	uinput_device_free(uidev);
++
++}
++END_TEST
++
++START_TEST(test_event_code_filtered)
++{
++	struct uinput_device* uidev;
++	struct libevdev *dev;
++	int rc;
++	struct input_event ev;
++
++	test_create_device(&uidev, &dev,
++			   EV_REL, REL_X,
++			   EV_REL, REL_Y,
++			   EV_KEY, BTN_LEFT,
++			   -1);
++
++	libevdev_disable_event_code(dev, EV_REL, REL_X);
++
++	rc = libevdev_next_event(dev, LIBEVDEV_READ_FLAG_NORMAL, &ev);
++	ck_assert_int_eq(rc, -EAGAIN);
++
++	uinput_device_event(uidev, EV_REL, REL_X, 1);
++	uinput_device_event(uidev, EV_REL, REL_Y, 1);
++	uinput_device_event(uidev, EV_SYN, SYN_REPORT, 0);
++	rc = libevdev_next_event(dev, LIBEVDEV_READ_FLAG_NORMAL, &ev);
++	ck_assert_int_eq(rc, LIBEVDEV_READ_STATUS_SUCCESS);
++	assert_event(&ev, EV_REL, REL_Y, 1);
++
++	rc = libevdev_next_event(dev, LIBEVDEV_READ_FLAG_NORMAL, &ev);
++	ck_assert_int_eq(rc, LIBEVDEV_READ_STATUS_SUCCESS);
++	assert_event(&ev, EV_SYN, SYN_REPORT, 0);
++
++	rc = libevdev_next_event(dev, LIBEVDEV_READ_FLAG_NORMAL, &ev);
++	ck_assert_int_eq(rc, -EAGAIN);
++
++	libevdev_free(dev);
++	uinput_device_free(uidev);
++
++}
++END_TEST
++
++START_TEST(test_has_event_pending)
++{
++	struct uinput_device* uidev;
++	struct libevdev *dev;
++	int rc;
++	struct input_event ev;
++
++	test_create_device(&uidev, &dev,
++			   EV_REL, REL_X,
++			   EV_REL, REL_Y,
++			   EV_KEY, BTN_LEFT,
++			   -1);
++
++	ck_assert_int_eq(libevdev_has_event_pending(dev), 0);
++
++	uinput_device_event(uidev, EV_REL, REL_X, 1);
++	uinput_device_event(uidev, EV_REL, REL_Y, 1);
++	uinput_device_event(uidev, EV_SYN, SYN_REPORT, 0);
++
++	ck_assert_int_eq(libevdev_has_event_pending(dev), 1);
++
++	libevdev_next_event(dev, LIBEVDEV_READ_FLAG_NORMAL, &ev);
++
++	ck_assert_int_eq(libevdev_has_event_pending(dev), 1);
++
++	while ((rc = libevdev_next_event(dev, LIBEVDEV_READ_FLAG_NORMAL, &ev)) != -EAGAIN)
++			;
++
++	ck_assert_int_eq(libevdev_has_event_pending(dev), 0);
++
++	libevdev_change_fd(dev, -1);
++	ck_assert_int_eq(libevdev_has_event_pending(dev), -EBADF);
++
++	libevdev_free(dev);
++	uinput_device_free(uidev);
++
++}
++END_TEST
++
++START_TEST(test_has_event_pending_invalid_fd)
++{
++	struct libevdev *dev;
++	int rc;
++
++	libevdev_set_log_function(test_logfunc_ignore_error, NULL);
++
++	dev = libevdev_new();
++	rc = libevdev_has_event_pending(dev);
++	ck_assert_int_eq(rc, -EBADF);
++
++	libevdev_set_log_function(test_logfunc_abort_on_error, NULL);
++
++	libevdev_free(dev);
++}
++END_TEST
++
++START_TEST(test_syn_delta_button)
++{
++	struct uinput_device* uidev;
++	struct libevdev *dev;
++	int rc;
++	struct input_event ev;
++
++	test_create_device(&uidev, &dev,
++			   EV_SYN, SYN_REPORT,
++			   EV_SYN, SYN_DROPPED,
++			   EV_REL, REL_X,
++			   EV_REL, REL_Y,
++			   EV_KEY, BTN_LEFT,
++			   EV_KEY, BTN_MIDDLE,
++			   EV_KEY, BTN_RIGHT,
++			   EV_KEY, KEY_MAX,
++			   -1);
++
++	uinput_device_event(uidev, EV_KEY, BTN_LEFT, 1);
++	uinput_device_event(uidev, EV_KEY, BTN_RIGHT, 1);
++	uinput_device_event(uidev, EV_KEY, KEY_MAX, 1);
++	uinput_device_event(uidev, EV_SYN, SYN_REPORT, 0);
++	rc = libevdev_next_event(dev, LIBEVDEV_READ_FLAG_FORCE_SYNC, &ev);
++	ck_assert_int_eq(rc, LIBEVDEV_READ_STATUS_SYNC);
++
++	rc = libevdev_next_event(dev, LIBEVDEV_READ_FLAG_SYNC, &ev);
++	ck_assert_int_eq(rc, LIBEVDEV_READ_STATUS_SYNC);
++	assert_event(&ev, EV_KEY, BTN_LEFT, 1);
++	rc = libevdev_next_event(dev, LIBEVDEV_READ_FLAG_SYNC, &ev);
++	ck_assert_int_eq(rc, LIBEVDEV_READ_STATUS_SYNC);
++	assert_event(&ev, EV_KEY, BTN_RIGHT, 1);
++	rc = libevdev_next_event(dev, LIBEVDEV_READ_FLAG_SYNC, &ev);
++	ck_assert_int_eq(rc, LIBEVDEV_READ_STATUS_SYNC);
++	assert_event(&ev, EV_KEY, KEY_MAX, 1);
++	rc = libevdev_next_event(dev, LIBEVDEV_READ_FLAG_SYNC, &ev);
++	ck_assert_int_eq(rc, LIBEVDEV_READ_STATUS_SYNC);
++	assert_event(&ev, EV_SYN, SYN_REPORT, 0);
++	rc = libevdev_next_event(dev, LIBEVDEV_READ_FLAG_SYNC, &ev);
++	ck_assert_int_eq(rc, -EAGAIN);
++
++	ck_assert(libevdev_get_event_value(dev, EV_KEY, BTN_LEFT));
++	ck_assert(libevdev_get_event_value(dev, EV_KEY, BTN_RIGHT));
++	ck_assert(!libevdev_get_event_value(dev, EV_KEY, BTN_MIDDLE));
++	ck_assert(libevdev_get_event_value(dev, EV_KEY, KEY_MAX));
++
++	uinput_device_free(uidev);
++	libevdev_free(dev);
++}
++END_TEST
++
++START_TEST(test_syn_delta_abs)
++{
++	struct uinput_device* uidev;
++	struct libevdev *dev;
++	int rc;
++	struct input_event ev;
++	struct input_absinfo abs[3] = {
++		{ .value = ABS_X, .maximum = 1000 },
++		{ .value = ABS_Y, .maximum = 1000 },
++		{ .value = ABS_MAX, .maximum = 1000 },
++	};
++
++	test_create_abs_device(&uidev, &dev,
++			       ARRAY_LENGTH(abs), abs,
++			       EV_SYN, SYN_REPORT,
++			       EV_SYN, SYN_DROPPED,
++			       EV_KEY, BTN_LEFT,
++			       EV_KEY, BTN_MIDDLE,
++			       EV_KEY, BTN_RIGHT,
++			       -1);
++
++	uinput_device_event(uidev, EV_ABS, ABS_X, 100);
++	uinput_device_event(uidev, EV_ABS, ABS_Y, 500);
++	uinput_device_event(uidev, EV_ABS, ABS_MAX, 700);
++	uinput_device_event(uidev, EV_SYN, SYN_REPORT, 0);
++	rc = libevdev_next_event(dev, LIBEVDEV_READ_FLAG_FORCE_SYNC, &ev);
++	ck_assert_int_eq(rc, LIBEVDEV_READ_STATUS_SYNC);
++
++	rc = libevdev_next_event(dev, LIBEVDEV_READ_FLAG_SYNC, &ev);
++	ck_assert_int_eq(rc, LIBEVDEV_READ_STATUS_SYNC);
++	assert_event(&ev, EV_ABS, ABS_X, 100);
++	rc = libevdev_next_event(dev, LIBEVDEV_READ_FLAG_SYNC, &ev);
++	ck_assert_int_eq(rc, LIBEVDEV_READ_STATUS_SYNC);
++	assert_event(&ev, EV_ABS, ABS_Y, 500);
++	rc = libevdev_next_event(dev, LIBEVDEV_READ_FLAG_SYNC, &ev);
++	ck_assert_int_eq(rc, LIBEVDEV_READ_STATUS_SYNC);
++	ck_assert_int_eq(ev.type, EV_ABS);
++	ck_assert_int_eq(ev.code, ABS_MAX);
++	ck_assert_int_eq(ev.value, 700);
++	assert_event(&ev, EV_ABS, ABS_MAX, 700);
++	rc = libevdev_next_event(dev, LIBEVDEV_READ_FLAG_SYNC, &ev);
++	ck_assert_int_eq(rc, LIBEVDEV_READ_STATUS_SYNC);
++	assert_event(&ev, EV_SYN, SYN_REPORT, 0);
++	rc = libevdev_next_event(dev, LIBEVDEV_READ_FLAG_SYNC, &ev);
++	ck_assert_int_eq(rc, -EAGAIN);
++
++	uinput_device_free(uidev);
++	libevdev_free(dev);
++}
++END_TEST
++
++START_TEST(test_syn_delta_mt)
++{
++	struct uinput_device* uidev;
++	struct libevdev *dev;
++	int rc;
++	struct input_event ev;
++	struct input_absinfo abs[6] = {
++		{ .value = ABS_X, .maximum = 1000 },
++		{ .value = ABS_Y, .maximum = 1000 },
++		{ .value = ABS_MT_POSITION_X, .maximum = 1000 },
++		{ .value = ABS_MT_POSITION_Y, .maximum = 1000 },
++		{ .value = ABS_MT_SLOT, .maximum = 1 },
++		{ .value = ABS_MT_TRACKING_ID, .minimum = -1, .maximum = 2 },
++	};
++
++	test_create_abs_device(&uidev, &dev,
++			       ARRAY_LENGTH(abs), abs,
++			       EV_SYN, SYN_REPORT,
++			       -1);
++
++	uinput_device_event_multiple(uidev,
++				     EV_ABS, ABS_MT_SLOT, 0,
++				     EV_ABS, ABS_X, 100,
++				     EV_ABS, ABS_Y, 500,
++				     EV_ABS, ABS_MT_POSITION_X, 100,
++				     EV_ABS, ABS_MT_POSITION_Y, 500,
++				     EV_ABS, ABS_MT_TRACKING_ID, 1,
++				     EV_ABS, ABS_MT_SLOT, 1,
++				     EV_ABS, ABS_X, 1,
++				     EV_ABS, ABS_Y, 5,
++				     EV_ABS, ABS_MT_POSITION_X, 1,
++				     EV_ABS, ABS_MT_POSITION_Y, 5,
++				     EV_ABS, ABS_MT_TRACKING_ID, 2,
++				     EV_SYN, SYN_REPORT, 0,
++				     -1, -1);
++
++	rc = libevdev_next_event(dev, LIBEVDEV_READ_FLAG_FORCE_SYNC, &ev);
++	ck_assert_int_eq(rc, LIBEVDEV_READ_STATUS_SYNC);
++
++	ck_assert_int_eq(libevdev_get_current_slot(dev), 0);
++	rc = libevdev_next_event(dev, LIBEVDEV_READ_FLAG_SYNC, &ev);
++	ck_assert_int_eq(rc, LIBEVDEV_READ_STATUS_SYNC);
++	assert_event(&ev, EV_ABS, ABS_X, 1);
++	rc = libevdev_next_event(dev, LIBEVDEV_READ_FLAG_SYNC, &ev);
++	ck_assert_int_eq(rc, LIBEVDEV_READ_STATUS_SYNC);
++	assert_event(&ev, EV_ABS, ABS_Y, 5);
++	rc = libevdev_next_event(dev, LIBEVDEV_READ_FLAG_SYNC, &ev);
++	ck_assert_int_eq(rc, LIBEVDEV_READ_STATUS_SYNC);
++	assert_event(&ev, EV_ABS, ABS_MT_SLOT, 0);
++	rc = libevdev_next_event(dev, LIBEVDEV_READ_FLAG_SYNC, &ev);
++	ck_assert_int_eq(rc, LIBEVDEV_READ_STATUS_SYNC);
++	assert_event(&ev, EV_ABS, ABS_MT_POSITION_X, 100);
++	rc = libevdev_next_event(dev, LIBEVDEV_READ_FLAG_SYNC, &ev);
++	ck_assert_int_eq(rc, LIBEVDEV_READ_STATUS_SYNC);
++	assert_event(&ev, EV_ABS, ABS_MT_POSITION_Y, 500);
++	rc = libevdev_next_event(dev, LIBEVDEV_READ_FLAG_SYNC, &ev);
++	ck_assert_int_eq(rc, LIBEVDEV_READ_STATUS_SYNC);
++	assert_event(&ev, EV_ABS, ABS_MT_TRACKING_ID, 1);
++	rc = libevdev_next_event(dev, LIBEVDEV_READ_FLAG_SYNC, &ev);
++	ck_assert_int_eq(rc, LIBEVDEV_READ_STATUS_SYNC);
++	assert_event(&ev, EV_ABS, ABS_MT_SLOT, 1);
++	ck_assert_int_eq(libevdev_get_current_slot(dev), 1);
++
++	rc = libevdev_next_event(dev, LIBEVDEV_READ_FLAG_SYNC, &ev);
++	ck_assert_int_eq(rc, LIBEVDEV_READ_STATUS_SYNC);
++	assert_event(&ev, EV_ABS, ABS_MT_POSITION_X, 1);
++	rc = libevdev_next_event(dev, LIBEVDEV_READ_FLAG_SYNC, &ev);
++	ck_assert_int_eq(rc, LIBEVDEV_READ_STATUS_SYNC);
++	assert_event(&ev, EV_ABS, ABS_MT_POSITION_Y, 5);
++	rc = libevdev_next_event(dev, LIBEVDEV_READ_FLAG_SYNC, &ev);
++	ck_assert_int_eq(rc, LIBEVDEV_READ_STATUS_SYNC);
++	assert_event(&ev, EV_ABS, ABS_MT_TRACKING_ID, 2);
++
++	rc = libevdev_next_event(dev, LIBEVDEV_READ_FLAG_SYNC, &ev);
++	ck_assert_int_eq(rc, LIBEVDEV_READ_STATUS_SYNC);
++	assert_event(&ev, EV_SYN, SYN_REPORT, 0);
++	rc = libevdev_next_event(dev, LIBEVDEV_READ_FLAG_SYNC, &ev);
++	ck_assert_int_eq(rc, -EAGAIN);
++
++	uinput_device_free(uidev);
++	libevdev_free(dev);
++}
++END_TEST
++
++START_TEST(test_syn_delta_mt_reset_slot)
++{
++	struct uinput_device* uidev;
++	struct libevdev *dev;
++	int rc;
++	struct input_event ev,
++			   last_slot_event = { .type = 0};
++	struct input_absinfo abs[6] = {
++		{ .value = ABS_X, .maximum = 1000 },
++		{ .value = ABS_Y, .maximum = 1000 },
++		{ .value = ABS_MT_POSITION_X, .maximum = 1000 },
++		{ .value = ABS_MT_POSITION_Y, .maximum = 1000 },
++		{ .value = ABS_MT_SLOT, .maximum = 1 },
++		{ .value = ABS_MT_TRACKING_ID, .minimum = -1, .maximum = 2 },
++	};
++
++	test_create_abs_device(&uidev, &dev,
++			       ARRAY_LENGTH(abs), abs,
++			       EV_SYN, SYN_REPORT,
++			       -1);
++
++	uinput_device_event_multiple(uidev,
++				     EV_ABS, ABS_MT_SLOT, 1,
++				     EV_ABS, ABS_MT_POSITION_X, 100,
++				     EV_ABS, ABS_MT_POSITION_Y, 500,
++				     EV_ABS, ABS_MT_TRACKING_ID, 1,
++				     EV_ABS, ABS_MT_SLOT, 0,
++				     EV_ABS, ABS_MT_POSITION_X, 1,
++				     EV_ABS, ABS_MT_POSITION_Y, 5,
++				     EV_ABS, ABS_MT_TRACKING_ID, 2,
++				     EV_SYN, SYN_REPORT, 0,
++				     -1, -1);
++
++	rc = libevdev_next_event(dev, LIBEVDEV_READ_FLAG_FORCE_SYNC, &ev);
++	ck_assert_int_eq(rc, LIBEVDEV_READ_STATUS_SYNC);
++
++	do {
++		rc = libevdev_next_event(dev, LIBEVDEV_READ_FLAG_SYNC, &ev);
++		if (libevdev_event_is_code(&ev, EV_ABS, ABS_MT_SLOT))
++			last_slot_event = ev;
++	} while (rc != -EAGAIN);
++
++	ck_assert(libevdev_event_is_code(&last_slot_event, EV_ABS, ABS_MT_SLOT));
++	ck_assert_int_eq(last_slot_event.value, 0);
++	ck_assert_int_eq(libevdev_get_current_slot(dev), 0);
++
++	last_slot_event.type = 0;
++
++	/* same thing again, this time swap the numbers */
++	uinput_device_event_multiple(uidev,
++				     EV_ABS, ABS_MT_SLOT, 0,
++				     EV_ABS, ABS_MT_POSITION_X, 100,
++				     EV_ABS, ABS_MT_POSITION_Y, 500,
++				     EV_ABS, ABS_MT_TRACKING_ID, 1,
++				     EV_ABS, ABS_MT_SLOT, 1,
++				     EV_ABS, ABS_MT_POSITION_X, 1,
++				     EV_ABS, ABS_MT_POSITION_Y, 5,
++				     EV_ABS, ABS_MT_TRACKING_ID, 2,
++				     EV_SYN, SYN_REPORT, 0,
++				     -1, -1);
++
++	rc = libevdev_next_event(dev, LIBEVDEV_READ_FLAG_FORCE_SYNC, &ev);
++	ck_assert_int_eq(rc, LIBEVDEV_READ_STATUS_SYNC);
++
++	do {
++		rc = libevdev_next_event(dev, LIBEVDEV_READ_FLAG_SYNC, &ev);
++		if (libevdev_event_is_code(&ev, EV_ABS, ABS_MT_SLOT))
++			last_slot_event = ev;
++	} while (rc != -EAGAIN);
++
++	ck_assert(libevdev_event_is_code(&last_slot_event, EV_ABS, ABS_MT_SLOT));
++	ck_assert_int_eq(last_slot_event.value, 1);
++	ck_assert_int_eq(libevdev_get_current_slot(dev), 1);
++
++	uinput_device_free(uidev);
++	libevdev_free(dev);
++}
++END_TEST
++
++START_TEST(test_syn_delta_led)
++{
++	struct uinput_device* uidev;
++	struct libevdev *dev;
++	int rc;
++	struct input_event ev;
++
++	test_create_device(&uidev, &dev,
++			   EV_SYN, SYN_REPORT,
++			   EV_SYN, SYN_DROPPED,
++			   EV_LED, LED_NUML,
++			   EV_LED, LED_CAPSL,
++			   EV_LED, LED_MAX,
++			   -1);
++
++	uinput_device_event(uidev, EV_LED, LED_NUML, 1);
++	uinput_device_event(uidev, EV_LED, LED_CAPSL, 1);
++	uinput_device_event(uidev, EV_LED, LED_MAX, 1);
++	uinput_device_event(uidev, EV_SYN, SYN_REPORT, 0);
++	rc = libevdev_next_event(dev, LIBEVDEV_READ_FLAG_FORCE_SYNC, &ev);
++	ck_assert_int_eq(rc, LIBEVDEV_READ_STATUS_SYNC);
++
++	rc = libevdev_next_event(dev, LIBEVDEV_READ_FLAG_SYNC, &ev);
++	ck_assert_int_eq(rc, LIBEVDEV_READ_STATUS_SYNC);
++	assert_event(&ev, EV_LED, LED_NUML, 1);
++	rc = libevdev_next_event(dev, LIBEVDEV_READ_FLAG_SYNC, &ev);
++	ck_assert_int_eq(rc, LIBEVDEV_READ_STATUS_SYNC);
++	assert_event(&ev, EV_LED, LED_CAPSL, 1);
++	rc = libevdev_next_event(dev, LIBEVDEV_READ_FLAG_SYNC, &ev);
++	ck_assert_int_eq(rc, LIBEVDEV_READ_STATUS_SYNC);
++	assert_event(&ev, EV_LED, LED_MAX, 1);
++	rc = libevdev_next_event(dev, LIBEVDEV_READ_FLAG_SYNC, &ev);
++	ck_assert_int_eq(rc, LIBEVDEV_READ_STATUS_SYNC);
++	assert_event(&ev, EV_SYN, SYN_REPORT, 0);
++	rc = libevdev_next_event(dev, LIBEVDEV_READ_FLAG_SYNC, &ev);
++	ck_assert_int_eq(rc, -EAGAIN);
++
++	ck_assert_int_eq(libevdev_get_event_value(dev, EV_LED, LED_NUML), 1);
++	ck_assert_int_eq(libevdev_get_event_value(dev, EV_LED, LED_CAPSL), 1);
++	ck_assert_int_eq(libevdev_get_event_value(dev, EV_LED, LED_MAX), 1);
++
++	uinput_device_free(uidev);
++	libevdev_free(dev);
++}
++END_TEST
++
++START_TEST(test_syn_delta_sw)
++{
++	struct uinput_device* uidev;
++	struct libevdev *dev;
++	int rc;
++	struct input_event ev;
++
++	test_create_device(&uidev, &dev,
++			   EV_SYN, SYN_REPORT,
++			   EV_SYN, SYN_DROPPED,
++			   EV_SW, SW_HEADPHONE_INSERT,
++			   EV_SW, SW_MICROPHONE_INSERT,
++			   EV_SW, SW_MAX,
++			   -1);
++
++	uinput_device_event(uidev, EV_SW, SW_HEADPHONE_INSERT, 1);
++	uinput_device_event(uidev, EV_SW, SW_MICROPHONE_INSERT, 1);
++	uinput_device_event(uidev, EV_SW, SW_MAX, 1);
++	uinput_device_event(uidev, EV_SYN, SYN_REPORT, 0);
++	rc = libevdev_next_event(dev, LIBEVDEV_READ_FLAG_FORCE_SYNC, &ev);
++	ck_assert_int_eq(rc, LIBEVDEV_READ_STATUS_SYNC);
++
++	rc = libevdev_next_event(dev, LIBEVDEV_READ_FLAG_SYNC, &ev);
++	ck_assert_int_eq(rc, LIBEVDEV_READ_STATUS_SYNC);
++	assert_event(&ev, EV_SW, SW_HEADPHONE_INSERT, 1);
++	rc = libevdev_next_event(dev, LIBEVDEV_READ_FLAG_SYNC, &ev);
++	ck_assert_int_eq(rc, LIBEVDEV_READ_STATUS_SYNC);
++	assert_event(&ev, EV_SW, SW_MICROPHONE_INSERT, 1);
++	rc = libevdev_next_event(dev, LIBEVDEV_READ_FLAG_SYNC, &ev);
++	ck_assert_int_eq(rc, LIBEVDEV_READ_STATUS_SYNC);
++	assert_event(&ev, EV_SW, SW_MAX, 1);
++	rc = libevdev_next_event(dev, LIBEVDEV_READ_FLAG_SYNC, &ev);
++	ck_assert_int_eq(rc, LIBEVDEV_READ_STATUS_SYNC);
++	assert_event(&ev, EV_SYN, SYN_REPORT, 0);
++	rc = libevdev_next_event(dev, LIBEVDEV_READ_FLAG_SYNC, &ev);
++	ck_assert_int_eq(rc, -EAGAIN);
++
++	ck_assert_int_eq(libevdev_get_event_value(dev, EV_SW, SW_HEADPHONE_INSERT), 1);
++	ck_assert_int_eq(libevdev_get_event_value(dev, EV_SW, SW_MICROPHONE_INSERT), 1);
++	ck_assert_int_eq(libevdev_get_event_value(dev, EV_SW, SW_MAX), 1);
++
++	uinput_device_free(uidev);
++	libevdev_free(dev);
++}
++END_TEST
++
++START_TEST(test_syn_delta_tracking_ids)
++{
++	struct uinput_device* uidev;
++	struct libevdev *dev;
++	int rc;
++	struct input_event ev;
++	int i;
++	const int num_slots = 15;
++	int slot = -1;
++	unsigned long terminated[NLONGS(num_slots)];
++	unsigned long restarted[NLONGS(num_slots)];
++	struct input_absinfo abs[6] = {
++		{ .value = ABS_X, .maximum = 1000 },
++		{ .value = ABS_Y, .maximum = 1000 },
++		{ .value = ABS_MT_POSITION_X, .maximum = 1000 },
++		{ .value = ABS_MT_POSITION_Y, .maximum = 1000 },
++		{ .value = ABS_MT_SLOT, .maximum = num_slots },
++		{ .value = ABS_MT_TRACKING_ID, .minimum = -1, .maximum = 0xff },
++	};
++
++	test_create_abs_device(&uidev, &dev,
++			       ARRAY_LENGTH(abs), abs,
++			       EV_SYN, SYN_REPORT,
++			       -1);
++
++	/* Test the sync process to make sure we get touches terminated when
++	 * the tracking id changes:
++	 * 1) start a bunch of touch points
++	 * 2) read data into libevdev, make sure state is up-to-date
++	 * 3) change touchpoints
++	 * 3.1) change the tracking ID on some (indicating terminated and
++	 * re-started touchpoint)
++	 * 3.2) change the tracking ID to -1 on some (indicating termianted
++	 * touchpoint)
++	 * 3.3) just update the data on others
++	 * 4) force a sync on the device
++	 * 5) make sure we get the right tracking ID changes in the caller
++	 */
++
++	/* Start a bunch of touch points  */
++	for (i = num_slots; i >= 0; i--) {
++		uinput_device_event_multiple(uidev,
++					     EV_ABS, ABS_MT_SLOT, i,
++					     EV_ABS, ABS_MT_TRACKING_ID, i,
++					     EV_ABS, ABS_X, 100 + i,
++					     EV_ABS, ABS_Y, 500 + i,
++					     EV_ABS, ABS_MT_POSITION_X, 100 + i,
++					     EV_ABS, ABS_MT_POSITION_Y, 500 + i,
++					     EV_SYN, SYN_REPORT, 0,
++					     -1, -1);
++		do {
++			rc = libevdev_next_event(dev, LIBEVDEV_READ_FLAG_NORMAL, &ev);
++			ck_assert_int_ne(rc, LIBEVDEV_READ_STATUS_SYNC);
++		} while (rc >= 0);
++	}
++
++	/* we have a bunch of touches now, and libevdev knows it. Change all
++	 * touches */
++	for (i = num_slots; i >= 0; i--) {
++		uinput_device_event(uidev, EV_ABS, ABS_MT_SLOT, i);
++		if (i % 3 == 0) {
++			/* change some slots with a new tracking id */
++			uinput_device_event_multiple(uidev,
++						     EV_ABS, ABS_MT_TRACKING_ID, num_slots + i,
++						     EV_ABS, ABS_X, 200 + i,
++						     EV_ABS, ABS_Y, 700 + i,
++						     EV_ABS, ABS_MT_POSITION_X, 200 + i,
++						     EV_ABS, ABS_MT_POSITION_Y, 700 + i,
++						     -1, -1);
++		} else if (i % 3 == 1) {
++			/* stop others */
++			uinput_device_event(uidev, EV_ABS, ABS_MT_TRACKING_ID, -1);
++		} else {
++			/* just update */
++			uinput_device_event_multiple(uidev,
++						     EV_ABS, ABS_X, 200 + i,
++						     EV_ABS, ABS_Y, 700 + i,
++						     EV_ABS, ABS_MT_POSITION_X, 200 + i,
++						     EV_ABS, ABS_MT_POSITION_Y, 700 + i,
++						     -1, -1);
++		}
++		uinput_device_event(uidev, EV_SYN, SYN_REPORT, 0);
++	}
++
++	/* Force sync */
++	rc = libevdev_next_event(dev, LIBEVDEV_READ_FLAG_FORCE_SYNC, &ev);
++	ck_assert_int_eq(rc, LIBEVDEV_READ_STATUS_SYNC);
++
++	/* now check for the right tracking IDs */
++	memset(terminated, 0, sizeof(terminated));
++	memset(restarted, 0, sizeof(restarted));
++	slot = -1;
++	while ((rc = libevdev_next_event(dev, LIBEVDEV_READ_FLAG_SYNC, &ev)) != -EAGAIN) {
++		if (libevdev_event_is_code(&ev, EV_SYN, SYN_REPORT))
++			continue;
++
++		if (libevdev_event_is_code(&ev, EV_ABS, ABS_MT_SLOT)) {
++			slot = ev.value;
++			continue;
++		}
++
++		if (libevdev_event_is_code(&ev, EV_ABS, ABS_X) ||
++		    libevdev_event_is_code(&ev, EV_ABS, ABS_Y))
++			continue;
++
++		ck_assert_int_ne(slot, -1);
++
++		if (libevdev_event_is_code(&ev, EV_ABS, ABS_MT_TRACKING_ID)) {
++			if (slot % 3 == 0) {
++				if (!bit_is_set(terminated, slot)) {
++					ck_assert_int_eq(ev.value, -1);
++					set_bit(terminated, slot);
++				} else {
++					ck_assert_int_eq(ev.value, num_slots + slot);
++					set_bit(restarted, slot);
++				}
++			} else if (slot % 3 == 1) {
++				ck_assert(!bit_is_set(terminated, slot));
++				ck_assert_int_eq(ev.value, -1);
++				set_bit(terminated, slot);
++			} else
++				ck_abort();
++
++			continue;
++		}
++
++		switch(ev.code) {
++			case ABS_MT_POSITION_X:
++				ck_assert_int_eq(ev.value, 200 + slot);
++				break;
++			case ABS_MT_POSITION_Y:
++				ck_assert_int_eq(ev.value, 700 + slot);
++				break;
++			default:
++				ck_abort();
++		}
++	}
++
++	for (i = 0; i < num_slots; i++) {
++		if (i % 3 == 0) {
++			ck_assert(bit_is_set(terminated, i));
++			ck_assert(bit_is_set(restarted, i));
++		} else if (i % 3 == 1) {
++			ck_assert(bit_is_set(terminated, i));
++			ck_assert(!bit_is_set(restarted, i));
++		} else {
++			ck_assert(!bit_is_set(terminated, i));
++			ck_assert(!bit_is_set(restarted, i));
++		}
++	}
++
++	uinput_device_free(uidev);
++	libevdev_free(dev);
++}
++END_TEST
++
++START_TEST(test_syn_delta_tracking_ids_btntool)
++{
++       struct uinput_device* uidev;
++       struct libevdev *dev;
++       int rc;
++       struct input_event ev;
++       const int num_slots = 5;
++       struct input_absinfo abs[6] = {
++               { .value = ABS_X, .maximum = 1000 },
++               { .value = ABS_Y, .maximum = 1000 },
++               { .value = ABS_MT_POSITION_X, .maximum = 1000 },
++               { .value = ABS_MT_POSITION_Y, .maximum = 1000 },
++               { .value = ABS_MT_SLOT, .maximum = num_slots },
++               { .value = ABS_MT_TRACKING_ID, .minimum = -1, .maximum = 0xffff },
++       };
++       bool have_doubletap = false,
++            have_quadtap = false,
++            have_quinttap = false;
++
++       test_create_abs_device(&uidev, &dev,
++                              ARRAY_LENGTH(abs), abs,
++                              EV_KEY, BTN_TOOL_FINGER,
++                              EV_KEY, BTN_TOOL_DOUBLETAP,
++                              EV_KEY, BTN_TOOL_TRIPLETAP,
++                              EV_KEY, BTN_TOOL_QUADTAP,
++                              EV_KEY, BTN_TOOL_QUINTTAP,
++                              EV_SYN, SYN_REPORT,
++                              -1);
++
++       /* Test the sync process to make sure we get the BTN_TOOL bits for
++        * touches adjusted correctly when the tracking id changes:
++        * 1) start a bunch of touch points
++        * 2) read data into libevdev, make sure state is up-to-date
++        * 3) change touchpoints
++        * 3.1) change the tracking ID on some (indicating terminated and
++        * re-started touchpoint)
++        * 3.2) change the tracking ID to -1 on some (indicating termianted
++        * touchpoint)
++        * 3.3) just update the data on others
++        * 4) force a sync on the device
++        * 5) make sure we get the right BTN_TOOL_ changes in the caller
++        */
++       for (int i = 0; i < num_slots; i++) {
++               uinput_device_event_multiple(uidev,
++                                            EV_ABS, ABS_MT_SLOT, i,
++                                            EV_ABS, ABS_MT_TRACKING_ID, 111,
++                                            EV_ABS, ABS_X, 100 + 10 * i,
++                                            EV_ABS, ABS_Y, 100 + 10 * i,
++                                            EV_ABS, ABS_MT_POSITION_X, 100,
++                                            EV_ABS, ABS_MT_POSITION_Y, 100,
++                                            -1, -1);
++               switch (i) {
++               case 0:
++                       uinput_device_event(uidev, EV_KEY, BTN_TOOL_FINGER, 1);
++                       break;
++               case 1:
++                       uinput_device_event(uidev, EV_KEY, BTN_TOOL_FINGER, 0);
++                       uinput_device_event(uidev, EV_KEY, BTN_TOOL_DOUBLETAP, 1);
++                       break;
++               case 2:
++                       uinput_device_event(uidev, EV_KEY, BTN_TOOL_DOUBLETAP, 0);
++                       uinput_device_event(uidev, EV_KEY, BTN_TOOL_TRIPLETAP, 1);
++                       break;
++               case 3:
++                       uinput_device_event(uidev, EV_KEY, BTN_TOOL_TRIPLETAP, 0);
++                       uinput_device_event(uidev, EV_KEY, BTN_TOOL_QUADTAP, 1);
++                       break;
++               case 4:
++                       uinput_device_event(uidev, EV_KEY, BTN_TOOL_QUADTAP, 0);
++                       uinput_device_event(uidev, EV_KEY, BTN_TOOL_QUINTTAP, 1);
++                       break;
++               default:
++                       ck_abort();
++               }
++               uinput_device_event(uidev, EV_SYN, SYN_REPORT, 0);
++       }
++
++       do {
++               rc = libevdev_next_event(dev, LIBEVDEV_READ_FLAG_NORMAL, &ev);
++               ck_assert_int_ne(rc, LIBEVDEV_READ_STATUS_SYNC);
++       } while (rc >= 0);
++
++       /* we have a bunch of touches now, and libevdev knows it.
++        * - stop touch 0
++        * - stop and restart touch 1 and 4
++        * - leave 2, 3 unchanged
++        */
++       uinput_device_event_multiple(uidev,
++                                    EV_ABS, ABS_MT_SLOT, 0,
++                                    EV_ABS, ABS_MT_TRACKING_ID, -1,
++                                    EV_KEY, BTN_TOOL_QUINTTAP, 0,
++                                    EV_KEY, BTN_TOOL_QUADTAP, 1,
++                                    EV_SYN, SYN_REPORT, 0,
++                                    -1, -1);
++       uinput_device_event_multiple(uidev,
++                                    EV_ABS, ABS_MT_SLOT, 1,
++                                    EV_ABS, ABS_MT_TRACKING_ID, -1,
++                                    EV_KEY, BTN_TOOL_QUADTAP, 0,
++                                    EV_KEY, BTN_TOOL_TRIPLETAP, 1,
++                                    EV_SYN, SYN_REPORT, 0,
++                                    -1, -1);
++       uinput_device_event_multiple(uidev,
++                                    EV_ABS, ABS_MT_SLOT, 1,
++                                    EV_ABS, ABS_MT_TRACKING_ID, 666,
++                                    EV_ABS, ABS_X, 666,
++                                    EV_ABS, ABS_Y, 666,
++                                    EV_ABS, ABS_MT_POSITION_X, 666,
++                                    EV_ABS, ABS_MT_POSITION_Y, 666,
++                                    EV_KEY, BTN_TOOL_TRIPLETAP, 0,
++                                    EV_KEY, BTN_TOOL_QUADTAP, 1,
++                                    EV_SYN, SYN_REPORT, 0,
++                                    -1, -1);
++       uinput_device_event_multiple(uidev,
++                                    EV_ABS, ABS_MT_SLOT, 4,
++                                    EV_ABS, ABS_MT_TRACKING_ID, -1,
++                                    EV_KEY, BTN_TOOL_QUADTAP, 0,
++                                    EV_KEY, BTN_TOOL_TRIPLETAP, 1,
++                                    EV_SYN, SYN_REPORT, 0,
++                                    -1, -1);
++       uinput_device_event_multiple(uidev,
++                                    EV_ABS, ABS_MT_SLOT, 4,
++                                    EV_ABS, ABS_MT_TRACKING_ID, 777,
++                                    EV_ABS, ABS_X, 777,
++                                    EV_ABS, ABS_Y, 777,
++                                    EV_ABS, ABS_MT_POSITION_X, 777,
++                                    EV_ABS, ABS_MT_POSITION_Y, 777,
++                                    EV_KEY, BTN_TOOL_QUADTAP, 1,
++                                    EV_KEY, BTN_TOOL_TRIPLETAP, 0,
++                                    EV_SYN, SYN_REPORT, 0,
++                                    -1, -1);
++
++       /* Force sync */
++       rc = libevdev_next_event(dev, LIBEVDEV_READ_FLAG_FORCE_SYNC, &ev);
++       ck_assert_int_eq(rc, LIBEVDEV_READ_STATUS_SYNC);
++
++       /* In the first sync frame, we expect us to drop to 2 touches - we
++        * started with 5, 1 stopped, 2 stopped+restarted */
++       while ((rc = libevdev_next_event(dev, LIBEVDEV_READ_FLAG_SYNC, &ev)) != -EAGAIN) {
++               if (libevdev_event_is_code(&ev, EV_KEY, BTN_TOOL_QUINTTAP)) {
++                       ck_assert(!have_quinttap);
++                       assert_event(&ev, EV_KEY, BTN_TOOL_QUINTTAP, 0);
++                       have_quinttap = true;
++               }
++
++               if (libevdev_event_is_code(&ev, EV_KEY, BTN_TOOL_TRIPLETAP))
++		       ck_abort();
++
++               if (libevdev_event_is_code(&ev, EV_KEY, BTN_TOOL_DOUBLETAP)) {
++                       ck_assert(!have_doubletap);
++                       assert_event(&ev, EV_KEY, BTN_TOOL_DOUBLETAP, 1);
++                       have_doubletap = true;
++               }
++
++               ck_assert(!libevdev_event_is_code(&ev, EV_KEY, BTN_TOOL_TRIPLETAP));
++               ck_assert(!libevdev_event_is_code(&ev, EV_KEY, BTN_TOOL_QUADTAP));
++               ck_assert(!libevdev_event_is_code(&ev, EV_KEY, BTN_TOOL_FINGER));
++
++               if (libevdev_event_is_code(&ev, EV_SYN, SYN_REPORT)) {
++                       ck_assert(have_doubletap);
++                       ck_assert(have_quinttap);
++                       break;
++               }
++       }
++
++       have_doubletap = false;
++       have_quadtap = false;
++
++       /* In the second sync frame, we expect to go back to 4 touches,
++        * recovering the two stopped+started touches */
++       while ((rc = libevdev_next_event(dev, LIBEVDEV_READ_FLAG_SYNC, &ev)) != -EAGAIN) {
++               if (libevdev_event_is_code(&ev, EV_KEY, BTN_TOOL_QUADTAP)) {
++                       ck_assert(!have_quadtap);
++                       assert_event(&ev, EV_KEY, BTN_TOOL_QUADTAP, 1);
++                       have_quadtap = true;
++               }
++
++               if (libevdev_event_is_code(&ev, EV_KEY, BTN_TOOL_TRIPLETAP))
++		       ck_abort();
++
++               if (libevdev_event_is_code(&ev, EV_KEY, BTN_TOOL_DOUBLETAP)) {
++                       ck_assert(!have_doubletap);
++                       assert_event(&ev, EV_KEY, BTN_TOOL_DOUBLETAP, 0);
++                       have_doubletap = true;
++               }
++
++               ck_assert(!libevdev_event_is_code(&ev, EV_KEY, BTN_TOOL_TRIPLETAP));
++               ck_assert(!libevdev_event_is_code(&ev, EV_KEY, BTN_TOOL_QUINTTAP));
++               ck_assert(!libevdev_event_is_code(&ev, EV_KEY, BTN_TOOL_FINGER));
++
++               if (libevdev_event_is_code(&ev, EV_SYN, SYN_REPORT)) {
++                       ck_assert(have_doubletap);
++                       ck_assert(have_quadtap);
++                       break;
++               }
++       }
++
++        uinput_device_free(uidev);
++        libevdev_free(dev);
++}
++END_TEST
++
++START_TEST(test_syn_delta_late_sync)
++{
++	struct uinput_device* uidev;
++	struct libevdev *dev;
++	int rc;
++	struct input_event ev;
++	struct input_absinfo abs[6] = {
++		{ .value = ABS_X, .maximum = 1000 },
++		{ .value = ABS_Y, .maximum = 1000 },
++		{ .value = ABS_MT_POSITION_X, .maximum = 1000 },
++		{ .value = ABS_MT_POSITION_Y, .maximum = 1000 },
++		{ .value = ABS_MT_SLOT, .maximum = 1 },
++		{ .value = ABS_MT_TRACKING_ID, .minimum = -1, .maximum = 0xff},
++	};
++	int i, slot;
++
++	test_create_abs_device(&uidev, &dev,
++			       ARRAY_LENGTH(abs), abs,
++			       EV_SYN, SYN_REPORT,
++			       -1);
++
++	/* emulate a touch down, make sure libevdev sees it */
++	uinput_device_event_multiple(uidev,
++				     EV_ABS, ABS_MT_SLOT, 0,
++				     EV_ABS, ABS_MT_TRACKING_ID, 1,
++				     EV_ABS, ABS_X, 100,
++				     EV_ABS, ABS_Y, 500,
++				     EV_ABS, ABS_MT_POSITION_X, 100,
++				     EV_ABS, ABS_MT_POSITION_Y, 500,
++				     EV_SYN, SYN_REPORT, 0,
++				     -1, -1);
++	do {
++		rc = libevdev_next_event(dev, LIBEVDEV_READ_FLAG_NORMAL, &ev);
++		ck_assert_int_ne(rc, LIBEVDEV_READ_STATUS_SYNC);
++	} while (rc >= 0);
++
++	/* force enough events to trigger a SYN_DROPPED */
++	for (i = 0; i < 100; i++) {
++		uinput_device_event_multiple(uidev,
++					     EV_ABS, ABS_X, 100 + i,
++					     EV_ABS, ABS_Y, 500 + i,
++					     EV_ABS, ABS_MT_POSITION_X, 100 + i,
++					     EV_ABS, ABS_MT_POSITION_Y, 500 + i,
++					     EV_SYN, SYN_REPORT, 0,
++					     -1, -1);
++	}
++
++	rc = libevdev_next_event(dev, LIBEVDEV_READ_FLAG_NORMAL, &ev);
++	ck_assert_int_eq(rc, LIBEVDEV_READ_STATUS_SYNC);
++
++	/* trigger the tracking ID change after getting the SYN_DROPPED */
++	uinput_device_event_multiple(uidev,
++				     EV_ABS, ABS_MT_SLOT, 0,
++				     EV_ABS, ABS_MT_TRACKING_ID, -1,
++				     EV_ABS, ABS_X, 200,
++				     EV_ABS, ABS_Y, 600,
++				     EV_ABS, ABS_MT_POSITION_X, 200,
++				     EV_ABS, ABS_MT_POSITION_Y, 600,
++				     EV_SYN, SYN_REPORT, 0,
++				     -1, -1);
++
++	slot = 0;
++
++	/* Now sync the device, expect the data to be equal to the last event*/
++	while ((rc = libevdev_next_event(dev, LIBEVDEV_READ_FLAG_SYNC, &ev)) != -EAGAIN) {
++		if (ev.type == EV_SYN)
++			continue;
++
++		ck_assert_int_eq(ev.type, EV_ABS);
++		switch(ev.code) {
++			case ABS_MT_SLOT:
++				slot = ev.value;
++				break;
++			case ABS_MT_TRACKING_ID:
++				if (slot == 0)
++					ck_assert_int_eq(ev.value, -1);
++				break;
++			case ABS_X:
++			case ABS_MT_POSITION_X:
++				ck_assert_int_eq(ev.value, 200);
++				break;
++			case ABS_Y:
++			case ABS_MT_POSITION_Y:
++				ck_assert_int_eq(ev.value, 600);
++				break;
++		}
++	}
++
++	/* And a new tracking ID */
++	uinput_device_event_multiple(uidev,
++				     EV_ABS, ABS_MT_SLOT, 0,
++				     EV_ABS, ABS_MT_TRACKING_ID, 2,
++				     EV_ABS, ABS_X, 201,
++				     EV_ABS, ABS_Y, 601,
++				     EV_ABS, ABS_MT_POSITION_X, 201,
++				     EV_ABS, ABS_MT_POSITION_Y, 601,
++				     EV_SYN, SYN_REPORT, 0,
++				     -1, -1);
++
++	while ((rc = libevdev_next_event(dev, LIBEVDEV_READ_FLAG_NORMAL, &ev)) != -EAGAIN) {
++		ck_assert_int_ne(rc, LIBEVDEV_READ_STATUS_SYNC);
++
++		if (ev.type == EV_SYN)
++			continue;
++
++		ck_assert_int_eq(ev.type, EV_ABS);
++
++		switch(ev.code) {
++			case ABS_MT_SLOT:
++				ck_assert_int_eq(ev.value, 0);
++				break;
++			case ABS_MT_TRACKING_ID:
++				ck_assert_int_eq(ev.value, 2);
++				break;
++			case ABS_X:
++			case ABS_MT_POSITION_X:
++				ck_assert_int_eq(ev.value, 201);
++				break;
++			case ABS_Y:
++			case ABS_MT_POSITION_Y:
++				ck_assert_int_eq(ev.value, 601);
++				break;
++		}
++	}
++
++	/* Now we basically re-do the exact same test, just with the
++	   tracking ID order inverted */
++
++	/* drop the tracking ID, make sure libevdev sees it */
++	uinput_device_event(uidev, EV_ABS, ABS_MT_SLOT, 0);
++	uinput_device_event(uidev, EV_ABS, ABS_MT_TRACKING_ID, -1);
++	uinput_device_event(uidev, EV_SYN, SYN_REPORT, 0);
++	do {
++		rc = libevdev_next_event(dev, LIBEVDEV_READ_FLAG_NORMAL, &ev);
++		ck_assert_int_ne(rc, LIBEVDEV_READ_STATUS_SYNC);
++	} while (rc >= 0);
++
++	/* force enough events to trigger a SYN_DROPPED */
++	for (i = 0; i < 100; i++) {
++		uinput_device_event_multiple(uidev,
++					     EV_ABS, ABS_X, 100 + i,
++					     EV_ABS, ABS_Y, 500 + i,
++					     EV_ABS, ABS_MT_POSITION_X, 100 + i,
++					     EV_ABS, ABS_MT_POSITION_Y, 500 + i,
++					     EV_SYN, SYN_REPORT, 0,
++					     -1, -1);
++	}
++
++	rc = libevdev_next_event(dev, LIBEVDEV_READ_FLAG_NORMAL, &ev);
++	ck_assert_int_eq(rc, LIBEVDEV_READ_STATUS_SYNC);
++
++	/* trigger the new tracking ID after getting the SYN_DROPPED */
++	uinput_device_event_multiple(uidev,
++				     EV_ABS, ABS_MT_SLOT, 0,
++				     EV_ABS, ABS_MT_TRACKING_ID, 5,
++				     EV_ABS, ABS_X, 200,
++				     EV_ABS, ABS_Y, 600,
++				     EV_ABS, ABS_MT_POSITION_X, 200,
++				     EV_ABS, ABS_MT_POSITION_Y, 600,
++				     EV_SYN, SYN_REPORT, 0,
++				     -1, -1);
++
++	slot = 0;
++
++	/* Now sync the device, expect the data to be equal to the last event*/
++	while ((rc = libevdev_next_event(dev, LIBEVDEV_READ_FLAG_SYNC, &ev)) != -EAGAIN) {
++		if (ev.type == EV_SYN)
++			continue;
++
++		ck_assert_int_eq(ev.type, EV_ABS);
++		switch(ev.code) {
++			case ABS_MT_SLOT:
++				slot = ev.value;
++				break;
++			case ABS_MT_TRACKING_ID:
++				if (slot == 0)
++					ck_assert_int_eq(ev.value, 5);
++				break;
++			case ABS_X:
++			case ABS_MT_POSITION_X:
++				ck_assert_int_eq(ev.value, 200);
++				break;
++			case ABS_Y:
++			case ABS_MT_POSITION_Y:
++				ck_assert_int_eq(ev.value, 600);
++				break;
++		}
++	}
++
++	/* Drop the tracking ID */
++	uinput_device_event(uidev, EV_ABS, ABS_MT_SLOT, 0);
++	uinput_device_event(uidev, EV_ABS, ABS_MT_TRACKING_ID, -1);
++	uinput_device_event(uidev, EV_SYN, SYN_REPORT, 0);
++
++	while ((rc = libevdev_next_event(dev, LIBEVDEV_READ_FLAG_NORMAL, &ev)) != -EAGAIN) {
++		ck_assert_int_ne(rc, LIBEVDEV_READ_STATUS_SYNC);
++
++		if (ev.type == EV_SYN)
++			continue;
++
++		ck_assert_int_eq(ev.type, EV_ABS);
++
++		switch(ev.code) {
++			case ABS_MT_SLOT:
++				ck_assert_int_eq(ev.value, 0);
++				break;
++			case ABS_MT_TRACKING_ID:
++				ck_assert_int_eq(ev.value, -1);
++				break;
++		}
++	}
++
++	uinput_device_free(uidev);
++	libevdev_free(dev);
++}
++END_TEST
++
++START_TEST(test_syn_delta_fake_mt)
++{
++	struct uinput_device* uidev;
++	struct libevdev *dev;
++	int rc;
++	struct input_event ev;
++	struct input_absinfo abs[] = {
++		{ .value = ABS_X, .minimum = 0, .maximum = 1000 },
++		{ .value = ABS_Y, .minimum = 0, .maximum = 1000 },
++		{ .value = ABS_MT_POSITION_X, .minimum = 0, .maximum = 1000 },
++		{ .value = ABS_MT_POSITION_Y, .minimum = 0, .maximum = 1000 },
++		{ .value = ABS_MT_SLOT - 1, .minimum = 0, .maximum = 2 }};
++		/* don't set ABS_MT_SLOT here, otherwise uinput will init
++		 * slots and the behavior is different to real devices with
++		 * such events */
++	unsigned long received[NLONGS(ABS_CNT)] = {0};
++
++	test_create_abs_device(&uidev, &dev, ARRAY_LENGTH(abs), abs, -1);
++	/* first set of events */
++	uinput_device_event_multiple(uidev,
++				     EV_ABS, ABS_X, 200,
++				     EV_ABS, ABS_Y, 400,
++				     EV_ABS, ABS_MT_POSITION_X, 100,
++				     EV_ABS, ABS_MT_POSITION_Y, 500,
++				     EV_ABS, ABS_MT_SLOT - 1, 1,
++				     EV_SYN, SYN_REPORT, 0,
++				     -1, -1);
++
++	/* second set of events */
++	uinput_device_event_multiple(uidev,
++				     EV_ABS, ABS_X, 201,
++				     EV_ABS, ABS_Y, 401,
++				     EV_ABS, ABS_MT_POSITION_X, 101,
++				     EV_ABS, ABS_MT_POSITION_Y, 501,
++				     EV_ABS, ABS_MT_SLOT - 1, 2,
++				     EV_SYN, SYN_REPORT, 0,
++				     -1, -1);
++
++	rc = libevdev_next_event(dev, LIBEVDEV_READ_FLAG_FORCE_SYNC, &ev);
++	ck_assert_int_eq(rc, LIBEVDEV_READ_STATUS_SYNC);
++
++	while ((rc = libevdev_next_event(dev, LIBEVDEV_READ_STATUS_SYNC, &ev)) != -EAGAIN) {
++		if (ev.type != EV_ABS)
++			continue;
++
++		ck_assert(!bit_is_set(received, ev.code));
++
++		switch(ev.code) {
++			/* see comment below for ABS_MT_POSITION_X
++			 * and ABS_MT_POSITION_Y */
++			case ABS_MT_POSITION_X:
++			case ABS_MT_POSITION_Y:
++				ck_abort();
++				break;
++
++			case ABS_MT_SLOT - 1: ck_assert_int_eq(ev.value, 2); break;
++			case ABS_X: ck_assert_int_eq(ev.value, 201); break;
++			case ABS_Y: ck_assert_int_eq(ev.value, 401); break;
++			default:
++				ck_abort();
++		}
++
++		set_bit(received, ev.code);
++	}
++
++	/* Dont' expect ABS_MT values, they are ignored during the sync
++	 * process */
++	ck_assert(!bit_is_set(received, ABS_MT_POSITION_X));
++	ck_assert(!bit_is_set(received, ABS_MT_POSITION_Y));
++	ck_assert(bit_is_set(received, ABS_MT_SLOT - 1));
++	ck_assert(bit_is_set(received, ABS_X));
++	ck_assert(bit_is_set(received, ABS_Y));
++
++	ck_assert_int_eq(libevdev_get_event_value(dev, EV_ABS, ABS_X), 201);
++	ck_assert_int_eq(libevdev_get_event_value(dev, EV_ABS, ABS_Y), 401);
++	ck_assert_int_eq(libevdev_get_event_value(dev, EV_ABS, ABS_MT_SLOT - 1), 2);
++
++	uinput_device_free(uidev);
++	libevdev_free(dev);
++}
++END_TEST
++
++START_TEST(test_skipped_sync)
++{
++	struct uinput_device* uidev;
++	struct libevdev *dev;
++	int rc;
++	struct input_event ev;
++	struct input_absinfo abs[2] = {
++		{ .value = ABS_X, .maximum = 1000 },
++		{ .value = ABS_Y, .maximum = 1000 },
++	};
++
++	test_create_abs_device(&uidev, &dev,
++			       ARRAY_LENGTH(abs), abs,
++			       EV_SYN, SYN_REPORT,
++			       EV_SYN, SYN_DROPPED,
++			       EV_KEY, BTN_LEFT,
++			       EV_KEY, BTN_MIDDLE,
++			       EV_KEY, BTN_RIGHT,
++			       -1);
++
++	uinput_device_event(uidev, EV_KEY, BTN_LEFT, 1);
++	uinput_device_event(uidev, EV_ABS, ABS_X, 100);
++	uinput_device_event(uidev, EV_ABS, ABS_Y, 500);
++	uinput_device_event(uidev, EV_SYN, SYN_REPORT, 0);
++	rc = libevdev_next_event(dev, LIBEVDEV_READ_FLAG_FORCE_SYNC, &ev);
++	ck_assert_int_eq(rc, LIBEVDEV_READ_STATUS_SYNC);
++
++	rc = libevdev_next_event(dev, LIBEVDEV_READ_FLAG_NORMAL, &ev);
++	ck_assert_int_eq(rc, -EAGAIN);
++
++	ck_assert_int_eq(libevdev_get_event_value(dev, EV_KEY, BTN_LEFT), 1);
++	ck_assert_int_eq(libevdev_get_event_value(dev, EV_ABS, ABS_X), 100);
++	ck_assert_int_eq(libevdev_get_event_value(dev, EV_ABS, ABS_Y), 500);
++
++	uinput_device_free(uidev);
++	libevdev_free(dev);
++}
++END_TEST
++
++START_TEST(test_incomplete_sync)
++{
++	struct uinput_device* uidev;
++	struct libevdev *dev;
++	int rc;
++	struct input_event ev;
++	struct input_absinfo abs[2] = {
++		{ .value = ABS_X, .maximum = 1000 },
++		{ .value = ABS_Y, .maximum = 1000 },
++	};
++
++	test_create_abs_device(&uidev, &dev,
++			       ARRAY_LENGTH(abs), abs,
++			       EV_SYN, SYN_REPORT,
++			       EV_SYN, SYN_DROPPED,
++			       EV_KEY, BTN_LEFT,
++			       EV_KEY, BTN_MIDDLE,
++			       EV_KEY, BTN_RIGHT,
++			       -1);
++
++	uinput_device_event(uidev, EV_KEY, BTN_LEFT, 1);
++	uinput_device_event(uidev, EV_ABS, ABS_X, 100);
++	uinput_device_event(uidev, EV_ABS, ABS_Y, 500);
++	uinput_device_event(uidev, EV_SYN, SYN_REPORT, 0);
++	rc = libevdev_next_event(dev, LIBEVDEV_READ_FLAG_FORCE_SYNC, &ev);
++	ck_assert_int_eq(rc, LIBEVDEV_READ_STATUS_SYNC);
++
++	rc = libevdev_next_event(dev, LIBEVDEV_READ_FLAG_SYNC, &ev);
++	ck_assert_int_eq(rc, LIBEVDEV_READ_STATUS_SYNC);
++	assert_event(&ev, EV_KEY, BTN_LEFT, 1);
++
++	rc = libevdev_next_event(dev, LIBEVDEV_READ_FLAG_NORMAL, &ev);
++	ck_assert_int_eq(rc, -EAGAIN);
++
++	ck_assert_int_eq(libevdev_get_event_value(dev, EV_KEY, BTN_LEFT), 1);
++	ck_assert_int_eq(libevdev_get_event_value(dev, EV_ABS, ABS_X), 100);
++	ck_assert_int_eq(libevdev_get_event_value(dev, EV_ABS, ABS_Y), 500);
++
++	uinput_device_free(uidev);
++	libevdev_free(dev);
++}
++END_TEST
++
++START_TEST(test_empty_sync)
++{
++	struct uinput_device* uidev;
++	struct libevdev *dev;
++	int rc;
++	struct input_event ev;
++
++	test_create_device(&uidev, &dev,
++			   EV_SYN, SYN_REPORT,
++			   EV_SYN, SYN_DROPPED,
++			   EV_KEY, BTN_LEFT,
++			   EV_KEY, BTN_MIDDLE,
++			   EV_KEY, BTN_RIGHT,
++			   -1);
++
++	rc = libevdev_next_event(dev, LIBEVDEV_READ_FLAG_FORCE_SYNC, &ev);
++	ck_assert_int_eq(rc, LIBEVDEV_READ_STATUS_SYNC);
++
++	rc = libevdev_next_event(dev, LIBEVDEV_READ_FLAG_SYNC, &ev);
++	ck_assert_int_eq(rc, -EAGAIN);
++
++	uinput_device_free(uidev);
++	libevdev_free(dev);
++}
++END_TEST
++
++START_TEST(test_event_values)
++{
++	struct uinput_device* uidev;
++	struct libevdev *dev;
++	int rc;
++	struct input_event ev;
++	struct input_absinfo abs[2] = {
++		{ .value = ABS_X, .maximum = 1000 },
++		{ .value = ABS_Y, .maximum = 1000 },
++	};
++	int value;
++
++	test_create_abs_device(&uidev, &dev,
++			       ARRAY_LENGTH(abs), abs,
++			       EV_SYN, SYN_REPORT,
++			       EV_SYN, SYN_DROPPED,
++			       EV_REL, REL_X,
++			       EV_REL, REL_Y,
++			       EV_KEY, BTN_LEFT,
++			       EV_KEY, BTN_MIDDLE,
++			       EV_KEY, BTN_RIGHT,
++			       -1);
++
++	uinput_device_event(uidev, EV_KEY, BTN_LEFT, 1);
++	uinput_device_event(uidev, EV_ABS, ABS_X, 100);
++	uinput_device_event(uidev, EV_ABS, ABS_Y, 500);
++	uinput_device_event(uidev, EV_SYN, SYN_REPORT, 0);
++
++	/* must still be on old values */
++	ck_assert_int_eq(libevdev_get_event_value(dev, EV_KEY, BTN_LEFT), 0);
++	ck_assert_int_eq(libevdev_get_event_value(dev, EV_ABS, ABS_X), 0);
++	ck_assert_int_eq(libevdev_get_event_value(dev, EV_ABS, ABS_Y), 0);
++	ck_assert_int_eq(libevdev_get_event_value(dev, EV_REL, REL_X), 0);
++	ck_assert_int_eq(libevdev_get_event_value(dev, EV_REL, REL_Y), 0);
++
++	ck_assert_int_eq(libevdev_fetch_event_value(dev, EV_KEY, BTN_LEFT, &value), 1);
++	ck_assert_int_eq(value, 0);
++
++	do {
++		rc = libevdev_next_event(dev, LIBEVDEV_READ_FLAG_NORMAL, &ev);
++	} while (rc == 0);
++	ck_assert_int_eq(rc, -EAGAIN);
++
++	ck_assert_int_eq(libevdev_get_event_value(dev, EV_KEY, BTN_LEFT), 1);
++	ck_assert_int_eq(libevdev_get_event_value(dev, EV_ABS, ABS_X), 100);
++	ck_assert_int_eq(libevdev_get_event_value(dev, EV_ABS, ABS_Y), 500);
++
++	/* always 0 */
++	ck_assert_int_eq(libevdev_get_event_value(dev, EV_REL, REL_X), 0);
++	ck_assert_int_eq(libevdev_get_event_value(dev, EV_REL, REL_Y), 0);
++
++	ck_assert_int_eq(libevdev_fetch_event_value(dev, EV_KEY, BTN_LEFT, &value), 1);
++	ck_assert_int_eq(value, 1);
++	ck_assert_int_eq(libevdev_fetch_event_value(dev, EV_ABS, ABS_X, &value), 1);
++	ck_assert_int_eq(value, 100);
++	ck_assert_int_eq(libevdev_fetch_event_value(dev, EV_ABS, ABS_Y, &value), 1);
++	ck_assert_int_eq(value, 500);
++
++	uinput_device_free(uidev);
++	libevdev_free(dev);
++
++}
++END_TEST
++
++START_TEST(test_event_values_invalid)
++{
++	struct uinput_device* uidev;
++	struct libevdev *dev;
++	struct input_absinfo abs[2] = {
++		{ .value = ABS_X, .maximum = 1000 },
++		{ .value = ABS_Y, .maximum = 1000 },
++	};
++	int value;
++
++	test_create_abs_device(&uidev, &dev,
++			       ARRAY_LENGTH(abs), abs,
++			       EV_SYN, SYN_REPORT,
++			       EV_SYN, SYN_DROPPED,
++			       EV_REL, REL_X,
++			       EV_REL, REL_Y,
++			       EV_KEY, BTN_LEFT,
++			       EV_KEY, BTN_MIDDLE,
++			       EV_KEY, BTN_RIGHT,
++			       -1);
++
++	ck_assert_int_eq(libevdev_get_event_value(dev, EV_KEY, BTN_EXTRA), 0);
++	ck_assert_int_eq(libevdev_get_event_value(dev, EV_ABS, ABS_Z), 0);
++	ck_assert_int_eq(libevdev_get_event_value(dev, EV_REL, REL_Z), 0);
++
++	value = 0xab;
++	ck_assert_int_eq(libevdev_fetch_event_value(dev, EV_KEY, BTN_EXTRA, &value), 0);
++	ck_assert_int_eq(value, 0xab);
++	ck_assert_int_eq(libevdev_fetch_event_value(dev, EV_ABS, ABS_Z, &value), 0);
++	ck_assert_int_eq(value, 0xab);
++	ck_assert_int_eq(libevdev_fetch_event_value(dev, EV_REL, REL_Z, &value), 0);
++	ck_assert_int_eq(value, 0xab);
++
++	uinput_device_free(uidev);
++	libevdev_free(dev);
++
++}
++END_TEST
++
++START_TEST(test_mt_event_values)
++{
++	struct uinput_device* uidev;
++	struct libevdev *dev;
++	int rc;
++	struct input_event ev;
++	struct input_absinfo abs[5] = {
++		{ .value = ABS_X, .maximum = 1000 },
++		{ .value = ABS_Y, .maximum = 1000 },
++		{ .value = ABS_MT_POSITION_X, .maximum = 1000 },
++		{ .value = ABS_MT_POSITION_Y, .maximum = 1000 },
++		{ .value = ABS_MT_SLOT, .maximum = 2 },
++	};
++	int value;
++	test_create_abs_device(&uidev, &dev,
++			       ARRAY_LENGTH(abs), abs,
++			       EV_SYN, SYN_REPORT,
++			       -1);
++
++	uinput_device_event_multiple(uidev,
++				     EV_ABS, ABS_MT_SLOT, 0,
++				     EV_ABS, ABS_X, 100,
++				     EV_ABS, ABS_Y, 500,
++				     EV_ABS, ABS_MT_POSITION_X, 100,
++				     EV_ABS, ABS_MT_POSITION_Y, 500,
++				     EV_ABS, ABS_MT_SLOT, 1,
++				     EV_ABS, ABS_X, 1,
++				     EV_ABS, ABS_Y, 5,
++				     EV_ABS, ABS_MT_POSITION_X, 1,
++				     EV_ABS, ABS_MT_POSITION_Y, 5,
++				     EV_SYN, SYN_REPORT, 0,
++				     -1, -1);
++
++	/* must still be on old values */
++	ck_assert_int_eq(libevdev_get_current_slot(dev), 0);
++	ck_assert_int_eq(libevdev_get_slot_value(dev, 0, ABS_MT_POSITION_X), 0);
++	ck_assert_int_eq(libevdev_get_slot_value(dev, 0, ABS_MT_POSITION_Y), 0);
++	ck_assert_int_eq(libevdev_get_slot_value(dev, 1, ABS_MT_POSITION_X), 0);
++	ck_assert_int_eq(libevdev_get_slot_value(dev, 1, ABS_MT_POSITION_Y), 0);
++
++	do {
++		rc = libevdev_next_event(dev, LIBEVDEV_READ_FLAG_NORMAL, &ev);
++	} while (rc == LIBEVDEV_READ_STATUS_SUCCESS);
++	ck_assert_int_eq(rc, -EAGAIN);
++
++	ck_assert_int_eq(libevdev_get_current_slot(dev), 1);
++	ck_assert_int_eq(libevdev_get_slot_value(dev, 0, ABS_MT_POSITION_X), 100);
++	ck_assert_int_eq(libevdev_get_slot_value(dev, 0, ABS_MT_POSITION_Y), 500);
++	ck_assert_int_eq(libevdev_get_slot_value(dev, 1, ABS_MT_POSITION_X), 1);
++	ck_assert_int_eq(libevdev_get_slot_value(dev, 1, ABS_MT_POSITION_Y), 5);
++
++	ck_assert_int_eq(libevdev_fetch_slot_value(dev, 0, ABS_MT_POSITION_X, &value), 1);
++	ck_assert_int_eq(value, 100);
++	ck_assert_int_eq(libevdev_fetch_slot_value(dev, 0, ABS_MT_POSITION_Y, &value), 1);
++	ck_assert_int_eq(value, 500);
++	ck_assert_int_eq(libevdev_fetch_slot_value(dev, 1, ABS_MT_POSITION_X, &value), 1);
++	ck_assert_int_eq(value, 1);
++	ck_assert_int_eq(libevdev_fetch_slot_value(dev, 1, ABS_MT_POSITION_Y, &value), 1);
++	ck_assert_int_eq(value, 5);
++
++	uinput_device_free(uidev);
++	libevdev_free(dev);
++
++}
++END_TEST
++
++START_TEST(test_mt_event_values_invalid)
++{
++	struct uinput_device* uidev;
++	struct libevdev *dev;
++	struct input_absinfo abs[5] = {
++		{ .value = ABS_X, .maximum = 1000 },
++		{ .value = ABS_Y, .maximum = 1000 },
++		{ .value = ABS_MT_POSITION_X, .maximum = 1000 },
++		{ .value = ABS_MT_POSITION_Y, .maximum = 1000 },
++		{ .value = ABS_MT_SLOT, .maximum = 2 },
++	};
++	int value;
++
++	test_create_abs_device(&uidev, &dev,
++			       ARRAY_LENGTH(abs), abs,
++			       EV_SYN, SYN_REPORT,
++			       -1);
++
++	ck_assert_int_eq(libevdev_get_current_slot(dev), 0);
++	ck_assert_int_eq(libevdev_get_slot_value(dev, 0, ABS_MT_TOUCH_MINOR), 0);
++	value = 0xab;
++	ck_assert_int_eq(libevdev_fetch_slot_value(dev, 0, ABS_MT_TOUCH_MINOR, &value), 0);
++	ck_assert_int_eq(value, 0xab);
++
++	ck_assert_int_eq(libevdev_get_slot_value(dev, 10, ABS_MT_POSITION_X), 0);
++	ck_assert_int_eq(libevdev_get_slot_value(dev, 0, ABS_X), 0);
++
++	uinput_device_free(uidev);
++	libevdev_free(dev);
++}
++END_TEST
++
++START_TEST(test_mt_slot_ranges_invalid)
++{
++	struct uinput_device* uidev;
++	struct libevdev *dev;
++	struct input_event ev[2];
++	int rc;
++	int num_slots = 2;
++	struct input_absinfo abs[5] = {
++		{ .value = ABS_X, .maximum = 1000 },
++		{ .value = ABS_Y, .maximum = 1000 },
++		{ .value = ABS_MT_POSITION_X, .maximum = 1000 },
++		{ .value = ABS_MT_POSITION_Y, .maximum = 1000 },
++		{ .value = ABS_MT_SLOT, .maximum = num_slots - 1 },
++	};
++	int pipefd[2];
++
++	test_create_abs_device(&uidev, &dev,
++			       ARRAY_LENGTH(abs), abs,
++			       EV_SYN, SYN_REPORT,
++			       -1);
++
++	rc = pipe2(pipefd, O_NONBLOCK);
++	ck_assert_int_eq(rc, 0);
++	libevdev_change_fd(dev, pipefd[0]);
++
++	memset(ev, 0, sizeof(ev));
++	ev[0].type = EV_ABS;
++	ev[0].code = ABS_MT_SLOT;
++	ev[0].value = num_slots;
++	ev[1].type = EV_SYN;
++	ev[1].code = SYN_REPORT;
++	ev[1].value = 0;
++	rc = write(pipefd[1], ev, sizeof(ev));
++	ck_assert_int_eq(rc, sizeof(ev));
++
++	libevdev_set_log_function(test_logfunc_ignore_error, NULL);
++
++	libevdev_next_event(dev, LIBEVDEV_READ_FLAG_NORMAL, ev);
++	ck_assert(libevdev_event_is_code(ev, EV_ABS, ABS_MT_SLOT));
++	ck_assert_int_eq(ev[0].value, num_slots - 1);
++
++	/* drain the EV_SYN */
++	libevdev_next_event(dev, LIBEVDEV_READ_FLAG_NORMAL, ev);
++
++	ev[0].type = EV_ABS;
++	ev[0].code = ABS_MT_SLOT;
++	ev[0].value = -1;
++	ev[1].type = EV_SYN;
++	ev[1].code = SYN_REPORT;
++	ev[1].value = 0;
++	rc = write(pipefd[1], ev, sizeof(ev));
++	ck_assert_int_eq(rc, sizeof(ev));
++
++	libevdev_next_event(dev, LIBEVDEV_READ_FLAG_NORMAL, ev);
++	ck_assert(libevdev_event_is_code(ev, EV_ABS, ABS_MT_SLOT));
++	ck_assert_int_eq(ev[0].value, num_slots - 1);
++
++	ck_assert_int_eq(libevdev_get_current_slot(dev), num_slots - 1);
++
++	ck_assert_int_eq(libevdev_set_event_value(dev, EV_ABS, ABS_MT_SLOT, num_slots), -1);
++	ck_assert_int_eq(libevdev_set_event_value(dev, EV_ABS, ABS_MT_SLOT, -1), -1);
++
++	libevdev_set_log_function(test_logfunc_abort_on_error, NULL);
++
++	uinput_device_free(uidev);
++	libevdev_free(dev);
++}
++END_TEST
++
++START_TEST(test_mt_tracking_id_discard)
++{
++	struct uinput_device* uidev;
++	struct libevdev *dev;
++	int rc;
++	struct input_event ev;
++	struct input_absinfo abs[6] = {
++		{ .value = ABS_X, .maximum = 1000 },
++		{ .value = ABS_Y, .maximum = 1000 },
++		{ .value = ABS_MT_POSITION_X, .maximum = 1000 },
++		{ .value = ABS_MT_POSITION_Y, .maximum = 1000 },
++		{ .value = ABS_MT_SLOT, .maximum = 10 },
++		{ .value = ABS_MT_TRACKING_ID, .minimum = -1, .maximum = 500 },
++	};
++
++	test_create_abs_device(&uidev, &dev,
++			       ARRAY_LENGTH(abs), abs,
++			       EV_SYN, SYN_REPORT,
++			       -1);
++
++	uinput_device_event(uidev, EV_ABS, ABS_MT_SLOT, 1);
++	uinput_device_event(uidev, EV_ABS, ABS_MT_TRACKING_ID, 1);
++	uinput_device_event(uidev, EV_SYN, SYN_REPORT, 0);
++
++	/* second tracking ID on same slot */
++	uinput_device_event(uidev, EV_ABS, ABS_MT_TRACKING_ID, 2);
++	uinput_device_event(uidev, EV_SYN, SYN_REPORT, 0);
++
++	libevdev_set_log_function(test_logfunc_ignore_error, NULL);
++
++	rc = libevdev_next_event(dev, LIBEVDEV_READ_FLAG_NORMAL, &ev);
++	ck_assert_int_eq(rc, LIBEVDEV_READ_STATUS_SUCCESS);
++	assert_event(&ev, EV_ABS, ABS_MT_SLOT, 1);
++
++	rc = libevdev_next_event(dev, LIBEVDEV_READ_FLAG_NORMAL, &ev);
++	ck_assert_int_eq(rc, LIBEVDEV_READ_STATUS_SUCCESS);
++	assert_event(&ev, EV_ABS, ABS_MT_TRACKING_ID, 1);
++
++	rc = libevdev_next_event(dev, LIBEVDEV_READ_FLAG_NORMAL, &ev);
++	ck_assert_int_eq(rc, LIBEVDEV_READ_STATUS_SUCCESS);
++	assert_event(&ev, EV_SYN, SYN_REPORT, 0);
++
++	/* expect tracking ID discarded */
++
++	rc = libevdev_next_event(dev, LIBEVDEV_READ_FLAG_NORMAL, &ev);
++	ck_assert_int_eq(rc, LIBEVDEV_READ_STATUS_SUCCESS);
++	assert_event(&ev, EV_SYN, SYN_REPORT, 0);
++
++	rc = libevdev_next_event(dev, LIBEVDEV_READ_FLAG_NORMAL, &ev);
++	ck_assert_int_eq(rc, -EAGAIN);
++
++	libevdev_set_log_function(test_logfunc_abort_on_error, NULL);
++
++	uinput_device_free(uidev);
++	libevdev_free(dev);
++}
++END_TEST
++
++START_TEST(test_mt_tracking_id_discard_neg_1)
++{
++	struct uinput_device* uidev;
++	struct libevdev *dev;
++	int rc;
++	struct input_event ev;
++	struct input_absinfo abs[6] = {
++		{ .value = ABS_X, .maximum = 1000 },
++		{ .value = ABS_Y, .maximum = 1000 },
++		{ .value = ABS_MT_POSITION_X, .maximum = 1000 },
++		{ .value = ABS_MT_POSITION_Y, .maximum = 1000 },
++		{ .value = ABS_MT_SLOT, .maximum = 10 },
++		{ .value = ABS_MT_TRACKING_ID, .minimum = -1, .maximum = 500 },
++	};
++	int pipefd[2];
++	struct input_event events[] = {
++		{ .type = EV_ABS, .code = ABS_MT_TRACKING_ID, .value = -1 },
++		{ .type = EV_SYN, .code = SYN_REPORT, .value = 0 },
++	};
++
++	rc = pipe2(pipefd, O_NONBLOCK);
++	ck_assert_int_eq(rc, 0);
++
++	test_create_abs_device(&uidev, &dev,
++			       ARRAY_LENGTH(abs), abs,
++			       EV_SYN, SYN_REPORT,
++			       -1);
++	uinput_device_event(uidev, EV_ABS, ABS_MT_SLOT, 1);
++	uinput_device_event(uidev, EV_ABS, ABS_MT_TRACKING_ID, 1);
++	uinput_device_event(uidev, EV_SYN, SYN_REPORT, 0);
++
++	while (libevdev_next_event(dev, LIBEVDEV_READ_FLAG_NORMAL, &ev) != -EAGAIN)
++		;
++
++	libevdev_set_log_function(test_logfunc_ignore_error, NULL);
++
++	/* two -1 tracking ids, need to use the pipe here, the kernel will
++	   filter it otherwise */
++	libevdev_change_fd(dev, pipefd[0]);
++
++	rc = write(pipefd[1], events, sizeof(events));
++	ck_assert_int_eq(rc, sizeof(events));
++	rc = write(pipefd[1], events, sizeof(events));
++	ck_assert_int_eq(rc, sizeof(events));
++
++	rc = libevdev_next_event(dev, LIBEVDEV_READ_FLAG_NORMAL, &ev);
++	ck_assert_int_eq(rc, LIBEVDEV_READ_STATUS_SUCCESS);
++	assert_event(&ev, EV_ABS, ABS_MT_TRACKING_ID, -1);
++	rc = libevdev_next_event(dev, LIBEVDEV_READ_FLAG_NORMAL, &ev);
++	ck_assert_int_eq(rc, LIBEVDEV_READ_STATUS_SUCCESS);
++	assert_event(&ev, EV_SYN, SYN_REPORT, 0);
++
++	/* expect second tracking ID discarded */
++
++	rc = libevdev_next_event(dev, LIBEVDEV_READ_FLAG_NORMAL, &ev);
++	ck_assert_int_eq(rc, LIBEVDEV_READ_STATUS_SUCCESS);
++	assert_event(&ev, EV_SYN, SYN_REPORT, 0);
++
++	rc = libevdev_next_event(dev, LIBEVDEV_READ_FLAG_NORMAL, &ev);
++	ck_assert_int_eq(rc, -EAGAIN);
++
++	libevdev_set_log_function(test_logfunc_abort_on_error, NULL);
++
++	uinput_device_free(uidev);
++	libevdev_free(dev);
++}
++END_TEST
++
++START_TEST(test_ev_rep_values)
++{
++	struct uinput_device* uidev;
++	struct libevdev *dev;
++	int delay = 500, period = 200;
++	test_create_device(&uidev, &dev,
++			   EV_KEY, BTN_LEFT,
++			   EV_REL, REL_X,
++			   EV_REL, REL_Y,
++			   EV_SYN, SYN_REPORT,
++			   -1);
++
++	libevdev_enable_event_code(dev, EV_REP, REP_DELAY, &delay);
++	libevdev_enable_event_code(dev, EV_REP, REP_PERIOD, &period);
++
++	ck_assert_int_eq(libevdev_has_event_type(dev, EV_REP), 1);
++	ck_assert_int_eq(libevdev_has_event_code(dev, EV_REP, REP_DELAY), 1);
++	ck_assert_int_eq(libevdev_has_event_code(dev, EV_REP, REP_PERIOD), 1);
++	ck_assert_int_eq(libevdev_get_event_value(dev, EV_REP, REP_DELAY), 500);
++	ck_assert_int_eq(libevdev_get_event_value(dev, EV_REP, REP_PERIOD), 200);
++
++	uinput_device_free(uidev);
++	libevdev_free(dev);
++}
++END_TEST
++
++START_TEST(test_event_value_setters)
++{
++	struct uinput_device* uidev;
++	struct libevdev *dev;
++	struct input_absinfo abs[2] = {
++		{ .value = ABS_X, .maximum = 1000 },
++		{ .value = ABS_Y, .maximum = 1000 },
++	};
++
++	test_create_abs_device(&uidev, &dev,
++			       ARRAY_LENGTH(abs), abs,
++			       EV_SYN, SYN_REPORT,
++			       EV_REL, REL_X,
++			       EV_REL, REL_Y,
++			       EV_KEY, BTN_LEFT,
++			       EV_KEY, BTN_MIDDLE,
++			       EV_KEY, BTN_RIGHT,
++			       EV_LED, LED_NUML,
++			       EV_LED, LED_CAPSL,
++			       EV_SW, SW_HEADPHONE_INSERT,
++			       EV_SW, SW_TABLET_MODE,
++			       -1);
++
++	ck_assert_int_eq(libevdev_get_event_value(dev, EV_KEY, BTN_LEFT), 0);
++	ck_assert_int_eq(libevdev_get_event_value(dev, EV_ABS, ABS_X), 0);
++	ck_assert_int_eq(libevdev_get_event_value(dev, EV_ABS, ABS_Y), 0);
++	ck_assert_int_eq(libevdev_get_event_value(dev, EV_REL, REL_X), 0);
++	ck_assert_int_eq(libevdev_get_event_value(dev, EV_REL, REL_Y), 0);
++
++	ck_assert_int_eq(libevdev_set_event_value(dev, EV_KEY, BTN_LEFT, 1), 0);
++	ck_assert_int_eq(libevdev_set_event_value(dev, EV_KEY, BTN_RIGHT, 1), 0);
++
++	ck_assert_int_eq(libevdev_get_event_value(dev, EV_KEY, BTN_LEFT), 1);
++	ck_assert_int_eq(libevdev_get_event_value(dev, EV_KEY, BTN_RIGHT), 1);
++
++	ck_assert_int_eq(libevdev_set_event_value(dev, EV_ABS, ABS_X, 10), 0);
++	ck_assert_int_eq(libevdev_set_event_value(dev, EV_ABS, ABS_Y, 20), 0);
++
++	ck_assert_int_eq(libevdev_get_event_value(dev, EV_ABS, ABS_X), 10);
++	ck_assert_int_eq(libevdev_get_event_value(dev, EV_ABS, ABS_Y), 20);
++
++	ck_assert_int_eq(libevdev_set_event_value(dev, EV_LED, LED_NUML, 1), 0);
++	ck_assert_int_eq(libevdev_set_event_value(dev, EV_LED, LED_CAPSL, 1), 0);
++
++	ck_assert_int_eq(libevdev_get_event_value(dev, EV_LED, LED_NUML), 1);
++	ck_assert_int_eq(libevdev_get_event_value(dev, EV_LED, LED_CAPSL), 1);
++
++	ck_assert_int_eq(libevdev_set_event_value(dev, EV_SW, SW_HEADPHONE_INSERT, 1), 0);
++	ck_assert_int_eq(libevdev_set_event_value(dev, EV_SW, SW_TABLET_MODE, 1), 0);
++
++	ck_assert_int_eq(libevdev_get_event_value(dev, EV_SW, SW_HEADPHONE_INSERT), 1);
++	ck_assert_int_eq(libevdev_get_event_value(dev, EV_SW, SW_TABLET_MODE), 1);
++
++	uinput_device_free(uidev);
++	libevdev_free(dev);
++
++}
++END_TEST
++
++START_TEST(test_event_value_setters_invalid)
++{
++	struct uinput_device* uidev;
++	struct libevdev *dev;
++	struct input_absinfo abs[2] = {
++		{ .value = ABS_X, .maximum = 1000 },
++		{ .value = ABS_Y, .maximum = 1000 },
++	};
++
++	test_create_abs_device(&uidev, &dev,
++			       ARRAY_LENGTH(abs), abs,
++			       EV_SYN, SYN_REPORT,
++			       EV_REL, REL_X,
++			       EV_REL, REL_Y,
++			       EV_KEY, BTN_LEFT,
++			       EV_KEY, BTN_MIDDLE,
++			       EV_KEY, BTN_RIGHT,
++			       -1);
++
++	ck_assert_int_eq(libevdev_set_event_value(dev, EV_REL, REL_X, 1), -1);
++	ck_assert_int_eq(libevdev_set_event_value(dev, EV_SW, SW_DOCK, 1), -1);
++	ck_assert_int_eq(libevdev_set_event_value(dev, EV_ABS, ABS_Z, 1), -1);
++	ck_assert_int_eq(libevdev_set_event_value(dev, EV_MAX + 1, 0, 1), -1);
++	ck_assert_int_eq(libevdev_set_event_value(dev, EV_SYN, SYN_REPORT, 0), -1);
++
++	uinput_device_free(uidev);
++	libevdev_free(dev);
++
++}
++END_TEST
++
++START_TEST(test_event_mt_value_setters)
++{
++	struct uinput_device* uidev;
++	struct libevdev *dev;
++	struct input_absinfo abs[5] = {
++		{ .value = ABS_X, .maximum = 1000 },
++		{ .value = ABS_Y, .maximum = 1000 },
++		{ .value = ABS_MT_POSITION_X, .maximum = 1000 },
++		{ .value = ABS_MT_POSITION_Y, .maximum = 1000 },
++		{ .value = ABS_MT_SLOT, .maximum = 2 },
++	};
++
++	test_create_abs_device(&uidev, &dev,
++			       ARRAY_LENGTH(abs), abs,
++			       EV_SYN, SYN_REPORT,
++			       -1);
++
++	ck_assert_int_eq(libevdev_set_slot_value(dev, 1, ABS_MT_POSITION_X, 1), 0);
++	ck_assert_int_eq(libevdev_set_slot_value(dev, 1, ABS_MT_POSITION_Y, 2), 0);
++	ck_assert_int_eq(libevdev_set_slot_value(dev, 0, ABS_MT_POSITION_X, 3), 0);
++	ck_assert_int_eq(libevdev_set_slot_value(dev, 0, ABS_MT_POSITION_Y, 4), 0);
++
++	ck_assert_int_eq(libevdev_get_slot_value(dev, 1, ABS_MT_POSITION_X), 1);
++	ck_assert_int_eq(libevdev_get_slot_value(dev, 1, ABS_MT_POSITION_Y), 2);
++	ck_assert_int_eq(libevdev_get_slot_value(dev, 0, ABS_MT_POSITION_X), 3);
++	ck_assert_int_eq(libevdev_get_slot_value(dev, 0, ABS_MT_POSITION_Y), 4);
++
++	ck_assert_int_eq(libevdev_set_slot_value(dev, 1, ABS_MT_SLOT, 1), 0);
++	ck_assert_int_eq(libevdev_get_slot_value(dev, 1, ABS_MT_SLOT), 1);
++	ck_assert_int_eq(libevdev_get_current_slot(dev), 1);
++
++	uinput_device_free(uidev);
++	libevdev_free(dev);
++}
++END_TEST
++
++START_TEST(test_event_mt_value_setters_invalid)
++{
++	struct uinput_device* uidev;
++	struct libevdev *dev;
++	struct input_absinfo abs[5] = {
++		{ .value = ABS_X, .maximum = 1000 },
++		{ .value = ABS_Y, .maximum = 1000 },
++		{ .value = ABS_MT_POSITION_X, .maximum = 1000 },
++		{ .value = ABS_MT_POSITION_Y, .maximum = 1000 },
++		{ .value = ABS_MT_SLOT, .maximum = 2 },
++	};
++
++	test_create_abs_device(&uidev, &dev,
++			       ARRAY_LENGTH(abs), abs,
++			       EV_SYN, SYN_REPORT,
++			       -1);
++
++	/* invalid axis */
++	ck_assert_int_eq(libevdev_set_slot_value(dev, 1, ABS_Z, 1), -1);
++	/* valid, but non-mt axis */
++	ck_assert_int_eq(libevdev_set_slot_value(dev, 1, ABS_X, 1), -1);
++	/* invalid mt axis */
++	ck_assert_int_eq(libevdev_set_slot_value(dev, 1, ABS_MT_PRESSURE, 1), -1);
++	/* invalid slot no */
++	ck_assert_int_eq(libevdev_set_slot_value(dev, 4, ABS_X, 1), -1);
++
++	uinput_device_free(uidev);
++	libevdev_free(dev);
++}
++END_TEST
++
++START_TEST(test_event_mt_value_setters_current_slot)
++{
++	struct uinput_device* uidev;
++	struct libevdev *dev;
++	struct input_absinfo abs[5] = {
++		{ .value = ABS_X, .maximum = 1000 },
++		{ .value = ABS_Y, .maximum = 1000 },
++		{ .value = ABS_MT_POSITION_X, .maximum = 1000 },
++		{ .value = ABS_MT_POSITION_Y, .maximum = 1000 },
++		{ .value = ABS_MT_SLOT, .maximum = 2 },
++	};
++
++	test_create_abs_device(&uidev, &dev,
++			       ARRAY_LENGTH(abs), abs,
++			       EV_SYN, SYN_REPORT,
++			       -1);
++
++	/* set_event_value/get_event_value works on the current slot */
++
++	ck_assert_int_eq(libevdev_get_current_slot(dev), 0);
++	ck_assert_int_eq(libevdev_set_event_value(dev, EV_ABS, ABS_MT_POSITION_X, 1), 0);
++	ck_assert_int_eq(libevdev_get_event_value(dev, EV_ABS, ABS_MT_POSITION_X), 1);
++	ck_assert_int_eq(libevdev_get_slot_value(dev, 0, ABS_MT_POSITION_X), 1);
++
++	ck_assert_int_eq(libevdev_set_event_value(dev, EV_ABS, ABS_MT_SLOT, 1), 0);
++	ck_assert_int_eq(libevdev_get_current_slot(dev), 1);
++	ck_assert_int_eq(libevdev_set_event_value(dev, EV_ABS, ABS_MT_POSITION_X, 2), 0);
++	ck_assert_int_eq(libevdev_get_event_value(dev, EV_ABS, ABS_MT_POSITION_X), 2);
++	ck_assert_int_eq(libevdev_get_slot_value(dev, 1, ABS_MT_POSITION_X), 2);
++
++	/* set slot 0, but current is still slot 1 */
++	ck_assert_int_eq(libevdev_set_slot_value(dev, 0, ABS_MT_POSITION_X, 3), 0);
++	ck_assert_int_eq(libevdev_get_event_value(dev, EV_ABS, ABS_MT_POSITION_X), 2);
++
++	ck_assert_int_eq(libevdev_set_event_value(dev, EV_ABS, ABS_MT_SLOT, 0), 0);
++	ck_assert_int_eq(libevdev_get_current_slot(dev), 0);
++	ck_assert_int_eq(libevdev_get_event_value(dev, EV_ABS, ABS_MT_POSITION_X), 3);
++
++	uinput_device_free(uidev);
++	libevdev_free(dev);
++}
++END_TEST
++
++TEST_SUITE_ROOT_PRIVILEGES(libevdev_events)
++{
++	Suite *s = suite_create("libevdev event tests");
++
++	add_test(s, test_next_event);
++	add_test(s, test_next_event_invalid_fd);
++	add_test(s, test_next_event_blocking);
++	add_test(s, test_syn_dropped_event);
++	add_test(s, test_event_type_filtered);
++	add_test(s, test_event_code_filtered);
++	add_test(s, test_has_event_pending);
++	add_test(s, test_has_event_pending_invalid_fd);
++
++	add_test(s, test_syn_delta_button);
++	add_test(s, test_syn_delta_abs);
++	add_test(s, test_syn_delta_mt);
++	add_test(s, test_syn_delta_mt_reset_slot);
++	add_test(s, test_syn_delta_led);
++	add_test(s, test_syn_delta_sw);
++	add_test(s, test_syn_delta_fake_mt);
++	add_test(s, test_syn_delta_late_sync);
++	add_test(s, test_syn_delta_tracking_ids);
++	add_test(s, test_syn_delta_tracking_ids_btntool);
++
++	add_test(s, test_skipped_sync);
++	add_test(s, test_incomplete_sync);
++	add_test(s, test_empty_sync);
++
++	add_test(s, test_event_values);
++	add_test(s, test_event_values_invalid);
++	add_test(s, test_mt_event_values);
++	add_test(s, test_mt_event_values_invalid);
++	add_test(s, test_mt_slot_ranges_invalid);
++	add_test(s, test_mt_tracking_id_discard);
++	add_test(s, test_mt_tracking_id_discard_neg_1);
++	add_test(s, test_ev_rep_values);
++
++	add_test(s, test_event_value_setters);
++	add_test(s, test_event_value_setters_invalid);
++	add_test(s, test_event_mt_value_setters);
++	add_test(s, test_event_mt_value_setters_invalid);
++	add_test(s, test_event_mt_value_setters_current_slot);
++
++	return s;
++}
+diff -Naur third-party-libevdev-bak/test/test-libevdev-has-event.c third-party-new/test/test-libevdev-has-event.c
+--- third-party-libevdev-bak/test/test-libevdev-has-event.c	1970-01-01 08:00:00.000000000 +0800
++++ third-party-new/test/test-libevdev-has-event.c	2022-03-25 12:33:26.000000000 +0800
+@@ -0,0 +1,1194 @@
++// SPDX-License-Identifier: MIT
++/*
++ * Copyright © 2013 Red Hat, Inc.
++ */
++
++#include "config.h"
++#include 
++#include 
++#include 
++#include 
++#include 
++
++#include "test-common.h"
++
++static int evbits[] = {
++	EV_SYN, EV_KEY, EV_REL, EV_ABS, EV_MSC,
++	EV_SW, EV_LED, EV_SND, EV_FF,
++	/* Intentionally skipping these, they're different
++	 * EV_PWR, EV_FF_STATUS, EV_REP, */
++	-1,
++};
++
++START_TEST(test_has_ev_bit)
++{
++	int *evbit = evbits;
++
++	while(*evbit != -1) {
++		struct uinput_device* uidev;
++		struct libevdev *dev;
++		int i;
++
++		if (*evbit == EV_ABS) {
++			struct input_absinfo abs = { ABS_X, 0, 2, 0, 0, 0};
++			test_create_abs_device(&uidev, &dev,
++					       1, &abs,
++					       -1);
++		} else
++			test_create_device(&uidev, &dev,
++					   *evbit, 0,
++					   -1);
++
++		ck_assert_msg(libevdev_has_event_type(dev, EV_SYN), "for event type %d\n", *evbit);
++		ck_assert_msg(libevdev_has_event_type(dev, *evbit), "for event type %d\n", *evbit);
++
++		for (i = 0; i <= EV_MAX; i++) {
++			if (i == EV_SYN || i == *evbit)
++				continue;
++
++			ck_assert_msg(!libevdev_has_event_type(dev, i), "for event type %d\n", i);
++		}
++
++		libevdev_free(dev);
++		uinput_device_free(uidev);
++
++		evbit++;
++	}
++}
++END_TEST
++
++START_TEST(test_ev_bit_limits)
++{
++	int *evbit = evbits;
++
++	while(*evbit != -1) {
++		struct uinput_device* uidev;
++		struct libevdev *dev;
++
++		if (*evbit == EV_ABS) {
++			struct input_absinfo abs = { ABS_X, 0, 2, 0, 0, 0};
++			test_create_abs_device(&uidev, &dev,
++					       1, &abs,
++					       -1);
++		} else
++			test_create_device(&uidev, &dev,
++					   *evbit, 0,
++					   -1);
++
++		ck_assert_int_eq(libevdev_has_event_type(dev, EV_MAX + 1), 0);
++		ck_assert_int_eq(libevdev_has_event_type(dev, INT_MAX), 0);
++		ck_assert_int_eq(libevdev_has_event_type(dev, UINT_MAX), 0);
++
++		libevdev_free(dev);
++		uinput_device_free(uidev);
++
++		evbit++;
++	}
++}
++END_TEST
++
++START_TEST(test_event_codes)
++{
++	int *evbit = evbits;
++
++	while(*evbit != -1) {
++		struct uinput_device* uidev;
++		struct libevdev *dev;
++		int code, max;
++		if (*evbit == EV_SYN) {
++			evbit++;
++			continue;
++		}
++
++#ifdef __FreeBSD__
++		/* Force feedback events are not supported by FreeBSD */
++		if (*evbit == EV_FF) {
++			evbit++;
++			continue;
++		}
++#endif
++
++		max = libevdev_event_type_get_max(*evbit);
++
++		for (code = 1; code < max; code += 10) {
++			if (*evbit == EV_ABS) {
++				struct input_absinfo abs = { code, 0, 2, 0, 0, 0};
++				test_create_abs_device(&uidev, &dev,
++						       1, &abs,
++						       -1);
++			} else
++				test_create_device(&uidev, &dev,
++						   *evbit, code,
++						   -1);
++
++			ck_assert_msg(libevdev_has_event_type(dev, *evbit), "for event type %d\n", *evbit);
++			ck_assert_msg(libevdev_has_event_code(dev, *evbit, code), "for type %d code %d", *evbit, code);
++			ck_assert_msg(libevdev_has_event_code(dev, EV_SYN, SYN_REPORT), "for EV_SYN");
++			/* always false */
++			ck_assert_msg(!libevdev_has_event_code(dev, EV_PWR, 0), "for EV_PWR");
++
++			libevdev_free(dev);
++			uinput_device_free(uidev);
++		}
++
++		evbit++;
++	}
++}
++END_TEST
++
++START_TEST(test_event_code_limits)
++{
++	int *evbit = evbits;
++
++	while(*evbit != -1) {
++		struct uinput_device* uidev;
++		struct libevdev *dev;
++		int max;
++
++		if (*evbit == EV_SYN) {
++			evbit++;
++			continue;
++		}
++
++		max = libevdev_event_type_get_max(*evbit);
++		ck_assert(max != -1);
++
++		if (*evbit == EV_ABS) {
++			struct input_absinfo abs = { ABS_X, 0, 2, 0, 0, 0};
++			test_create_abs_device(&uidev, &dev,
++					       1, &abs,
++					       -1);
++		} else
++			test_create_device(&uidev, &dev,
++					   *evbit, 1,
++					   -1);
++
++		ck_assert_msg(!libevdev_has_event_code(dev, *evbit, max), "for type %d code %d", *evbit, max);
++		ck_assert_msg(!libevdev_has_event_code(dev, *evbit, INT_MAX), "for type %d code %d", *evbit, INT_MAX);
++		ck_assert_msg(!libevdev_has_event_code(dev, *evbit, UINT_MAX), "for type %d code %d", *evbit, UINT_MAX);
++
++		libevdev_free(dev);
++		uinput_device_free(uidev);
++
++		evbit++;
++	}
++}
++END_TEST
++
++START_TEST(test_ev_rep)
++{
++	struct libevdev *dev;
++	struct uinput_device* uidev;
++	int rc;
++	int rep, delay;
++	const int KERNEL_DEFAULT_REP = 250;
++	const int KERNEL_DEFAULT_DELAY = 33;
++
++	/* EV_REP is special, it's always fully set if set at all,
++	   can't test this through uinput though */
++	uidev = uinput_device_new(TEST_DEVICE_NAME);
++	ck_assert(uidev != NULL);
++	rc = uinput_device_set_bit(uidev, EV_REP);
++	ck_assert_int_eq(rc, 0);
++
++	rc = uinput_device_create(uidev);
++	ck_assert_int_eq(rc, 0);
++
++	rc = libevdev_new_from_fd(uinput_device_get_fd(uidev), &dev);
++	ck_assert_int_eq(rc, 0);
++
++	ck_assert_int_eq(libevdev_has_event_type(dev, EV_REP), 1);
++	ck_assert_int_eq(libevdev_has_event_code(dev, EV_REP, REP_DELAY), 1);
++	ck_assert_int_eq(libevdev_has_event_code(dev, EV_REP, REP_PERIOD), 1);
++
++	ck_assert_int_eq(libevdev_get_repeat(dev, &rep, &delay), 0);
++	/* default values as set by the kernel,
++	   see drivers/input/input.c:input_register_device() */
++	ck_assert_int_eq(rep, KERNEL_DEFAULT_REP);
++	ck_assert_int_eq(delay, KERNEL_DEFAULT_DELAY);
++
++	libevdev_free(dev);
++	uinput_device_free(uidev);
++}
++END_TEST
++
++START_TEST(test_ev_rep_values)
++{
++	struct uinput_device* uidev;
++	struct libevdev *dev;
++	int delay = 0xab, period = 0xbc;
++
++	/* EV_REP is special, it's always fully set if set at all, can't set
++	   it through uinput though. */
++	test_create_device(&uidev, &dev, -1);
++
++	ck_assert_int_eq(libevdev_get_repeat(dev, NULL, NULL), -1);
++	ck_assert_int_eq(libevdev_get_repeat(dev, &delay, NULL), -1);
++	ck_assert_int_eq(libevdev_get_repeat(dev, NULL, &period), -1);
++	ck_assert_int_eq(libevdev_get_repeat(dev, &delay, &period), -1);
++
++	ck_assert_int_eq(delay, 0xab);
++	ck_assert_int_eq(period, 0xbc);
++
++	uinput_device_free(uidev);
++	libevdev_free(dev);
++}
++END_TEST
++
++START_TEST(test_input_props)
++{
++	struct uinput_device* uidev;
++	struct libevdev *dev;
++	int rc, i;
++	struct input_absinfo abs = { .value = 0, .minimum = 0, .maximum = 2};
++
++	uidev = uinput_device_new(TEST_DEVICE_NAME);
++	rc = uinput_device_set_abs_bit(uidev, ABS_X, &abs);
++	ck_assert_int_eq(rc, 0);
++	uinput_device_set_prop(uidev, INPUT_PROP_DIRECT);
++	uinput_device_set_prop(uidev, INPUT_PROP_BUTTONPAD);
++	rc = uinput_device_create(uidev);
++	ck_assert_msg(rc == 0, "Failed to create uinput device: %s", strerror(-rc));
++
++	rc = libevdev_new_from_fd(uinput_device_get_fd(uidev), &dev);
++	ck_assert_msg(rc == 0, "Failed to create device: %s", strerror(-rc));
++
++	for (i = 0; i < INPUT_PROP_CNT; i++) {
++		if (i == INPUT_PROP_DIRECT || i == INPUT_PROP_BUTTONPAD)
++			ck_assert_int_eq(libevdev_has_property(dev, i), 1);
++		else
++			ck_assert_int_eq(libevdev_has_property(dev, i), 0);
++	}
++
++	ck_assert_int_eq(libevdev_has_property(dev, INPUT_PROP_MAX + 1), 0);
++	ck_assert_int_eq(libevdev_has_property(dev, INPUT_PROP_MAX), 0);
++
++	uinput_device_free(uidev);
++	libevdev_free(dev);
++}
++END_TEST
++
++START_TEST(test_set_input_props)
++{
++	struct uinput_device* uidev;
++	struct libevdev *dev;
++	int rc, fd;
++	struct input_absinfo abs = { .value = 0, .minimum = 0, .maximum = 2};
++
++	dev = libevdev_new();
++	ck_assert_int_eq(libevdev_enable_property(dev, INPUT_PROP_MAX + 1), -1);
++	ck_assert_int_eq(libevdev_enable_property(dev, INPUT_PROP_DIRECT), 0);
++	ck_assert_int_eq(libevdev_enable_property(dev, INPUT_PROP_BUTTONPAD), 0);
++	ck_assert_int_eq(libevdev_has_property(dev, INPUT_PROP_DIRECT), 1);
++	ck_assert_int_eq(libevdev_has_property(dev, INPUT_PROP_BUTTONPAD), 1);
++
++	uidev = uinput_device_new(TEST_DEVICE_NAME);
++	rc = uinput_device_set_abs_bit(uidev, ABS_X, &abs);
++	ck_assert_int_eq(rc, 0);
++	uinput_device_set_prop(uidev, INPUT_PROP_BUTTONPAD);
++	rc = uinput_device_create(uidev);
++	ck_assert_msg(rc == 0, "Failed to create uinput device: %s", strerror(-rc));
++
++	fd = uinput_device_get_fd(uidev);
++	rc = libevdev_set_fd(dev, fd);
++	ck_assert_msg(rc == 0, "Failed to create device: %s", strerror(-rc));
++
++	ck_assert_int_eq(libevdev_has_property(dev, INPUT_PROP_DIRECT), 0);
++	ck_assert_int_eq(libevdev_has_property(dev, INPUT_PROP_BUTTONPAD), 1);
++
++	/* Test disabling the properties too */
++	ck_assert_int_eq(libevdev_disable_property(dev, INPUT_PROP_MAX + 1), -1);
++	ck_assert_int_eq(libevdev_disable_property(dev, INPUT_PROP_DIRECT), 0);
++	ck_assert_int_eq(libevdev_disable_property(dev, INPUT_PROP_BUTTONPAD), 0);
++	ck_assert_int_eq(libevdev_has_property(dev, INPUT_PROP_DIRECT), 0);
++	ck_assert_int_eq(libevdev_has_property(dev, INPUT_PROP_BUTTONPAD), 0);
++
++	uinput_device_free(uidev);
++	libevdev_free(dev);
++}
++END_TEST
++
++START_TEST(test_slot_init_value)
++{
++	struct uinput_device *uidev;
++	struct libevdev *dev;
++	int rc;
++	const int nabs = 6;
++	int i;
++	int fd;
++	struct input_absinfo abs[] = {
++		{ .value = ABS_X, .minimum = 0, .maximum = 1000 },
++		{ .value = ABS_Y, .minimum = 0, .maximum = 1000 },
++		{ .value = ABS_MT_POSITION_X, .minimum = 0, .maximum = 1000 },
++		{ .value = ABS_MT_POSITION_Y, .minimum = 0, .maximum = 1000 },
++		{ .value = ABS_MT_TRACKING_ID, .minimum = -1, .maximum = 2 },
++		{ .value = ABS_MT_SLOT, .minimum = 0, .maximum = 1 }
++	};
++
++	uidev = uinput_device_new(TEST_DEVICE_NAME);
++
++	for (i = 0; i < nabs; i++) {
++		rc = uinput_device_set_abs_bit(uidev, abs[i].value, &abs[i]);
++		ck_assert_int_eq(rc, 0);
++	}
++
++	rc = uinput_device_create(uidev);
++	ck_assert_msg(rc == 0, "Failed to create uinput device: %s", strerror(-rc));
++
++	fd = uinput_device_get_fd(uidev);
++	rc = fcntl(fd, F_SETFL, O_NONBLOCK);
++	ck_assert_msg(rc == 0, "fcntl failed: %s", strerror(errno));
++
++	uinput_device_event(uidev, EV_ABS, ABS_MT_SLOT, 0);
++	uinput_device_event(uidev, EV_ABS, ABS_X, 100);
++	uinput_device_event(uidev, EV_ABS, ABS_Y, 500);
++	uinput_device_event(uidev, EV_ABS, ABS_MT_POSITION_X, 100);
++	uinput_device_event(uidev, EV_ABS, ABS_MT_POSITION_Y, 500);
++	uinput_device_event(uidev, EV_ABS, ABS_MT_TRACKING_ID, 1);
++	uinput_device_event(uidev, EV_ABS, ABS_MT_SLOT, 1);
++	uinput_device_event(uidev, EV_ABS, ABS_X, 1);
++	uinput_device_event(uidev, EV_ABS, ABS_Y, 5);
++	uinput_device_event(uidev, EV_ABS, ABS_MT_POSITION_X, 1);
++	uinput_device_event(uidev, EV_ABS, ABS_MT_POSITION_Y, 5);
++	uinput_device_event(uidev, EV_ABS, ABS_MT_TRACKING_ID, 2);
++	uinput_device_event(uidev, EV_SYN, SYN_REPORT, 0);
++
++	rc = libevdev_new_from_fd(fd, &dev);
++	ck_assert_int_eq(rc, 0);
++
++	ck_assert_int_eq(libevdev_get_current_slot(dev), 1);
++	ck_assert_int_eq(libevdev_get_slot_value(dev, 0, ABS_MT_POSITION_X), 100);
++	ck_assert_int_eq(libevdev_get_slot_value(dev, 0, ABS_MT_POSITION_Y), 500);
++	ck_assert_int_eq(libevdev_get_slot_value(dev, 1, ABS_MT_POSITION_X), 1);
++	ck_assert_int_eq(libevdev_get_slot_value(dev, 1, ABS_MT_POSITION_Y), 5);
++
++	uinput_device_free(uidev);
++	libevdev_free(dev);
++}
++END_TEST
++
++START_TEST(test_no_slots)
++{
++	struct uinput_device* uidev;
++	struct libevdev *dev;
++	struct input_absinfo abs[] = {
++		{ .value = ABS_X, .minimum = 0, .maximum = 2 },
++		{ .value = ABS_Y, .minimum = 0, .maximum = 2 },
++		{ .value = ABS_MT_POSITION_X, .minimum = 0, .maximum = 2 },
++		{ .value = ABS_MT_POSITION_Y, .minimum = 0, .maximum = 2 }
++	};
++
++	test_create_abs_device(&uidev, &dev, 4, abs,
++			       -1);
++
++	ck_assert_int_eq(libevdev_get_num_slots(dev), -1);
++	ck_assert_int_eq(libevdev_get_current_slot(dev), -1);
++
++	uinput_device_free(uidev);
++	libevdev_free(dev);
++}
++END_TEST
++
++START_TEST(test_slot_number)
++{
++	struct uinput_device* uidev;
++	struct libevdev *dev;
++	const int nslots = 4;
++	struct input_absinfo abs[] = {
++		{ .value = ABS_X, .minimum = 0, .maximum = 2 },
++		{ .value = ABS_Y, .minimum = 0, .maximum = 2 },
++		{ .value = ABS_MT_POSITION_X, .minimum = 0, .maximum = 2 },
++		{ .value = ABS_MT_POSITION_Y, .minimum = 0, .maximum = 2 },
++		{ .value = ABS_MT_SLOT, .minimum = 0, .maximum = nslots - 1 }
++	};
++
++	test_create_abs_device(&uidev, &dev, 5, abs,
++			       -1);
++
++	ck_assert_int_eq(libevdev_get_num_slots(dev), nslots);
++	ck_assert_int_eq(libevdev_get_current_slot(dev), 0);
++
++	uinput_device_free(uidev);
++	libevdev_free(dev);
++}
++END_TEST
++
++START_TEST(test_invalid_mt_device)
++{
++	struct uinput_device* uidev;
++	struct libevdev *dev;
++	const int nslots = 4;
++	int value;
++	struct input_absinfo abs[] = {
++		{ .value = ABS_X, .minimum = 0, .maximum = 2 },
++		{ .value = ABS_Y, .minimum = 0, .maximum = 2 },
++		{ .value = ABS_MT_POSITION_X, .minimum = 0, .maximum = 2 },
++		{ .value = ABS_MT_POSITION_Y, .minimum = 0, .maximum = 2 },
++		{ .value = ABS_MT_SLOT - 1, .minimum = 0, .maximum = 2 },
++		{ .value = ABS_MT_SLOT, .minimum = 0, .maximum = nslots - 1 }
++	};
++
++	test_create_abs_device(&uidev, &dev, 6, abs,
++			       -1);
++
++	ck_assert_int_eq(libevdev_get_num_slots(dev), -1);
++	ck_assert_int_eq(libevdev_get_current_slot(dev), -1);
++	ck_assert_int_eq(libevdev_set_slot_value(dev, 0, ABS_MT_POSITION_X, 0), -1);
++	ck_assert_int_eq(libevdev_fetch_slot_value(dev, 0, ABS_MT_POSITION_X, &value), 0);
++
++	ck_assert(libevdev_has_event_code(dev, EV_ABS, ABS_MT_SLOT - 1));
++	ck_assert(libevdev_has_event_code(dev, EV_ABS, ABS_MT_SLOT));
++
++	ck_assert_int_eq(libevdev_set_event_value(dev, EV_ABS, ABS_MT_SLOT, 1), 0);
++	ck_assert(libevdev_get_event_value(dev, EV_ABS, ABS_MT_SLOT) == 1);
++
++	uinput_device_free(uidev);
++	libevdev_free(dev);
++}
++END_TEST
++
++START_TEST(test_device_name)
++{
++	struct uinput_device* uidev;
++	struct libevdev *dev;
++	struct input_id ids = {1, 2, 3, 4};
++	const char *str;
++	int rc;
++
++	dev = libevdev_new();
++
++	str = libevdev_get_name(dev);
++	ck_assert(str != NULL);
++	ck_assert_int_eq(strlen(str), 0);
++
++	rc = uinput_device_new_with_events(&uidev, TEST_DEVICE_NAME, &ids,
++					   EV_REL, REL_X,
++					   -1);
++	ck_assert_msg(rc == 0, "Failed to create uinput device: %s", strerror(-rc));
++	rc = libevdev_set_fd(dev, uinput_device_get_fd(uidev));
++	ck_assert_msg(rc == 0, "Failed to init device: %s", strerror(-rc));;
++
++	str = libevdev_get_name(dev);
++	ck_assert_int_eq(strcmp(str, TEST_DEVICE_NAME), 0);
++
++	str = libevdev_get_phys(dev);
++	ck_assert(str == NULL);
++
++	str = libevdev_get_uniq(dev);
++	ck_assert(str == NULL);
++
++	ck_assert_int_eq(libevdev_get_id_bustype(dev), ids.bustype);
++	ck_assert_int_eq(libevdev_get_id_vendor(dev), ids.vendor);
++	ck_assert_int_eq(libevdev_get_id_product(dev), ids.product);
++	ck_assert_int_eq(libevdev_get_id_version(dev), ids.version);
++	ck_assert_int_eq(libevdev_get_driver_version(dev), EV_VERSION);
++
++	uinput_device_free(uidev);
++	libevdev_free(dev);
++}
++END_TEST
++
++START_TEST(test_device_set_name)
++{
++	struct uinput_device* uidev;
++	struct libevdev *dev;
++	struct input_id ids = {1, 2, 3, 4};
++	const char *str;
++	int rc;
++
++	dev = libevdev_new();
++
++	libevdev_set_name(dev, "the name");
++	libevdev_set_phys(dev, "the phys");
++	libevdev_set_uniq(dev, "the uniq");
++
++	str = libevdev_get_name(dev);
++	ck_assert(str != NULL);
++	ck_assert_int_eq(strcmp(str, "the name"), 0);
++
++	str = libevdev_get_phys(dev);
++	ck_assert(str != NULL);
++	ck_assert_int_eq(strcmp(str, "the phys"), 0);
++
++	str = libevdev_get_uniq(dev);
++	ck_assert(str != NULL);
++	ck_assert_int_eq(strcmp(str, "the uniq"), 0);
++
++	rc = uinput_device_new_with_events(&uidev, TEST_DEVICE_NAME, &ids,
++					   EV_REL, REL_X,
++					   -1);
++	ck_assert_msg(rc == 0, "Failed to create uinput device: %s", strerror(-rc));
++	rc = libevdev_set_fd(dev, uinput_device_get_fd(uidev));
++	ck_assert_msg(rc == 0, "Failed to init device: %s", strerror(-rc));;
++
++	str = libevdev_get_name(dev);
++	ck_assert_int_eq(strcmp(str, TEST_DEVICE_NAME), 0);
++
++	str = libevdev_get_phys(dev);
++	ck_assert(str == NULL);
++
++	str = libevdev_get_uniq(dev);
++	ck_assert(str == NULL);
++
++	uinput_device_free(uidev);
++	libevdev_free(dev);
++}
++END_TEST
++
++START_TEST(test_device_set_ids)
++{
++	struct uinput_device* uidev;
++	struct libevdev *dev;
++	struct input_id ids = {1, 2, 3, 4};
++	int rc;
++
++	dev = libevdev_new();
++
++	libevdev_set_id_product(dev, 10);
++	libevdev_set_id_vendor(dev, 20);
++	libevdev_set_id_bustype(dev, 30);
++	libevdev_set_id_version(dev, 40);
++
++	ck_assert_int_eq(libevdev_get_id_product(dev), 10);
++	ck_assert_int_eq(libevdev_get_id_vendor(dev), 20);
++	ck_assert_int_eq(libevdev_get_id_bustype(dev), 30);
++	ck_assert_int_eq(libevdev_get_id_version(dev), 40);
++
++	rc = uinput_device_new_with_events(&uidev, TEST_DEVICE_NAME, &ids,
++					   EV_REL, REL_X,
++					   -1);
++	ck_assert_msg(rc == 0, "Failed to create uinput device: %s", strerror(-rc));
++	rc = libevdev_set_fd(dev, uinput_device_get_fd(uidev));
++	ck_assert_msg(rc == 0, "Failed to init device: %s", strerror(-rc));;
++
++	ck_assert_int_eq(libevdev_get_id_bustype(dev), ids.bustype);
++	ck_assert_int_eq(libevdev_get_id_vendor(dev), ids.vendor);
++	ck_assert_int_eq(libevdev_get_id_product(dev), ids.product);
++	ck_assert_int_eq(libevdev_get_id_version(dev), ids.version);
++
++	uinput_device_free(uidev);
++	libevdev_free(dev);
++}
++END_TEST
++
++START_TEST(test_device_get_abs_info)
++{
++	struct uinput_device* uidev;
++	struct libevdev *dev;
++	struct input_absinfo abs;
++	const struct input_absinfo *a;
++	int rc;
++
++	uidev = uinput_device_new(TEST_DEVICE_NAME);
++	ck_assert(uidev != NULL);
++
++	abs.minimum = 0;
++	abs.maximum = 1000;
++	abs.fuzz = 1;
++	abs.flat = 2;
++	abs.resolution = 3;
++	abs.value = 0;
++
++	uinput_device_set_abs_bit(uidev, ABS_X, &abs);
++	uinput_device_set_abs_bit(uidev, ABS_MT_POSITION_X, &abs);
++
++	abs.minimum = -500;
++	abs.maximum = 500;
++	abs.fuzz = 10;
++	abs.flat = 20;
++	abs.resolution = 30;
++	abs.value = 0;
++
++	uinput_device_set_abs_bit(uidev, ABS_Y, &abs);
++	uinput_device_set_abs_bit(uidev, ABS_MT_POSITION_Y, &abs);
++
++	rc = uinput_device_create(uidev);
++	ck_assert_msg(rc == 0, "Failed to create device: %s", strerror(-rc));
++
++	rc = libevdev_new_from_fd(uinput_device_get_fd(uidev), &dev);
++	ck_assert_msg(rc == 0, "Failed to init device: %s", strerror(-rc));;
++
++	ck_assert_int_eq(libevdev_get_abs_minimum(dev, ABS_MAX + 1), 0);
++	ck_assert_int_eq(libevdev_get_abs_maximum(dev, ABS_MAX + 1), 0);
++	ck_assert_int_eq(libevdev_get_abs_fuzz(dev, ABS_MAX + 1), 0);
++	ck_assert_int_eq(libevdev_get_abs_flat(dev, ABS_MAX + 1), 0);
++	ck_assert_int_eq(libevdev_get_abs_resolution(dev, ABS_MAX + 1), 0);
++	ck_assert(!libevdev_get_abs_info(dev, ABS_MAX + 1));
++
++	ck_assert_int_eq(libevdev_get_abs_minimum(dev, ABS_X), 0);
++	ck_assert_int_eq(libevdev_get_abs_maximum(dev, ABS_X), 1000);
++	ck_assert_int_eq(libevdev_get_abs_fuzz(dev, ABS_X), 1);
++	ck_assert_int_eq(libevdev_get_abs_flat(dev, ABS_X), 2);
++	ck_assert_int_eq(libevdev_get_abs_resolution(dev, ABS_X), 3);
++	a = libevdev_get_abs_info(dev, ABS_X);
++	ck_assert(a != NULL);
++	ck_assert_int_eq(a->minimum, 0);
++	ck_assert_int_eq(a->maximum, 1000);
++	ck_assert_int_eq(a->fuzz, 1);
++	ck_assert_int_eq(a->flat, 2);
++	ck_assert_int_eq(a->resolution, 3);
++
++	ck_assert_int_eq(libevdev_get_abs_minimum(dev, ABS_MT_POSITION_X), 0);
++	ck_assert_int_eq(libevdev_get_abs_maximum(dev, ABS_MT_POSITION_X), 1000);
++	ck_assert_int_eq(libevdev_get_abs_fuzz(dev, ABS_MT_POSITION_X), 1);
++	ck_assert_int_eq(libevdev_get_abs_flat(dev, ABS_MT_POSITION_X), 2);
++	ck_assert_int_eq(libevdev_get_abs_resolution(dev, ABS_MT_POSITION_X), 3);
++	a = libevdev_get_abs_info(dev, ABS_MT_POSITION_X);
++	ck_assert(a != NULL);
++	ck_assert_int_eq(a->minimum, 0);
++	ck_assert_int_eq(a->maximum, 1000);
++	ck_assert_int_eq(a->fuzz, 1);
++	ck_assert_int_eq(a->flat, 2);
++	ck_assert_int_eq(a->resolution, 3);
++
++	ck_assert_int_eq(libevdev_get_abs_minimum(dev, ABS_Y), -500);
++	ck_assert_int_eq(libevdev_get_abs_maximum(dev, ABS_Y), 500);
++	ck_assert_int_eq(libevdev_get_abs_fuzz(dev, ABS_Y), 10);
++	ck_assert_int_eq(libevdev_get_abs_flat(dev, ABS_Y), 20);
++	ck_assert_int_eq(libevdev_get_abs_resolution(dev, ABS_Y), 30);
++	a = libevdev_get_abs_info(dev, ABS_Y);
++	ck_assert(a != NULL);
++	ck_assert_int_eq(a->minimum, -500);
++	ck_assert_int_eq(a->maximum, 500);
++	ck_assert_int_eq(a->fuzz, 10);
++	ck_assert_int_eq(a->flat, 20);
++	ck_assert_int_eq(a->resolution, 30);
++
++	ck_assert_int_eq(libevdev_get_abs_minimum(dev, ABS_MT_POSITION_Y), -500);
++	ck_assert_int_eq(libevdev_get_abs_maximum(dev, ABS_MT_POSITION_Y), 500);
++	ck_assert_int_eq(libevdev_get_abs_fuzz(dev, ABS_MT_POSITION_Y), 10);
++	ck_assert_int_eq(libevdev_get_abs_flat(dev, ABS_MT_POSITION_Y), 20);
++	ck_assert_int_eq(libevdev_get_abs_resolution(dev, ABS_MT_POSITION_Y), 30);
++	a = libevdev_get_abs_info(dev, ABS_MT_POSITION_Y);
++	ck_assert(a != NULL);
++	ck_assert_int_eq(a->minimum, -500);
++	ck_assert_int_eq(a->maximum, 500);
++	ck_assert_int_eq(a->fuzz, 10);
++	ck_assert_int_eq(a->flat, 20);
++	ck_assert_int_eq(a->resolution, 30);
++
++	uinput_device_free(uidev);
++	libevdev_free(dev);
++}
++END_TEST
++
++START_TEST(test_device_set_abs)
++{
++	struct uinput_device* uidev;
++	struct libevdev *dev;
++	struct input_absinfo abs[2];
++	struct input_absinfo a;
++
++	memset(abs, 0, sizeof(abs));
++	abs[0].value = ABS_X;
++	abs[0].maximum = 1000;
++
++	abs[1].value = ABS_Y;
++	abs[1].maximum = 1000;
++
++	test_create_abs_device(&uidev, &dev,
++			       2, abs,
++			       EV_SYN,
++			       -1);
++
++	libevdev_set_abs_minimum(dev, ABS_X, 1);
++	libevdev_set_abs_minimum(dev, ABS_Y, 5);
++	ck_assert_int_eq(libevdev_get_abs_minimum(dev, ABS_X),  1);
++	ck_assert_int_eq(libevdev_get_abs_minimum(dev, ABS_Y),  5);
++
++	libevdev_set_abs_maximum(dev, ABS_X, 3000);
++	libevdev_set_abs_maximum(dev, ABS_Y, 5000);
++	ck_assert_int_eq(libevdev_get_abs_maximum(dev, ABS_X),  3000);
++	ck_assert_int_eq(libevdev_get_abs_maximum(dev, ABS_Y),  5000);
++
++	libevdev_set_abs_fuzz(dev, ABS_X, 3);
++	libevdev_set_abs_fuzz(dev, ABS_Y, 5);
++	ck_assert_int_eq(libevdev_get_abs_fuzz(dev, ABS_X),  3);
++	ck_assert_int_eq(libevdev_get_abs_fuzz(dev, ABS_Y),  5);
++
++	libevdev_set_abs_flat(dev, ABS_X, 8);
++	libevdev_set_abs_flat(dev, ABS_Y, 15);
++	ck_assert_int_eq(libevdev_get_abs_flat(dev, ABS_X),  8);
++	ck_assert_int_eq(libevdev_get_abs_flat(dev, ABS_Y),  15);
++
++	libevdev_set_abs_resolution(dev, ABS_X, 80);
++	libevdev_set_abs_resolution(dev, ABS_Y, 150);
++	ck_assert_int_eq(libevdev_get_abs_resolution(dev, ABS_X),  80);
++	ck_assert_int_eq(libevdev_get_abs_resolution(dev, ABS_Y),  150);
++
++	a.value = 0;
++	a.minimum = 10;
++	a.maximum = 100;
++	a.fuzz = 13;
++	a.flat = 1;
++	a.resolution = 16;
++
++	libevdev_set_abs_info(dev, ABS_X, &a);
++	ck_assert_int_eq(memcmp(&a, libevdev_get_abs_info(dev, ABS_X), sizeof(a)), 0);
++
++	libevdev_set_abs_minimum(dev, ABS_Z, 10);
++	ck_assert_int_eq(libevdev_has_event_code(dev, EV_ABS, ABS_Z),  0);
++
++	uinput_device_free(uidev);
++	libevdev_free(dev);
++}
++END_TEST
++
++START_TEST(test_device_enable_bit)
++{
++	struct uinput_device* uidev;
++	struct libevdev *dev, *dev2;
++	struct input_absinfo abs = { .value = ABS_X, .minimum = 0, .maximum = 2 };
++	int rc;
++
++	test_create_abs_device(&uidev, &dev, 1, &abs,
++			       -1);
++
++	ck_assert(!libevdev_has_event_code(dev, EV_ABS, ABS_Y));
++	ck_assert(!libevdev_has_event_type(dev, EV_REL));
++	ck_assert(!libevdev_has_event_code(dev, EV_REL, REL_X));
++
++	abs.minimum = 0;
++	abs.maximum = 100;
++	abs.fuzz = 1;
++	abs.flat = 2;
++	abs.resolution = 3;
++
++	ck_assert_int_eq(libevdev_enable_event_code(dev, EV_ABS, ABS_Y, &abs), 0);
++	ck_assert(libevdev_has_event_code(dev, EV_ABS, ABS_Y));
++
++	ck_assert_int_eq(libevdev_enable_event_type(dev, EV_REL), 0);
++	ck_assert(libevdev_has_event_type(dev, EV_REL));
++	ck_assert(!libevdev_has_event_code(dev, EV_REL, REL_X));
++
++	ck_assert_int_eq(libevdev_enable_event_code(dev, EV_REL, REL_X, NULL), 0);
++	ck_assert(libevdev_has_event_code(dev, EV_REL, REL_X));
++
++	/* make sure kernel device is unchanged */
++	rc = libevdev_new_from_fd(uinput_device_get_fd(uidev), &dev2);
++	ck_assert_msg(rc == 0, "Failed to init device: %s", strerror(-rc));
++	ck_assert(libevdev_has_event_code(dev2, EV_ABS, ABS_X));
++	ck_assert(!libevdev_has_event_code(dev2, EV_ABS, ABS_Y));
++	ck_assert(!libevdev_has_event_type(dev2, EV_REL));
++	ck_assert(!libevdev_has_event_code(dev2, EV_REL, REL_X));
++	libevdev_free(dev2);
++
++	uinput_device_free(uidev);
++	libevdev_free(dev);
++}
++END_TEST
++
++START_TEST(test_device_enable_bit_invalid)
++{
++	struct uinput_device* uidev;
++	struct libevdev *dev;
++	struct input_absinfo abs = { .value = ABS_X, .minimum = 0, .maximum = 1 };
++
++	test_create_abs_device(&uidev, &dev, 1, &abs,
++			       -1);
++
++	ck_assert_int_eq(libevdev_enable_event_code(dev, EV_ABS, ABS_MAX + 1, &abs), -1);
++	ck_assert_int_eq(libevdev_enable_event_code(dev, EV_MAX + 1, ABS_MAX + 1, &abs), -1);
++	ck_assert_int_eq(libevdev_enable_event_type(dev, EV_MAX + 1), -1);
++	/* there's a gap between EV_SW and EV_LED */
++	ck_assert_int_eq(libevdev_enable_event_type(dev, EV_LED - 1), -1);
++	ck_assert_int_eq(libevdev_enable_event_code(dev, EV_LED - 1, 0, NULL), -1);
++
++	ck_assert_int_eq(libevdev_enable_event_code(dev, EV_ABS, ABS_Y, NULL), -1);
++	ck_assert_int_eq(libevdev_enable_event_code(dev, EV_REP, REP_DELAY, NULL), -1);
++	ck_assert_int_eq(libevdev_enable_event_code(dev, EV_REL, REL_X, &abs), -1);
++
++	uinput_device_free(uidev);
++	libevdev_free(dev);
++}
++END_TEST
++
++START_TEST(test_device_disable_bit)
++{
++	struct uinput_device* uidev;
++	struct libevdev *dev, *dev2;
++	int rc;
++	struct input_absinfo abs[2] = {
++		{ .value = ABS_X, .minimum = 0, .maximum = 1 },
++		{ .value = ABS_Y, .minimum = 0, .maximum = 1 },
++	};
++
++	test_create_abs_device(&uidev, &dev,
++			       2, abs,
++			       EV_REL, REL_X,
++			       EV_REL, REL_Y,
++			       -1);
++
++	ck_assert(libevdev_has_event_code(dev, EV_ABS, ABS_X));
++	ck_assert(libevdev_has_event_code(dev, EV_ABS, ABS_Y));
++	ck_assert(libevdev_has_event_type(dev, EV_REL));
++	ck_assert(libevdev_has_event_code(dev, EV_REL, REL_X));
++	ck_assert(libevdev_has_event_code(dev, EV_REL, REL_Y));
++
++	ck_assert_int_eq(libevdev_disable_event_code(dev, EV_ABS, ABS_Y), 0);
++	ck_assert(!libevdev_has_event_code(dev, EV_ABS, ABS_Y));
++
++	ck_assert_int_eq(libevdev_disable_event_code(dev, EV_REL, REL_X), 0);
++	ck_assert(!libevdev_has_event_code(dev, EV_REL, REL_X));
++	ck_assert(libevdev_has_event_code(dev, EV_REL, REL_Y));
++	ck_assert(libevdev_has_event_type(dev, EV_REL));
++
++	ck_assert_int_eq(libevdev_disable_event_type(dev, EV_REL), 0);
++	ck_assert(!libevdev_has_event_type(dev, EV_REL));
++	ck_assert(!libevdev_has_event_code(dev, EV_REL, REL_X));
++	ck_assert(!libevdev_has_event_code(dev, EV_REL, REL_Y));
++
++	/* make sure kernel device is unchanged */
++	rc = libevdev_new_from_fd(uinput_device_get_fd(uidev), &dev2);
++	ck_assert_msg(rc == 0, "Failed to init device: %s", strerror(-rc));
++	ck_assert(libevdev_has_event_code(dev2, EV_ABS, ABS_X));
++	ck_assert(libevdev_has_event_code(dev2, EV_ABS, ABS_Y));
++	ck_assert(libevdev_has_event_type(dev2, EV_REL));
++	ck_assert(libevdev_has_event_code(dev2, EV_REL, REL_X));
++	ck_assert(libevdev_has_event_code(dev2, EV_REL, REL_Y));
++	libevdev_free(dev2);
++
++	uinput_device_free(uidev);
++	libevdev_free(dev);
++}
++END_TEST
++
++START_TEST(test_device_disable_bit_invalid)
++{
++	struct uinput_device* uidev;
++	struct libevdev *dev;
++	struct input_absinfo abs = { .value = ABS_X, .minimum = 0, .maximum = 1 };
++
++	test_create_abs_device(&uidev, &dev, 1, &abs, -1);
++
++	/* there's a gap between EV_SW and EV_LED */
++	ck_assert_int_eq(libevdev_disable_event_type(dev, EV_LED - 1), -1);
++	ck_assert_int_eq(libevdev_disable_event_code(dev, EV_LED - 1, 0), -1);
++	ck_assert_int_eq(libevdev_disable_event_code(dev, EV_ABS, ABS_MAX + 1), -1);
++	ck_assert_int_eq(libevdev_disable_event_code(dev, EV_MAX + 1, ABS_MAX + 1), -1);
++	ck_assert_int_eq(libevdev_disable_event_type(dev, EV_MAX + 1), -1);
++	ck_assert_int_eq(libevdev_disable_event_type(dev, EV_SYN), -1);
++	ck_assert_int_eq(libevdev_disable_event_code(dev, EV_SYN, SYN_REPORT), -1);
++
++	uinput_device_free(uidev);
++	libevdev_free(dev);
++}
++END_TEST
++
++START_TEST(test_device_kernel_change_axis)
++{
++	struct uinput_device* uidev;
++	struct libevdev *dev, *dev2;
++	struct input_absinfo abs;
++	int rc;
++
++	uidev = uinput_device_new(TEST_DEVICE_NAME);
++	ck_assert(uidev != NULL);
++
++	abs.minimum = 0;
++	abs.maximum = 1000;
++	abs.fuzz = 1;
++	abs.flat = 2;
++	abs.resolution = 3;
++	abs.value = 0;
++
++	uinput_device_set_abs_bit(uidev, ABS_X, &abs);
++
++	rc = uinput_device_create(uidev);
++	ck_assert_msg(rc == 0, "Failed to create device: %s", strerror(-rc));
++
++	rc = libevdev_new_from_fd(uinput_device_get_fd(uidev), &dev);
++	ck_assert_msg(rc == 0, "Failed to init device: %s", strerror(-rc));;
++
++	ck_assert_int_eq(libevdev_get_abs_minimum(dev, ABS_X), 0);
++	ck_assert_int_eq(libevdev_get_abs_maximum(dev, ABS_X), 1000);
++	ck_assert_int_eq(libevdev_get_abs_fuzz(dev, ABS_X), 1);
++	ck_assert_int_eq(libevdev_get_abs_flat(dev, ABS_X), 2);
++	ck_assert_int_eq(libevdev_get_abs_resolution(dev, ABS_X), 3);
++
++	abs.minimum = 500;
++	abs.maximum = 5000;
++	abs.fuzz = 10;
++	abs.flat = 20;
++	abs.resolution = 30;
++	rc = libevdev_kernel_set_abs_info(dev, ABS_X, &abs);
++	ck_assert_int_eq(rc, 0);
++
++	ck_assert_int_eq(libevdev_get_abs_minimum(dev, ABS_X), 500);
++	ck_assert_int_eq(libevdev_get_abs_maximum(dev, ABS_X), 5000);
++	ck_assert_int_eq(libevdev_get_abs_fuzz(dev, ABS_X), 10);
++	ck_assert_int_eq(libevdev_get_abs_flat(dev, ABS_X), 20);
++	ck_assert_int_eq(libevdev_get_abs_resolution(dev, ABS_X), 30);
++
++	/* make sure kernel device is changed */
++	rc = libevdev_new_from_fd(uinput_device_get_fd(uidev), &dev2);
++	ck_assert_msg(rc == 0, "Failed to init device: %s", strerror(-rc));
++	ck_assert_int_eq(libevdev_get_abs_minimum(dev2, ABS_X), 500);
++	ck_assert_int_eq(libevdev_get_abs_maximum(dev2, ABS_X), 5000);
++	ck_assert_int_eq(libevdev_get_abs_fuzz(dev2, ABS_X), 10);
++	ck_assert_int_eq(libevdev_get_abs_flat(dev2, ABS_X), 20);
++	ck_assert_int_eq(libevdev_get_abs_resolution(dev2, ABS_X), 30);
++	libevdev_free(dev2);
++
++	libevdev_free(dev);
++	uinput_device_free(uidev);
++}
++END_TEST
++
++START_TEST(test_device_kernel_change_axis_invalid)
++{
++	struct uinput_device* uidev;
++	struct libevdev *dev;
++	struct input_absinfo abs;
++	int rc;
++
++	uidev = uinput_device_new(TEST_DEVICE_NAME);
++	ck_assert(uidev != NULL);
++
++	abs.minimum = 0;
++	abs.maximum = 1000;
++	abs.fuzz = 1;
++	abs.flat = 2;
++	abs.resolution = 3; /* FIXME: value is unused, we can't test resolution */
++	abs.value = 0;
++
++	uinput_device_set_abs_bit(uidev, ABS_X, &abs);
++
++	rc = uinput_device_create(uidev);
++	ck_assert_msg(rc == 0, "Failed to create device: %s", strerror(-rc));
++
++	rc = libevdev_new_from_fd(uinput_device_get_fd(uidev), &dev);
++	ck_assert_msg(rc == 0, "Failed to init device: %s", strerror(-rc));;
++
++	rc = libevdev_kernel_set_abs_info(dev, ABS_MAX + 1, &abs);
++	ck_assert_int_eq(rc, -EINVAL);
++
++	libevdev_free(dev);
++	uinput_device_free(uidev);
++}
++END_TEST
++
++START_TEST(test_device_kernel_set_abs_invalid_fd)
++{
++	struct uinput_device* uidev;
++	struct libevdev *dev;
++	struct input_absinfo abs[2];
++	struct input_absinfo a;
++	int rc;
++
++	libevdev_set_log_function(test_logfunc_ignore_error, NULL);
++
++	memset(abs, 0, sizeof(abs));
++	abs[0].value = ABS_X;
++	abs[0].maximum = 1000;
++
++	abs[1].value = ABS_Y;
++	abs[1].maximum = 1000;
++
++	dev = libevdev_new();
++	rc = libevdev_kernel_set_abs_info(dev, ABS_X, &a);
++	ck_assert_int_eq(rc, -EBADF);
++	libevdev_free(dev);
++
++	test_create_abs_device(&uidev, &dev,
++			       2, abs,
++			       EV_SYN,
++			       -1);
++
++	libevdev_change_fd(dev, -2);
++	rc = libevdev_kernel_set_abs_info(dev, ABS_X, &a);
++	ck_assert_int_eq(rc, -EBADF);
++
++	libevdev_set_log_function(test_logfunc_abort_on_error, NULL);
++
++	uinput_device_free(uidev);
++	libevdev_free(dev);
++}
++END_TEST
++
++START_TEST(test_led_valid)
++{
++	struct uinput_device* uidev;
++	struct libevdev *dev;
++	int rc;
++
++	test_create_device(&uidev, &dev,
++			   EV_LED, LED_NUML,
++			   EV_LED, LED_CAPSL,
++			   EV_LED, LED_COMPOSE,
++			   -1);
++
++	rc = libevdev_kernel_set_led_value(dev, LED_NUML, LIBEVDEV_LED_ON);
++	ck_assert_int_eq(rc, 0);
++	rc = libevdev_kernel_set_led_value(dev, LED_NUML, LIBEVDEV_LED_OFF);
++	ck_assert_int_eq(rc, 0);
++
++	rc = libevdev_kernel_set_led_values(dev,
++					    LED_NUML, LIBEVDEV_LED_OFF,
++					    LED_CAPSL, LIBEVDEV_LED_ON,
++					    LED_COMPOSE, LIBEVDEV_LED_OFF,
++					    -1);
++	ck_assert_int_eq(rc, 0);
++	ck_assert_int_eq(0, libevdev_get_event_value(dev, EV_LED, LED_NUML));
++	ck_assert_int_eq(1, libevdev_get_event_value(dev, EV_LED, LED_CAPSL));
++	ck_assert_int_eq(0, libevdev_get_event_value(dev, EV_LED, LED_COMPOSE));
++
++	rc = libevdev_kernel_set_led_values(dev,
++					    LED_NUML, LIBEVDEV_LED_ON,
++					    LED_CAPSL, LIBEVDEV_LED_OFF,
++					    LED_COMPOSE, LIBEVDEV_LED_ON,
++					    -1);
++	ck_assert_int_eq(rc, 0);
++	ck_assert_int_eq(1, libevdev_get_event_value(dev, EV_LED, LED_NUML));
++	ck_assert_int_eq(0, libevdev_get_event_value(dev, EV_LED, LED_CAPSL));
++	ck_assert_int_eq(1, libevdev_get_event_value(dev, EV_LED, LED_COMPOSE));
++
++	/* make sure we ignore unset leds */
++	rc = libevdev_kernel_set_led_values(dev,
++					    LED_NUML, LIBEVDEV_LED_ON,
++					    LED_CAPSL, LIBEVDEV_LED_OFF,
++					    LED_SCROLLL, LIBEVDEV_LED_OFF,
++					    LED_COMPOSE, LIBEVDEV_LED_ON,
++					    -1);
++	ck_assert_int_eq(rc, 0);
++	ck_assert_int_eq(1, libevdev_get_event_value(dev, EV_LED, LED_NUML));
++	ck_assert_int_eq(0, libevdev_get_event_value(dev, EV_LED, LED_CAPSL));
++	ck_assert_int_eq(1, libevdev_get_event_value(dev, EV_LED, LED_COMPOSE));
++
++	libevdev_free(dev);
++	uinput_device_free(uidev);
++}
++END_TEST
++
++START_TEST(test_led_invalid)
++{
++	struct uinput_device* uidev;
++	struct libevdev *dev;
++	int rc;
++
++	test_create_device(&uidev, &dev,
++			   EV_LED, LED_NUML,
++			   EV_LED, LED_CAPSL,
++			   EV_LED, LED_COMPOSE,
++			   -1);
++
++	rc = libevdev_kernel_set_led_value(dev, LED_MAX + 1, LIBEVDEV_LED_ON);
++	ck_assert_int_eq(rc, -EINVAL);
++
++	rc = libevdev_kernel_set_led_value(dev, LED_NUML, LIBEVDEV_LED_OFF + 1);
++	ck_assert_int_eq(rc, -EINVAL);
++
++	rc = libevdev_kernel_set_led_value(dev, LED_SCROLLL, LIBEVDEV_LED_ON);
++	ck_assert_int_eq(rc, 0);
++
++	rc = libevdev_kernel_set_led_values(dev,
++					    LED_NUML, LIBEVDEV_LED_OFF + 1,
++					    -1);
++	ck_assert_int_eq(rc, -EINVAL);
++
++	rc = libevdev_kernel_set_led_values(dev,
++					    LED_MAX + 1, LIBEVDEV_LED_ON,
++					    LED_NUML, LIBEVDEV_LED_OFF + 1,
++					    -1);
++	ck_assert_int_eq(rc, -EINVAL);
++
++	rc = libevdev_kernel_set_led_values(dev,
++					    LED_SCROLLL, LIBEVDEV_LED_OFF,
++					    -1);
++	ck_assert_int_eq(rc, 0);
++
++	libevdev_free(dev);
++	uinput_device_free(uidev);
++}
++END_TEST
++
++START_TEST(test_led_same)
++{
++	struct uinput_device* uidev;
++	struct libevdev *dev;
++	int rc;
++
++	test_create_device(&uidev, &dev,
++			   EV_LED, LED_NUML,
++			   EV_LED, LED_CAPSL,
++			   EV_LED, LED_COMPOSE,
++			   -1);
++
++	rc = libevdev_kernel_set_led_values(dev,
++					    LED_NUML, LIBEVDEV_LED_OFF,
++					    LED_NUML, LIBEVDEV_LED_ON,
++					    LED_NUML, LIBEVDEV_LED_OFF,
++					    LED_NUML, LIBEVDEV_LED_ON,
++					    LED_NUML, LIBEVDEV_LED_OFF,
++					    LED_NUML, LIBEVDEV_LED_ON,
++					    LED_NUML, LIBEVDEV_LED_OFF,
++					    LED_NUML, LIBEVDEV_LED_ON,
++					    LED_NUML, LIBEVDEV_LED_OFF,
++					    LED_NUML, LIBEVDEV_LED_ON,
++					    LED_NUML, LIBEVDEV_LED_OFF,
++					    LED_NUML, LIBEVDEV_LED_ON,
++					    LED_NUML, LIBEVDEV_LED_OFF,
++					    LED_NUML, LIBEVDEV_LED_ON,
++					    LED_NUML, LIBEVDEV_LED_OFF,
++					    LED_NUML, LIBEVDEV_LED_ON,
++					    LED_NUML, LIBEVDEV_LED_OFF,
++					    LED_NUML, LIBEVDEV_LED_ON,
++					    LED_NUML, LIBEVDEV_LED_OFF,
++					    LED_NUML, LIBEVDEV_LED_ON,
++					    LED_NUML, LIBEVDEV_LED_OFF,
++					    LED_NUML, LIBEVDEV_LED_ON,
++					    LED_NUML, LIBEVDEV_LED_OFF,
++					    LED_NUML, LIBEVDEV_LED_ON,
++					    /* more than LED_CNT */
++					    -1);
++	ck_assert_int_eq(rc, 0);
++	ck_assert_int_eq(1, libevdev_get_event_value(dev, EV_LED, LED_NUML));
++	ck_assert_int_eq(0, libevdev_get_event_value(dev, EV_LED, LED_CAPSL));
++	ck_assert_int_eq(0, libevdev_get_event_value(dev, EV_LED, LED_COMPOSE));
++
++	libevdev_free(dev);
++	uinput_device_free(uidev);
++}
++END_TEST
++
++TEST_SUITE_ROOT_PRIVILEGES(has_events)
++{
++	Suite *s = suite_create("libevdev_has_event tests");
++
++	add_test(s, test_ev_bit_limits);
++	add_test(s, test_has_ev_bit);
++
++	add_test(s, test_event_codes);
++	add_test(s, test_event_code_limits);
++
++	add_test(s, test_ev_rep);
++	add_test(s, test_ev_rep_values);
++
++	add_test(s, test_input_props);
++	add_test(s, test_set_input_props);
++
++	add_test(s, test_no_slots);
++	add_test(s, test_slot_number);
++	add_test(s, test_slot_init_value);
++	add_test(s, test_invalid_mt_device);
++
++	add_test(s, test_device_name);
++	add_test(s, test_device_set_name);
++	add_test(s, test_device_set_ids);
++	add_test(s, test_device_get_abs_info);
++
++	add_test(s, test_device_set_abs);
++	add_test(s, test_device_enable_bit);
++	add_test(s, test_device_enable_bit_invalid);
++	add_test(s, test_device_disable_bit);
++	add_test(s, test_device_disable_bit_invalid);
++	add_test(s, test_device_kernel_change_axis);
++	add_test(s, test_device_kernel_change_axis_invalid);
++	add_test(s, test_device_kernel_set_abs_invalid_fd);
++
++	add_test(s, test_led_valid);
++	add_test(s, test_led_invalid);
++	add_test(s, test_led_same);
++
++	return s;
++}
+diff -Naur third-party-libevdev-bak/test/test-libevdev-init.c third-party-new/test/test-libevdev-init.c
+--- third-party-libevdev-bak/test/test-libevdev-init.c	1970-01-01 08:00:00.000000000 +0800
++++ third-party-new/test/test-libevdev-init.c	2022-03-25 12:33:26.000000000 +0800
+@@ -0,0 +1,704 @@
++// SPDX-License-Identifier: MIT
++/*
++ * Copyright © 2013 Red Hat, Inc.
++ */
++
++#include "config.h"
++#include 
++#include 
++#include 
++#include 
++#include 
++#include 
++#include 
++
++#include 
++#include "test-common.h"
++
++START_TEST(test_new_device)
++{
++	struct libevdev *dev;
++
++	dev = libevdev_new();
++	ck_assert(dev != NULL);
++	libevdev_free(dev);
++}
++END_TEST
++
++START_TEST(test_free_device)
++{
++	libevdev_free(NULL);
++}
++END_TEST
++
++START_TEST(test_init_from_invalid_fd)
++{
++	int rc;
++	struct libevdev *dev = NULL;
++
++	rc = libevdev_new_from_fd(-1, &dev);
++
++	ck_assert(dev == NULL);
++	ck_assert_int_eq(rc, -EBADF);
++
++	rc = libevdev_new_from_fd(STDIN_FILENO, &dev);
++	ck_assert(dev == NULL);
++	ck_assert_int_eq(rc, -ENOTTY);
++}
++END_TEST
++
++START_TEST(test_init_and_change_fd)
++{
++	struct uinput_device* uidev;
++	struct libevdev *dev;
++	int rc;
++
++	dev = libevdev_new();
++	ck_assert(dev != NULL);
++	ck_assert_int_eq(libevdev_set_fd(dev, -1), -EBADF);
++
++	libevdev_set_log_function(test_logfunc_ignore_error, NULL);
++	ck_assert_int_eq(libevdev_change_fd(dev, -1), -1);
++	libevdev_set_log_function(test_logfunc_abort_on_error, NULL);
++
++	rc = uinput_device_new_with_events(&uidev,
++					   TEST_DEVICE_NAME, DEFAULT_IDS,
++					   EV_SYN, SYN_REPORT,
++					   EV_REL, REL_X,
++					   EV_REL, REL_Y,
++					   EV_REL, REL_WHEEL,
++					   EV_KEY, BTN_LEFT,
++					   EV_KEY, BTN_MIDDLE,
++					   EV_KEY, BTN_RIGHT,
++					   -1);
++	ck_assert_msg(rc == 0, "Failed to create uinput device: %s", strerror(-rc));
++	ck_assert_int_eq(libevdev_set_fd(dev, uinput_device_get_fd(uidev)), 0);
++
++	libevdev_set_log_function(test_logfunc_ignore_error, NULL);
++	ck_assert_int_eq(libevdev_set_fd(dev, 0), -EBADF);
++	libevdev_set_log_function(test_logfunc_abort_on_error, NULL);
++
++	ck_assert_int_eq(libevdev_get_fd(dev), uinput_device_get_fd(uidev));
++
++	ck_assert_int_eq(libevdev_change_fd(dev, 0), 0);
++	ck_assert_int_eq(libevdev_get_fd(dev), 0);
++
++	uinput_device_free(uidev);
++	libevdev_free(dev);
++}
++END_TEST
++
++static int log_fn_called = 0;
++static char *logdata = "test";
++static void logfunc(enum libevdev_log_priority priority,
++		    void *data,
++		    const char *file, int line, const char *func,
++		    const char *f, va_list args) {
++	ck_assert_int_eq(strcmp(logdata, data), 0);
++	log_fn_called++;
++}
++
++START_TEST(test_log_init)
++{
++	struct libevdev *dev = NULL;
++	enum libevdev_log_priority old;
++
++	old = libevdev_get_log_priority();
++
++	libevdev_set_log_priority(LIBEVDEV_LOG_DEBUG);
++
++	libevdev_set_log_function(logfunc, NULL);
++	libevdev_set_log_function(NULL, NULL);
++
++	dev = libevdev_new();
++	ck_assert(dev != NULL);
++
++	libevdev_set_log_function(logfunc, logdata);
++	libevdev_next_event(dev, LIBEVDEV_READ_FLAG_NORMAL, NULL);
++
++	libevdev_set_log_function(NULL, NULL);
++	libevdev_next_event(dev, LIBEVDEV_READ_FLAG_NORMAL, NULL);
++
++	libevdev_set_log_function(logfunc, logdata);
++	libevdev_next_event(dev, LIBEVDEV_READ_FLAG_NORMAL, NULL);
++
++	/* libevdev_next_event(dev, LIBEVDEV_READ_FLAG_NORMAL, NULL) should
++	   trigger a log message. We called it three times, but only twice
++	   with the logfunc set, thus, ensure we only called the logfunc
++	   twice */
++	ck_assert_int_eq(log_fn_called, 2);
++
++	libevdev_free(dev);
++
++	libevdev_set_log_function(test_logfunc_abort_on_error, NULL);
++
++	log_fn_called = 0;
++
++	libevdev_set_log_priority(old);
++}
++END_TEST
++
++START_TEST(test_log_default_priority)
++{
++	ck_assert_int_eq(libevdev_get_log_priority(), LIBEVDEV_LOG_INFO);
++}
++END_TEST
++
++START_TEST(test_log_set_get_priority)
++{
++	enum libevdev_log_priority pri;
++	enum libevdev_log_priority old;
++
++	old = libevdev_get_log_priority();
++
++	pri = LIBEVDEV_LOG_DEBUG;
++	libevdev_set_log_priority(pri);
++	ck_assert_int_eq(libevdev_get_log_priority(), pri);
++
++	pri = LIBEVDEV_LOG_INFO;
++	libevdev_set_log_priority(pri);
++	ck_assert_int_eq(libevdev_get_log_priority(), pri);
++
++	pri = LIBEVDEV_LOG_ERROR;
++	libevdev_set_log_priority(pri);
++	ck_assert_int_eq(libevdev_get_log_priority(), pri);
++
++	/* debug and above is clamped */
++	pri = LIBEVDEV_LOG_DEBUG + 1;
++	libevdev_set_log_priority(pri);
++	ck_assert_int_eq(libevdev_get_log_priority(), LIBEVDEV_LOG_DEBUG);
++
++	/*  error and below is not clamped, we need this for another test */
++	pri = LIBEVDEV_LOG_ERROR - 1;
++	libevdev_set_log_priority(pri);
++	ck_assert_int_eq(libevdev_get_log_priority(), pri);
++
++	libevdev_set_log_priority(old);
++}
++END_TEST
++
++START_TEST(test_log_priority)
++{
++	struct libevdev *dev = NULL;
++	enum libevdev_log_priority old;
++
++	old = libevdev_get_log_priority();
++
++	libevdev_set_log_function(logfunc, logdata);
++
++	dev = libevdev_new();
++	ck_assert(dev != NULL);
++
++	libevdev_set_log_priority(LIBEVDEV_LOG_DEBUG);
++	libevdev_next_event(dev, LIBEVDEV_READ_FLAG_NORMAL, NULL);
++	ck_assert_int_eq(log_fn_called, 1);
++
++	libevdev_set_log_priority(LIBEVDEV_LOG_INFO);
++	libevdev_next_event(dev, LIBEVDEV_READ_FLAG_NORMAL, NULL);
++	ck_assert_int_eq(log_fn_called, 2);
++
++	libevdev_set_log_priority(LIBEVDEV_LOG_ERROR);
++	libevdev_next_event(dev, LIBEVDEV_READ_FLAG_NORMAL, NULL);
++	ck_assert_int_eq(log_fn_called, 3);
++
++	/* we don't have any log msgs > ERROR at the moment, so test it by
++	   setting an invalid priority. */
++	libevdev_set_log_priority(LIBEVDEV_LOG_ERROR - 1);
++	libevdev_next_event(dev, LIBEVDEV_READ_FLAG_NORMAL, NULL);
++	ck_assert_int_eq(log_fn_called, 3);
++
++	libevdev_free(dev);
++
++	libevdev_set_log_function(test_logfunc_abort_on_error, NULL);
++
++	log_fn_called = 0;
++
++	libevdev_set_log_priority(old);
++}
++END_TEST
++
++static char *logdata_1 = "foo";
++static char *logdata_2 = "bar";
++static int log_data_fn_called = 0;
++static void logfunc_data(enum libevdev_log_priority priority,
++			 void *data,
++			 const char *file, int line, const char *func,
++			 const char *f, va_list args) {
++	switch(log_data_fn_called) {
++		case 0: ck_assert(data == logdata_1); break;
++		case 1: ck_assert(data == logdata_2); break;
++		case 2: ck_assert(data == NULL); break;
++		default:
++			ck_abort();
++	}
++	log_data_fn_called++;
++}
++
++START_TEST(test_log_data)
++{
++	struct libevdev *dev = NULL;
++
++	dev = libevdev_new();
++	ck_assert(dev != NULL);
++
++	libevdev_set_log_function(logfunc_data, logdata_1);
++	libevdev_next_event(dev, LIBEVDEV_READ_FLAG_NORMAL, NULL);
++
++	libevdev_set_log_function(logfunc_data, logdata_2);
++	libevdev_next_event(dev, LIBEVDEV_READ_FLAG_NORMAL, NULL);
++
++	libevdev_set_log_function(logfunc_data, NULL);
++	libevdev_next_event(dev, LIBEVDEV_READ_FLAG_NORMAL, NULL);
++
++	libevdev_free(dev);
++}
++END_TEST
++
++struct libevdev *devlogdata;
++static int dev_log_fn_called = 0;
++static void devlogfunc(const struct libevdev *dev,
++		    enum libevdev_log_priority priority,
++		    void *data,
++		    const char *file, int line, const char *func,
++		    const char *f, va_list args)
++{
++	ck_assert(dev == data);
++	dev_log_fn_called++;
++}
++
++START_TEST(test_device_log_init)
++{
++	struct libevdev *dev = NULL;
++	enum libevdev_log_priority old;
++
++	old = libevdev_get_log_priority();
++	libevdev_set_log_priority(LIBEVDEV_LOG_DEBUG);
++	libevdev_set_log_function(logfunc, logdata);
++
++	/* error for NULL device */
++	libevdev_set_device_log_function(NULL, NULL,
++					 LIBEVDEV_LOG_ERROR, NULL);
++	ck_assert_int_eq(log_fn_called, 1);
++
++	/* error for NULL device */
++	libevdev_set_device_log_function(NULL, devlogfunc,
++					 LIBEVDEV_LOG_ERROR, NULL);
++	ck_assert_int_eq(log_fn_called, 2);
++
++	log_fn_called = 0;
++
++	dev = libevdev_new();
++	ck_assert(dev != NULL);
++
++	libevdev_set_device_log_function(dev, NULL,
++					 LIBEVDEV_LOG_ERROR, NULL);
++
++	/* libevdev_next_event(dev, LIBEVDEV_READ_FLAG_NORMAL, NULL) should
++	   trigger a log message. */
++
++	/* expect global handler triggered */
++	libevdev_next_event(dev, LIBEVDEV_READ_FLAG_NORMAL, NULL);
++	ck_assert_int_eq(log_fn_called, 1);
++	ck_assert_int_eq(dev_log_fn_called, 0);
++
++	/* expect device handler triggered */
++	libevdev_set_device_log_function(dev, devlogfunc,
++					 LIBEVDEV_LOG_ERROR, dev);
++	libevdev_next_event(dev, LIBEVDEV_READ_FLAG_NORMAL, NULL);
++	ck_assert_int_eq(log_fn_called, 1);
++	ck_assert_int_eq(dev_log_fn_called, 1);
++
++	/* device handler set, but priority filters. don't expect any log
++	   handler to be called.
++	   we don't have any log msgs > ERROR at the moment, so test it by
++	   setting an invalid priority. */
++	libevdev_set_device_log_function(dev, devlogfunc,
++					 LIBEVDEV_LOG_ERROR - 1, dev);
++	libevdev_next_event(dev, LIBEVDEV_READ_FLAG_NORMAL, NULL);
++	ck_assert_int_eq(log_fn_called, 1);
++	ck_assert_int_eq(dev_log_fn_called, 1);
++
++	libevdev_free(dev);
++
++	log_fn_called = 0;
++	libevdev_set_log_priority(old);
++	libevdev_set_log_function(test_logfunc_abort_on_error, NULL);
++
++}
++END_TEST
++
++START_TEST(test_device_init)
++{
++	struct uinput_device* uidev;
++	struct libevdev *dev;
++	int rc;
++
++	rc = uinput_device_new_with_events(&uidev,
++					   TEST_DEVICE_NAME, DEFAULT_IDS,
++					   EV_SYN, SYN_REPORT,
++					   EV_REL, REL_X,
++					   EV_REL, REL_Y,
++					   EV_REL, REL_WHEEL,
++					   EV_KEY, BTN_LEFT,
++					   EV_KEY, BTN_MIDDLE,
++					   EV_KEY, BTN_RIGHT,
++					   -1);
++	ck_assert_msg(rc == 0, "Failed to create uinput device: %s", strerror(-rc));
++
++	dev = libevdev_new();
++	ck_assert(dev != NULL);
++	rc = libevdev_set_fd(dev, uinput_device_get_fd(uidev));
++	ck_assert_msg(rc == 0, "Failed to init device: %s", strerror(-rc));;
++
++	uinput_device_free(uidev);
++	libevdev_free(dev);
++}
++END_TEST
++
++START_TEST(test_device_init_from_fd)
++{
++	struct uinput_device* uidev;
++	struct libevdev *dev;
++	int rc;
++
++	rc = uinput_device_new_with_events(&uidev,
++					   TEST_DEVICE_NAME, DEFAULT_IDS,
++					   EV_SYN, SYN_REPORT,
++					   EV_REL, REL_X,
++					   EV_REL, REL_Y,
++					   EV_REL, REL_WHEEL,
++					   EV_KEY, BTN_LEFT,
++					   EV_KEY, BTN_MIDDLE,
++					   EV_KEY, BTN_RIGHT,
++					   -1);
++	ck_assert_msg(rc == 0, "Failed to create uinput device: %s", strerror(-rc));
++
++	rc = libevdev_new_from_fd(uinput_device_get_fd(uidev), &dev);
++	ck_assert_msg(rc == 0, "Failed to init device: %s", strerror(-rc));;
++
++	uinput_device_free(uidev);
++	libevdev_free(dev);
++}
++END_TEST
++
++START_TEST(test_device_grab)
++{
++	struct uinput_device* uidev;
++	struct libevdev *dev;
++	int rc;
++
++	test_create_device(&uidev, &dev,
++			   EV_SYN, SYN_REPORT,
++			   EV_REL, REL_X,
++			   EV_REL, REL_Y,
++			   EV_REL, REL_WHEEL,
++			   EV_KEY, BTN_LEFT,
++			   EV_KEY, BTN_MIDDLE,
++			   EV_KEY, BTN_RIGHT,
++			   -1);
++
++	libevdev_set_log_function(test_logfunc_ignore_error, NULL);
++	rc = libevdev_grab(dev, 0);
++	ck_assert_int_eq(rc, -EINVAL);
++	rc = libevdev_grab(dev, 1);
++	ck_assert_int_eq(rc, -EINVAL);
++	libevdev_set_log_function(test_logfunc_abort_on_error, NULL);
++
++	rc = libevdev_grab(dev, LIBEVDEV_UNGRAB);
++	ck_assert_int_eq(rc, 0);
++	rc = libevdev_grab(dev, LIBEVDEV_GRAB);
++	ck_assert_int_eq(rc, 0);
++	rc = libevdev_grab(dev, LIBEVDEV_GRAB);
++	ck_assert_int_eq(rc, 0);
++	rc = libevdev_grab(dev, LIBEVDEV_UNGRAB);
++	ck_assert_int_eq(rc, 0);
++
++	uinput_device_free(uidev);
++	libevdev_free(dev);
++}
++END_TEST
++
++START_TEST(test_device_grab_invalid_fd)
++{
++	struct uinput_device* uidev;
++	struct libevdev *dev;
++	int rc;
++
++	libevdev_set_log_function(test_logfunc_ignore_error, NULL);
++
++	dev = libevdev_new();
++	rc = libevdev_grab(dev, 0);
++	ck_assert_int_eq(rc, -EBADF);
++	libevdev_free(dev);
++
++	test_create_device(&uidev, &dev,
++			   EV_SYN, SYN_REPORT,
++			   EV_REL, REL_X,
++			   EV_REL, REL_Y,
++			   EV_REL, REL_WHEEL,
++			   EV_KEY, BTN_LEFT,
++			   EV_KEY, BTN_MIDDLE,
++			   EV_KEY, BTN_RIGHT,
++			   -1);
++	libevdev_change_fd(dev, -2);
++	rc = libevdev_grab(dev, 0);
++	ck_assert_int_eq(rc, -EBADF);
++
++	libevdev_set_log_function(test_logfunc_abort_on_error, NULL);
++
++	uinput_device_free(uidev);
++	libevdev_free(dev);
++}
++END_TEST
++
++START_TEST(test_device_grab_change_fd)
++{
++	struct libevdev_uinput *uidev;
++	struct libevdev *dev, *other;
++	struct input_event e;
++	int rc;
++	int other_fd;
++	int dev_fd;
++
++	dev = libevdev_new();
++	libevdev_set_name(dev, "libevdev test device");
++	libevdev_enable_event_code(dev, EV_REL, REL_X, NULL);
++	libevdev_enable_event_code(dev, EV_REL, REL_Y, NULL);
++	libevdev_enable_event_code(dev, EV_KEY, BTN_LEFT, NULL);
++
++	rc = libevdev_uinput_create_from_device(dev,
++						LIBEVDEV_UINPUT_OPEN_MANAGED,
++						&uidev);
++	ck_assert_int_eq(rc, 0);
++	libevdev_free(dev);
++
++	dev_fd = open(libevdev_uinput_get_devnode(uidev),
++		      O_RDONLY|O_NONBLOCK);
++	ck_assert_int_ne(dev_fd, -1);
++	rc = libevdev_new_from_fd(dev_fd, &dev);
++	ck_assert_int_eq(rc, 0);
++
++	other_fd = open(libevdev_uinput_get_devnode(uidev),
++			O_RDONLY|O_NONBLOCK);
++	ck_assert_int_ne(other_fd, -1);
++	rc = libevdev_new_from_fd(other_fd, &other);
++	ck_assert_int_eq(rc, 0);
++
++	/* check we're getting the events before the grab */
++	libevdev_uinput_write_event(uidev, EV_REL, REL_X, -1);
++	libevdev_uinput_write_event(uidev, EV_SYN, SYN_REPORT, 0);
++	rc = libevdev_next_event(other, LIBEVDEV_READ_FLAG_NORMAL, &e);
++	ck_assert_int_eq(rc, LIBEVDEV_READ_STATUS_SUCCESS);
++	rc = libevdev_next_event(other, LIBEVDEV_READ_FLAG_NORMAL, &e);
++	ck_assert_int_eq(rc, LIBEVDEV_READ_STATUS_SUCCESS);
++	rc = libevdev_next_event(other, LIBEVDEV_READ_FLAG_NORMAL, &e);
++	ck_assert_int_eq(rc, -EAGAIN);
++
++	/* no events after the grab */
++	rc = libevdev_grab(dev, LIBEVDEV_GRAB);
++	ck_assert_int_eq(rc, 0);
++	libevdev_uinput_write_event(uidev, EV_REL, REL_X, -1);
++	libevdev_uinput_write_event(uidev, EV_SYN, SYN_REPORT, 0);
++	rc = libevdev_grab(dev, LIBEVDEV_GRAB);
++	ck_assert_int_eq(rc, 0);
++	rc = libevdev_next_event(other, LIBEVDEV_READ_FLAG_NORMAL, &e);
++	ck_assert_int_eq(rc, -EAGAIN);
++
++	/* swapping the fd removes the grab */
++	close(dev_fd);
++	dev_fd = open(libevdev_uinput_get_devnode(uidev),
++		      O_RDONLY|O_NONBLOCK);
++	ck_assert_int_ne(dev_fd, -1);
++	rc = libevdev_change_fd(dev, dev_fd);
++	ck_assert_int_eq(rc, 0);
++
++	/* check we're getting the events again */
++	libevdev_uinput_write_event(uidev, EV_REL, REL_X, -1);
++	libevdev_uinput_write_event(uidev, EV_SYN, SYN_REPORT, 0);
++	rc = libevdev_next_event(other, LIBEVDEV_READ_FLAG_NORMAL, &e);
++	ck_assert_int_eq(rc, LIBEVDEV_READ_STATUS_SUCCESS);
++	rc = libevdev_next_event(other, LIBEVDEV_READ_FLAG_NORMAL, &e);
++	ck_assert_int_eq(rc, LIBEVDEV_READ_STATUS_SUCCESS);
++	rc = libevdev_next_event(other, LIBEVDEV_READ_FLAG_NORMAL, &e);
++	ck_assert_int_eq(rc, -EAGAIN);
++
++	/* no events after the grab */
++	rc = libevdev_grab(dev, LIBEVDEV_GRAB);
++	ck_assert_int_eq(rc, 0);
++	libevdev_uinput_write_event(uidev, EV_REL, REL_X, -1);
++	libevdev_uinput_write_event(uidev, EV_SYN, SYN_REPORT, 0);
++	rc = libevdev_next_event(other, LIBEVDEV_READ_FLAG_NORMAL, &e);
++	ck_assert_int_eq(rc, -EAGAIN);
++
++	libevdev_uinput_destroy(uidev);
++	libevdev_free(dev);
++	libevdev_free(other);
++	close(dev_fd);
++	close(other_fd);
++}
++END_TEST
++
++START_TEST(test_set_clock_id)
++{
++	struct uinput_device* uidev;
++	struct libevdev *dev;
++	int clockid;
++	int rc;
++
++	test_create_device(&uidev, &dev,
++			   EV_SYN, SYN_REPORT,
++			   EV_REL, REL_X,
++			   EV_REL, REL_Y,
++			   EV_REL, REL_WHEEL,
++			   EV_KEY, BTN_LEFT,
++			   EV_KEY, BTN_MIDDLE,
++			   EV_KEY, BTN_RIGHT,
++			   -1);
++
++	rc = libevdev_set_clock_id(dev, CLOCK_REALTIME);
++	ck_assert_int_eq(rc, 0);
++
++	rc = libevdev_set_clock_id(dev, CLOCK_MONOTONIC);
++	ck_assert_int_eq(rc, 0);
++
++#ifdef __FreeBSD__
++	clockid = CLOCK_MONOTONIC_FAST;
++#else
++	clockid = CLOCK_MONOTONIC_RAW;
++#endif
++
++	rc = libevdev_set_clock_id(dev, clockid);
++	ck_assert_int_eq(rc, -EINVAL);
++
++	uinput_device_free(uidev);
++	libevdev_free(dev);
++}
++END_TEST
++
++START_TEST(test_set_clock_id_invalid_fd)
++{
++	struct uinput_device* uidev;
++	struct libevdev *dev;
++	int rc;
++
++	libevdev_set_log_function(test_logfunc_ignore_error, NULL);
++
++	dev = libevdev_new();
++	rc = libevdev_set_clock_id(dev, CLOCK_MONOTONIC);
++	ck_assert_int_eq(rc, -EBADF);
++	libevdev_free(dev);
++
++	test_create_device(&uidev, &dev,
++			   EV_SYN, SYN_REPORT,
++			   EV_REL, REL_X,
++			   EV_REL, REL_Y,
++			   EV_REL, REL_WHEEL,
++			   EV_KEY, BTN_LEFT,
++			   EV_KEY, BTN_MIDDLE,
++			   EV_KEY, BTN_RIGHT,
++			   -1);
++	libevdev_change_fd(dev, -2);
++	rc = libevdev_set_clock_id(dev, CLOCK_MONOTONIC);
++	ck_assert_int_eq(rc, -EBADF);
++
++	uinput_device_free(uidev);
++	libevdev_free(dev);
++}
++END_TEST
++
++START_TEST(test_clock_id_events)
++{
++	struct uinput_device* uidev;
++	struct libevdev *dev, *dev2;
++	int rc, fd;
++	struct input_event ev1, ev2;
++	struct timespec t1_real, t2_real;
++	struct timespec t1_mono, t2_mono;
++	int64_t t1, t2;
++
++	test_create_device(&uidev, &dev,
++			   EV_SYN, SYN_REPORT,
++			   EV_REL, REL_X,
++			   EV_REL, REL_Y,
++			   EV_REL, REL_WHEEL,
++			   EV_KEY, BTN_LEFT,
++			   EV_KEY, BTN_MIDDLE,
++			   EV_KEY, BTN_RIGHT,
++			   -1);
++
++	fd = open(uinput_device_get_devnode(uidev), O_RDONLY);
++	ck_assert_int_gt(fd, -1);
++
++	rc = libevdev_new_from_fd(fd, &dev2);
++	ck_assert_msg(rc == 0, "Failed to create second device: %s", strerror(-rc));
++
++	rc = libevdev_set_clock_id(dev2, CLOCK_MONOTONIC);
++	ck_assert_int_eq(rc, 0);
++
++	clock_gettime(CLOCK_REALTIME, &t1_real);
++	clock_gettime(CLOCK_MONOTONIC, &t1_mono);
++	uinput_device_event(uidev, EV_REL, REL_X, 1);
++	uinput_device_event(uidev, EV_SYN, SYN_REPORT, 0);
++	clock_gettime(CLOCK_REALTIME, &t2_real);
++	clock_gettime(CLOCK_MONOTONIC, &t2_mono);
++
++	rc = libevdev_next_event(dev, LIBEVDEV_READ_FLAG_NORMAL, &ev1);
++	ck_assert_int_eq(rc, LIBEVDEV_READ_STATUS_SUCCESS);
++
++	rc = libevdev_next_event(dev2, LIBEVDEV_READ_FLAG_NORMAL, &ev2);
++	ck_assert_int_eq(rc, LIBEVDEV_READ_STATUS_SUCCESS);
++
++	ck_assert_int_eq(ev1.type, ev2.type);
++	ck_assert_int_eq(ev1.code, ev2.code);
++	ck_assert_int_eq(ev1.value, ev2.value);
++
++	t1 = ev1.input_event_sec * 1000000LL + ev1.input_event_usec;
++	t2 = ev2.input_event_sec * 1000000LL + ev2.input_event_usec;
++	ck_assert_int_ne(t1, t2);
++
++	ck_assert_int_ge(ev1.input_event_sec, t1_real.tv_sec);
++	ck_assert_int_ge(ev1.input_event_usec, t1_real.tv_nsec/1000);
++	ck_assert_int_le(ev1.input_event_sec, t2_real.tv_sec);
++	ck_assert_int_le(ev1.input_event_usec, t2_real.tv_nsec/1000);
++
++	ck_assert_int_ge(ev2.input_event_sec, t1_mono.tv_sec);
++	ck_assert_int_ge(ev2.input_event_usec, t1_mono.tv_nsec/1000);
++	ck_assert_int_le(ev2.input_event_sec, t2_mono.tv_sec);
++	ck_assert_int_le(ev2.input_event_usec, t2_mono.tv_nsec/1000);
++
++	uinput_device_free(uidev);
++	libevdev_free(dev);
++	libevdev_free(dev2);
++	close(fd);
++}
++END_TEST
++
++TEST_SUITE_ROOT_PRIVILEGES(libevdev_init_test)
++{
++	Suite *s = suite_create("libevdev init tests");
++
++	add_test(s, test_new_device);
++	add_test(s, test_free_device);
++	add_test(s, test_init_from_invalid_fd);
++	add_test(s, test_init_and_change_fd);
++
++	add_test(s, test_log_init);
++	add_test(s, test_log_priority);
++	add_test(s, test_log_set_get_priority);
++	add_test(s, test_log_default_priority);
++	add_test(s, test_log_data);
++	add_test(s, test_device_log_init);
++
++	add_test(s, test_device_init);
++	add_test(s, test_device_init_from_fd);
++
++	add_test(s, test_device_grab);
++	add_test(s, test_device_grab_invalid_fd);
++	add_test(s, test_device_grab_change_fd);
++
++	add_test(s, test_set_clock_id);
++	add_test(s, test_set_clock_id_invalid_fd);
++	add_test(s, test_clock_id_events);
++
++	return s;
++}
+diff -Naur third-party-libevdev-bak/test/test-link.c third-party-new/test/test-link.c
+--- third-party-libevdev-bak/test/test-link.c	1970-01-01 08:00:00.000000000 +0800
++++ third-party-new/test/test-link.c	2022-03-25 12:33:26.000000000 +0800
+@@ -0,0 +1,6 @@
++#include 
++#include 
++
++int main(void) {
++	return libevdev_new_from_fd(0, NULL);
++}
+diff -Naur third-party-libevdev-bak/test/test-main.c third-party-new/test/test-main.c
+--- third-party-libevdev-bak/test/test-main.c	1970-01-01 08:00:00.000000000 +0800
++++ third-party-new/test/test-main.c	2022-03-25 12:33:26.000000000 +0800
+@@ -0,0 +1,117 @@
++// SPDX-License-Identifier: MIT
++/*
++ * Copyright © 2013 Red Hat, Inc.
++ */
++
++#include "config.h"
++#include 
++#include 
++#include 
++#include 
++#include 
++#include 
++#include 
++#include 
++#include 
++#include 
++#include 
++
++#include "test-common.h"
++
++static int
++is_debugger_attached(void)
++{
++	int rc = 1;
++	/*
++	 * FreeBSD does not support PTRACE_ATTACH, disable attaching a debugger
++	 * on FreeBSD by skipping the rest of the function and just return 1.
++	 */
++#ifndef __FreeBSD__
++	int status;
++	int pid = fork();
++
++	if (pid == -1)
++		return 0;
++
++	if (pid == 0) {
++		int ppid = getppid();
++		if (ptrace(PTRACE_ATTACH, ppid, NULL, NULL) == 0) {
++			waitpid(ppid, NULL, 0);
++			ptrace(PTRACE_CONT, NULL, NULL);
++			ptrace(PTRACE_DETACH, ppid, NULL, NULL);
++			rc = 0;
++		}
++		_exit(rc);
++	} else {
++		waitpid(pid, &status, 0);
++		rc = WEXITSTATUS(status);
++	}
++
++#endif /* !__FreeBSD__ */
++	return rc;
++}
++
++static bool
++device_nodes_exist(void)
++{
++	struct stat st;
++	int rc;
++
++	rc = stat("/dev/uinput", &st);
++	if (rc == -1 && errno == ENOENT)
++		return false;
++
++	rc = stat("/dev/input", &st);
++	if (rc == -1 && errno == ENOENT)
++		return false;
++
++	/* Any issues but ENOENT we just let the test suite blow up later */
++	return true;
++}
++
++extern const struct libevdev_test __start_test_section, __stop_test_section;
++
++int main(void)
++{
++	const struct libevdev_test *t;
++	const struct rlimit corelimit = {0, 0};
++	int failed;
++
++	for (t = &__start_test_section; t < &__stop_test_section; t++) {
++		if (t->needs_root_privileges) {
++			if (getenv("LIBEVDEV_SKIP_ROOT_TESTS"))
++				return 77;
++
++			if (getuid() != 0) {
++				fprintf(stderr, "This test needs to run as root\n");
++				return 77;
++			}
++			if (!device_nodes_exist()) {
++				fprintf(stderr, "This test needs /dev/input and /dev/uinput to exist\n");
++				return 77;
++			}
++
++			break;
++		}
++	}
++
++	if (is_debugger_attached())
++		setenv("CK_FORK", "no", 0);
++
++	if (setrlimit(RLIMIT_CORE, &corelimit) != 0)
++		perror("WARNING: Core dumps not disabled. Reason");
++
++	libevdev_set_log_function(test_logfunc_abort_on_error, NULL);
++
++	SRunner *sr = srunner_create(NULL);
++	for (t = &__start_test_section; t < &__stop_test_section; t++) {
++		srunner_add_suite(sr, t->setup());
++	}
++
++	srunner_run_all(sr, CK_NORMAL);
++
++	failed = srunner_ntests_failed(sr);
++	srunner_free(sr);
++
++	return failed;
++}
+diff -Naur third-party-libevdev-bak/test/test-static-symbols-leak.sh third-party-new/test/test-static-symbols-leak.sh
+--- third-party-libevdev-bak/test/test-static-symbols-leak.sh	1970-01-01 08:00:00.000000000 +0800
++++ third-party-new/test/test-static-symbols-leak.sh	2022-03-25 12:33:26.000000000 +0800
+@@ -0,0 +1,21 @@
++#!/usr/bin/env bash
++#
++# Hack to check for leaking symbols in the static library.
++# See https://bugs.freedesktop.org/show_bug.cgi?id=82785
++# Note the spaces in the expressions! After the first grep, each line
++# is " T symbol_name"
++
++test -z "$RUNNING_ON_VALGRIND" || exit 77
++
++builddir="$1"
++
++test -f "$builddir/test-static-link" || (echo "Unable to find test file" && exit 1)
++nm --extern-only "$builddir/test-static-link" |
++	grep -o -e " T .*" | \
++	grep -v -e " main\$" \
++		-e " atexit" \
++		-e " mangle_path" \
++		-e " *gcov.*" \
++		-e " _.*" \
++		-e " libevdev_*" && \
++		echo "Leaking symbols found" && exit 1 || exit 0
+diff -Naur third-party-libevdev-bak/test/test-uinput.c third-party-new/test/test-uinput.c
+--- third-party-libevdev-bak/test/test-uinput.c	1970-01-01 08:00:00.000000000 +0800
++++ third-party-new/test/test-uinput.c	2022-03-25 12:33:26.000000000 +0800
+@@ -0,0 +1,463 @@
++// SPDX-License-Identifier: MIT
++/*
++ * Copyright © 2013 Red Hat, Inc.
++ */
++
++#include "config.h"
++#include 
++#include 
++#include 
++#include 
++#include 
++#include 
++
++#include "test-common.h"
++#define UINPUT_NODE "/dev/uinput"
++
++START_TEST(test_uinput_create_device)
++{
++	struct libevdev *dev, *dev2;
++	struct libevdev_uinput *uidev;
++	int fd, uinput_fd;
++	unsigned int type, code;
++	int rc;
++	const char *devnode;
++
++	dev = libevdev_new();
++	ck_assert(dev != NULL);
++	libevdev_set_name(dev, TEST_DEVICE_NAME);
++	libevdev_enable_event_type(dev, EV_SYN);
++	libevdev_enable_event_type(dev, EV_REL);
++	libevdev_enable_event_code(dev, EV_REL, REL_X, NULL);
++	libevdev_enable_event_code(dev, EV_REL, REL_Y, NULL);
++	libevdev_enable_event_code(dev, EV_REL, REL_MAX, NULL);
++
++	rc = libevdev_uinput_create_from_device(dev, LIBEVDEV_UINPUT_OPEN_MANAGED, &uidev);
++	ck_assert_int_eq(rc, 0);
++	ck_assert(uidev != NULL);
++
++	uinput_fd = libevdev_uinput_get_fd(uidev);
++	ck_assert_int_gt(uinput_fd, -1);
++
++	devnode = libevdev_uinput_get_devnode(uidev);
++	ck_assert(devnode != NULL);
++
++	fd = open(devnode, O_RDONLY);
++	ck_assert_int_gt(fd, -1);
++	rc = libevdev_new_from_fd(fd, &dev2);
++	ck_assert_int_eq(rc, 0);
++
++	for (type = 0; type < EV_CNT; type++) {
++		int max = libevdev_event_type_get_max(type);
++		if (max == -1)
++			continue;
++
++		for (code = 0; code < (unsigned int)max; code++) {
++			ck_assert_int_eq(libevdev_has_event_code(dev, type, code),
++					 libevdev_has_event_code(dev2, type, code));
++		}
++	}
++
++	libevdev_free(dev);
++	libevdev_free(dev2);
++	libevdev_uinput_destroy(uidev);
++	close(fd);
++
++	/* uinput fd is managed, so make sure it did get closed */
++	ck_assert_int_eq(close(uinput_fd), -1);
++	ck_assert_int_eq(errno, EBADF);
++
++}
++END_TEST
++
++START_TEST(test_uinput_create_device_invalid)
++{
++	struct libevdev *dev;
++	struct libevdev_uinput *uidev = NULL;
++	int rc;
++
++	dev = libevdev_new();
++	ck_assert(dev != NULL);
++	libevdev_set_name(dev, TEST_DEVICE_NAME);
++	libevdev_enable_event_type(dev, EV_SYN);
++	libevdev_enable_event_type(dev, EV_REL);
++	libevdev_enable_event_code(dev, EV_REL, REL_X, NULL);
++	libevdev_enable_event_code(dev, EV_REL, REL_Y, NULL);
++
++	libevdev_set_log_function(test_logfunc_ignore_error, NULL);
++	rc = libevdev_uinput_create_from_device(dev, -1, &uidev);
++	ck_assert_int_eq(rc, -EBADF);
++	ck_assert(uidev == NULL);
++	libevdev_set_log_function(test_logfunc_abort_on_error, NULL);
++
++	libevdev_free(dev);
++}
++END_TEST
++
++START_TEST(test_uinput_create_device_from_fd)
++{
++	struct libevdev *dev, *dev2;
++	struct libevdev_uinput *uidev;
++	int fd, fd2;
++	unsigned int type, code;
++	int rc;
++	const char *devnode;
++
++	dev = libevdev_new();
++	ck_assert(dev != NULL);
++	libevdev_set_name(dev, TEST_DEVICE_NAME);
++	libevdev_enable_event_type(dev, EV_SYN);
++	libevdev_enable_event_type(dev, EV_REL);
++	libevdev_enable_event_code(dev, EV_REL, REL_X, NULL);
++	libevdev_enable_event_code(dev, EV_REL, REL_Y, NULL);
++
++	fd = open(UINPUT_NODE, O_RDWR);
++	ck_assert_int_gt(fd, -1);
++
++	rc = libevdev_uinput_create_from_device(dev, fd, &uidev);
++	ck_assert_int_eq(rc, 0);
++	ck_assert(uidev != NULL);
++
++	ck_assert_int_eq(libevdev_uinput_get_fd(uidev), fd);
++
++	devnode = libevdev_uinput_get_devnode(uidev);
++	ck_assert(devnode != NULL);
++
++	fd2 = open(devnode, O_RDONLY);
++	ck_assert_int_gt(fd2, -1);
++	rc = libevdev_new_from_fd(fd2, &dev2);
++	ck_assert_int_eq(rc, 0);
++
++	for (type = 0; type < EV_CNT; type++) {
++		int max = libevdev_event_type_get_max(type);
++		if (max == -1)
++			continue;
++
++		for (code = 0; code < (unsigned int)max; code++) {
++			ck_assert_int_eq(libevdev_has_event_code(dev, type, code),
++					 libevdev_has_event_code(dev2, type, code));
++		}
++	}
++
++	libevdev_free(dev);
++	libevdev_free(dev2);
++	libevdev_uinput_destroy(uidev);
++	close(fd);
++	close(fd2);
++}
++END_TEST
++
++#ifdef __FreeBSD__
++START_TEST(test_uinput_check_devnode_bsd)
++{
++	struct libevdev *dev;
++	struct libevdev_uinput *uidev, *uidev2;
++	const char *devnode, *devnode2;
++	int fd, fd2;
++	int rc;
++
++	dev = libevdev_new();
++	ck_assert(dev != NULL);
++	libevdev_set_name(dev, TEST_DEVICE_NAME);
++	libevdev_enable_event_type(dev, EV_SYN);
++	libevdev_enable_event_type(dev, EV_REL);
++	libevdev_enable_event_code(dev, EV_REL, REL_X, NULL);
++	libevdev_enable_event_code(dev, EV_REL, REL_Y, NULL);
++
++	fd = open(UINPUT_NODE, O_RDWR);
++	ck_assert_int_gt(fd, -1);
++	fd2 = open(UINPUT_NODE, O_RDWR);
++	ck_assert_int_gt(fd2, -1);
++
++	rc = libevdev_uinput_create_from_device(dev, fd, &uidev);
++	ck_assert_int_eq(rc, 0);
++
++	/* create a second one */
++	libevdev_set_name(dev, TEST_DEVICE_NAME " 2");
++	rc = libevdev_uinput_create_from_device(dev, fd2, &uidev2);
++	ck_assert_int_eq(rc, 0);
++
++	devnode = libevdev_uinput_get_devnode(uidev);
++	ck_assert(devnode != NULL);
++
++	/* get syspath twice returns same pointer */
++	devnode2 = libevdev_uinput_get_devnode(uidev);
++	ck_assert(devnode == devnode2);
++
++	/* second dev has different devnode */
++	devnode2 = libevdev_uinput_get_devnode(uidev2);
++	ck_assert(strcmp(devnode, devnode2) != 0);
++
++	libevdev_uinput_destroy(uidev2);
++	libevdev_uinput_destroy(uidev);
++
++	close(fd2);
++	close(fd);
++
++	libevdev_free(dev);
++}
++END_TEST
++
++START_TEST(test_uinput_check_syspath_bsd)
++{
++	struct libevdev *dev;
++	struct libevdev_uinput *uidev;
++	const char *syspath;
++	int fd;
++	int rc;
++
++	dev = libevdev_new();
++	ck_assert(dev != NULL);
++	libevdev_set_name(dev, TEST_DEVICE_NAME);
++	libevdev_enable_event_type(dev, EV_SYN);
++	libevdev_enable_event_type(dev, EV_REL);
++	libevdev_enable_event_code(dev, EV_REL, REL_X, NULL);
++	libevdev_enable_event_code(dev, EV_REL, REL_Y, NULL);
++
++	fd = open(UINPUT_NODE, O_RDWR);
++	ck_assert_int_gt(fd, -1);
++
++	rc = libevdev_uinput_create_from_device(dev, fd, &uidev);
++	ck_assert_int_eq(rc, 0);
++
++	syspath = libevdev_uinput_get_syspath(uidev);
++	/* FreeBSD should always return NULL for libevdev_unput_get_syspath() */
++	ck_assert(syspath == NULL);
++
++	libevdev_uinput_destroy(uidev);
++
++	close(fd);
++
++	libevdev_free(dev);
++}
++END_TEST
++
++#else /* !__FreeBSD__ */
++
++START_TEST(test_uinput_check_syspath_time)
++{
++	struct libevdev *dev;
++	struct libevdev_uinput *uidev, *uidev2;
++	const char *syspath, *syspath2;
++	int fd, fd2;
++	int rc;
++
++	dev = libevdev_new();
++	ck_assert(dev != NULL);
++	libevdev_set_name(dev, TEST_DEVICE_NAME);
++	libevdev_enable_event_type(dev, EV_SYN);
++	libevdev_enable_event_type(dev, EV_REL);
++	libevdev_enable_event_code(dev, EV_REL, REL_X, NULL);
++	libevdev_enable_event_code(dev, EV_REL, REL_Y, NULL);
++
++	fd = open(UINPUT_NODE, O_RDWR);
++	ck_assert_int_gt(fd, -1);
++	fd2 = open(UINPUT_NODE, O_RDWR);
++	ck_assert_int_gt(fd2, -1);
++
++	rc = libevdev_uinput_create_from_device(dev, fd, &uidev);
++	ck_assert_int_eq(rc, 0);
++
++	/* sleep for 1.5 seconds. sysfs resolution is 1 second, so
++	   creating both devices without delay means
++	   libevdev_uinput_get_syspath can't actually differ between
++	   them. By waiting, we get different ctime for uidev and uidev2,
++	   and exercise that part of the code.
++	 */
++	usleep(1500000);
++
++	/* create a second one to test the syspath time filtering code */
++	rc = libevdev_uinput_create_from_device(dev, fd2, &uidev2);
++	ck_assert_int_eq(rc, 0);
++
++	syspath = libevdev_uinput_get_syspath(uidev);
++	ck_assert(syspath != NULL);
++
++	/* get syspath twice returns same pointer */
++	syspath2 = libevdev_uinput_get_syspath(uidev);
++	ck_assert(syspath == syspath2);
++
++	/* second dev has different syspath */
++	syspath2 = libevdev_uinput_get_syspath(uidev2);
++	ck_assert(strcmp(syspath, syspath2) != 0);
++
++	libevdev_free(dev);
++	libevdev_uinput_destroy(uidev);
++	libevdev_uinput_destroy(uidev2);
++
++	close(fd);
++	close(fd2);
++}
++END_TEST
++
++START_TEST(test_uinput_check_syspath_name)
++{
++	struct libevdev *dev;
++	struct libevdev_uinput *uidev, *uidev2;
++	const char *syspath, *syspath2;
++	int fd, fd2;
++	int rc;
++
++	dev = libevdev_new();
++	ck_assert(dev != NULL);
++	libevdev_set_name(dev, TEST_DEVICE_NAME);
++	libevdev_enable_event_type(dev, EV_SYN);
++	libevdev_enable_event_type(dev, EV_REL);
++	libevdev_enable_event_code(dev, EV_REL, REL_X, NULL);
++	libevdev_enable_event_code(dev, EV_REL, REL_Y, NULL);
++
++	fd = open(UINPUT_NODE, O_RDWR);
++	ck_assert_int_gt(fd, -1);
++	fd2 = open(UINPUT_NODE, O_RDWR);
++	ck_assert_int_gt(fd2, -1);
++
++	rc = libevdev_uinput_create_from_device(dev, fd, &uidev);
++	ck_assert_int_eq(rc, 0);
++
++	/* create a second one to stress the syspath filtering code */
++	libevdev_set_name(dev, TEST_DEVICE_NAME " 2");
++	rc = libevdev_uinput_create_from_device(dev, fd2, &uidev2);
++	ck_assert_int_eq(rc, 0);
++
++	syspath = libevdev_uinput_get_syspath(uidev);
++	ck_assert(syspath != NULL);
++
++	/* get syspath twice returns same pointer */
++	syspath2 = libevdev_uinput_get_syspath(uidev);
++	ck_assert(syspath == syspath2);
++
++	/* second dev has different syspath */
++	syspath2 = libevdev_uinput_get_syspath(uidev2);
++	ck_assert(strcmp(syspath, syspath2) != 0);
++
++	libevdev_free(dev);
++	libevdev_uinput_destroy(uidev);
++	libevdev_uinput_destroy(uidev2);
++
++	close(fd);
++	close(fd2);
++}
++END_TEST
++
++#endif /* __FreeBSD __ */
++
++START_TEST(test_uinput_events)
++{
++	struct libevdev *dev;
++	struct libevdev_uinput *uidev;
++	int fd, fd2;
++	int rc;
++	const char *devnode;
++	int i;
++	const int nevents = 5;
++	struct input_event events[] = { {{0, 0}, EV_REL, REL_X, 1},
++					{{0, 0}, EV_REL, REL_Y, -1},
++					{{0, 0}, EV_SYN, SYN_REPORT, 0},
++					{{0, 0}, EV_KEY, BTN_LEFT, 1},
++					{{0, 0}, EV_SYN, SYN_REPORT, 0}};
++	struct input_event events_read[nevents];
++
++	dev = libevdev_new();
++	ck_assert(dev != NULL);
++	libevdev_set_name(dev, TEST_DEVICE_NAME);
++	libevdev_enable_event_type(dev, EV_SYN);
++	libevdev_enable_event_type(dev, EV_REL);
++	libevdev_enable_event_type(dev, EV_KEY);
++	libevdev_enable_event_code(dev, EV_REL, REL_X, NULL);
++	libevdev_enable_event_code(dev, EV_REL, REL_Y, NULL);
++	libevdev_enable_event_code(dev, EV_KEY, BTN_LEFT, NULL);
++
++	fd = open(UINPUT_NODE, O_RDWR);
++	ck_assert_int_gt(fd, -1);
++
++	rc = libevdev_uinput_create_from_device(dev, fd, &uidev);
++	ck_assert_int_eq(rc, 0);
++	ck_assert(uidev != NULL);
++
++	devnode = libevdev_uinput_get_devnode(uidev);
++	ck_assert(devnode != NULL);
++
++	fd2 = open(devnode, O_RDONLY);
++
++	for (i = 0; i < nevents; i++)
++		libevdev_uinput_write_event(uidev, events[i].type, events[i].code, events[i].value);
++
++	rc = read(fd2, events_read, sizeof(events_read));
++	ck_assert_int_eq(rc, sizeof(events_read));
++
++	for (i = 0; i < nevents; i++) {
++		ck_assert_int_eq(events[i].type, events_read[i].type);
++		ck_assert_int_eq(events[i].code, events_read[i].code);
++		ck_assert_int_eq(events[i].value, events_read[i].value);
++	}
++
++	libevdev_free(dev);
++	libevdev_uinput_destroy(uidev);
++	close(fd);
++	close(fd2);
++}
++END_TEST
++
++START_TEST(test_uinput_properties)
++{
++	struct libevdev *dev, *dev2;
++	struct libevdev_uinput *uidev;
++	int fd;
++	int rc;
++	const char *devnode;
++
++	dev = libevdev_new();
++	ck_assert(dev != NULL);
++	libevdev_set_name(dev, TEST_DEVICE_NAME);
++	libevdev_enable_event_type(dev, EV_SYN);
++	libevdev_enable_event_type(dev, EV_REL);
++	libevdev_enable_event_type(dev, EV_KEY);
++	libevdev_enable_event_code(dev, EV_REL, REL_X, NULL);
++	libevdev_enable_event_code(dev, EV_REL, REL_Y, NULL);
++	libevdev_enable_event_code(dev, EV_KEY, BTN_LEFT, NULL);
++	libevdev_enable_property(dev, INPUT_PROP_BUTTONPAD);
++	libevdev_enable_property(dev, INPUT_PROP_MAX);
++
++	rc = libevdev_uinput_create_from_device(dev, LIBEVDEV_UINPUT_OPEN_MANAGED, &uidev);
++	ck_assert_int_eq(rc, 0);
++	ck_assert(uidev != NULL);
++
++	devnode = libevdev_uinput_get_devnode(uidev);
++	ck_assert(devnode != NULL);
++
++	fd = open(devnode, O_RDONLY);
++	ck_assert_int_gt(fd, -1);
++	rc = libevdev_new_from_fd(fd, &dev2);
++	ck_assert_int_eq(rc, 0);
++
++	ck_assert(libevdev_has_property(dev2, INPUT_PROP_BUTTONPAD));
++	ck_assert(libevdev_has_property(dev2, INPUT_PROP_MAX));
++
++	libevdev_free(dev);
++	libevdev_free(dev2);
++	libevdev_uinput_destroy(uidev);
++	close(fd);
++}
++END_TEST
++
++TEST_SUITE_ROOT_PRIVILEGES(uinput_suite)
++{
++	Suite *s = suite_create("libevdev uinput device tests");
++
++	add_test(s, test_uinput_create_device);
++	add_test(s, test_uinput_create_device_invalid);
++	add_test(s, test_uinput_create_device_from_fd);
++#ifdef __FreeBSD__
++	add_test(s, test_uinput_check_devnode_bsd);
++	add_test(s, test_uinput_check_syspath_bsd);
++#else
++	add_test(s, test_uinput_check_syspath_time);
++	add_test(s, test_uinput_check_syspath_name);
++#endif
++
++	add_test(s, test_uinput_events);
++
++	add_test(s, test_uinput_properties);
++
++	return s;
++}
+diff -Naur third-party-libevdev-bak/test/valgrind.suppressions third-party-new/test/valgrind.suppressions
+--- third-party-libevdev-bak/test/valgrind.suppressions	1970-01-01 08:00:00.000000000 +0800
++++ third-party-new/test/valgrind.suppressions	2022-03-25 12:33:26.000000000 +0800
+@@ -0,0 +1,27 @@
++{
++   
++   Memcheck:Param
++   timer_create(evp)
++   fun:timer_create@@GLIBC_2.3.3
++}
++{
++   
++   Memcheck:Param
++   ioctl(generic)
++   fun:ioctl
++   fun:libevdev_grab
++}
++{
++   
++   Memcheck:Param
++   ioctl(generic)
++   fun:ioctl
++   fun:test_revoke*
++}
++{
++   
++   Memcheck:Leak
++   ...
++   fun:reader_loop
++   fun:main
++}
+diff -Naur third-party-libevdev-bak/tools/Makefile.am third-party-new/tools/Makefile.am
+--- third-party-libevdev-bak/tools/Makefile.am	1970-01-01 08:00:00.000000000 +0800
++++ third-party-new/tools/Makefile.am	2022-03-25 12:33:26.000000000 +0800
+@@ -0,0 +1,29 @@
++noinst_PROGRAMS = libevdev-events libevdev-list-codes
++bin_PROGRAMS = \
++	       touchpad-edge-detector \
++	       mouse-dpi-tool \
++	       libevdev-tweak-device
++
++AM_CPPFLAGS = $(GCC_CFLAGS) -I$(top_srcdir) -I$(top_srcdir)/include -I$(top_srcdir)/libevdev
++libevdev_ldadd = $(top_builddir)/libevdev/libevdev.la
++
++libevdev_events_SOURCES = libevdev-events.c
++libevdev_events_LDADD = $(libevdev_ldadd)
++
++libevdev_list_codes_SOURCES = libevdev-list-codes.c
++libevdev_list_codes_LDADD = $(libevdev_ldadd)
++
++touchpad_edge_detector_SOURCES = touchpad-edge-detector.c
++touchpad_edge_detector_LDADD = $(libevdev_ldadd)
++
++mouse_dpi_tool_SOURCES = mouse-dpi-tool.c
++mouse_dpi_tool_LDADD = $(libevdev_ldadd)
++
++libevdev_tweak_device_SOURCES = libevdev-tweak-device.c
++libevdev_tweak_device_LDADD = $(libevdev_ldadd)
++
++dist_man_MANS = \
++		libevdev-tweak-device.1 \
++		mouse-dpi-tool.1 \
++		touchpad-edge-detector.1 \
++		$(NULL)
+diff -Naur third-party-libevdev-bak/tools/Makefile.in third-party-new/tools/Makefile.in
+--- third-party-libevdev-bak/tools/Makefile.in	1970-01-01 08:00:00.000000000 +0800
++++ third-party-new/tools/Makefile.in	2022-03-25 12:33:32.000000000 +0800
+@@ -0,0 +1,816 @@
++# Makefile.in generated by automake 1.16.5 from Makefile.am.
++# @configure_input@
++
++# Copyright (C) 1994-2021 Free Software Foundation, Inc.
++
++# This Makefile.in is free software; the Free Software Foundation
++# gives unlimited permission to copy and/or distribute it,
++# with or without modifications, as long as this notice is preserved.
++
++# This program is distributed in the hope that it will be useful,
++# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
++# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
++# PARTICULAR PURPOSE.
++
++@SET_MAKE@
++
++VPATH = @srcdir@
++am__is_gnu_make = { \
++  if test -z '$(MAKELEVEL)'; then \
++    false; \
++  elif test -n '$(MAKE_HOST)'; then \
++    true; \
++  elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
++    true; \
++  else \
++    false; \
++  fi; \
++}
++am__make_running_with_option = \
++  case $${target_option-} in \
++      ?) ;; \
++      *) echo "am__make_running_with_option: internal error: invalid" \
++              "target option '$${target_option-}' specified" >&2; \
++         exit 1;; \
++  esac; \
++  has_opt=no; \
++  sane_makeflags=$$MAKEFLAGS; \
++  if $(am__is_gnu_make); then \
++    sane_makeflags=$$MFLAGS; \
++  else \
++    case $$MAKEFLAGS in \
++      *\\[\ \	]*) \
++        bs=\\; \
++        sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
++          | sed "s/$$bs$$bs[$$bs $$bs	]*//g"`;; \
++    esac; \
++  fi; \
++  skip_next=no; \
++  strip_trailopt () \
++  { \
++    flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
++  }; \
++  for flg in $$sane_makeflags; do \
++    test $$skip_next = yes && { skip_next=no; continue; }; \
++    case $$flg in \
++      *=*|--*) continue;; \
++        -*I) strip_trailopt 'I'; skip_next=yes;; \
++      -*I?*) strip_trailopt 'I';; \
++        -*O) strip_trailopt 'O'; skip_next=yes;; \
++      -*O?*) strip_trailopt 'O';; \
++        -*l) strip_trailopt 'l'; skip_next=yes;; \
++      -*l?*) strip_trailopt 'l';; \
++      -[dEDm]) skip_next=yes;; \
++      -[JT]) skip_next=yes;; \
++    esac; \
++    case $$flg in \
++      *$$target_option*) has_opt=yes; break;; \
++    esac; \
++  done; \
++  test $$has_opt = yes
++am__make_dryrun = (target_option=n; $(am__make_running_with_option))
++am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
++pkgdatadir = $(datadir)/@PACKAGE@
++pkgincludedir = $(includedir)/@PACKAGE@
++pkglibdir = $(libdir)/@PACKAGE@
++pkglibexecdir = $(libexecdir)/@PACKAGE@
++am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
++install_sh_DATA = $(install_sh) -c -m 644
++install_sh_PROGRAM = $(install_sh) -c
++install_sh_SCRIPT = $(install_sh) -c
++INSTALL_HEADER = $(INSTALL_DATA)
++transform = $(program_transform_name)
++NORMAL_INSTALL = :
++PRE_INSTALL = :
++POST_INSTALL = :
++NORMAL_UNINSTALL = :
++PRE_UNINSTALL = :
++POST_UNINSTALL = :
++build_triplet = @build@
++host_triplet = @host@
++noinst_PROGRAMS = libevdev-events$(EXEEXT) \
++	libevdev-list-codes$(EXEEXT)
++bin_PROGRAMS = touchpad-edge-detector$(EXEEXT) mouse-dpi-tool$(EXEEXT) \
++	libevdev-tweak-device$(EXEEXT)
++subdir = tools
++ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
++am__aclocal_m4_deps = $(top_srcdir)/m4/attributes.m4 \
++	$(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \
++	$(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \
++	$(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac
++am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
++	$(ACLOCAL_M4)
++DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON)
++mkinstalldirs = $(install_sh) -d
++CONFIG_HEADER = $(top_builddir)/config.h
++CONFIG_CLEAN_FILES =
++CONFIG_CLEAN_VPATH_FILES =
++am__installdirs = "$(DESTDIR)$(bindir)" "$(DESTDIR)$(man1dir)"
++PROGRAMS = $(bin_PROGRAMS) $(noinst_PROGRAMS)
++am_libevdev_events_OBJECTS = libevdev-events.$(OBJEXT)
++libevdev_events_OBJECTS = $(am_libevdev_events_OBJECTS)
++libevdev_events_DEPENDENCIES = $(libevdev_ldadd)
++AM_V_lt = $(am__v_lt_@AM_V@)
++am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
++am__v_lt_0 = --silent
++am__v_lt_1 = 
++am_libevdev_list_codes_OBJECTS = libevdev-list-codes.$(OBJEXT)
++libevdev_list_codes_OBJECTS = $(am_libevdev_list_codes_OBJECTS)
++libevdev_list_codes_DEPENDENCIES = $(libevdev_ldadd)
++am_libevdev_tweak_device_OBJECTS = libevdev-tweak-device.$(OBJEXT)
++libevdev_tweak_device_OBJECTS = $(am_libevdev_tweak_device_OBJECTS)
++libevdev_tweak_device_DEPENDENCIES = $(libevdev_ldadd)
++am_mouse_dpi_tool_OBJECTS = mouse-dpi-tool.$(OBJEXT)
++mouse_dpi_tool_OBJECTS = $(am_mouse_dpi_tool_OBJECTS)
++mouse_dpi_tool_DEPENDENCIES = $(libevdev_ldadd)
++am_touchpad_edge_detector_OBJECTS = touchpad-edge-detector.$(OBJEXT)
++touchpad_edge_detector_OBJECTS = $(am_touchpad_edge_detector_OBJECTS)
++touchpad_edge_detector_DEPENDENCIES = $(libevdev_ldadd)
++AM_V_P = $(am__v_P_@AM_V@)
++am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
++am__v_P_0 = false
++am__v_P_1 = :
++AM_V_GEN = $(am__v_GEN_@AM_V@)
++am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
++am__v_GEN_0 = @echo "  GEN     " $@;
++am__v_GEN_1 = 
++AM_V_at = $(am__v_at_@AM_V@)
++am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
++am__v_at_0 = @
++am__v_at_1 = 
++DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
++depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp
++am__maybe_remake_depfiles = depfiles
++am__depfiles_remade = ./$(DEPDIR)/libevdev-events.Po \
++	./$(DEPDIR)/libevdev-list-codes.Po \
++	./$(DEPDIR)/libevdev-tweak-device.Po \
++	./$(DEPDIR)/mouse-dpi-tool.Po \
++	./$(DEPDIR)/touchpad-edge-detector.Po
++am__mv = mv -f
++COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
++	$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
++LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
++	$(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \
++	$(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
++	$(AM_CFLAGS) $(CFLAGS)
++AM_V_CC = $(am__v_CC_@AM_V@)
++am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@)
++am__v_CC_0 = @echo "  CC      " $@;
++am__v_CC_1 = 
++CCLD = $(CC)
++LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
++	$(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
++	$(AM_LDFLAGS) $(LDFLAGS) -o $@
++AM_V_CCLD = $(am__v_CCLD_@AM_V@)
++am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@)
++am__v_CCLD_0 = @echo "  CCLD    " $@;
++am__v_CCLD_1 = 
++SOURCES = $(libevdev_events_SOURCES) $(libevdev_list_codes_SOURCES) \
++	$(libevdev_tweak_device_SOURCES) $(mouse_dpi_tool_SOURCES) \
++	$(touchpad_edge_detector_SOURCES)
++DIST_SOURCES = $(libevdev_events_SOURCES) \
++	$(libevdev_list_codes_SOURCES) \
++	$(libevdev_tweak_device_SOURCES) $(mouse_dpi_tool_SOURCES) \
++	$(touchpad_edge_detector_SOURCES)
++am__can_run_installinfo = \
++  case $$AM_UPDATE_INFO_DIR in \
++    n|no|NO) false;; \
++    *) (install-info --version) >/dev/null 2>&1;; \
++  esac
++am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
++am__vpath_adj = case $$p in \
++    $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
++    *) f=$$p;; \
++  esac;
++am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
++am__install_max = 40
++am__nobase_strip_setup = \
++  srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
++am__nobase_strip = \
++  for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
++am__nobase_list = $(am__nobase_strip_setup); \
++  for p in $$list; do echo "$$p $$p"; done | \
++  sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
++  $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
++    if (++n[$$2] == $(am__install_max)) \
++      { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
++    END { for (dir in files) print dir, files[dir] }'
++am__base_list = \
++  sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
++  sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
++am__uninstall_files_from_dir = { \
++  test -z "$$files" \
++    || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
++    || { echo " ( cd '$$dir' && rm -f" $$files ")"; \
++         $(am__cd) "$$dir" && rm -f $$files; }; \
++  }
++man1dir = $(mandir)/man1
++NROFF = nroff
++MANS = $(dist_man_MANS)
++am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
++# Read a list of newline-separated strings from the standard input,
++# and print each of them once, without duplicates.  Input order is
++# *not* preserved.
++am__uniquify_input = $(AWK) '\
++  BEGIN { nonempty = 0; } \
++  { items[$$0] = 1; nonempty = 1; } \
++  END { if (nonempty) { for (i in items) print i; }; } \
++'
++# Make sure the list of sources is unique.  This is necessary because,
++# e.g., the same source file might be shared among _SOURCES variables
++# for different programs/libraries.
++am__define_uniq_tagged_files = \
++  list='$(am__tagged_files)'; \
++  unique=`for i in $$list; do \
++    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
++  done | $(am__uniquify_input)`
++am__DIST_COMMON = $(dist_man_MANS) $(srcdir)/Makefile.in \
++	$(top_srcdir)/build-aux/depcomp
++DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
++ACLOCAL = @ACLOCAL@
++AMTAR = @AMTAR@
++AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
++AR = @AR@
++AUTOCONF = @AUTOCONF@
++AUTOHEADER = @AUTOHEADER@
++AUTOMAKE = @AUTOMAKE@
++AWK = @AWK@
++CC = @CC@
++CCDEPMODE = @CCDEPMODE@
++CFLAGS = @CFLAGS@
++CHECK_CFLAGS = @CHECK_CFLAGS@
++CHECK_LIBS = @CHECK_LIBS@
++CPPFLAGS = @CPPFLAGS@
++CSCOPE = @CSCOPE@
++CTAGS = @CTAGS@
++CYGPATH_W = @CYGPATH_W@
++DEFS = @DEFS@
++DEPDIR = @DEPDIR@
++DLLTOOL = @DLLTOOL@
++DOXYGEN = @DOXYGEN@
++DSYMUTIL = @DSYMUTIL@
++DUMPBIN = @DUMPBIN@
++ECHO_C = @ECHO_C@
++ECHO_N = @ECHO_N@
++ECHO_T = @ECHO_T@
++EGREP = @EGREP@
++ETAGS = @ETAGS@
++EXEEXT = @EXEEXT@
++FGREP = @FGREP@
++GCC_CFLAGS = @GCC_CFLAGS@
++GCOV_CFLAGS = @GCOV_CFLAGS@
++GCOV_LDFLAGS = @GCOV_LDFLAGS@
++GNU_LD_FLAGS = @GNU_LD_FLAGS@
++GREP = @GREP@
++INSTALL = @INSTALL@
++INSTALL_DATA = @INSTALL_DATA@
++INSTALL_PROGRAM = @INSTALL_PROGRAM@
++INSTALL_SCRIPT = @INSTALL_SCRIPT@
++INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
++LD = @LD@
++LDFLAGS = @LDFLAGS@
++LIBEVDEV_LT_VERSION = @LIBEVDEV_LT_VERSION@
++LIBOBJS = @LIBOBJS@
++LIBS = @LIBS@
++LIBTOOL = @LIBTOOL@
++LIPO = @LIPO@
++LN_S = @LN_S@
++LTLIBOBJS = @LTLIBOBJS@
++LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
++MAKEINFO = @MAKEINFO@
++MANIFEST_TOOL = @MANIFEST_TOOL@
++MKDIR_P = @MKDIR_P@
++NM = @NM@
++NMEDIT = @NMEDIT@
++OBJDUMP = @OBJDUMP@
++OBJEXT = @OBJEXT@
++OS = @OS@
++OTOOL = @OTOOL@
++OTOOL64 = @OTOOL64@
++PACKAGE = @PACKAGE@
++PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
++PACKAGE_NAME = @PACKAGE_NAME@
++PACKAGE_STRING = @PACKAGE_STRING@
++PACKAGE_TARNAME = @PACKAGE_TARNAME@
++PACKAGE_URL = @PACKAGE_URL@
++PACKAGE_VERSION = @PACKAGE_VERSION@
++PATH_SEPARATOR = @PATH_SEPARATOR@
++PKG_CONFIG = @PKG_CONFIG@
++PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
++PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
++PYTHON = @PYTHON@
++PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
++PYTHON_PLATFORM = @PYTHON_PLATFORM@
++PYTHON_PREFIX = @PYTHON_PREFIX@
++PYTHON_VERSION = @PYTHON_VERSION@
++RANLIB = @RANLIB@
++SED = @SED@
++SET_MAKE = @SET_MAKE@
++SHELL = @SHELL@
++STRIP = @STRIP@
++VALGRIND = @VALGRIND@
++VERSION = @VERSION@
++abs_builddir = @abs_builddir@
++abs_srcdir = @abs_srcdir@
++abs_top_builddir = @abs_top_builddir@
++abs_top_srcdir = @abs_top_srcdir@
++ac_ct_AR = @ac_ct_AR@
++ac_ct_CC = @ac_ct_CC@
++ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
++am__include = @am__include@
++am__leading_dot = @am__leading_dot@
++am__quote = @am__quote@
++am__tar = @am__tar@
++am__untar = @am__untar@
++bindir = @bindir@
++build = @build@
++build_alias = @build_alias@
++build_cpu = @build_cpu@
++build_os = @build_os@
++build_vendor = @build_vendor@
++builddir = @builddir@
++datadir = @datadir@
++datarootdir = @datarootdir@
++docdir = @docdir@
++dvidir = @dvidir@
++exec_prefix = @exec_prefix@
++host = @host@
++host_alias = @host_alias@
++host_cpu = @host_cpu@
++host_os = @host_os@
++host_vendor = @host_vendor@
++htmldir = @htmldir@
++includedir = @includedir@
++infodir = @infodir@
++install_sh = @install_sh@
++libdir = @libdir@
++libexecdir = @libexecdir@
++localedir = @localedir@
++localstatedir = @localstatedir@
++mandir = @mandir@
++mkdir_p = @mkdir_p@
++oldincludedir = @oldincludedir@
++pdfdir = @pdfdir@
++pkgpyexecdir = @pkgpyexecdir@
++pkgpythondir = @pkgpythondir@
++prefix = @prefix@
++program_transform_name = @program_transform_name@
++psdir = @psdir@
++pyexecdir = @pyexecdir@
++pythondir = @pythondir@
++runstatedir = @runstatedir@
++sbindir = @sbindir@
++sharedstatedir = @sharedstatedir@
++srcdir = @srcdir@
++sysconfdir = @sysconfdir@
++target_alias = @target_alias@
++top_build_prefix = @top_build_prefix@
++top_builddir = @top_builddir@
++top_srcdir = @top_srcdir@
++AM_CPPFLAGS = $(GCC_CFLAGS) -I$(top_srcdir) -I$(top_srcdir)/include -I$(top_srcdir)/libevdev
++libevdev_ldadd = $(top_builddir)/libevdev/libevdev.la
++libevdev_events_SOURCES = libevdev-events.c
++libevdev_events_LDADD = $(libevdev_ldadd)
++libevdev_list_codes_SOURCES = libevdev-list-codes.c
++libevdev_list_codes_LDADD = $(libevdev_ldadd)
++touchpad_edge_detector_SOURCES = touchpad-edge-detector.c
++touchpad_edge_detector_LDADD = $(libevdev_ldadd)
++mouse_dpi_tool_SOURCES = mouse-dpi-tool.c
++mouse_dpi_tool_LDADD = $(libevdev_ldadd)
++libevdev_tweak_device_SOURCES = libevdev-tweak-device.c
++libevdev_tweak_device_LDADD = $(libevdev_ldadd)
++dist_man_MANS = \
++		libevdev-tweak-device.1 \
++		mouse-dpi-tool.1 \
++		touchpad-edge-detector.1 \
++		$(NULL)
++
++all: all-am
++
++.SUFFIXES:
++.SUFFIXES: .c .lo .o .obj
++$(srcdir)/Makefile.in:  $(srcdir)/Makefile.am  $(am__configure_deps)
++	@for dep in $?; do \
++	  case '$(am__configure_deps)' in \
++	    *$$dep*) \
++	      ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
++	        && { if test -f $@; then exit 0; else break; fi; }; \
++	      exit 1;; \
++	  esac; \
++	done; \
++	echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign tools/Makefile'; \
++	$(am__cd) $(top_srcdir) && \
++	  $(AUTOMAKE) --foreign tools/Makefile
++Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
++	@case '$?' in \
++	  *config.status*) \
++	    cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
++	  *) \
++	    echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \
++	    cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \
++	esac;
++
++$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
++	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
++
++$(top_srcdir)/configure:  $(am__configure_deps)
++	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
++$(ACLOCAL_M4):  $(am__aclocal_m4_deps)
++	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
++$(am__aclocal_m4_deps):
++install-binPROGRAMS: $(bin_PROGRAMS)
++	@$(NORMAL_INSTALL)
++	@list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \
++	if test -n "$$list"; then \
++	  echo " $(MKDIR_P) '$(DESTDIR)$(bindir)'"; \
++	  $(MKDIR_P) "$(DESTDIR)$(bindir)" || exit 1; \
++	fi; \
++	for p in $$list; do echo "$$p $$p"; done | \
++	sed 's/$(EXEEXT)$$//' | \
++	while read p p1; do if test -f $$p \
++	 || test -f $$p1 \
++	  ; then echo "$$p"; echo "$$p"; else :; fi; \
++	done | \
++	sed -e 'p;s,.*/,,;n;h' \
++	    -e 's|.*|.|' \
++	    -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \
++	sed 'N;N;N;s,\n, ,g' | \
++	$(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \
++	  { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \
++	    if ($$2 == $$4) files[d] = files[d] " " $$1; \
++	    else { print "f", $$3 "/" $$4, $$1; } } \
++	  END { for (d in files) print "f", d, files[d] }' | \
++	while read type dir files; do \
++	    if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \
++	    test -z "$$files" || { \
++	    echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(bindir)$$dir'"; \
++	    $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(bindir)$$dir" || exit $$?; \
++	    } \
++	; done
++
++uninstall-binPROGRAMS:
++	@$(NORMAL_UNINSTALL)
++	@list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \
++	files=`for p in $$list; do echo "$$p"; done | \
++	  sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \
++	      -e 's/$$/$(EXEEXT)/' \
++	`; \
++	test -n "$$list" || exit 0; \
++	echo " ( cd '$(DESTDIR)$(bindir)' && rm -f" $$files ")"; \
++	cd "$(DESTDIR)$(bindir)" && rm -f $$files
++
++clean-binPROGRAMS:
++	@list='$(bin_PROGRAMS)'; test -n "$$list" || exit 0; \
++	echo " rm -f" $$list; \
++	rm -f $$list || exit $$?; \
++	test -n "$(EXEEXT)" || exit 0; \
++	list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \
++	echo " rm -f" $$list; \
++	rm -f $$list
++
++clean-noinstPROGRAMS:
++	@list='$(noinst_PROGRAMS)'; test -n "$$list" || exit 0; \
++	echo " rm -f" $$list; \
++	rm -f $$list || exit $$?; \
++	test -n "$(EXEEXT)" || exit 0; \
++	list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \
++	echo " rm -f" $$list; \
++	rm -f $$list
++
++libevdev-events$(EXEEXT): $(libevdev_events_OBJECTS) $(libevdev_events_DEPENDENCIES) $(EXTRA_libevdev_events_DEPENDENCIES) 
++	@rm -f libevdev-events$(EXEEXT)
++	$(AM_V_CCLD)$(LINK) $(libevdev_events_OBJECTS) $(libevdev_events_LDADD) $(LIBS)
++
++libevdev-list-codes$(EXEEXT): $(libevdev_list_codes_OBJECTS) $(libevdev_list_codes_DEPENDENCIES) $(EXTRA_libevdev_list_codes_DEPENDENCIES) 
++	@rm -f libevdev-list-codes$(EXEEXT)
++	$(AM_V_CCLD)$(LINK) $(libevdev_list_codes_OBJECTS) $(libevdev_list_codes_LDADD) $(LIBS)
++
++libevdev-tweak-device$(EXEEXT): $(libevdev_tweak_device_OBJECTS) $(libevdev_tweak_device_DEPENDENCIES) $(EXTRA_libevdev_tweak_device_DEPENDENCIES) 
++	@rm -f libevdev-tweak-device$(EXEEXT)
++	$(AM_V_CCLD)$(LINK) $(libevdev_tweak_device_OBJECTS) $(libevdev_tweak_device_LDADD) $(LIBS)
++
++mouse-dpi-tool$(EXEEXT): $(mouse_dpi_tool_OBJECTS) $(mouse_dpi_tool_DEPENDENCIES) $(EXTRA_mouse_dpi_tool_DEPENDENCIES) 
++	@rm -f mouse-dpi-tool$(EXEEXT)
++	$(AM_V_CCLD)$(LINK) $(mouse_dpi_tool_OBJECTS) $(mouse_dpi_tool_LDADD) $(LIBS)
++
++touchpad-edge-detector$(EXEEXT): $(touchpad_edge_detector_OBJECTS) $(touchpad_edge_detector_DEPENDENCIES) $(EXTRA_touchpad_edge_detector_DEPENDENCIES) 
++	@rm -f touchpad-edge-detector$(EXEEXT)
++	$(AM_V_CCLD)$(LINK) $(touchpad_edge_detector_OBJECTS) $(touchpad_edge_detector_LDADD) $(LIBS)
++
++mostlyclean-compile:
++	-rm -f *.$(OBJEXT)
++
++distclean-compile:
++	-rm -f *.tab.c
++
++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libevdev-events.Po@am__quote@ # am--include-marker
++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libevdev-list-codes.Po@am__quote@ # am--include-marker
++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libevdev-tweak-device.Po@am__quote@ # am--include-marker
++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mouse-dpi-tool.Po@am__quote@ # am--include-marker
++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/touchpad-edge-detector.Po@am__quote@ # am--include-marker
++
++$(am__depfiles_remade):
++	@$(MKDIR_P) $(@D)
++	@echo '# dummy' >$@-t && $(am__mv) $@-t $@
++
++am--depfiles: $(am__depfiles_remade)
++
++.c.o:
++@am__fastdepCC_TRUE@	$(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\
++@am__fastdepCC_TRUE@	$(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
++@am__fastdepCC_TRUE@	$(am__mv) $$depbase.Tpo $$depbase.Po
++@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
++@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
++@am__fastdepCC_FALSE@	$(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $<
++
++.c.obj:
++@am__fastdepCC_TRUE@	$(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\
++@am__fastdepCC_TRUE@	$(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\
++@am__fastdepCC_TRUE@	$(am__mv) $$depbase.Tpo $$depbase.Po
++@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
++@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
++@am__fastdepCC_FALSE@	$(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
++
++.c.lo:
++@am__fastdepCC_TRUE@	$(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\
++@am__fastdepCC_TRUE@	$(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
++@am__fastdepCC_TRUE@	$(am__mv) $$depbase.Tpo $$depbase.Plo
++@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
++@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
++@am__fastdepCC_FALSE@	$(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $<
++
++mostlyclean-libtool:
++	-rm -f *.lo
++
++clean-libtool:
++	-rm -rf .libs _libs
++install-man1: $(dist_man_MANS)
++	@$(NORMAL_INSTALL)
++	@list1=''; \
++	list2='$(dist_man_MANS)'; \
++	test -n "$(man1dir)" \
++	  && test -n "`echo $$list1$$list2`" \
++	  || exit 0; \
++	echo " $(MKDIR_P) '$(DESTDIR)$(man1dir)'"; \
++	$(MKDIR_P) "$(DESTDIR)$(man1dir)" || exit 1; \
++	{ for i in $$list1; do echo "$$i"; done;  \
++	if test -n "$$list2"; then \
++	  for i in $$list2; do echo "$$i"; done \
++	    | sed -n '/\.1[a-z]*$$/p'; \
++	fi; \
++	} | while read p; do \
++	  if test -f $$p; then d=; else d="$(srcdir)/"; fi; \
++	  echo "$$d$$p"; echo "$$p"; \
++	done | \
++	sed -e 'n;s,.*/,,;p;h;s,.*\.,,;s,^[^1][0-9a-z]*$$,1,;x' \
++	      -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,' | \
++	sed 'N;N;s,\n, ,g' | { \
++	list=; while read file base inst; do \
++	  if test "$$base" = "$$inst"; then list="$$list $$file"; else \
++	    echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man1dir)/$$inst'"; \
++	    $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man1dir)/$$inst" || exit $$?; \
++	  fi; \
++	done; \
++	for i in $$list; do echo "$$i"; done | $(am__base_list) | \
++	while read files; do \
++	  test -z "$$files" || { \
++	    echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man1dir)'"; \
++	    $(INSTALL_DATA) $$files "$(DESTDIR)$(man1dir)" || exit $$?; }; \
++	done; }
++
++uninstall-man1:
++	@$(NORMAL_UNINSTALL)
++	@list=''; test -n "$(man1dir)" || exit 0; \
++	files=`{ for i in $$list; do echo "$$i"; done; \
++	l2='$(dist_man_MANS)'; for i in $$l2; do echo "$$i"; done | \
++	  sed -n '/\.1[a-z]*$$/p'; \
++	} | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^1][0-9a-z]*$$,1,;x' \
++	      -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \
++	dir='$(DESTDIR)$(man1dir)'; $(am__uninstall_files_from_dir)
++
++ID: $(am__tagged_files)
++	$(am__define_uniq_tagged_files); mkid -fID $$unique
++tags: tags-am
++TAGS: tags
++
++tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
++	set x; \
++	here=`pwd`; \
++	$(am__define_uniq_tagged_files); \
++	shift; \
++	if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
++	  test -n "$$unique" || unique=$$empty_fix; \
++	  if test $$# -gt 0; then \
++	    $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
++	      "$$@" $$unique; \
++	  else \
++	    $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
++	      $$unique; \
++	  fi; \
++	fi
++ctags: ctags-am
++
++CTAGS: ctags
++ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
++	$(am__define_uniq_tagged_files); \
++	test -z "$(CTAGS_ARGS)$$unique" \
++	  || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
++	     $$unique
++
++GTAGS:
++	here=`$(am__cd) $(top_builddir) && pwd` \
++	  && $(am__cd) $(top_srcdir) \
++	  && gtags -i $(GTAGS_ARGS) "$$here"
++cscopelist: cscopelist-am
++
++cscopelist-am: $(am__tagged_files)
++	list='$(am__tagged_files)'; \
++	case "$(srcdir)" in \
++	  [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
++	  *) sdir=$(subdir)/$(srcdir) ;; \
++	esac; \
++	for i in $$list; do \
++	  if test -f "$$i"; then \
++	    echo "$(subdir)/$$i"; \
++	  else \
++	    echo "$$sdir/$$i"; \
++	  fi; \
++	done >> $(top_builddir)/cscope.files
++
++distclean-tags:
++	-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
++distdir: $(BUILT_SOURCES)
++	$(MAKE) $(AM_MAKEFLAGS) distdir-am
++
++distdir-am: $(DISTFILES)
++	@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
++	topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
++	list='$(DISTFILES)'; \
++	  dist_files=`for file in $$list; do echo $$file; done | \
++	  sed -e "s|^$$srcdirstrip/||;t" \
++	      -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
++	case $$dist_files in \
++	  */*) $(MKDIR_P) `echo "$$dist_files" | \
++			   sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
++			   sort -u` ;; \
++	esac; \
++	for file in $$dist_files; do \
++	  if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
++	  if test -d $$d/$$file; then \
++	    dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
++	    if test -d "$(distdir)/$$file"; then \
++	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
++	    fi; \
++	    if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
++	      cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
++	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
++	    fi; \
++	    cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
++	  else \
++	    test -f "$(distdir)/$$file" \
++	    || cp -p $$d/$$file "$(distdir)/$$file" \
++	    || exit 1; \
++	  fi; \
++	done
++check-am: all-am
++check: check-am
++all-am: Makefile $(PROGRAMS) $(MANS)
++installdirs:
++	for dir in "$(DESTDIR)$(bindir)" "$(DESTDIR)$(man1dir)"; do \
++	  test -z "$$dir" || $(MKDIR_P) "$$dir"; \
++	done
++install: install-am
++install-exec: install-exec-am
++install-data: install-data-am
++uninstall: uninstall-am
++
++install-am: all-am
++	@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
++
++installcheck: installcheck-am
++install-strip:
++	if test -z '$(STRIP)'; then \
++	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
++	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
++	      install; \
++	else \
++	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
++	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
++	    "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
++	fi
++mostlyclean-generic:
++
++clean-generic:
++
++distclean-generic:
++	-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
++	-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
++
++maintainer-clean-generic:
++	@echo "This command is intended for maintainers to use"
++	@echo "it deletes files that may require special tools to rebuild."
++clean: clean-am
++
++clean-am: clean-binPROGRAMS clean-generic clean-libtool \
++	clean-noinstPROGRAMS mostlyclean-am
++
++distclean: distclean-am
++		-rm -f ./$(DEPDIR)/libevdev-events.Po
++	-rm -f ./$(DEPDIR)/libevdev-list-codes.Po
++	-rm -f ./$(DEPDIR)/libevdev-tweak-device.Po
++	-rm -f ./$(DEPDIR)/mouse-dpi-tool.Po
++	-rm -f ./$(DEPDIR)/touchpad-edge-detector.Po
++	-rm -f Makefile
++distclean-am: clean-am distclean-compile distclean-generic \
++	distclean-tags
++
++dvi: dvi-am
++
++dvi-am:
++
++html: html-am
++
++html-am:
++
++info: info-am
++
++info-am:
++
++install-data-am: install-man
++
++install-dvi: install-dvi-am
++
++install-dvi-am:
++
++install-exec-am: install-binPROGRAMS
++
++install-html: install-html-am
++
++install-html-am:
++
++install-info: install-info-am
++
++install-info-am:
++
++install-man: install-man1
++
++install-pdf: install-pdf-am
++
++install-pdf-am:
++
++install-ps: install-ps-am
++
++install-ps-am:
++
++installcheck-am:
++
++maintainer-clean: maintainer-clean-am
++		-rm -f ./$(DEPDIR)/libevdev-events.Po
++	-rm -f ./$(DEPDIR)/libevdev-list-codes.Po
++	-rm -f ./$(DEPDIR)/libevdev-tweak-device.Po
++	-rm -f ./$(DEPDIR)/mouse-dpi-tool.Po
++	-rm -f ./$(DEPDIR)/touchpad-edge-detector.Po
++	-rm -f Makefile
++maintainer-clean-am: distclean-am maintainer-clean-generic
++
++mostlyclean: mostlyclean-am
++
++mostlyclean-am: mostlyclean-compile mostlyclean-generic \
++	mostlyclean-libtool
++
++pdf: pdf-am
++
++pdf-am:
++
++ps: ps-am
++
++ps-am:
++
++uninstall-am: uninstall-binPROGRAMS uninstall-man
++
++uninstall-man: uninstall-man1
++
++.MAKE: install-am install-strip
++
++.PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \
++	clean-binPROGRAMS clean-generic clean-libtool \
++	clean-noinstPROGRAMS cscopelist-am ctags ctags-am distclean \
++	distclean-compile distclean-generic distclean-libtool \
++	distclean-tags distdir dvi dvi-am html html-am info info-am \
++	install install-am install-binPROGRAMS install-data \
++	install-data-am install-dvi install-dvi-am install-exec \
++	install-exec-am install-html install-html-am install-info \
++	install-info-am install-man install-man1 install-pdf \
++	install-pdf-am install-ps install-ps-am install-strip \
++	installcheck installcheck-am installdirs maintainer-clean \
++	maintainer-clean-generic mostlyclean mostlyclean-compile \
++	mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
++	tags tags-am uninstall uninstall-am uninstall-binPROGRAMS \
++	uninstall-man uninstall-man1
++
++.PRECIOUS: Makefile
++
++
++# Tell versions [3.59,3.63) of GNU make to not export all variables.
++# Otherwise a system limit (for SysV at least) may be exceeded.
++.NOEXPORT:
+diff -Naur third-party-libevdev-bak/tools/libevdev-events.c third-party-new/tools/libevdev-events.c
+--- third-party-libevdev-bak/tools/libevdev-events.c	1970-01-01 08:00:00.000000000 +0800
++++ third-party-new/tools/libevdev-events.c	2022-03-25 12:33:26.000000000 +0800
+@@ -0,0 +1,178 @@
++// SPDX-License-Identifier: MIT
++/*
++ * Copyright © 2013 Red Hat, Inc.
++ */
++
++#include "config.h"
++
++#include 
++#include 
++#include 
++#include 
++#include 
++#include 
++#include 
++#include 
++
++#include "libevdev/libevdev.h"
++
++static void
++print_abs_bits(struct libevdev *dev, int axis)
++{
++	const struct input_absinfo *abs;
++
++	if (!libevdev_has_event_code(dev, EV_ABS, axis))
++		return;
++
++	abs = libevdev_get_abs_info(dev, axis);
++
++	printf("	Value	%6d\n", abs->value);
++	printf("	Min	%6d\n", abs->minimum);
++	printf("	Max	%6d\n", abs->maximum);
++	if (abs->fuzz)
++		printf("	Fuzz	%6d\n", abs->fuzz);
++	if (abs->flat)
++		printf("	Flat	%6d\n", abs->flat);
++	if (abs->resolution)
++		printf("	Resolution	%6d\n", abs->resolution);
++}
++
++static void
++print_code_bits(struct libevdev *dev, unsigned int type, unsigned int max)
++{
++	unsigned int i;
++	for (i = 0; i <= max; i++) {
++		if (!libevdev_has_event_code(dev, type, i))
++			continue;
++
++		printf("    Event code %i (%s)\n", i, libevdev_event_code_get_name(type, i));
++		if (type == EV_ABS)
++			print_abs_bits(dev, i);
++	}
++}
++
++static void
++print_bits(struct libevdev *dev)
++{
++	unsigned int i;
++	printf("Supported events:\n");
++
++	for (i = 0; i <= EV_MAX; i++) {
++		if (libevdev_has_event_type(dev, i))
++			printf("  Event type %d (%s)\n", i, libevdev_event_type_get_name(i));
++		switch(i) {
++			case EV_KEY:
++				print_code_bits(dev, EV_KEY, KEY_MAX);
++				break;
++			case EV_REL:
++				print_code_bits(dev, EV_REL, REL_MAX);
++				break;
++			case EV_ABS:
++				print_code_bits(dev, EV_ABS, ABS_MAX);
++				break;
++			case EV_LED:
++				print_code_bits(dev, EV_LED, LED_MAX);
++				break;
++		}
++	}
++}
++
++static void
++print_props(struct libevdev *dev)
++{
++	unsigned int i;
++	printf("Properties:\n");
++
++	for (i = 0; i <= INPUT_PROP_MAX; i++) {
++		if (libevdev_has_property(dev, i))
++			printf("  Property type %d (%s)\n", i,
++					libevdev_property_get_name(i));
++	}
++}
++
++static int
++print_event(struct input_event *ev)
++{
++	if (ev->type == EV_SYN)
++		printf("Event: time %ld.%06ld, ++++++++++++++++++++ %s +++++++++++++++\n",
++				ev->input_event_sec,
++				ev->input_event_usec,
++				libevdev_event_type_get_name(ev->type));
++	else
++		printf("Event: time %ld.%06ld, type %d (%s), code %d (%s), value %d\n",
++			ev->input_event_sec,
++			ev->input_event_usec,
++			ev->type,
++			libevdev_event_type_get_name(ev->type),
++			ev->code,
++			libevdev_event_code_get_name(ev->type, ev->code),
++			ev->value);
++	return 0;
++}
++
++static int
++print_sync_event(struct input_event *ev)
++{
++	printf("SYNC: ");
++	print_event(ev);
++	return 0;
++}
++
++int
++main(int argc, char **argv)
++{
++	struct libevdev *dev = NULL;
++	const char *file;
++	int fd;
++	int rc = 1;
++
++	if (argc < 2)
++		goto out;
++
++	file = argv[1];
++	fd = open(file, O_RDONLY);
++	if (fd < 0) {
++		perror("Failed to open device");
++		goto out;
++	}
++
++	rc = libevdev_new_from_fd(fd, &dev);
++	if (rc < 0) {
++		fprintf(stderr, "Failed to init libevdev (%s)\n", strerror(-rc));
++		goto out;
++	}
++
++	printf("Input device ID: bus %#x vendor %#x product %#x\n",
++			libevdev_get_id_bustype(dev),
++			libevdev_get_id_vendor(dev),
++			libevdev_get_id_product(dev));
++	printf("Evdev version: %x\n", libevdev_get_driver_version(dev));
++	printf("Input device name: \"%s\"\n", libevdev_get_name(dev));
++	printf("Phys location: %s\n", libevdev_get_phys(dev));
++	printf("Uniq identifier: %s\n", libevdev_get_uniq(dev));
++	print_bits(dev);
++	print_props(dev);
++
++	do {
++		struct input_event ev;
++		rc = libevdev_next_event(dev, LIBEVDEV_READ_FLAG_NORMAL|LIBEVDEV_READ_FLAG_BLOCKING, &ev);
++		if (rc == LIBEVDEV_READ_STATUS_SYNC) {
++			printf("::::::::::::::::::::: dropped ::::::::::::::::::::::\n");
++			while (rc == LIBEVDEV_READ_STATUS_SYNC) {
++				print_sync_event(&ev);
++				rc = libevdev_next_event(dev, LIBEVDEV_READ_FLAG_SYNC, &ev);
++			}
++			printf("::::::::::::::::::::: re-synced ::::::::::::::::::::::\n");
++		} else if (rc == LIBEVDEV_READ_STATUS_SUCCESS)
++			print_event(&ev);
++	} while (rc == LIBEVDEV_READ_STATUS_SYNC || rc == LIBEVDEV_READ_STATUS_SUCCESS || rc == -EAGAIN);
++
++	if (rc != LIBEVDEV_READ_STATUS_SUCCESS && rc != -EAGAIN)
++		fprintf(stderr, "Failed to handle events: %s\n", strerror(-rc));
++
++	rc = 0;
++out:
++	libevdev_free(dev);
++
++	return rc;
++}
+diff -Naur third-party-libevdev-bak/tools/libevdev-list-codes.c third-party-new/tools/libevdev-list-codes.c
+--- third-party-libevdev-bak/tools/libevdev-list-codes.c	1970-01-01 08:00:00.000000000 +0800
++++ third-party-new/tools/libevdev-list-codes.c	2022-03-25 12:33:26.000000000 +0800
+@@ -0,0 +1,47 @@
++// SPDX-License-Identifier: MIT
++/*
++ * Copyright © 2021 Red Hat, Inc.
++ */
++
++/* Lists all event types and codes currently known by libevdev. */
++
++#include "config.h"
++
++#include 
++#include 
++#include "libevdev/libevdev.h"
++
++static void
++list_event_codes(unsigned int type, unsigned int max)
++{
++	const char *typestr = libevdev_event_type_get_name(type);
++
++	if (!typestr)
++		return;
++
++	printf("- %s:\n", typestr);
++
++	for (unsigned int code = 0; code <= max; code++) {
++		const char *str = libevdev_event_code_get_name(type, code);
++
++		if (!str)
++			continue;
++
++		printf("    %d: %s\n", code, str);
++	}
++}
++
++int
++main (int argc, char **argv)
++{
++	printf("codes:\n");
++	for (unsigned int type = 0; type <= EV_MAX; type++) {
++		int max = libevdev_event_type_get_max(type);
++		if (max == -1)
++			continue;
++
++		list_event_codes(type, (unsigned int)max);
++	}
++
++	return 0;
++}
+diff -Naur third-party-libevdev-bak/tools/libevdev-tweak-device.1 third-party-new/tools/libevdev-tweak-device.1
+--- third-party-libevdev-bak/tools/libevdev-tweak-device.1	1970-01-01 08:00:00.000000000 +0800
++++ third-party-new/tools/libevdev-tweak-device.1	2022-03-25 12:33:26.000000000 +0800
+@@ -0,0 +1,69 @@
++.TH LIBEVDEV-TWEAK-DEVICE "1"
++.SH NAME
++libevdev-tweak-device \- modify an evdev kernel device
++.SH SYNOPSIS
++.B libevdev-tweak-device
++--abs ABS_X [--min a] [--max b] [--res c] [--fuzz d] [--flat e]
++/dev/input/eventX
++.B libevdev-tweak-device
++--resolution res[,yres] /dev/input/eventX
++.PP
++.B libevdev-tweak-device
++--led LED_NUML --on|--off /dev/input/eventX
++.SH DESCRIPTION
++.PP
++The
++.I libevdev-tweak-device
++tool changes the properties of the evdev kernel device at
++.I /dev/input/eventX.
++Currently this may be used to force an LED on or off, or to change the
++properties of an absolute axis (e.g. its minimum/maximum range or
++resolution). Changes are permanent until the device is removed.
++.SH OPTIONS
++.SS Changing absolute axes
++.TP 8
++.B --abs axis
++Change the given named ABS_ kernel axis, e.g. ABS_X. For a full list, see linux/input.h.
++Each of the options
++.B min, max, res, fuzz, flat
++may be given.
++.TP 8
++.B --min v
++Set the absinfo minimum to the value v
++.TP 8
++.B --max v
++Set the absinfo maximum to the value v
++.TP 8
++.B --res v
++Set the absinfo resolution to the value v
++.TP 8
++.B --fuzz v
++Set the absinfo fuzz to the value v
++.TP 8
++.B --flat v
++Set the absinfo flat to the value v
++.PP
++.SS Changing the x/y resolution
++.TP 8
++.B --resolution res[,yres]
++Changes the resolution of the ABS_X, ABS_MT_POSITION_X, ABS_Y, and
++ABS_MT_POSITION_Y axis to the given resolution. If only one resolution value
++is provided, both x and y axis are set to the same resolution, otherwise the
++first resolution value is applied to the x axes and the second value to the
++y axes.
++.SS Toggling LEDs
++.TP 8
++.B --led led
++Change the given LED, e.g. LED_NUML. For a full list, see linux/input.h.
++.TP 8
++.B --on
++Change the LED state to on
++.TP 8
++.B --off
++Change the LED state to off
++.SH NOTES
++.PP
++The kernel does not notify processes about absinfo property changes. Any
++process that has previously obtained the absinfo from the device will remain
++on the old information. This makes using this tool potentially racy, use
++with caution.
+diff -Naur third-party-libevdev-bak/tools/libevdev-tweak-device.c third-party-new/tools/libevdev-tweak-device.c
+--- third-party-libevdev-bak/tools/libevdev-tweak-device.c	1970-01-01 08:00:00.000000000 +0800
++++ third-party-new/tools/libevdev-tweak-device.c	2022-03-25 12:33:26.000000000 +0800
+@@ -0,0 +1,465 @@
++// SPDX-License-Identifier: MIT
++/*
++ * Copyright © 2014 Red Hat, Inc.
++ */
++
++#include "config.h"
++
++#include 
++#include 
++#include 
++#include 
++#include 
++#include 
++#include 
++#include 
++#include 
++#include 
++#include 
++#include 
++#include 
++#include 
++
++#include "libevdev/libevdev.h"
++
++static void
++usage(const char *progname)
++{
++	printf("%s --abs  [--min min] [--max max] [--res res] [--fuzz fuzz] [--flat flat] /dev/input/eventXYZ\n"
++	       "\tChange the absinfo struct for the named axis\n"
++	       "%s --resolution res[,yres] /dev/input/eventXYZ\n"
++	       "\tChange the x/y resolution on the given device\n"
++	       "%s --led  --on|--off /dev/input/eventXYZ\n"
++	       "\tEnable or disable the named LED\n",
++	       progname,
++	       progname,
++	       progname);
++}
++
++enum mode {
++	MODE_NONE = 0,
++	MODE_ABS,
++	MODE_LED,
++	MODE_RESOLUTION,
++	MODE_HELP,
++};
++
++enum opts {
++	OPT_ABS = 1 << 0,
++	OPT_MIN = 1 << 1,
++	OPT_MAX = 1 << 2,
++	OPT_FUZZ = 1 << 3,
++	OPT_FLAT = 1 << 4,
++	OPT_RES = 1 << 5,
++	OPT_LED = 1 << 6,
++	OPT_ON = 1 << 7,
++	OPT_OFF = 1 << 8,
++	OPT_RESOLUTION = 1 << 9,
++	OPT_HELP = 1 << 10,
++};
++
++static bool
++parse_resolution_argument(const char *arg, int *xres, int *yres)
++{
++	int matched;
++
++	matched = sscanf(arg, "%d,%d", xres, yres);
++
++	switch(matched) {
++		case 2:
++			break;
++		case 1:
++			*yres = *xres;
++			break;
++		default:
++			return false;
++	}
++
++	return true;
++}
++
++static inline bool
++safe_atoi(const char *str, int *val)
++{
++        char *endptr;
++        long v;
++
++        v = strtol(str, &endptr, 10);
++        if (str == endptr)
++                return false;
++        if (*str != '\0' && *endptr != '\0')
++                return false;
++
++        if (v > INT_MAX || v < INT_MIN)
++                return false;
++
++        *val = v;
++        return true;
++}
++
++static int
++parse_event_code(int type, const char *str)
++{
++	int code;
++
++	code = libevdev_event_code_from_name(type, str);
++	if (code != -1)
++		return code;
++
++	if (safe_atoi(str, &code))
++		return code;
++
++	return -1;
++}
++
++static int
++parse_options_abs(int argc, char **argv, unsigned int *changes,
++		  int *axis, struct input_absinfo *absinfo)
++{
++	int rc = 1;
++	int c;
++	int option_index = 0;
++	static struct option opts[] = {
++		{ "abs", 1, 0, OPT_ABS },
++		{ "min", 1, 0, OPT_MIN },
++		{ "max", 1, 0, OPT_MAX },
++		{ "fuzz", 1, 0, OPT_FUZZ },
++		{ "flat", 1, 0, OPT_FLAT },
++		{ "res", 1, 0, OPT_RES },
++		{ NULL, 0, 0, 0 },
++	};
++
++	if (argc < 2)
++		goto error;
++
++	optind = 1;
++	while (1) {
++		c = getopt_long(argc, argv, "h", opts, &option_index);
++		if (c == -1)
++			break;
++
++		switch (c) {
++			case OPT_ABS:
++				*axis = parse_event_code(EV_ABS, optarg);
++				if (*axis == -1)
++					goto error;
++				break;
++			case OPT_MIN:
++				absinfo->minimum = atoi(optarg);
++				break;
++			case OPT_MAX:
++				absinfo->maximum = atoi(optarg);
++				break;
++			case OPT_FUZZ:
++				absinfo->fuzz = atoi(optarg);
++				break;
++			case OPT_FLAT:
++				absinfo->flat = atoi(optarg);
++				break;
++			case OPT_RES:
++				absinfo->resolution = atoi(optarg);
++				break;
++			default:
++				goto error;
++		}
++		*changes |= c;
++	}
++	rc = 0;
++error:
++	return rc;
++}
++
++static int
++parse_options_led(int argc, char **argv, int *led, int *led_state)
++{
++	int rc = 1;
++	int c;
++	int option_index = 0;
++	static struct option opts[] = {
++		{ "led", 1, 0, OPT_LED },
++		{ "on", 0, 0, OPT_ON },
++		{ "off", 0, 0, OPT_OFF },
++		{ NULL, 0, 0, 0 },
++	};
++
++	if (argc < 2)
++		goto error;
++
++	optind = 1;
++	while (1) {
++		c = getopt_long(argc, argv, "h", opts, &option_index);
++		if (c == -1)
++			break;
++
++		switch (c) {
++			case OPT_LED:
++				*led = parse_event_code(EV_LED, optarg);
++				if (*led == -1)
++					goto error;
++				break;
++			case OPT_ON:
++				if (*led_state != -1)
++					goto error;
++				*led_state = 1;
++				break;
++			case OPT_OFF:
++				if (*led_state != -1)
++					goto error;
++				*led_state = 0;
++				break;
++			default:
++				goto error;
++		}
++	}
++
++	rc = 0;
++error:
++	return rc;
++}
++
++static int
++parse_options_resolution(int argc, char **argv, int *xres, int *yres)
++{
++	int rc = 1;
++	int c;
++	int option_index = 0;
++	static struct option opts[] = {
++		{ "resolution", 1, 0, OPT_RESOLUTION },
++		{ NULL, 0, 0, 0 },
++	};
++
++	if (argc < 2)
++		goto error;
++
++	optind = 1;
++	while (1) {
++		c = getopt_long(argc, argv, "h", opts, &option_index);
++		if (c == -1)
++			break;
++
++		switch (c) {
++			case OPT_RESOLUTION:
++				if (!parse_resolution_argument(optarg,
++							       xres, yres))
++					goto error;
++				break;
++			default:
++				goto error;
++		}
++	}
++
++	rc = 0;
++error:
++	return rc;
++}
++
++static enum mode
++parse_options_mode(int argc, char **argv)
++{
++	int c;
++	int option_index = 0;
++	static const struct option opts[] = {
++		{ "abs", 1, 0, OPT_ABS },
++		{ "led", 1, 0, OPT_LED },
++		{ "resolution", 1, 0, OPT_RESOLUTION },
++		{ "help", 0, 0, OPT_HELP },
++		{ NULL, 0, 0, 0 },
++	};
++	enum mode mode = MODE_NONE;
++
++	if (argc < 2)
++		return mode;
++
++	while (mode == MODE_NONE) {
++		c = getopt_long(argc, argv, "h", opts, &option_index);
++		if (c == -1)
++			break;
++
++		switch (c) {
++			case 'h':
++			case OPT_HELP:
++				mode = MODE_HELP;
++				break;
++			case OPT_ABS:
++				mode = MODE_ABS;
++				break;
++			case OPT_LED:
++				mode = MODE_LED;
++				break;
++			case OPT_RESOLUTION:
++				mode = MODE_RESOLUTION;
++				break;
++			default:
++				break;
++		}
++	}
++
++	if (optind >= argc && mode != MODE_HELP)
++		return MODE_NONE;
++
++	return mode;
++}
++
++static void
++set_abs(struct libevdev *dev, unsigned int changes,
++	unsigned int axis, struct input_absinfo *absinfo)
++{
++	int rc;
++	struct input_absinfo abs;
++	const struct input_absinfo *a;
++
++	if ((a = libevdev_get_abs_info(dev, axis)) == NULL) {
++		fprintf(stderr,
++			"Device '%s' doesn't have axis %s\n",
++			libevdev_get_name(dev),
++			libevdev_event_code_get_name(EV_ABS, axis));
++		return;
++	}
++
++	abs = *a;
++	if (changes & OPT_MIN)
++		abs.minimum = absinfo->minimum;
++	if (changes & OPT_MAX)
++		abs.maximum = absinfo->maximum;
++	if (changes & OPT_FUZZ)
++		abs.fuzz = absinfo->fuzz;
++	if (changes & OPT_FLAT)
++		abs.flat = absinfo->flat;
++	if (changes & OPT_RES)
++		abs.resolution = absinfo->resolution;
++
++	rc = libevdev_kernel_set_abs_info(dev, axis, &abs);
++	if (rc != 0)
++		fprintf(stderr,
++			"Failed to set absinfo %s: %s",
++			libevdev_event_code_get_name(EV_ABS, axis),
++			strerror(-rc));
++}
++
++static void
++set_led(struct libevdev *dev, unsigned int led, int led_state)
++{
++	int rc;
++	enum libevdev_led_value state =
++		led_state ? LIBEVDEV_LED_ON : LIBEVDEV_LED_OFF;
++
++	if (!libevdev_has_event_code(dev, EV_LED, led)) {
++		fprintf(stderr,
++			"Device '%s' doesn't have %s\n",
++			libevdev_get_name(dev),
++			libevdev_event_code_get_name(EV_LED, led));
++		return;
++	}
++
++	rc = libevdev_kernel_set_led_value(dev, led, state);
++	if (rc != 0)
++		fprintf(stderr,
++			"Failed to set LED %s: %s",
++			libevdev_event_code_get_name(EV_LED, led),
++			strerror(-rc));
++}
++
++static void
++set_resolution(struct libevdev *dev, int xres, int yres)
++{
++	struct input_absinfo abs;
++
++	abs.resolution = xres;
++	if (libevdev_has_event_code(dev, EV_ABS, ABS_X))
++		set_abs(dev, OPT_RES, ABS_X, &abs);
++	if (libevdev_has_event_code(dev, EV_ABS, ABS_MT_POSITION_X))
++		set_abs(dev, OPT_RES, ABS_MT_POSITION_X, &abs);
++
++	abs.resolution = yres;
++	if (libevdev_has_event_code(dev, EV_ABS, ABS_Y))
++		set_abs(dev, OPT_RES, ABS_Y, &abs);
++	if (libevdev_has_event_code(dev, EV_ABS, ABS_MT_POSITION_Y))
++		set_abs(dev, OPT_RES, ABS_MT_POSITION_Y, &abs);
++}
++
++int
++main(int argc, char **argv)
++{
++	struct libevdev *dev = NULL;
++	int fd = -1;
++	int rc = EXIT_FAILURE;
++	enum mode mode;
++	const char *path;
++	struct input_absinfo absinfo;
++	int axis = -1;
++	int led = -1;
++	int led_state = -1;
++	unsigned int changes = 0; /* bitmask of changes */
++	int xres = 0,
++	    yres = 0;
++
++	mode = parse_options_mode(argc, argv);
++	switch (mode) {
++		case MODE_HELP:
++			rc = EXIT_SUCCESS;
++			/* fallthrough */
++		case MODE_NONE:
++			usage(basename(argv[0]));
++			goto out;
++		case MODE_ABS:
++			rc = parse_options_abs(argc, argv, &changes, &axis,
++					       &absinfo);
++			break;
++		case MODE_LED:
++			rc = parse_options_led(argc, argv, &led, &led_state);
++			break;
++		case MODE_RESOLUTION:
++			rc = parse_options_resolution(argc, argv, &xres,
++						      &yres);
++			break;
++		default:
++			fprintf(stderr,
++				"++?????++ Out of Cheese Error. Redo From Start.\n");
++			goto out;
++	}
++
++	if (rc != EXIT_SUCCESS)
++		goto out;
++
++	if (optind >= argc) {
++		rc = EXIT_FAILURE;
++		usage(basename(argv[0]));
++		goto out;
++	}
++
++	path = argv[optind];
++
++	fd = open(path, O_RDWR);
++	if (fd < 0) {
++		rc = EXIT_FAILURE;
++		perror("Failed to open device");
++		goto out;
++	}
++
++	rc = libevdev_new_from_fd(fd, &dev);
++	if (rc < 0) {
++		fprintf(stderr, "Failed to init libevdev (%s)\n", strerror(-rc));
++		goto out;
++	}
++
++	switch (mode) {
++		case MODE_ABS:
++			set_abs(dev, changes, axis, &absinfo);
++			break;
++		case MODE_LED:
++			set_led(dev, led, led_state);
++			break;
++		case MODE_RESOLUTION:
++			set_resolution(dev, xres, yres);
++			break;
++		default:
++			break;
++	}
++
++out:
++	libevdev_free(dev);
++	if (fd != -1)
++		close(fd);
++
++	return rc;
++}
+diff -Naur third-party-libevdev-bak/tools/mouse-dpi-tool.1 third-party-new/tools/mouse-dpi-tool.1
+--- third-party-libevdev-bak/tools/mouse-dpi-tool.1	1970-01-01 08:00:00.000000000 +0800
++++ third-party-new/tools/mouse-dpi-tool.1	2022-03-25 12:33:26.000000000 +0800
+@@ -0,0 +1,18 @@
++.TH MOUSE-DPI-TOOL "1"
++.SH NAME
++mouse-dpi-tool \- mouse resolution estimation tool
++.SH SYNOPSIS
++.BR mouse-dpi-tool " <\fIevdev device\fP>"
++.SH DESCRIPTION
++.B mouse-dpi-tool
++reads relative events (mouse movement events) and calculates the
++distance covered and maximum frequency of the incoming events.
++Combined with a measurement of the actual distance physically covered,
++this allows the mouse's resolution to be estimated.
++.PP
++Some mouse devices provide dynamic frequencies, it is
++recommended to measure multiple times to obtain the highest value.
++.PP
++.SH OPTIONS
++.B mouse-dpi-tool
++accepts no options.
+diff -Naur third-party-libevdev-bak/tools/mouse-dpi-tool.c third-party-new/tools/mouse-dpi-tool.c
+--- third-party-libevdev-bak/tools/mouse-dpi-tool.c	1970-01-01 08:00:00.000000000 +0800
++++ third-party-new/tools/mouse-dpi-tool.c	2022-03-25 12:33:26.000000000 +0800
+@@ -0,0 +1,293 @@
++// SPDX-License-Identifier: MIT
++/*
++ * Copyright © 2014 Red Hat, Inc.
++ */
++
++#include "config.h"
++
++#include 
++#include 
++#include 
++#include 
++#include 
++#include 
++#include 
++#include 
++#include 
++#include 
++#include 
++
++#include "libevdev/libevdev.h"
++
++#define min(a, b) (((a) < (b)) ? (a) : (b))
++#define max(a, b) (((a) > (b)) ? (a) : (b))
++
++static int signalled = 0;
++
++struct measurements {
++	int distance;
++	double max_frequency;
++	double *frequencies;
++	size_t frequencies_sz;
++	size_t nfrequencies;
++	uint64_t us;
++};
++
++static int
++usage(const char *progname) {
++	printf("Usage: %s /dev/input/event0\n", progname);
++	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"
++	       "Some mouse devices provide dynamic frequencies, it is\n"
++	       "recommended to measure multiple times to obtain the highest value.\n");
++	return 1;
++}
++
++static inline double
++get_frequency(uint64_t last, uint64_t current)
++{
++	return 1000000.0/(current - last);
++}
++
++static inline void
++push_frequency(struct measurements *m, double freq)
++{
++	if (m->nfrequencies == m->frequencies_sz) {
++		m->frequencies_sz += 100;
++		m->frequencies = realloc(m->frequencies,
++					 m->frequencies_sz * sizeof *m->frequencies);
++		if (!m->frequencies)
++			abort();
++	}
++
++	m->frequencies[m->nfrequencies] = freq;
++	m->nfrequencies++;
++}
++
++static int
++print_current_values(const struct measurements *m)
++{
++	static int progress = 0;
++	char status = 0;
++
++	switch (progress) {
++		case 0: status = '|'; break;
++		case 1: status = '/'; break;
++		case 2: status = '-'; break;
++		case 3: status = '\\'; break;
++		default:
++			status = '?';
++			break;
++	}
++
++	progress = (progress + 1) % 4;
++
++	printf("\rCovered distance in device units: %8d at frequency %3.1fHz 	%c",
++	       abs(m->distance), m->max_frequency, status);
++
++	return 0;
++}
++
++static int
++handle_event(struct measurements *m, const struct input_event *ev)
++{
++	if (ev->type == EV_SYN) {
++		const int idle_reset = 3000000; /* us */
++		uint64_t last_us = m->us;
++
++		m->us = ev->input_event_sec * 1000000 + ev->input_event_usec;
++
++		/* reset after pause */
++		if (last_us + idle_reset < m->us) {
++			m->max_frequency = 0.0;
++			m->distance = 0;
++		} else {
++			double freq = get_frequency(last_us, m->us);
++			push_frequency(m, freq);
++			m->max_frequency = max(freq, m->max_frequency);
++			return print_current_values(m);
++		}
++
++		return 0;
++	}
++
++	if (ev->type != EV_REL)
++		return 0;
++
++	switch(ev->code) {
++		case REL_X:
++			m->distance += ev->value;
++			break;
++	}
++
++	return 0;
++}
++
++static void
++signal_handler(__attribute__((__unused__)) int signal)
++{
++	signalled++;
++}
++
++static int
++mainloop(struct libevdev *dev, struct measurements *m) {
++	struct pollfd fds;
++
++	fds.fd = libevdev_get_fd(dev);
++	fds.events = POLLIN;
++
++	signal(SIGINT, signal_handler);
++
++	while (poll(&fds, 1, -1)) {
++		struct input_event ev;
++		int rc;
++
++		if (signalled)
++			break;
++
++		do {
++			rc = libevdev_next_event(dev, LIBEVDEV_READ_FLAG_NORMAL, &ev);
++			if (rc == LIBEVDEV_READ_STATUS_SYNC) {
++				fprintf(stderr, "Error: cannot keep up\n");
++				return 1;
++			}
++
++			if (rc != -EAGAIN && rc < 0) {
++				fprintf(stderr, "Error: %s\n", strerror(-rc));
++				return 1;
++			}
++
++			if (rc == LIBEVDEV_READ_STATUS_SUCCESS)
++				handle_event(m, &ev);
++		} while (rc != -EAGAIN);
++	}
++
++	return 0;
++}
++
++static inline double
++mean_frequency(struct measurements *m)
++{
++	int idx;
++
++	idx = m->nfrequencies/2;
++	return m->frequencies[idx];
++}
++
++static inline const char*
++bustype(int bustype)
++{
++	const char *bus;
++
++	switch(bustype) {
++		case BUS_PCI: bus = "pci"; break;
++		case BUS_ISAPNP: bus = "isapnp"; break;
++		case BUS_USB: bus = "usb"; break;
++		case BUS_HIL: bus = "hil"; break;
++		case BUS_BLUETOOTH: bus = "bluetooth"; break;
++		case BUS_VIRTUAL: bus = "virtual"; break;
++		default: bus = "unknown bus type"; break;
++	}
++
++	return bus;
++}
++
++static void
++print_summary(struct libevdev *dev, struct measurements *m)
++{
++	int res;
++	int max_freq, mean_freq;
++
++	if (m->nfrequencies == 0) {
++		fprintf(stderr, "Error: no matching events received.\n");
++		return;
++	}
++
++	max_freq = (int)m->max_frequency;
++	mean_freq = (int)mean_frequency(m);
++
++	printf("Estimated sampling frequency: %dHz (mean %dHz)\n",
++	       max_freq, mean_freq);
++
++	if (max_freq > mean_freq * 1.3)
++		printf("WARNING: Max frequency is more than 30%% higher "
++		       "than mean frequency. Manual verification required!\n");
++
++	printf("To calculate resolution, measure physical distance covered\n"
++	       "and look up the matching resolution in the table below\n");
++
++	m->distance = abs(m->distance);
++
++	/* If the mouse has more than 2500dpi, the manufacturer usually
++	   shows off on their website anyway */
++	for (res = 400; res <= 2500; res += 200) {
++		double inch = m->distance/(double)res;
++		printf("%8dmm	%8.2fin	%8ddpi\n",
++		       (int)(inch * 25.4), inch, res);
++	}
++	printf("If your resolution is not in the list, calculate it with:\n"
++	       "\tresolution=%d/inches, or\n"
++	       "\tresolution=%d * 25.4/mm\n", m->distance, m->distance);
++
++	printf("\n");
++	printf("Entry for hwdb match (replace XXX with the resolution in DPI):\n"
++	       "mouse:%s:v%04xp%04x:name:%s:\n"
++	       " MOUSE_DPI=XXX@%d\n",
++	       bustype(libevdev_get_id_bustype(dev)),
++	       libevdev_get_id_vendor(dev),
++	       libevdev_get_id_product(dev),
++	       libevdev_get_name(dev),
++	       (int)m->max_frequency);
++}
++
++int
++main (int argc, char **argv) {
++	int rc;
++	int fd;
++	const char *path;
++	struct libevdev *dev;
++	struct measurements measurements = {0};
++
++	if (argc < 2)
++		return usage(basename(argv[0]));
++
++	path = argv[1];
++	if (path[0] == '-')
++		return usage(basename(argv[0]));
++
++	fd = open(path, O_RDONLY|O_NONBLOCK);
++	if (fd < 0) {
++		fprintf(stderr, "Error opening the device: %s\n", strerror(errno));
++		return 1;
++	}
++
++	rc = libevdev_new_from_fd(fd, &dev);
++	if (rc != 0) {
++		fprintf(stderr, "Error fetching the device info: %s\n", strerror(-rc));
++		return 1;
++	}
++
++	if (libevdev_grab(dev, LIBEVDEV_GRAB) != 0) {
++		fprintf(stderr, "Error: cannot grab the device, something else is grabbing it.\n");
++		fprintf(stderr, "Use 'fuser -v %s' to find processes with an open fd\n", path);
++		return 1;
++	}
++	libevdev_grab(dev, LIBEVDEV_UNGRAB);
++
++	printf("Mouse %s on %s\n", libevdev_get_name(dev), path);
++	printf("Move the device 250mm/10in or more along the x-axis.\n");
++	printf("Pause 3 seconds before movement to reset, Ctrl+C to exit.\n");
++	setbuf(stdout, NULL);
++
++	rc = mainloop(dev, &measurements);
++
++	printf("\n");
++
++	print_summary(dev, &measurements);
++
++	libevdev_free(dev);
++	close(fd);
++
++	return rc;
++}
+diff -Naur third-party-libevdev-bak/tools/touchpad-edge-detector.1 third-party-new/tools/touchpad-edge-detector.1
+--- third-party-libevdev-bak/tools/touchpad-edge-detector.1	1970-01-01 08:00:00.000000000 +0800
++++ third-party-new/tools/touchpad-edge-detector.1	2022-03-25 12:33:26.000000000 +0800
+@@ -0,0 +1,44 @@
++.TH TOUCHPAD-EDGE-DETECTOR "1"
++.SH NAME
++touchpad-edge-detector \- print the axis ranges for a touchpad device
++.SH SYNOPSIS
++.B touchpad-edge-detector [--help] \fIWxH /dev/input/eventX\fR
++.SH DESCRIPTION
++.PP
++The
++.B touchpad-edge-detector
++tool reads touchpad events from the kernel and records the minimum and
++maximum coordinates based on user input. This is an interactive tool, the
++user must move a finger around the touchpad, attempting to trigger an
++event at all edges of the touchpad.
++.PP
++To terminate the event collection and print a summary, press Ctrl+C. It is
++recommended that the tool is run several times to guarantee a reliable
++result.
++.SH OPTIONS
++.TP 8
++.I WxH
++The width and height of the touchpad in mm. For a touchpad 100mm wide and
++75mm high, the argument is thus \fI100x75\fR. This is a required argument.
++.TP 8
++.I /dev/input/eventX
++The event node of the touchpad to read events from. A list of possible event
++nodes can be obtained with either one of the following commands: \fBlibinput
++record\fR, \fBevemu-record\fR, or \fBevtest\fR. Alternatively the event node
++for a device is listed in the \fBHandlers=\fR line \fI/proc/bus/input/devices\fR.
++This is a required argument.
++.TP 8
++.B --help
++Print a short help description
++.SH NOTES
++.PP
++On completion, this tool prints a summary of the collected events and a
++suggested udev rule. Due to rounding errors it is rare to get an exact match
++for the touchpad's dimensions, but any discrepancy of more than 5mm should
++be corrected with the suggested udev rule.
++.PP
++The udev rule should be simplified and submitted as a pull request to the
++system repository at \fIhttps://github.com/systemd/systemd\fR. For further
++guidance, see the file \fI/usr/lib/udev/hwdb.d/60-evdev.hwdb\fR.
++.SH SEE ALSO
++udev(7)
+diff -Naur third-party-libevdev-bak/tools/touchpad-edge-detector.c third-party-new/tools/touchpad-edge-detector.c
+--- third-party-libevdev-bak/tools/touchpad-edge-detector.c	1970-01-01 08:00:00.000000000 +0800
++++ third-party-new/tools/touchpad-edge-detector.c	2022-03-25 12:33:26.000000000 +0800
+@@ -0,0 +1,294 @@
++// SPDX-License-Identifier: MIT
++/*
++ * Copyright © 2014 Red Hat, Inc.
++ */
++
++#include "config.h"
++
++#include 
++#include 
++#include 
++#include 
++#include 
++#include 
++#include 
++#include 
++#include 
++#include 
++#include 
++#include 
++
++#include "libevdev/libevdev.h"
++
++#define min(a, b) (((a) < (b)) ? (a) : (b))
++#define max(a, b) (((a) > (b)) ? (a) : (b))
++
++static int signalled = 0;
++
++static int
++usage(const char *progname) {
++	printf("Usage: %s 12x34 /dev/input/eventX\n", progname);
++	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"
++	       "The first argument is the physical size of the touchpad in mm (WIDTHxHEIGHT).\n");
++	return 1;
++}
++
++struct dimensions {
++	int top, bottom, left, right;
++};
++
++struct size {
++	int w, h;
++};
++
++static int
++print_current_values(const struct dimensions *d)
++{
++	static int progress;
++	char status = 0;
++
++	switch (progress) {
++		case 0: status = '|'; break;
++		case 1: status = '/'; break;
++		case 2: status = '-'; break;
++		case 3: status = '\\'; break;
++	}
++
++	progress = (progress + 1) % 4;
++
++	printf("\rTouchpad sends:	x [%d..%d], y [%d..%d] %c",
++			d->left, d->right, d->top, d->bottom, status);
++	return 0;
++}
++
++static int
++handle_event(struct dimensions *d, const struct input_event *ev) {
++	if (ev->type == EV_SYN)
++		return print_current_values(d);
++
++	if (ev->type != EV_ABS)
++		return 0;
++
++	switch(ev->code) {
++		case ABS_X:
++		case ABS_MT_POSITION_X:
++			d->left = min(d->left, ev->value);
++			d->right = max(d->right, ev->value);
++			break;
++		case ABS_Y:
++		case ABS_MT_POSITION_Y:
++			d->top = min(d->top, ev->value);
++			d->bottom = max(d->bottom, ev->value);
++			break;
++	}
++
++	return 0;
++}
++
++static void
++signal_handler(__attribute__((__unused__)) int signal)
++{
++	signalled++;
++}
++
++static int
++mainloop(struct libevdev *dev, struct dimensions *dim) {
++	struct pollfd fds;
++
++	fds.fd = libevdev_get_fd(dev);
++	fds.events = POLLIN;
++
++	signal(SIGINT, signal_handler);
++
++	while (poll(&fds, 1, -1)) {
++		struct input_event ev;
++		int rc;
++
++		if (signalled)
++			break;
++
++		do {
++			rc = libevdev_next_event(dev, LIBEVDEV_READ_FLAG_NORMAL, &ev);
++			if (rc == LIBEVDEV_READ_STATUS_SYNC) {
++				fprintf(stderr, "Error: cannot keep up\n");
++				return 1;
++			}
++
++			if (rc != -EAGAIN && rc < 0) {
++				fprintf(stderr, "Error: %s\n", strerror(-rc));
++				return 1;
++
++			}
++
++			if (rc == LIBEVDEV_READ_STATUS_SUCCESS)
++				handle_event(dim, &ev);
++		} while (rc != -EAGAIN);
++	}
++
++	return 0;
++}
++
++static inline void
++pid_vid_matchstr(struct libevdev *dev, char *match, size_t sz)
++{
++	snprintf(match, sz, "input:b%04Xv%04Xp%04X",
++		libevdev_get_id_bustype(dev),
++		libevdev_get_id_vendor(dev),
++		libevdev_get_id_product(dev));
++}
++
++static inline void
++dmi_matchstr(struct libevdev *dev, char *match, size_t sz)
++{
++	char modalias[PATH_MAX];
++	FILE *fp;
++
++	fp = fopen("/sys/class/dmi/id/modalias", "r");
++	if (!fp || fgets(modalias, sizeof(modalias), fp) == NULL) {
++		sprintf(match, "ERROR READING DMI MODALIAS");
++		if (fp)
++			fclose(fp);
++		return;
++	}
++
++	fclose(fp);
++
++	modalias[strlen(modalias) - 1] = '\0'; /* drop \n */
++	snprintf(match, sz, "name:%s:%s", libevdev_get_name(dev), modalias);
++}
++
++static void
++print_udev_override_rule(struct libevdev *dev,
++			 const struct dimensions *dim,
++			 const struct size *size) {
++	const struct input_absinfo *x, *y;
++	char match[PATH_MAX];
++	int w, h;
++	int xres, yres;
++
++	x = libevdev_get_abs_info(dev, ABS_X);
++	y = libevdev_get_abs_info(dev, ABS_Y);
++	w = dim->right - dim->left;
++	h = dim->bottom - dim->top;
++	xres = round((double)w/size->w);
++	yres = round((double)h/size->h);
++
++	if (x->resolution && y->resolution) {
++		int width = x->maximum - x->minimum,
++		    height = y->maximum - y->minimum;
++		printf("Touchpad size as listed by the kernel: %dx%dmm\n",
++		       width/x->resolution, height/y->resolution);
++	} else {
++		printf("Touchpad has no resolution, size unknown\n");
++	}
++
++	printf("User-specified touchpad size: %dx%dmm\n", size->w, size->h);
++	printf("Calculated ranges: %d/%d\n", w, h);
++	printf("\n");
++	printf("Suggested udev rule:\n");
++
++	switch(libevdev_get_id_bustype(dev)) {
++	case BUS_USB:
++	case BUS_BLUETOOTH:
++		pid_vid_matchstr(dev, match, sizeof(match));
++		break;
++	default:
++		dmi_matchstr(dev, match, sizeof(match));
++		break;
++	}
++
++	printf("# \n"
++	       "evdev:%s*\n"
++	       " EVDEV_ABS_00=%d:%d:%d\n"
++	       " EVDEV_ABS_01=%d:%d:%d\n",
++	       match,
++	       dim->left, dim->right, xres,
++	       dim->top, dim->bottom, yres);
++	if (libevdev_has_event_code(dev, EV_ABS, ABS_MT_POSITION_X))
++		printf(" EVDEV_ABS_35=%d:%d:%d\n"
++		       " EVDEV_ABS_36=%d:%d:%d\n",
++		       dim->left, dim->right, xres,
++		       dim->top, dim->bottom, yres);
++}
++
++int main (int argc, char **argv) {
++	int rc;
++	int fd;
++	const char *path;
++	struct libevdev *dev;
++	struct dimensions dim;
++	struct size size;
++
++	if (argc < 3)
++		return usage(basename(argv[0]));
++
++	if (sscanf(argv[1], "%dx%d", &size.w, &size.h) != 2 ||
++	    size.w <= 0 || size.h <= 0)
++		return usage(basename(argv[0]));
++
++	if (size.w < 30 || size.h < 30) {
++		fprintf(stderr,
++			"%dx%dmm is too small for a touchpad.\n"
++			"Please specify the touchpad size in mm.\n",
++			size.w, size.h);
++		return 1;
++	}
++
++	path = argv[2];
++	if (path[0] == '-')
++		return usage(basename(argv[0]));
++
++	fd = open(path, O_RDONLY|O_NONBLOCK);
++	if (fd < 0) {
++		fprintf(stderr, "Error opening the device: %s\n", strerror(errno));
++		return 1;
++	}
++
++	rc = libevdev_new_from_fd(fd, &dev);
++	if (rc != 0) {
++		fprintf(stderr, "Error fetching the device info: %s\n", strerror(-rc));
++		return 1;
++	}
++
++	if (libevdev_grab(dev, LIBEVDEV_GRAB) != 0) {
++		fprintf(stderr, "Error: cannot grab the device, something else is grabbing it.\n");
++		fprintf(stderr, "Use 'fuser -v %s' to find processes with an open fd\n", path);
++		return 1;
++	}
++	libevdev_grab(dev, LIBEVDEV_UNGRAB);
++
++	if (!libevdev_has_event_code(dev, EV_ABS, ABS_X) ||
++	    !libevdev_has_event_code(dev, EV_ABS, ABS_Y)) {
++		fprintf(stderr, "Error: this device does not have abs axes\n");
++		rc = EXIT_FAILURE;
++		goto out;
++	}
++
++	dim.left = INT_MAX;
++	dim.right = INT_MIN;
++	dim.top = INT_MAX;
++	dim.bottom = INT_MIN;
++
++	printf("Touchpad %s on %s\n", libevdev_get_name(dev), path);
++	printf("Move one finger around the touchpad to detect the actual edges\n");
++	printf("Kernel says:	x [%d..%d], y [%d..%d]\n",
++			libevdev_get_abs_minimum(dev, ABS_X),
++			libevdev_get_abs_maximum(dev, ABS_X),
++			libevdev_get_abs_minimum(dev, ABS_Y),
++			libevdev_get_abs_maximum(dev, ABS_Y));
++
++	setbuf(stdout, NULL);
++
++	rc = mainloop(dev, &dim);
++	printf("\n\n");
++
++	print_udev_override_rule(dev, &dim, &size);
++
++out:
++	libevdev_free(dev);
++	close(fd);
++
++	return rc;
++}
diff --git a/tools/Makefile.am b/tools/Makefile.am
new file mode 100644
index 0000000000000000000000000000000000000000..423404013d66d90a1400cc077e471852046485db
--- /dev/null
+++ b/tools/Makefile.am
@@ -0,0 +1,29 @@
+noinst_PROGRAMS = libevdev-events libevdev-list-codes
+bin_PROGRAMS = \
+	       touchpad-edge-detector \
+	       mouse-dpi-tool \
+	       libevdev-tweak-device
+
+AM_CPPFLAGS = $(GCC_CFLAGS) -I$(top_srcdir) -I$(top_srcdir)/include -I$(top_srcdir)/libevdev
+libevdev_ldadd = $(top_builddir)/libevdev/libevdev.la
+
+libevdev_events_SOURCES = libevdev-events.c
+libevdev_events_LDADD = $(libevdev_ldadd)
+
+libevdev_list_codes_SOURCES = libevdev-list-codes.c
+libevdev_list_codes_LDADD = $(libevdev_ldadd)
+
+touchpad_edge_detector_SOURCES = touchpad-edge-detector.c
+touchpad_edge_detector_LDADD = $(libevdev_ldadd)
+
+mouse_dpi_tool_SOURCES = mouse-dpi-tool.c
+mouse_dpi_tool_LDADD = $(libevdev_ldadd)
+
+libevdev_tweak_device_SOURCES = libevdev-tweak-device.c
+libevdev_tweak_device_LDADD = $(libevdev_ldadd)
+
+dist_man_MANS = \
+		libevdev-tweak-device.1 \
+		mouse-dpi-tool.1 \
+		touchpad-edge-detector.1 \
+		$(NULL)
diff --git a/tools/Makefile.in b/tools/Makefile.in
new file mode 100644
index 0000000000000000000000000000000000000000..82c5ea05420b8bf6591f76d0e1e97a611fa122db
--- /dev/null
+++ b/tools/Makefile.in
@@ -0,0 +1,816 @@
+# Makefile.in generated by automake 1.16.5 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994-2021 Free Software Foundation, Inc.
+
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+VPATH = @srcdir@
+am__is_gnu_make = { \
+  if test -z '$(MAKELEVEL)'; then \
+    false; \
+  elif test -n '$(MAKE_HOST)'; then \
+    true; \
+  elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
+    true; \
+  else \
+    false; \
+  fi; \
+}
+am__make_running_with_option = \
+  case $${target_option-} in \
+      ?) ;; \
+      *) echo "am__make_running_with_option: internal error: invalid" \
+              "target option '$${target_option-}' specified" >&2; \
+         exit 1;; \
+  esac; \
+  has_opt=no; \
+  sane_makeflags=$$MAKEFLAGS; \
+  if $(am__is_gnu_make); then \
+    sane_makeflags=$$MFLAGS; \
+  else \
+    case $$MAKEFLAGS in \
+      *\\[\ \	]*) \
+        bs=\\; \
+        sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+          | sed "s/$$bs$$bs[$$bs $$bs	]*//g"`;; \
+    esac; \
+  fi; \
+  skip_next=no; \
+  strip_trailopt () \
+  { \
+    flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+  }; \
+  for flg in $$sane_makeflags; do \
+    test $$skip_next = yes && { skip_next=no; continue; }; \
+    case $$flg in \
+      *=*|--*) continue;; \
+        -*I) strip_trailopt 'I'; skip_next=yes;; \
+      -*I?*) strip_trailopt 'I';; \
+        -*O) strip_trailopt 'O'; skip_next=yes;; \
+      -*O?*) strip_trailopt 'O';; \
+        -*l) strip_trailopt 'l'; skip_next=yes;; \
+      -*l?*) strip_trailopt 'l';; \
+      -[dEDm]) skip_next=yes;; \
+      -[JT]) skip_next=yes;; \
+    esac; \
+    case $$flg in \
+      *$$target_option*) has_opt=yes; break;; \
+    esac; \
+  done; \
+  test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+noinst_PROGRAMS = libevdev-events$(EXEEXT) \
+	libevdev-list-codes$(EXEEXT)
+bin_PROGRAMS = touchpad-edge-detector$(EXEEXT) mouse-dpi-tool$(EXEEXT) \
+	libevdev-tweak-device$(EXEEXT)
+subdir = tools
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/m4/attributes.m4 \
+	$(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \
+	$(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \
+	$(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+	$(ACLOCAL_M4)
+DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+am__installdirs = "$(DESTDIR)$(bindir)" "$(DESTDIR)$(man1dir)"
+PROGRAMS = $(bin_PROGRAMS) $(noinst_PROGRAMS)
+am_libevdev_events_OBJECTS = libevdev-events.$(OBJEXT)
+libevdev_events_OBJECTS = $(am_libevdev_events_OBJECTS)
+libevdev_events_DEPENDENCIES = $(libevdev_ldadd)
+AM_V_lt = $(am__v_lt_@AM_V@)
+am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
+am__v_lt_0 = --silent
+am__v_lt_1 = 
+am_libevdev_list_codes_OBJECTS = libevdev-list-codes.$(OBJEXT)
+libevdev_list_codes_OBJECTS = $(am_libevdev_list_codes_OBJECTS)
+libevdev_list_codes_DEPENDENCIES = $(libevdev_ldadd)
+am_libevdev_tweak_device_OBJECTS = libevdev-tweak-device.$(OBJEXT)
+libevdev_tweak_device_OBJECTS = $(am_libevdev_tweak_device_OBJECTS)
+libevdev_tweak_device_DEPENDENCIES = $(libevdev_ldadd)
+am_mouse_dpi_tool_OBJECTS = mouse-dpi-tool.$(OBJEXT)
+mouse_dpi_tool_OBJECTS = $(am_mouse_dpi_tool_OBJECTS)
+mouse_dpi_tool_DEPENDENCIES = $(libevdev_ldadd)
+am_touchpad_edge_detector_OBJECTS = touchpad-edge-detector.$(OBJEXT)
+touchpad_edge_detector_OBJECTS = $(am_touchpad_edge_detector_OBJECTS)
+touchpad_edge_detector_DEPENDENCIES = $(libevdev_ldadd)
+AM_V_P = $(am__v_P_@AM_V@)
+am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_@AM_V@)
+am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
+am__v_GEN_0 = @echo "  GEN     " $@;
+am__v_GEN_1 = 
+AM_V_at = $(am__v_at_@AM_V@)
+am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 = 
+DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
+depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp
+am__maybe_remake_depfiles = depfiles
+am__depfiles_remade = ./$(DEPDIR)/libevdev-events.Po \
+	./$(DEPDIR)/libevdev-list-codes.Po \
+	./$(DEPDIR)/libevdev-tweak-device.Po \
+	./$(DEPDIR)/mouse-dpi-tool.Po \
+	./$(DEPDIR)/touchpad-edge-detector.Po
+am__mv = mv -f
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+	$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+	$(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \
+	$(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
+	$(AM_CFLAGS) $(CFLAGS)
+AM_V_CC = $(am__v_CC_@AM_V@)
+am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@)
+am__v_CC_0 = @echo "  CC      " $@;
+am__v_CC_1 = 
+CCLD = $(CC)
+LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+	$(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+	$(AM_LDFLAGS) $(LDFLAGS) -o $@
+AM_V_CCLD = $(am__v_CCLD_@AM_V@)
+am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@)
+am__v_CCLD_0 = @echo "  CCLD    " $@;
+am__v_CCLD_1 = 
+SOURCES = $(libevdev_events_SOURCES) $(libevdev_list_codes_SOURCES) \
+	$(libevdev_tweak_device_SOURCES) $(mouse_dpi_tool_SOURCES) \
+	$(touchpad_edge_detector_SOURCES)
+DIST_SOURCES = $(libevdev_events_SOURCES) \
+	$(libevdev_list_codes_SOURCES) \
+	$(libevdev_tweak_device_SOURCES) $(mouse_dpi_tool_SOURCES) \
+	$(touchpad_edge_detector_SOURCES)
+am__can_run_installinfo = \
+  case $$AM_UPDATE_INFO_DIR in \
+    n|no|NO) false;; \
+    *) (install-info --version) >/dev/null 2>&1;; \
+  esac
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+    $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+    *) f=$$p;; \
+  esac;
+am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
+am__install_max = 40
+am__nobase_strip_setup = \
+  srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
+am__nobase_strip = \
+  for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
+am__nobase_list = $(am__nobase_strip_setup); \
+  for p in $$list; do echo "$$p $$p"; done | \
+  sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
+  $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
+    if (++n[$$2] == $(am__install_max)) \
+      { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
+    END { for (dir in files) print dir, files[dir] }'
+am__base_list = \
+  sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
+  sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
+am__uninstall_files_from_dir = { \
+  test -z "$$files" \
+    || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
+    || { echo " ( cd '$$dir' && rm -f" $$files ")"; \
+         $(am__cd) "$$dir" && rm -f $$files; }; \
+  }
+man1dir = $(mandir)/man1
+NROFF = nroff
+MANS = $(dist_man_MANS)
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
+# Read a list of newline-separated strings from the standard input,
+# and print each of them once, without duplicates.  Input order is
+# *not* preserved.
+am__uniquify_input = $(AWK) '\
+  BEGIN { nonempty = 0; } \
+  { items[$$0] = 1; nonempty = 1; } \
+  END { if (nonempty) { for (i in items) print i; }; } \
+'
+# Make sure the list of sources is unique.  This is necessary because,
+# e.g., the same source file might be shared among _SOURCES variables
+# for different programs/libraries.
+am__define_uniq_tagged_files = \
+  list='$(am__tagged_files)'; \
+  unique=`for i in $$list; do \
+    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+  done | $(am__uniquify_input)`
+am__DIST_COMMON = $(dist_man_MANS) $(srcdir)/Makefile.in \
+	$(top_srcdir)/build-aux/depcomp
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CHECK_CFLAGS = @CHECK_CFLAGS@
+CHECK_LIBS = @CHECK_LIBS@
+CPPFLAGS = @CPPFLAGS@
+CSCOPE = @CSCOPE@
+CTAGS = @CTAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLTOOL = @DLLTOOL@
+DOXYGEN = @DOXYGEN@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+ETAGS = @ETAGS@
+EXEEXT = @EXEEXT@
+FGREP = @FGREP@
+GCC_CFLAGS = @GCC_CFLAGS@
+GCOV_CFLAGS = @GCOV_CFLAGS@
+GCOV_LDFLAGS = @GCOV_LDFLAGS@
+GNU_LD_FLAGS = @GNU_LD_FLAGS@
+GREP = @GREP@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LIBEVDEV_LT_VERSION = @LIBEVDEV_LT_VERSION@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
+MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MKDIR_P = @MKDIR_P@
+NM = @NM@
+NMEDIT = @NMEDIT@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OS = @OS@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PKG_CONFIG = @PKG_CONFIG@
+PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
+PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
+PYTHON = @PYTHON@
+PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
+PYTHON_PLATFORM = @PYTHON_PLATFORM@
+PYTHON_PREFIX = @PYTHON_PREFIX@
+PYTHON_VERSION = @PYTHON_VERSION@
+RANLIB = @RANLIB@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+VALGRIND = @VALGRIND@
+VERSION = @VERSION@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+pkgpyexecdir = @pkgpyexecdir@
+pkgpythondir = @pkgpythondir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+pyexecdir = @pyexecdir@
+pythondir = @pythondir@
+runstatedir = @runstatedir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+AM_CPPFLAGS = $(GCC_CFLAGS) -I$(top_srcdir) -I$(top_srcdir)/include -I$(top_srcdir)/libevdev
+libevdev_ldadd = $(top_builddir)/libevdev/libevdev.la
+libevdev_events_SOURCES = libevdev-events.c
+libevdev_events_LDADD = $(libevdev_ldadd)
+libevdev_list_codes_SOURCES = libevdev-list-codes.c
+libevdev_list_codes_LDADD = $(libevdev_ldadd)
+touchpad_edge_detector_SOURCES = touchpad-edge-detector.c
+touchpad_edge_detector_LDADD = $(libevdev_ldadd)
+mouse_dpi_tool_SOURCES = mouse-dpi-tool.c
+mouse_dpi_tool_LDADD = $(libevdev_ldadd)
+libevdev_tweak_device_SOURCES = libevdev-tweak-device.c
+libevdev_tweak_device_LDADD = $(libevdev_ldadd)
+dist_man_MANS = \
+		libevdev-tweak-device.1 \
+		mouse-dpi-tool.1 \
+		touchpad-edge-detector.1 \
+		$(NULL)
+
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .lo .o .obj
+$(srcdir)/Makefile.in:  $(srcdir)/Makefile.am  $(am__configure_deps)
+	@for dep in $?; do \
+	  case '$(am__configure_deps)' in \
+	    *$$dep*) \
+	      ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+	        && { if test -f $@; then exit 0; else break; fi; }; \
+	      exit 1;; \
+	  esac; \
+	done; \
+	echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign tools/Makefile'; \
+	$(am__cd) $(top_srcdir) && \
+	  $(AUTOMAKE) --foreign tools/Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+	@case '$?' in \
+	  *config.status*) \
+	    cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+	  *) \
+	    echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \
+	    cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \
+	esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure:  $(am__configure_deps)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4):  $(am__aclocal_m4_deps)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+install-binPROGRAMS: $(bin_PROGRAMS)
+	@$(NORMAL_INSTALL)
+	@list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \
+	if test -n "$$list"; then \
+	  echo " $(MKDIR_P) '$(DESTDIR)$(bindir)'"; \
+	  $(MKDIR_P) "$(DESTDIR)$(bindir)" || exit 1; \
+	fi; \
+	for p in $$list; do echo "$$p $$p"; done | \
+	sed 's/$(EXEEXT)$$//' | \
+	while read p p1; do if test -f $$p \
+	 || test -f $$p1 \
+	  ; then echo "$$p"; echo "$$p"; else :; fi; \
+	done | \
+	sed -e 'p;s,.*/,,;n;h' \
+	    -e 's|.*|.|' \
+	    -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \
+	sed 'N;N;N;s,\n, ,g' | \
+	$(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \
+	  { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \
+	    if ($$2 == $$4) files[d] = files[d] " " $$1; \
+	    else { print "f", $$3 "/" $$4, $$1; } } \
+	  END { for (d in files) print "f", d, files[d] }' | \
+	while read type dir files; do \
+	    if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \
+	    test -z "$$files" || { \
+	    echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(bindir)$$dir'"; \
+	    $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(bindir)$$dir" || exit $$?; \
+	    } \
+	; done
+
+uninstall-binPROGRAMS:
+	@$(NORMAL_UNINSTALL)
+	@list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \
+	files=`for p in $$list; do echo "$$p"; done | \
+	  sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \
+	      -e 's/$$/$(EXEEXT)/' \
+	`; \
+	test -n "$$list" || exit 0; \
+	echo " ( cd '$(DESTDIR)$(bindir)' && rm -f" $$files ")"; \
+	cd "$(DESTDIR)$(bindir)" && rm -f $$files
+
+clean-binPROGRAMS:
+	@list='$(bin_PROGRAMS)'; test -n "$$list" || exit 0; \
+	echo " rm -f" $$list; \
+	rm -f $$list || exit $$?; \
+	test -n "$(EXEEXT)" || exit 0; \
+	list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \
+	echo " rm -f" $$list; \
+	rm -f $$list
+
+clean-noinstPROGRAMS:
+	@list='$(noinst_PROGRAMS)'; test -n "$$list" || exit 0; \
+	echo " rm -f" $$list; \
+	rm -f $$list || exit $$?; \
+	test -n "$(EXEEXT)" || exit 0; \
+	list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \
+	echo " rm -f" $$list; \
+	rm -f $$list
+
+libevdev-events$(EXEEXT): $(libevdev_events_OBJECTS) $(libevdev_events_DEPENDENCIES) $(EXTRA_libevdev_events_DEPENDENCIES) 
+	@rm -f libevdev-events$(EXEEXT)
+	$(AM_V_CCLD)$(LINK) $(libevdev_events_OBJECTS) $(libevdev_events_LDADD) $(LIBS)
+
+libevdev-list-codes$(EXEEXT): $(libevdev_list_codes_OBJECTS) $(libevdev_list_codes_DEPENDENCIES) $(EXTRA_libevdev_list_codes_DEPENDENCIES) 
+	@rm -f libevdev-list-codes$(EXEEXT)
+	$(AM_V_CCLD)$(LINK) $(libevdev_list_codes_OBJECTS) $(libevdev_list_codes_LDADD) $(LIBS)
+
+libevdev-tweak-device$(EXEEXT): $(libevdev_tweak_device_OBJECTS) $(libevdev_tweak_device_DEPENDENCIES) $(EXTRA_libevdev_tweak_device_DEPENDENCIES) 
+	@rm -f libevdev-tweak-device$(EXEEXT)
+	$(AM_V_CCLD)$(LINK) $(libevdev_tweak_device_OBJECTS) $(libevdev_tweak_device_LDADD) $(LIBS)
+
+mouse-dpi-tool$(EXEEXT): $(mouse_dpi_tool_OBJECTS) $(mouse_dpi_tool_DEPENDENCIES) $(EXTRA_mouse_dpi_tool_DEPENDENCIES) 
+	@rm -f mouse-dpi-tool$(EXEEXT)
+	$(AM_V_CCLD)$(LINK) $(mouse_dpi_tool_OBJECTS) $(mouse_dpi_tool_LDADD) $(LIBS)
+
+touchpad-edge-detector$(EXEEXT): $(touchpad_edge_detector_OBJECTS) $(touchpad_edge_detector_DEPENDENCIES) $(EXTRA_touchpad_edge_detector_DEPENDENCIES) 
+	@rm -f touchpad-edge-detector$(EXEEXT)
+	$(AM_V_CCLD)$(LINK) $(touchpad_edge_detector_OBJECTS) $(touchpad_edge_detector_LDADD) $(LIBS)
+
+mostlyclean-compile:
+	-rm -f *.$(OBJEXT)
+
+distclean-compile:
+	-rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libevdev-events.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libevdev-list-codes.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libevdev-tweak-device.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mouse-dpi-tool.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/touchpad-edge-detector.Po@am__quote@ # am--include-marker
+
+$(am__depfiles_remade):
+	@$(MKDIR_P) $(@D)
+	@echo '# dummy' >$@-t && $(am__mv) $@-t $@
+
+am--depfiles: $(am__depfiles_remade)
+
+.c.o:
+@am__fastdepCC_TRUE@	$(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\
+@am__fastdepCC_TRUE@	$(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
+@am__fastdepCC_TRUE@	$(am__mv) $$depbase.Tpo $$depbase.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $<
+
+.c.obj:
+@am__fastdepCC_TRUE@	$(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\
+@am__fastdepCC_TRUE@	$(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\
+@am__fastdepCC_TRUE@	$(am__mv) $$depbase.Tpo $$depbase.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
+
+.c.lo:
+@am__fastdepCC_TRUE@	$(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\
+@am__fastdepCC_TRUE@	$(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
+@am__fastdepCC_TRUE@	$(am__mv) $$depbase.Tpo $$depbase.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $<
+
+mostlyclean-libtool:
+	-rm -f *.lo
+
+clean-libtool:
+	-rm -rf .libs _libs
+install-man1: $(dist_man_MANS)
+	@$(NORMAL_INSTALL)
+	@list1=''; \
+	list2='$(dist_man_MANS)'; \
+	test -n "$(man1dir)" \
+	  && test -n "`echo $$list1$$list2`" \
+	  || exit 0; \
+	echo " $(MKDIR_P) '$(DESTDIR)$(man1dir)'"; \
+	$(MKDIR_P) "$(DESTDIR)$(man1dir)" || exit 1; \
+	{ for i in $$list1; do echo "$$i"; done;  \
+	if test -n "$$list2"; then \
+	  for i in $$list2; do echo "$$i"; done \
+	    | sed -n '/\.1[a-z]*$$/p'; \
+	fi; \
+	} | while read p; do \
+	  if test -f $$p; then d=; else d="$(srcdir)/"; fi; \
+	  echo "$$d$$p"; echo "$$p"; \
+	done | \
+	sed -e 'n;s,.*/,,;p;h;s,.*\.,,;s,^[^1][0-9a-z]*$$,1,;x' \
+	      -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,' | \
+	sed 'N;N;s,\n, ,g' | { \
+	list=; while read file base inst; do \
+	  if test "$$base" = "$$inst"; then list="$$list $$file"; else \
+	    echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man1dir)/$$inst'"; \
+	    $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man1dir)/$$inst" || exit $$?; \
+	  fi; \
+	done; \
+	for i in $$list; do echo "$$i"; done | $(am__base_list) | \
+	while read files; do \
+	  test -z "$$files" || { \
+	    echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man1dir)'"; \
+	    $(INSTALL_DATA) $$files "$(DESTDIR)$(man1dir)" || exit $$?; }; \
+	done; }
+
+uninstall-man1:
+	@$(NORMAL_UNINSTALL)
+	@list=''; test -n "$(man1dir)" || exit 0; \
+	files=`{ for i in $$list; do echo "$$i"; done; \
+	l2='$(dist_man_MANS)'; for i in $$l2; do echo "$$i"; done | \
+	  sed -n '/\.1[a-z]*$$/p'; \
+	} | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^1][0-9a-z]*$$,1,;x' \
+	      -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \
+	dir='$(DESTDIR)$(man1dir)'; $(am__uninstall_files_from_dir)
+
+ID: $(am__tagged_files)
+	$(am__define_uniq_tagged_files); mkid -fID $$unique
+tags: tags-am
+TAGS: tags
+
+tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+	set x; \
+	here=`pwd`; \
+	$(am__define_uniq_tagged_files); \
+	shift; \
+	if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+	  test -n "$$unique" || unique=$$empty_fix; \
+	  if test $$# -gt 0; then \
+	    $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+	      "$$@" $$unique; \
+	  else \
+	    $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+	      $$unique; \
+	  fi; \
+	fi
+ctags: ctags-am
+
+CTAGS: ctags
+ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+	$(am__define_uniq_tagged_files); \
+	test -z "$(CTAGS_ARGS)$$unique" \
+	  || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+	     $$unique
+
+GTAGS:
+	here=`$(am__cd) $(top_builddir) && pwd` \
+	  && $(am__cd) $(top_srcdir) \
+	  && gtags -i $(GTAGS_ARGS) "$$here"
+cscopelist: cscopelist-am
+
+cscopelist-am: $(am__tagged_files)
+	list='$(am__tagged_files)'; \
+	case "$(srcdir)" in \
+	  [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
+	  *) sdir=$(subdir)/$(srcdir) ;; \
+	esac; \
+	for i in $$list; do \
+	  if test -f "$$i"; then \
+	    echo "$(subdir)/$$i"; \
+	  else \
+	    echo "$$sdir/$$i"; \
+	  fi; \
+	done >> $(top_builddir)/cscope.files
+
+distclean-tags:
+	-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+distdir: $(BUILT_SOURCES)
+	$(MAKE) $(AM_MAKEFLAGS) distdir-am
+
+distdir-am: $(DISTFILES)
+	@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+	topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+	list='$(DISTFILES)'; \
+	  dist_files=`for file in $$list; do echo $$file; done | \
+	  sed -e "s|^$$srcdirstrip/||;t" \
+	      -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+	case $$dist_files in \
+	  */*) $(MKDIR_P) `echo "$$dist_files" | \
+			   sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+			   sort -u` ;; \
+	esac; \
+	for file in $$dist_files; do \
+	  if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+	  if test -d $$d/$$file; then \
+	    dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+	    if test -d "$(distdir)/$$file"; then \
+	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+	    fi; \
+	    if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+	      cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+	    fi; \
+	    cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+	  else \
+	    test -f "$(distdir)/$$file" \
+	    || cp -p $$d/$$file "$(distdir)/$$file" \
+	    || exit 1; \
+	  fi; \
+	done
+check-am: all-am
+check: check-am
+all-am: Makefile $(PROGRAMS) $(MANS)
+installdirs:
+	for dir in "$(DESTDIR)$(bindir)" "$(DESTDIR)$(man1dir)"; do \
+	  test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+	done
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+	@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+	if test -z '$(STRIP)'; then \
+	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	      install; \
+	else \
+	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	    "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+	fi
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+	-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+	-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+	@echo "This command is intended for maintainers to use"
+	@echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-binPROGRAMS clean-generic clean-libtool \
+	clean-noinstPROGRAMS mostlyclean-am
+
+distclean: distclean-am
+		-rm -f ./$(DEPDIR)/libevdev-events.Po
+	-rm -f ./$(DEPDIR)/libevdev-list-codes.Po
+	-rm -f ./$(DEPDIR)/libevdev-tweak-device.Po
+	-rm -f ./$(DEPDIR)/mouse-dpi-tool.Po
+	-rm -f ./$(DEPDIR)/touchpad-edge-detector.Po
+	-rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+	distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am: install-man
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am: install-binPROGRAMS
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man: install-man1
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+		-rm -f ./$(DEPDIR)/libevdev-events.Po
+	-rm -f ./$(DEPDIR)/libevdev-list-codes.Po
+	-rm -f ./$(DEPDIR)/libevdev-tweak-device.Po
+	-rm -f ./$(DEPDIR)/mouse-dpi-tool.Po
+	-rm -f ./$(DEPDIR)/touchpad-edge-detector.Po
+	-rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+	mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-binPROGRAMS uninstall-man
+
+uninstall-man: uninstall-man1
+
+.MAKE: install-am install-strip
+
+.PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \
+	clean-binPROGRAMS clean-generic clean-libtool \
+	clean-noinstPROGRAMS cscopelist-am ctags ctags-am distclean \
+	distclean-compile distclean-generic distclean-libtool \
+	distclean-tags distdir dvi dvi-am html html-am info info-am \
+	install install-am install-binPROGRAMS install-data \
+	install-data-am install-dvi install-dvi-am install-exec \
+	install-exec-am install-html install-html-am install-info \
+	install-info-am install-man install-man1 install-pdf \
+	install-pdf-am install-ps install-ps-am install-strip \
+	installcheck installcheck-am installdirs maintainer-clean \
+	maintainer-clean-generic mostlyclean mostlyclean-compile \
+	mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+	tags tags-am uninstall uninstall-am uninstall-binPROGRAMS \
+	uninstall-man uninstall-man1
+
+.PRECIOUS: Makefile
+
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/tools/libevdev-events.c b/tools/libevdev-events.c
new file mode 100644
index 0000000000000000000000000000000000000000..f82277fc12154b1dbd386e4010a53557184a44ac
--- /dev/null
+++ b/tools/libevdev-events.c
@@ -0,0 +1,178 @@
+// SPDX-License-Identifier: MIT
+/*
+ * Copyright © 2013 Red Hat, Inc.
+ */
+
+#include "config.h"
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "libevdev/libevdev.h"
+
+static void
+print_abs_bits(struct libevdev *dev, int axis)
+{
+	const struct input_absinfo *abs;
+
+	if (!libevdev_has_event_code(dev, EV_ABS, axis))
+		return;
+
+	abs = libevdev_get_abs_info(dev, axis);
+
+	printf("	Value	%6d\n", abs->value);
+	printf("	Min	%6d\n", abs->minimum);
+	printf("	Max	%6d\n", abs->maximum);
+	if (abs->fuzz)
+		printf("	Fuzz	%6d\n", abs->fuzz);
+	if (abs->flat)
+		printf("	Flat	%6d\n", abs->flat);
+	if (abs->resolution)
+		printf("	Resolution	%6d\n", abs->resolution);
+}
+
+static void
+print_code_bits(struct libevdev *dev, unsigned int type, unsigned int max)
+{
+	unsigned int i;
+	for (i = 0; i <= max; i++) {
+		if (!libevdev_has_event_code(dev, type, i))
+			continue;
+
+		printf("    Event code %i (%s)\n", i, libevdev_event_code_get_name(type, i));
+		if (type == EV_ABS)
+			print_abs_bits(dev, i);
+	}
+}
+
+static void
+print_bits(struct libevdev *dev)
+{
+	unsigned int i;
+	printf("Supported events:\n");
+
+	for (i = 0; i <= EV_MAX; i++) {
+		if (libevdev_has_event_type(dev, i))
+			printf("  Event type %d (%s)\n", i, libevdev_event_type_get_name(i));
+		switch(i) {
+			case EV_KEY:
+				print_code_bits(dev, EV_KEY, KEY_MAX);
+				break;
+			case EV_REL:
+				print_code_bits(dev, EV_REL, REL_MAX);
+				break;
+			case EV_ABS:
+				print_code_bits(dev, EV_ABS, ABS_MAX);
+				break;
+			case EV_LED:
+				print_code_bits(dev, EV_LED, LED_MAX);
+				break;
+		}
+	}
+}
+
+static void
+print_props(struct libevdev *dev)
+{
+	unsigned int i;
+	printf("Properties:\n");
+
+	for (i = 0; i <= INPUT_PROP_MAX; i++) {
+		if (libevdev_has_property(dev, i))
+			printf("  Property type %d (%s)\n", i,
+					libevdev_property_get_name(i));
+	}
+}
+
+static int
+print_event(struct input_event *ev)
+{
+	if (ev->type == EV_SYN)
+		printf("Event: time %ld.%06ld, ++++++++++++++++++++ %s +++++++++++++++\n",
+				ev->input_event_sec,
+				ev->input_event_usec,
+				libevdev_event_type_get_name(ev->type));
+	else
+		printf("Event: time %ld.%06ld, type %d (%s), code %d (%s), value %d\n",
+			ev->input_event_sec,
+			ev->input_event_usec,
+			ev->type,
+			libevdev_event_type_get_name(ev->type),
+			ev->code,
+			libevdev_event_code_get_name(ev->type, ev->code),
+			ev->value);
+	return 0;
+}
+
+static int
+print_sync_event(struct input_event *ev)
+{
+	printf("SYNC: ");
+	print_event(ev);
+	return 0;
+}
+
+int
+main(int argc, char **argv)
+{
+	struct libevdev *dev = NULL;
+	const char *file;
+	int fd;
+	int rc = 1;
+
+	if (argc < 2)
+		goto out;
+
+	file = argv[1];
+	fd = open(file, O_RDONLY);
+	if (fd < 0) {
+		perror("Failed to open device");
+		goto out;
+	}
+
+	rc = libevdev_new_from_fd(fd, &dev);
+	if (rc < 0) {
+		fprintf(stderr, "Failed to init libevdev (%s)\n", strerror(-rc));
+		goto out;
+	}
+
+	printf("Input device ID: bus %#x vendor %#x product %#x\n",
+			libevdev_get_id_bustype(dev),
+			libevdev_get_id_vendor(dev),
+			libevdev_get_id_product(dev));
+	printf("Evdev version: %x\n", libevdev_get_driver_version(dev));
+	printf("Input device name: \"%s\"\n", libevdev_get_name(dev));
+	printf("Phys location: %s\n", libevdev_get_phys(dev));
+	printf("Uniq identifier: %s\n", libevdev_get_uniq(dev));
+	print_bits(dev);
+	print_props(dev);
+
+	do {
+		struct input_event ev;
+		rc = libevdev_next_event(dev, LIBEVDEV_READ_FLAG_NORMAL|LIBEVDEV_READ_FLAG_BLOCKING, &ev);
+		if (rc == LIBEVDEV_READ_STATUS_SYNC) {
+			printf("::::::::::::::::::::: dropped ::::::::::::::::::::::\n");
+			while (rc == LIBEVDEV_READ_STATUS_SYNC) {
+				print_sync_event(&ev);
+				rc = libevdev_next_event(dev, LIBEVDEV_READ_FLAG_SYNC, &ev);
+			}
+			printf("::::::::::::::::::::: re-synced ::::::::::::::::::::::\n");
+		} else if (rc == LIBEVDEV_READ_STATUS_SUCCESS)
+			print_event(&ev);
+	} while (rc == LIBEVDEV_READ_STATUS_SYNC || rc == LIBEVDEV_READ_STATUS_SUCCESS || rc == -EAGAIN);
+
+	if (rc != LIBEVDEV_READ_STATUS_SUCCESS && rc != -EAGAIN)
+		fprintf(stderr, "Failed to handle events: %s\n", strerror(-rc));
+
+	rc = 0;
+out:
+	libevdev_free(dev);
+
+	return rc;
+}
diff --git a/tools/libevdev-list-codes.c b/tools/libevdev-list-codes.c
new file mode 100644
index 0000000000000000000000000000000000000000..8d4f7c29e74055112cd78cc5a8502ac8cddf5353
--- /dev/null
+++ b/tools/libevdev-list-codes.c
@@ -0,0 +1,47 @@
+// SPDX-License-Identifier: MIT
+/*
+ * Copyright © 2021 Red Hat, Inc.
+ */
+
+/* Lists all event types and codes currently known by libevdev. */
+
+#include "config.h"
+
+#include 
+#include 
+#include "libevdev/libevdev.h"
+
+static void
+list_event_codes(unsigned int type, unsigned int max)
+{
+	const char *typestr = libevdev_event_type_get_name(type);
+
+	if (!typestr)
+		return;
+
+	printf("- %s:\n", typestr);
+
+	for (unsigned int code = 0; code <= max; code++) {
+		const char *str = libevdev_event_code_get_name(type, code);
+
+		if (!str)
+			continue;
+
+		printf("    %d: %s\n", code, str);
+	}
+}
+
+int
+main (int argc, char **argv)
+{
+	printf("codes:\n");
+	for (unsigned int type = 0; type <= EV_MAX; type++) {
+		int max = libevdev_event_type_get_max(type);
+		if (max == -1)
+			continue;
+
+		list_event_codes(type, (unsigned int)max);
+	}
+
+	return 0;
+}
diff --git a/tools/libevdev-tweak-device.1 b/tools/libevdev-tweak-device.1
new file mode 100644
index 0000000000000000000000000000000000000000..bb33387e70d52564e34b317a11f7ada846030be9
--- /dev/null
+++ b/tools/libevdev-tweak-device.1
@@ -0,0 +1,69 @@
+.TH LIBEVDEV-TWEAK-DEVICE "1"
+.SH NAME
+libevdev-tweak-device \- modify an evdev kernel device
+.SH SYNOPSIS
+.B libevdev-tweak-device
+--abs ABS_X [--min a] [--max b] [--res c] [--fuzz d] [--flat e]
+/dev/input/eventX
+.B libevdev-tweak-device
+--resolution res[,yres] /dev/input/eventX
+.PP
+.B libevdev-tweak-device
+--led LED_NUML --on|--off /dev/input/eventX
+.SH DESCRIPTION
+.PP
+The
+.I libevdev-tweak-device
+tool changes the properties of the evdev kernel device at
+.I /dev/input/eventX.
+Currently this may be used to force an LED on or off, or to change the
+properties of an absolute axis (e.g. its minimum/maximum range or
+resolution). Changes are permanent until the device is removed.
+.SH OPTIONS
+.SS Changing absolute axes
+.TP 8
+.B --abs axis
+Change the given named ABS_ kernel axis, e.g. ABS_X. For a full list, see linux/input.h.
+Each of the options
+.B min, max, res, fuzz, flat
+may be given.
+.TP 8
+.B --min v
+Set the absinfo minimum to the value v
+.TP 8
+.B --max v
+Set the absinfo maximum to the value v
+.TP 8
+.B --res v
+Set the absinfo resolution to the value v
+.TP 8
+.B --fuzz v
+Set the absinfo fuzz to the value v
+.TP 8
+.B --flat v
+Set the absinfo flat to the value v
+.PP
+.SS Changing the x/y resolution
+.TP 8
+.B --resolution res[,yres]
+Changes the resolution of the ABS_X, ABS_MT_POSITION_X, ABS_Y, and
+ABS_MT_POSITION_Y axis to the given resolution. If only one resolution value
+is provided, both x and y axis are set to the same resolution, otherwise the
+first resolution value is applied to the x axes and the second value to the
+y axes.
+.SS Toggling LEDs
+.TP 8
+.B --led led
+Change the given LED, e.g. LED_NUML. For a full list, see linux/input.h.
+.TP 8
+.B --on
+Change the LED state to on
+.TP 8
+.B --off
+Change the LED state to off
+.SH NOTES
+.PP
+The kernel does not notify processes about absinfo property changes. Any
+process that has previously obtained the absinfo from the device will remain
+on the old information. This makes using this tool potentially racy, use
+with caution.
diff --git a/tools/libevdev-tweak-device.c b/tools/libevdev-tweak-device.c
new file mode 100644
index 0000000000000000000000000000000000000000..56b66125295be1b54b27dc019795e51ec1afec40
--- /dev/null
+++ b/tools/libevdev-tweak-device.c
@@ -0,0 +1,465 @@
+// SPDX-License-Identifier: MIT
+/*
+ * Copyright © 2014 Red Hat, Inc.
+ */
+
+#include "config.h"
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "libevdev/libevdev.h"
+
+static void
+usage(const char *progname)
+{
+	printf("%s --abs  [--min min] [--max max] [--res res] [--fuzz fuzz] [--flat flat] /dev/input/eventXYZ\n"
+	       "\tChange the absinfo struct for the named axis\n"
+	       "%s --resolution res[,yres] /dev/input/eventXYZ\n"
+	       "\tChange the x/y resolution on the given device\n"
+	       "%s --led  --on|--off /dev/input/eventXYZ\n"
+	       "\tEnable or disable the named LED\n",
+	       progname,
+	       progname,
+	       progname);
+}
+
+enum mode {
+	MODE_NONE = 0,
+	MODE_ABS,
+	MODE_LED,
+	MODE_RESOLUTION,
+	MODE_HELP,
+};
+
+enum opts {
+	OPT_ABS = 1 << 0,
+	OPT_MIN = 1 << 1,
+	OPT_MAX = 1 << 2,
+	OPT_FUZZ = 1 << 3,
+	OPT_FLAT = 1 << 4,
+	OPT_RES = 1 << 5,
+	OPT_LED = 1 << 6,
+	OPT_ON = 1 << 7,
+	OPT_OFF = 1 << 8,
+	OPT_RESOLUTION = 1 << 9,
+	OPT_HELP = 1 << 10,
+};
+
+static bool
+parse_resolution_argument(const char *arg, int *xres, int *yres)
+{
+	int matched;
+
+	matched = sscanf(arg, "%d,%d", xres, yres);
+
+	switch(matched) {
+		case 2:
+			break;
+		case 1:
+			*yres = *xres;
+			break;
+		default:
+			return false;
+	}
+
+	return true;
+}
+
+static inline bool
+safe_atoi(const char *str, int *val)
+{
+        char *endptr;
+        long v;
+
+        v = strtol(str, &endptr, 10);
+        if (str == endptr)
+                return false;
+        if (*str != '\0' && *endptr != '\0')
+                return false;
+
+        if (v > INT_MAX || v < INT_MIN)
+                return false;
+
+        *val = v;
+        return true;
+}
+
+static int
+parse_event_code(int type, const char *str)
+{
+	int code;
+
+	code = libevdev_event_code_from_name(type, str);
+	if (code != -1)
+		return code;
+
+	if (safe_atoi(str, &code))
+		return code;
+
+	return -1;
+}
+
+static int
+parse_options_abs(int argc, char **argv, unsigned int *changes,
+		  int *axis, struct input_absinfo *absinfo)
+{
+	int rc = 1;
+	int c;
+	int option_index = 0;
+	static struct option opts[] = {
+		{ "abs", 1, 0, OPT_ABS },
+		{ "min", 1, 0, OPT_MIN },
+		{ "max", 1, 0, OPT_MAX },
+		{ "fuzz", 1, 0, OPT_FUZZ },
+		{ "flat", 1, 0, OPT_FLAT },
+		{ "res", 1, 0, OPT_RES },
+		{ NULL, 0, 0, 0 },
+	};
+
+	if (argc < 2)
+		goto error;
+
+	optind = 1;
+	while (1) {
+		c = getopt_long(argc, argv, "h", opts, &option_index);
+		if (c == -1)
+			break;
+
+		switch (c) {
+			case OPT_ABS:
+				*axis = parse_event_code(EV_ABS, optarg);
+				if (*axis == -1)
+					goto error;
+				break;
+			case OPT_MIN:
+				absinfo->minimum = atoi(optarg);
+				break;
+			case OPT_MAX:
+				absinfo->maximum = atoi(optarg);
+				break;
+			case OPT_FUZZ:
+				absinfo->fuzz = atoi(optarg);
+				break;
+			case OPT_FLAT:
+				absinfo->flat = atoi(optarg);
+				break;
+			case OPT_RES:
+				absinfo->resolution = atoi(optarg);
+				break;
+			default:
+				goto error;
+		}
+		*changes |= c;
+	}
+	rc = 0;
+error:
+	return rc;
+}
+
+static int
+parse_options_led(int argc, char **argv, int *led, int *led_state)
+{
+	int rc = 1;
+	int c;
+	int option_index = 0;
+	static struct option opts[] = {
+		{ "led", 1, 0, OPT_LED },
+		{ "on", 0, 0, OPT_ON },
+		{ "off", 0, 0, OPT_OFF },
+		{ NULL, 0, 0, 0 },
+	};
+
+	if (argc < 2)
+		goto error;
+
+	optind = 1;
+	while (1) {
+		c = getopt_long(argc, argv, "h", opts, &option_index);
+		if (c == -1)
+			break;
+
+		switch (c) {
+			case OPT_LED:
+				*led = parse_event_code(EV_LED, optarg);
+				if (*led == -1)
+					goto error;
+				break;
+			case OPT_ON:
+				if (*led_state != -1)
+					goto error;
+				*led_state = 1;
+				break;
+			case OPT_OFF:
+				if (*led_state != -1)
+					goto error;
+				*led_state = 0;
+				break;
+			default:
+				goto error;
+		}
+	}
+
+	rc = 0;
+error:
+	return rc;
+}
+
+static int
+parse_options_resolution(int argc, char **argv, int *xres, int *yres)
+{
+	int rc = 1;
+	int c;
+	int option_index = 0;
+	static struct option opts[] = {
+		{ "resolution", 1, 0, OPT_RESOLUTION },
+		{ NULL, 0, 0, 0 },
+	};
+
+	if (argc < 2)
+		goto error;
+
+	optind = 1;
+	while (1) {
+		c = getopt_long(argc, argv, "h", opts, &option_index);
+		if (c == -1)
+			break;
+
+		switch (c) {
+			case OPT_RESOLUTION:
+				if (!parse_resolution_argument(optarg,
+							       xres, yres))
+					goto error;
+				break;
+			default:
+				goto error;
+		}
+	}
+
+	rc = 0;
+error:
+	return rc;
+}
+
+static enum mode
+parse_options_mode(int argc, char **argv)
+{
+	int c;
+	int option_index = 0;
+	static const struct option opts[] = {
+		{ "abs", 1, 0, OPT_ABS },
+		{ "led", 1, 0, OPT_LED },
+		{ "resolution", 1, 0, OPT_RESOLUTION },
+		{ "help", 0, 0, OPT_HELP },
+		{ NULL, 0, 0, 0 },
+	};
+	enum mode mode = MODE_NONE;
+
+	if (argc < 2)
+		return mode;
+
+	while (mode == MODE_NONE) {
+		c = getopt_long(argc, argv, "h", opts, &option_index);
+		if (c == -1)
+			break;
+
+		switch (c) {
+			case 'h':
+			case OPT_HELP:
+				mode = MODE_HELP;
+				break;
+			case OPT_ABS:
+				mode = MODE_ABS;
+				break;
+			case OPT_LED:
+				mode = MODE_LED;
+				break;
+			case OPT_RESOLUTION:
+				mode = MODE_RESOLUTION;
+				break;
+			default:
+				break;
+		}
+	}
+
+	if (optind >= argc && mode != MODE_HELP)
+		return MODE_NONE;
+
+	return mode;
+}
+
+static void
+set_abs(struct libevdev *dev, unsigned int changes,
+	unsigned int axis, struct input_absinfo *absinfo)
+{
+	int rc;
+	struct input_absinfo abs;
+	const struct input_absinfo *a;
+
+	if ((a = libevdev_get_abs_info(dev, axis)) == NULL) {
+		fprintf(stderr,
+			"Device '%s' doesn't have axis %s\n",
+			libevdev_get_name(dev),
+			libevdev_event_code_get_name(EV_ABS, axis));
+		return;
+	}
+
+	abs = *a;
+	if (changes & OPT_MIN)
+		abs.minimum = absinfo->minimum;
+	if (changes & OPT_MAX)
+		abs.maximum = absinfo->maximum;
+	if (changes & OPT_FUZZ)
+		abs.fuzz = absinfo->fuzz;
+	if (changes & OPT_FLAT)
+		abs.flat = absinfo->flat;
+	if (changes & OPT_RES)
+		abs.resolution = absinfo->resolution;
+
+	rc = libevdev_kernel_set_abs_info(dev, axis, &abs);
+	if (rc != 0)
+		fprintf(stderr,
+			"Failed to set absinfo %s: %s",
+			libevdev_event_code_get_name(EV_ABS, axis),
+			strerror(-rc));
+}
+
+static void
+set_led(struct libevdev *dev, unsigned int led, int led_state)
+{
+	int rc;
+	enum libevdev_led_value state =
+		led_state ? LIBEVDEV_LED_ON : LIBEVDEV_LED_OFF;
+
+	if (!libevdev_has_event_code(dev, EV_LED, led)) {
+		fprintf(stderr,
+			"Device '%s' doesn't have %s\n",
+			libevdev_get_name(dev),
+			libevdev_event_code_get_name(EV_LED, led));
+		return;
+	}
+
+	rc = libevdev_kernel_set_led_value(dev, led, state);
+	if (rc != 0)
+		fprintf(stderr,
+			"Failed to set LED %s: %s",
+			libevdev_event_code_get_name(EV_LED, led),
+			strerror(-rc));
+}
+
+static void
+set_resolution(struct libevdev *dev, int xres, int yres)
+{
+	struct input_absinfo abs;
+
+	abs.resolution = xres;
+	if (libevdev_has_event_code(dev, EV_ABS, ABS_X))
+		set_abs(dev, OPT_RES, ABS_X, &abs);
+	if (libevdev_has_event_code(dev, EV_ABS, ABS_MT_POSITION_X))
+		set_abs(dev, OPT_RES, ABS_MT_POSITION_X, &abs);
+
+	abs.resolution = yres;
+	if (libevdev_has_event_code(dev, EV_ABS, ABS_Y))
+		set_abs(dev, OPT_RES, ABS_Y, &abs);
+	if (libevdev_has_event_code(dev, EV_ABS, ABS_MT_POSITION_Y))
+		set_abs(dev, OPT_RES, ABS_MT_POSITION_Y, &abs);
+}
+
+int
+main(int argc, char **argv)
+{
+	struct libevdev *dev = NULL;
+	int fd = -1;
+	int rc = EXIT_FAILURE;
+	enum mode mode;
+	const char *path;
+	struct input_absinfo absinfo;
+	int axis = -1;
+	int led = -1;
+	int led_state = -1;
+	unsigned int changes = 0; /* bitmask of changes */
+	int xres = 0,
+	    yres = 0;
+
+	mode = parse_options_mode(argc, argv);
+	switch (mode) {
+		case MODE_HELP:
+			rc = EXIT_SUCCESS;
+			/* fallthrough */
+		case MODE_NONE:
+			usage(basename(argv[0]));
+			goto out;
+		case MODE_ABS:
+			rc = parse_options_abs(argc, argv, &changes, &axis,
+					       &absinfo);
+			break;
+		case MODE_LED:
+			rc = parse_options_led(argc, argv, &led, &led_state);
+			break;
+		case MODE_RESOLUTION:
+			rc = parse_options_resolution(argc, argv, &xres,
+						      &yres);
+			break;
+		default:
+			fprintf(stderr,
+				"++?????++ Out of Cheese Error. Redo From Start.\n");
+			goto out;
+	}
+
+	if (rc != EXIT_SUCCESS)
+		goto out;
+
+	if (optind >= argc) {
+		rc = EXIT_FAILURE;
+		usage(basename(argv[0]));
+		goto out;
+	}
+
+	path = argv[optind];
+
+	fd = open(path, O_RDWR);
+	if (fd < 0) {
+		rc = EXIT_FAILURE;
+		perror("Failed to open device");
+		goto out;
+	}
+
+	rc = libevdev_new_from_fd(fd, &dev);
+	if (rc < 0) {
+		fprintf(stderr, "Failed to init libevdev (%s)\n", strerror(-rc));
+		goto out;
+	}
+
+	switch (mode) {
+		case MODE_ABS:
+			set_abs(dev, changes, axis, &absinfo);
+			break;
+		case MODE_LED:
+			set_led(dev, led, led_state);
+			break;
+		case MODE_RESOLUTION:
+			set_resolution(dev, xres, yres);
+			break;
+		default:
+			break;
+	}
+
+out:
+	libevdev_free(dev);
+	if (fd != -1)
+		close(fd);
+
+	return rc;
+}
diff --git a/tools/mouse-dpi-tool.1 b/tools/mouse-dpi-tool.1
new file mode 100644
index 0000000000000000000000000000000000000000..1629e0e52a821340d8327c98fa6e7b5adbc1d95b
--- /dev/null
+++ b/tools/mouse-dpi-tool.1
@@ -0,0 +1,18 @@
+.TH MOUSE-DPI-TOOL "1"
+.SH NAME
+mouse-dpi-tool \- mouse resolution estimation tool
+.SH SYNOPSIS
+.BR mouse-dpi-tool " <\fIevdev device\fP>"
+.SH DESCRIPTION
+.B mouse-dpi-tool
+reads relative events (mouse movement events) and calculates the
+distance covered and maximum frequency of the incoming events.
+Combined with a measurement of the actual distance physically covered,
+this allows the mouse's resolution to be estimated.
+.PP
+Some mouse devices provide dynamic frequencies, it is
+recommended to measure multiple times to obtain the highest value.
+.PP
+.SH OPTIONS
+.B mouse-dpi-tool
+accepts no options.
diff --git a/tools/mouse-dpi-tool.c b/tools/mouse-dpi-tool.c
new file mode 100644
index 0000000000000000000000000000000000000000..3c4608fc139fa78fa09e3f22a61d67caaa09dbf3
--- /dev/null
+++ b/tools/mouse-dpi-tool.c
@@ -0,0 +1,293 @@
+// SPDX-License-Identifier: MIT
+/*
+ * Copyright © 2014 Red Hat, Inc.
+ */
+
+#include "config.h"
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "libevdev/libevdev.h"
+
+#define min(a, b) (((a) < (b)) ? (a) : (b))
+#define max(a, b) (((a) > (b)) ? (a) : (b))
+
+static int signalled = 0;
+
+struct measurements {
+	int distance;
+	double max_frequency;
+	double *frequencies;
+	size_t frequencies_sz;
+	size_t nfrequencies;
+	uint64_t us;
+};
+
+static int
+usage(const char *progname) {
+	printf("Usage: %s /dev/input/event0\n", progname);
+	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"
+	       "Some mouse devices provide dynamic frequencies, it is\n"
+	       "recommended to measure multiple times to obtain the highest value.\n");
+	return 1;
+}
+
+static inline double
+get_frequency(uint64_t last, uint64_t current)
+{
+	return 1000000.0/(current - last);
+}
+
+static inline void
+push_frequency(struct measurements *m, double freq)
+{
+	if (m->nfrequencies == m->frequencies_sz) {
+		m->frequencies_sz += 100;
+		m->frequencies = realloc(m->frequencies,
+					 m->frequencies_sz * sizeof *m->frequencies);
+		if (!m->frequencies)
+			abort();
+	}
+
+	m->frequencies[m->nfrequencies] = freq;
+	m->nfrequencies++;
+}
+
+static int
+print_current_values(const struct measurements *m)
+{
+	static int progress = 0;
+	char status = 0;
+
+	switch (progress) {
+		case 0: status = '|'; break;
+		case 1: status = '/'; break;
+		case 2: status = '-'; break;
+		case 3: status = '\\'; break;
+		default:
+			status = '?';
+			break;
+	}
+
+	progress = (progress + 1) % 4;
+
+	printf("\rCovered distance in device units: %8d at frequency %3.1fHz 	%c",
+	       abs(m->distance), m->max_frequency, status);
+
+	return 0;
+}
+
+static int
+handle_event(struct measurements *m, const struct input_event *ev)
+{
+	if (ev->type == EV_SYN) {
+		const int idle_reset = 3000000; /* us */
+		uint64_t last_us = m->us;
+
+		m->us = ev->input_event_sec * 1000000 + ev->input_event_usec;
+
+		/* reset after pause */
+		if (last_us + idle_reset < m->us) {
+			m->max_frequency = 0.0;
+			m->distance = 0;
+		} else {
+			double freq = get_frequency(last_us, m->us);
+			push_frequency(m, freq);
+			m->max_frequency = max(freq, m->max_frequency);
+			return print_current_values(m);
+		}
+
+		return 0;
+	}
+
+	if (ev->type != EV_REL)
+		return 0;
+
+	switch(ev->code) {
+		case REL_X:
+			m->distance += ev->value;
+			break;
+	}
+
+	return 0;
+}
+
+static void
+signal_handler(__attribute__((__unused__)) int signal)
+{
+	signalled++;
+}
+
+static int
+mainloop(struct libevdev *dev, struct measurements *m) {
+	struct pollfd fds;
+
+	fds.fd = libevdev_get_fd(dev);
+	fds.events = POLLIN;
+
+	signal(SIGINT, signal_handler);
+
+	while (poll(&fds, 1, -1)) {
+		struct input_event ev;
+		int rc;
+
+		if (signalled)
+			break;
+
+		do {
+			rc = libevdev_next_event(dev, LIBEVDEV_READ_FLAG_NORMAL, &ev);
+			if (rc == LIBEVDEV_READ_STATUS_SYNC) {
+				fprintf(stderr, "Error: cannot keep up\n");
+				return 1;
+			}
+
+			if (rc != -EAGAIN && rc < 0) {
+				fprintf(stderr, "Error: %s\n", strerror(-rc));
+				return 1;
+			}
+
+			if (rc == LIBEVDEV_READ_STATUS_SUCCESS)
+				handle_event(m, &ev);
+		} while (rc != -EAGAIN);
+	}
+
+	return 0;
+}
+
+static inline double
+mean_frequency(struct measurements *m)
+{
+	int idx;
+
+	idx = m->nfrequencies/2;
+	return m->frequencies[idx];
+}
+
+static inline const char*
+bustype(int bustype)
+{
+	const char *bus;
+
+	switch(bustype) {
+		case BUS_PCI: bus = "pci"; break;
+		case BUS_ISAPNP: bus = "isapnp"; break;
+		case BUS_USB: bus = "usb"; break;
+		case BUS_HIL: bus = "hil"; break;
+		case BUS_BLUETOOTH: bus = "bluetooth"; break;
+		case BUS_VIRTUAL: bus = "virtual"; break;
+		default: bus = "unknown bus type"; break;
+	}
+
+	return bus;
+}
+
+static void
+print_summary(struct libevdev *dev, struct measurements *m)
+{
+	int res;
+	int max_freq, mean_freq;
+
+	if (m->nfrequencies == 0) {
+		fprintf(stderr, "Error: no matching events received.\n");
+		return;
+	}
+
+	max_freq = (int)m->max_frequency;
+	mean_freq = (int)mean_frequency(m);
+
+	printf("Estimated sampling frequency: %dHz (mean %dHz)\n",
+	       max_freq, mean_freq);
+
+	if (max_freq > mean_freq * 1.3)
+		printf("WARNING: Max frequency is more than 30%% higher "
+		       "than mean frequency. Manual verification required!\n");
+
+	printf("To calculate resolution, measure physical distance covered\n"
+	       "and look up the matching resolution in the table below\n");
+
+	m->distance = abs(m->distance);
+
+	/* If the mouse has more than 2500dpi, the manufacturer usually
+	   shows off on their website anyway */
+	for (res = 400; res <= 2500; res += 200) {
+		double inch = m->distance/(double)res;
+		printf("%8dmm	%8.2fin	%8ddpi\n",
+		       (int)(inch * 25.4), inch, res);
+	}
+	printf("If your resolution is not in the list, calculate it with:\n"
+	       "\tresolution=%d/inches, or\n"
+	       "\tresolution=%d * 25.4/mm\n", m->distance, m->distance);
+
+	printf("\n");
+	printf("Entry for hwdb match (replace XXX with the resolution in DPI):\n"
+	       "mouse:%s:v%04xp%04x:name:%s:\n"
+	       " MOUSE_DPI=XXX@%d\n",
+	       bustype(libevdev_get_id_bustype(dev)),
+	       libevdev_get_id_vendor(dev),
+	       libevdev_get_id_product(dev),
+	       libevdev_get_name(dev),
+	       (int)m->max_frequency);
+}
+
+int
+main (int argc, char **argv) {
+	int rc;
+	int fd;
+	const char *path;
+	struct libevdev *dev;
+	struct measurements measurements = {0};
+
+	if (argc < 2)
+		return usage(basename(argv[0]));
+
+	path = argv[1];
+	if (path[0] == '-')
+		return usage(basename(argv[0]));
+
+	fd = open(path, O_RDONLY|O_NONBLOCK);
+	if (fd < 0) {
+		fprintf(stderr, "Error opening the device: %s\n", strerror(errno));
+		return 1;
+	}
+
+	rc = libevdev_new_from_fd(fd, &dev);
+	if (rc != 0) {
+		fprintf(stderr, "Error fetching the device info: %s\n", strerror(-rc));
+		return 1;
+	}
+
+	if (libevdev_grab(dev, LIBEVDEV_GRAB) != 0) {
+		fprintf(stderr, "Error: cannot grab the device, something else is grabbing it.\n");
+		fprintf(stderr, "Use 'fuser -v %s' to find processes with an open fd\n", path);
+		return 1;
+	}
+	libevdev_grab(dev, LIBEVDEV_UNGRAB);
+
+	printf("Mouse %s on %s\n", libevdev_get_name(dev), path);
+	printf("Move the device 250mm/10in or more along the x-axis.\n");
+	printf("Pause 3 seconds before movement to reset, Ctrl+C to exit.\n");
+	setbuf(stdout, NULL);
+
+	rc = mainloop(dev, &measurements);
+
+	printf("\n");
+
+	print_summary(dev, &measurements);
+
+	libevdev_free(dev);
+	close(fd);
+
+	return rc;
+}
diff --git a/tools/touchpad-edge-detector.1 b/tools/touchpad-edge-detector.1
new file mode 100644
index 0000000000000000000000000000000000000000..e9a4b9cdda33fcca415445bf45ff67a7719303da
--- /dev/null
+++ b/tools/touchpad-edge-detector.1
@@ -0,0 +1,44 @@
+.TH TOUCHPAD-EDGE-DETECTOR "1"
+.SH NAME
+touchpad-edge-detector \- print the axis ranges for a touchpad device
+.SH SYNOPSIS
+.B touchpad-edge-detector [--help] \fIWxH /dev/input/eventX\fR
+.SH DESCRIPTION
+.PP
+The
+.B touchpad-edge-detector
+tool reads touchpad events from the kernel and records the minimum and
+maximum coordinates based on user input. This is an interactive tool, the
+user must move a finger around the touchpad, attempting to trigger an
+event at all edges of the touchpad.
+.PP
+To terminate the event collection and print a summary, press Ctrl+C. It is
+recommended that the tool is run several times to guarantee a reliable
+result.
+.SH OPTIONS
+.TP 8
+.I WxH
+The width and height of the touchpad in mm. For a touchpad 100mm wide and
+75mm high, the argument is thus \fI100x75\fR. This is a required argument.
+.TP 8
+.I /dev/input/eventX
+The event node of the touchpad to read events from. A list of possible event
+nodes can be obtained with either one of the following commands: \fBlibinput
+record\fR, \fBevemu-record\fR, or \fBevtest\fR. Alternatively the event node
+for a device is listed in the \fBHandlers=\fR line \fI/proc/bus/input/devices\fR.
+This is a required argument.
+.TP 8
+.B --help
+Print a short help description
+.SH NOTES
+.PP
+On completion, this tool prints a summary of the collected events and a
+suggested udev rule. Due to rounding errors it is rare to get an exact match
+for the touchpad's dimensions, but any discrepancy of more than 5mm should
+be corrected with the suggested udev rule.
+.PP
+The udev rule should be simplified and submitted as a pull request to the
+system repository at \fIhttps://github.com/systemd/systemd\fR. For further
+guidance, see the file \fI/usr/lib/udev/hwdb.d/60-evdev.hwdb\fR.
+.SH SEE ALSO
+udev(7)
diff --git a/tools/touchpad-edge-detector.c b/tools/touchpad-edge-detector.c
new file mode 100644
index 0000000000000000000000000000000000000000..c1e8224861a8b23d15aeb943813d2e774db9c07b
--- /dev/null
+++ b/tools/touchpad-edge-detector.c
@@ -0,0 +1,294 @@
+// SPDX-License-Identifier: MIT
+/*
+ * Copyright © 2014 Red Hat, Inc.
+ */
+
+#include "config.h"
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "libevdev/libevdev.h"
+
+#define min(a, b) (((a) < (b)) ? (a) : (b))
+#define max(a, b) (((a) > (b)) ? (a) : (b))
+
+static int signalled = 0;
+
+static int
+usage(const char *progname) {
+	printf("Usage: %s 12x34 /dev/input/eventX\n", progname);
+	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"
+	       "The first argument is the physical size of the touchpad in mm (WIDTHxHEIGHT).\n");
+	return 1;
+}
+
+struct dimensions {
+	int top, bottom, left, right;
+};
+
+struct size {
+	int w, h;
+};
+
+static int
+print_current_values(const struct dimensions *d)
+{
+	static int progress;
+	char status = 0;
+
+	switch (progress) {
+		case 0: status = '|'; break;
+		case 1: status = '/'; break;
+		case 2: status = '-'; break;
+		case 3: status = '\\'; break;
+	}
+
+	progress = (progress + 1) % 4;
+
+	printf("\rTouchpad sends:	x [%d..%d], y [%d..%d] %c",
+			d->left, d->right, d->top, d->bottom, status);
+	return 0;
+}
+
+static int
+handle_event(struct dimensions *d, const struct input_event *ev) {
+	if (ev->type == EV_SYN)
+		return print_current_values(d);
+
+	if (ev->type != EV_ABS)
+		return 0;
+
+	switch(ev->code) {
+		case ABS_X:
+		case ABS_MT_POSITION_X:
+			d->left = min(d->left, ev->value);
+			d->right = max(d->right, ev->value);
+			break;
+		case ABS_Y:
+		case ABS_MT_POSITION_Y:
+			d->top = min(d->top, ev->value);
+			d->bottom = max(d->bottom, ev->value);
+			break;
+	}
+
+	return 0;
+}
+
+static void
+signal_handler(__attribute__((__unused__)) int signal)
+{
+	signalled++;
+}
+
+static int
+mainloop(struct libevdev *dev, struct dimensions *dim) {
+	struct pollfd fds;
+
+	fds.fd = libevdev_get_fd(dev);
+	fds.events = POLLIN;
+
+	signal(SIGINT, signal_handler);
+
+	while (poll(&fds, 1, -1)) {
+		struct input_event ev;
+		int rc;
+
+		if (signalled)
+			break;
+
+		do {
+			rc = libevdev_next_event(dev, LIBEVDEV_READ_FLAG_NORMAL, &ev);
+			if (rc == LIBEVDEV_READ_STATUS_SYNC) {
+				fprintf(stderr, "Error: cannot keep up\n");
+				return 1;
+			}
+
+			if (rc != -EAGAIN && rc < 0) {
+				fprintf(stderr, "Error: %s\n", strerror(-rc));
+				return 1;
+
+			}
+
+			if (rc == LIBEVDEV_READ_STATUS_SUCCESS)
+				handle_event(dim, &ev);
+		} while (rc != -EAGAIN);
+	}
+
+	return 0;
+}
+
+static inline void
+pid_vid_matchstr(struct libevdev *dev, char *match, size_t sz)
+{
+	snprintf(match, sz, "input:b%04Xv%04Xp%04X",
+		libevdev_get_id_bustype(dev),
+		libevdev_get_id_vendor(dev),
+		libevdev_get_id_product(dev));
+}
+
+static inline void
+dmi_matchstr(struct libevdev *dev, char *match, size_t sz)
+{
+	char modalias[PATH_MAX];
+	FILE *fp;
+
+	fp = fopen("/sys/class/dmi/id/modalias", "r");
+	if (!fp || fgets(modalias, sizeof(modalias), fp) == NULL) {
+		sprintf(match, "ERROR READING DMI MODALIAS");
+		if (fp)
+			fclose(fp);
+		return;
+	}
+
+	fclose(fp);
+
+	modalias[strlen(modalias) - 1] = '\0'; /* drop \n */
+	snprintf(match, sz, "name:%s:%s", libevdev_get_name(dev), modalias);
+}
+
+static void
+print_udev_override_rule(struct libevdev *dev,
+			 const struct dimensions *dim,
+			 const struct size *size) {
+	const struct input_absinfo *x, *y;
+	char match[PATH_MAX];
+	int w, h;
+	int xres, yres;
+
+	x = libevdev_get_abs_info(dev, ABS_X);
+	y = libevdev_get_abs_info(dev, ABS_Y);
+	w = dim->right - dim->left;
+	h = dim->bottom - dim->top;
+	xres = round((double)w/size->w);
+	yres = round((double)h/size->h);
+
+	if (x->resolution && y->resolution) {
+		int width = x->maximum - x->minimum,
+		    height = y->maximum - y->minimum;
+		printf("Touchpad size as listed by the kernel: %dx%dmm\n",
+		       width/x->resolution, height/y->resolution);
+	} else {
+		printf("Touchpad has no resolution, size unknown\n");
+	}
+
+	printf("User-specified touchpad size: %dx%dmm\n", size->w, size->h);
+	printf("Calculated ranges: %d/%d\n", w, h);
+	printf("\n");
+	printf("Suggested udev rule:\n");
+
+	switch(libevdev_get_id_bustype(dev)) {
+	case BUS_USB:
+	case BUS_BLUETOOTH:
+		pid_vid_matchstr(dev, match, sizeof(match));
+		break;
+	default:
+		dmi_matchstr(dev, match, sizeof(match));
+		break;
+	}
+
+	printf("# \n"
+	       "evdev:%s*\n"
+	       " EVDEV_ABS_00=%d:%d:%d\n"
+	       " EVDEV_ABS_01=%d:%d:%d\n",
+	       match,
+	       dim->left, dim->right, xres,
+	       dim->top, dim->bottom, yres);
+	if (libevdev_has_event_code(dev, EV_ABS, ABS_MT_POSITION_X))
+		printf(" EVDEV_ABS_35=%d:%d:%d\n"
+		       " EVDEV_ABS_36=%d:%d:%d\n",
+		       dim->left, dim->right, xres,
+		       dim->top, dim->bottom, yres);
+}
+
+int main (int argc, char **argv) {
+	int rc;
+	int fd;
+	const char *path;
+	struct libevdev *dev;
+	struct dimensions dim;
+	struct size size;
+
+	if (argc < 3)
+		return usage(basename(argv[0]));
+
+	if (sscanf(argv[1], "%dx%d", &size.w, &size.h) != 2 ||
+	    size.w <= 0 || size.h <= 0)
+		return usage(basename(argv[0]));
+
+	if (size.w < 30 || size.h < 30) {
+		fprintf(stderr,
+			"%dx%dmm is too small for a touchpad.\n"
+			"Please specify the touchpad size in mm.\n",
+			size.w, size.h);
+		return 1;
+	}
+
+	path = argv[2];
+	if (path[0] == '-')
+		return usage(basename(argv[0]));
+
+	fd = open(path, O_RDONLY|O_NONBLOCK);
+	if (fd < 0) {
+		fprintf(stderr, "Error opening the device: %s\n", strerror(errno));
+		return 1;
+	}
+
+	rc = libevdev_new_from_fd(fd, &dev);
+	if (rc != 0) {
+		fprintf(stderr, "Error fetching the device info: %s\n", strerror(-rc));
+		return 1;
+	}
+
+	if (libevdev_grab(dev, LIBEVDEV_GRAB) != 0) {
+		fprintf(stderr, "Error: cannot grab the device, something else is grabbing it.\n");
+		fprintf(stderr, "Use 'fuser -v %s' to find processes with an open fd\n", path);
+		return 1;
+	}
+	libevdev_grab(dev, LIBEVDEV_UNGRAB);
+
+	if (!libevdev_has_event_code(dev, EV_ABS, ABS_X) ||
+	    !libevdev_has_event_code(dev, EV_ABS, ABS_Y)) {
+		fprintf(stderr, "Error: this device does not have abs axes\n");
+		rc = EXIT_FAILURE;
+		goto out;
+	}
+
+	dim.left = INT_MAX;
+	dim.right = INT_MIN;
+	dim.top = INT_MAX;
+	dim.bottom = INT_MIN;
+
+	printf("Touchpad %s on %s\n", libevdev_get_name(dev), path);
+	printf("Move one finger around the touchpad to detect the actual edges\n");
+	printf("Kernel says:	x [%d..%d], y [%d..%d]\n",
+			libevdev_get_abs_minimum(dev, ABS_X),
+			libevdev_get_abs_maximum(dev, ABS_X),
+			libevdev_get_abs_minimum(dev, ABS_Y),
+			libevdev_get_abs_maximum(dev, ABS_Y));
+
+	setbuf(stdout, NULL);
+
+	rc = mainloop(dev, &dim);
+	printf("\n\n");
+
+	print_udev_override_rule(dev, &dim, &size);
+
+out:
+	libevdev_free(dev);
+	close(fd);
+
+	return rc;
+}