.vimdir
ylwrap
# Application Specific Files
+*.trs
+*.log
+*.sig
AC_PREREQ([2.62])
AC_INIT([libevdev],
- [1.2.2],
+ [1.5.4],
[https://bugs.freedesktop.org/enter_bug.cgi?product=libevdev],
[libevdev],
[http://freedesktop.org/wiki/Software/libevdev/])
# - If binary compatibility has been broken (eg removed or changed interfaces)
# change to C+1:0:0
# - If the interface is the same as the previous version, change to C:R+1:A
-LIBEVDEV_LT_VERSION=2:3:0
+LIBEVDEV_LT_VERSION=3:16:1
AC_SUBST(LIBEVDEV_LT_VERSION)
fi
AC_SUBST([GNU_LD_FLAGS], $with_ldflags)
+AC_CHECK_LIB([m], [round])
+
PKG_PROG_PKG_CONFIG()
PKG_CHECK_MODULES(CHECK, [check >= 0.9.9], [HAVE_CHECK="yes"], [HAVE_CHECK="no"])
if test "x$HAVE_CHECK" = "xyes"; then
AC_MSG_WARN([check not found - skipping building unit tests])
fi
AM_CONDITIONAL(HAVE_VALGRIND, [test "x$VALGRIND" != "x"])
-AM_CONDITIONAL(BUILD_TESTS, [test "x$HAVE_CHECK" = "xyes"])
+AM_CONDITIONAL(ENABLE_RUNTIME_TESTS, [test "x$HAVE_CHECK" = "xyes"])
+AM_CONDITIONAL(ENABLE_STATIC_LINK_TEST, [test "x$enable_static" = "xyes"])
with_cflags=""
if test "x$GCC" = "xyes"; then
enable_gcov=yes
],
)
-
-AM_PATH_PYTHON([2.6])
-
AM_CONDITIONAL([GCOV_ENABLED], [test "x$enable_gcov" != "xno"])
AC_SUBST([GCOV_CFLAGS])
AC_SUBST([GCOV_LDFLAGS])
AC_MSG_RESULT([$enable_gcov])
+AM_PATH_PYTHON([2.6])
+AC_PATH_PROG(CAT, [cat])
+
+# nm to check for leaking symbols in the static library
+AC_PATH_PROG(NM, [nm])
+AM_CONDITIONAL(HAVE_NM, [test "x$NM" != "x"])
+if test "x$enable_static" = "xno"; then
+ static_symbol_leaks_test="no - static build disabled"
+else
+ if test "x$NM" = "x"; then
+ AC_MSG_WARN([nm not found - skipping symbol leak test])
+ have_nm="no"
+ static_symbol_leaks_test="no - nm not found"
+ else
+ have_nm="yes"
+ static_symbol_leaks_test="yes"
+ fi
+fi
+
+AM_CONDITIONAL(ENABLE_STATIC_SYMBOL_LEAKS_TEST, [test "x$static_symbol_leaks_test" = "xyes"])
+
AC_CONFIG_FILES([Makefile
libevdev/Makefile
doc/Makefile
AC_OUTPUT
AC_MSG_RESULT([
- Build documentation ${have_doxygen}
- Build unit-tests ${HAVE_CHECK}
- Enable profiling ${enable_gcov}
+ Prefix ${prefix}
+ Libdir ${libdir}
+
+ Build documentation ${have_doxygen}
+ Enable unit-tests ${HAVE_CHECK}
+ Enable profiling ${enable_gcov}
+ Static library symbol check ${static_symbol_leaks_test}
])
-# Doxyfile 1.8.3.1
-
-# This file describes the settings to be used by the documentation system
-# doxygen (www.doxygen.org) for a project.
-#
-# All text after a hash (#) is considered a comment and will be ignored.
-# The format is:
-# TAG = value [value, ...]
-# For lists items can also be appended using:
-# TAG += value [value, ...]
-# Values that contain spaces should be placed between quotes (" ").
-
-#---------------------------------------------------------------------------
-# Project related configuration options
-#---------------------------------------------------------------------------
-
-# This tag specifies the encoding used for all characters in the config file
-# that follow. The default is UTF-8 which is also the encoding used for all
-# text before the first occurrence of this tag. Doxygen uses libiconv (or the
-# iconv built into libc) for the transcoding. See
-# http://www.gnu.org/software/libiconv for the list of possible encodings.
-
-DOXYFILE_ENCODING = UTF-8
-
-# The PROJECT_NAME tag is a single word (or sequence of words) that should
-# identify the project. Note that if you do not use Doxywizard you need
-# to put quotes around the project name if it contains spaces.
-
PROJECT_NAME = @PACKAGE_NAME@
-
-# The PROJECT_NUMBER tag can be used to enter a project or revision number.
-# This could be handy for archiving the generated documentation or
-# if some version control system is used.
-
PROJECT_NUMBER = @PACKAGE_VERSION@
-
-# Using the PROJECT_BRIEF tag one can provide an optional one line description
-# for a project that appears at the top of each page and should give viewer
-# a quick idea about the purpose of the project. Keep the description short.
-
PROJECT_BRIEF = "A wrapper library for evdev devices"
-
-# With the PROJECT_LOGO tag one can specify an logo or icon that is
-# included in the documentation. The maximum height of the logo should not
-# exceed 55 pixels and the maximum width should not exceed 200 pixels.
-# Doxygen will copy the logo to the output directory.
-
-PROJECT_LOGO =
-
-# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute)
-# base path where the generated documentation will be put.
-# If a relative path is entered, it will be relative to the location
-# where doxygen was started. If left blank the current directory will be used.
-
-OUTPUT_DIRECTORY =
-
-# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create
-# 4096 sub-directories (in 2 levels) under the output directory of each output
-# format and will distribute the generated files over these directories.
-# Enabling this option can be useful when feeding doxygen a huge amount of
-# source files, where putting all generated files in the same directory would
-# otherwise cause performance problems for the file system.
-
-CREATE_SUBDIRS = NO
-
-# The OUTPUT_LANGUAGE tag is used to specify the language in which all
-# documentation generated by doxygen is written. Doxygen will use this
-# information to generate all constant output in the proper language.
-# The default language is English, other supported languages are:
-# Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional,
-# Croatian, Czech, Danish, Dutch, Esperanto, Farsi, Finnish, French, German,
-# Greek, Hungarian, Italian, Japanese, Japanese-en (Japanese with English
-# messages), Korean, Korean-en, Lithuanian, Norwegian, Macedonian, Persian,
-# Polish, Portuguese, Romanian, Russian, Serbian, Serbian-Cyrillic, Slovak,
-# Slovene, Spanish, Swedish, Ukrainian, and Vietnamese.
-
-OUTPUT_LANGUAGE = English
-
-# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will
-# include brief member descriptions after the members that are listed in
-# the file and class documentation (similar to JavaDoc).
-# Set to NO to disable this.
-
-BRIEF_MEMBER_DESC = YES
-
-# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend
-# the brief description of a member or function before the detailed description.
-# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the
-# brief descriptions will be completely suppressed.
-
-REPEAT_BRIEF = YES
-
-# This tag implements a quasi-intelligent brief description abbreviator
-# that is used to form the text in various listings. Each string
-# in this list, if found as the leading text of the brief description, will be
-# stripped from the text and the result after processing the whole list, is
-# used as the annotated text. Otherwise, the brief description is used as-is.
-# If left blank, the following values are used ("$name" is automatically
-# replaced with the name of the entity): "The $name class" "The $name widget"
-# "The $name file" "is" "provides" "specifies" "contains"
-# "represents" "a" "an" "the"
-
-ABBREVIATE_BRIEF =
-
-# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then
-# Doxygen will generate a detailed section even if there is only a brief
-# description.
-
-ALWAYS_DETAILED_SEC = NO
-
-# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all
-# inherited members of a class in the documentation of that class as if those
-# members were ordinary class members. Constructors, destructors and assignment
-# operators of the base classes will not be shown.
-
-INLINE_INHERITED_MEMB = NO
-
-# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full
-# path before files name in the file list and in the header files. If set
-# to NO the shortest path that makes the file name unique will be used.
-
-FULL_PATH_NAMES = YES
-
-# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag
-# can be used to strip a user-defined part of the path. Stripping is
-# only done if one of the specified strings matches the left-hand part of
-# the path. The tag can be used to show relative paths in the file list.
-# If left blank the directory from which doxygen is run is used as the
-# path to strip. Note that you specify absolute paths here, but also
-# relative paths, which will be relative from the directory where doxygen is
-# started.
-
-STRIP_FROM_PATH =
-
-# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of
-# the path mentioned in the documentation of a class, which tells
-# the reader which header file to include in order to use a class.
-# If left blank only the name of the header file containing the class
-# definition is used. Otherwise one should specify the include paths that
-# are normally passed to the compiler using the -I flag.
-
-STRIP_FROM_INC_PATH =
-
-# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter
-# (but less readable) file names. This can be useful if your file system
-# doesn't support long names like on DOS, Mac, or CD-ROM.
-
-SHORT_NAMES = NO
-
-# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen
-# will interpret the first line (until the first dot) of a JavaDoc-style
-# comment as the brief description. If set to NO, the JavaDoc
-# comments will behave just like regular Qt-style comments
-# (thus requiring an explicit @brief command for a brief description.)
-
JAVADOC_AUTOBRIEF = YES
-
-# If the QT_AUTOBRIEF tag is set to YES then Doxygen will
-# interpret the first line (until the first dot) of a Qt-style
-# comment as the brief description. If set to NO, the comments
-# will behave just like regular Qt-style comments (thus requiring
-# an explicit \brief command for a brief description.)
-
-QT_AUTOBRIEF = NO
-
-# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen
-# treat a multi-line C++ special comment block (i.e. a block of //! or ///
-# comments) as a brief description. This used to be the default behaviour.
-# The new default is to treat a multi-line C++ comment block as a detailed
-# description. Set this tag to YES if you prefer the old behaviour instead.
-
-MULTILINE_CPP_IS_BRIEF = NO
-
-# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented
-# member inherits the documentation from any documented member that it
-# re-implements.
-
-INHERIT_DOCS = YES
-
-# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce
-# a new page for each member. If set to NO, the documentation of a member will
-# be part of the file/class/namespace that contains it.
-
-SEPARATE_MEMBER_PAGES = NO
-
-# The TAB_SIZE tag can be used to set the number of spaces in a tab.
-# Doxygen uses this value to replace tabs by spaces in code fragments.
-
TAB_SIZE = 8
-
-# This tag can be used to specify a number of aliases that acts
-# as commands in the documentation. An alias has the form "name=value".
-# For example adding "sideeffect=\par Side Effects:\n" will allow you to
-# put the command \sideeffect (or @sideeffect) in the documentation, which
-# will result in a user-defined paragraph with heading "Side Effects:".
-# You can put \n's in the value part of an alias to insert newlines.
-
-ALIASES =
-
-# This tag can be used to specify a number of word-keyword mappings (TCL only).
-# A mapping has the form "name=value". For example adding
-# "class=itcl::class" will allow you to use the command class in the
-# itcl::class meaning.
-
-TCL_SUBST =
-
-# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C
-# sources only. Doxygen will then generate output that is more tailored for C.
-# For instance, some of the names that are used will be different. The list
-# of all members will be omitted, etc.
-
OPTIMIZE_OUTPUT_FOR_C = YES
-
-# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java
-# sources only. Doxygen will then generate output that is more tailored for
-# Java. For instance, namespaces will be presented as packages, qualified
-# scopes will look different, etc.
-
-OPTIMIZE_OUTPUT_JAVA = NO
-
-# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran
-# sources only. Doxygen will then generate output that is more tailored for
-# Fortran.
-
-OPTIMIZE_FOR_FORTRAN = NO
-
-# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL
-# sources. Doxygen will then generate output that is tailored for
-# VHDL.
-
-OPTIMIZE_OUTPUT_VHDL = NO
-
-# Doxygen selects the parser to use depending on the extension of the files it
-# parses. With this tag you can assign which parser to use for a given
-# extension. Doxygen has a built-in mapping, but you can override or extend it
-# using this tag. The format is ext=language, where ext is a file extension,
-# and language is one of the parsers supported by doxygen: IDL, Java,
-# Javascript, CSharp, C, C++, D, PHP, Objective-C, Python, Fortran, VHDL, C,
-# C++. For instance to make doxygen treat .inc files as Fortran files (default
-# is PHP), and .f files as C (default is Fortran), use: inc=Fortran f=C. Note
-# that for custom extensions you also need to set FILE_PATTERNS otherwise the
-# files are not read by doxygen.
-
-EXTENSION_MAPPING =
-
-# If MARKDOWN_SUPPORT is enabled (the default) then doxygen pre-processes all
-# comments according to the Markdown format, which allows for more readable
-# documentation. See http://daringfireball.net/projects/markdown/ for details.
-# The output of markdown processing is further processed by doxygen, so you
-# can mix doxygen, HTML, and XML commands with Markdown formatting.
-# Disable only in case of backward compatibilities issues.
-
-MARKDOWN_SUPPORT = YES
-
-# When enabled doxygen tries to link words that correspond to documented classes,
-# or namespaces to their corresponding documentation. Such a link can be
-# prevented in individual cases by by putting a % sign in front of the word or
-# globally by setting AUTOLINK_SUPPORT to NO.
-
-AUTOLINK_SUPPORT = YES
-
-# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want
-# to include (a tag file for) the STL sources as input, then you should
-# set this tag to YES in order to let doxygen match functions declarations and
-# definitions whose arguments contain STL classes (e.g. func(std::string); v.s.
-# func(std::string) {}). This also makes the inheritance and collaboration
-# diagrams that involve STL classes more complete and accurate.
-
-BUILTIN_STL_SUPPORT = NO
-
-# If you use Microsoft's C++/CLI language, you should set this option to YES to
-# enable parsing support.
-
-CPP_CLI_SUPPORT = NO
-
-# Set the SIP_SUPPORT tag to YES if your project consists of sip sources only.
-# Doxygen will parse them like normal C++ but will assume all classes use public
-# instead of private inheritance when no explicit protection keyword is present.
-
-SIP_SUPPORT = NO
-
-# For Microsoft's IDL there are propget and propput attributes to indicate
-# getter and setter methods for a property. Setting this option to YES (the
-# default) will make doxygen replace the get and set methods by a property in
-# the documentation. This will only work if the methods are indeed getting or
-# setting a simple type. If this is not the case, or you want to show the
-# methods anyway, you should set this option to NO.
-
-IDL_PROPERTY_SUPPORT = YES
-
-# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC
-# tag is set to YES, then doxygen will reuse the documentation of the first
-# member in the group (if any) for the other members of the group. By default
-# all members of a group must be documented explicitly.
-
-DISTRIBUTE_GROUP_DOC = NO
-
-# Set the SUBGROUPING tag to YES (the default) to allow class member groups of
-# the same type (for instance a group of public functions) to be put as a
-# subgroup of that type (e.g. under the Public Functions section). Set it to
-# NO to prevent subgrouping. Alternatively, this can be done per class using
-# the \nosubgrouping command.
-
-SUBGROUPING = YES
-
-# When the INLINE_GROUPED_CLASSES tag is set to YES, classes, structs and
-# unions are shown inside the group in which they are included (e.g. using
-# @ingroup) instead of on a separate page (for HTML and Man pages) or
-# section (for LaTeX and RTF).
-
-INLINE_GROUPED_CLASSES = NO
-
-# When the INLINE_SIMPLE_STRUCTS tag is set to YES, structs, classes, and
-# unions with only public data fields will be shown inline in the documentation
-# of the scope in which they are defined (i.e. file, namespace, or group
-# documentation), provided this scope is documented. If set to NO (the default),
-# structs, classes, and unions are shown on a separate page (for HTML and Man
-# pages) or section (for LaTeX and RTF).
-
-INLINE_SIMPLE_STRUCTS = NO
-
-# When TYPEDEF_HIDES_STRUCT is enabled, a typedef of a struct, union, or enum
-# is documented as struct, union, or enum with the name of the typedef. So
-# typedef struct TypeS {} TypeT, will appear in the documentation as a struct
-# with name TypeT. When disabled the typedef will appear as a member of a file,
-# namespace, or class. And the struct will be named TypeS. This can typically
-# be useful for C code in case the coding convention dictates that all compound
-# types are typedef'ed and only the typedef is referenced, never the tag name.
-
-TYPEDEF_HIDES_STRUCT = NO
-
-# Similar to the SYMBOL_CACHE_SIZE the size of the symbol lookup cache can be
-# set using LOOKUP_CACHE_SIZE. This cache is used to resolve symbols given
-# their name and scope. Since this can be an expensive process and often the
-# same symbol appear multiple times in the code, doxygen keeps a cache of
-# pre-resolved symbols. If the cache is too small doxygen will become slower.
-# If the cache is too large, memory is wasted. The cache size is given by this
-# formula: 2^(16+LOOKUP_CACHE_SIZE). The valid range is 0..9, the default is 0,
-# corresponding to a cache size of 2^16 = 65536 symbols.
-
-LOOKUP_CACHE_SIZE = 0
-
-#---------------------------------------------------------------------------
-# Build related configuration options
-#---------------------------------------------------------------------------
-
-# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in
-# documentation are documented, even if no documentation was available.
-# Private class members and static file members will be hidden unless
-# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES
-
EXTRACT_ALL = YES
-
-# If the EXTRACT_PRIVATE tag is set to YES all private members of a class
-# will be included in the documentation.
-
-EXTRACT_PRIVATE = NO
-
-# If the EXTRACT_PACKAGE tag is set to YES all members with package or internal
-# scope will be included in the documentation.
-
-EXTRACT_PACKAGE = NO
-
-# If the EXTRACT_STATIC tag is set to YES all static members of a file
-# will be included in the documentation.
-
-EXTRACT_STATIC = NO
-
-# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs)
-# defined locally in source files will be included in the documentation.
-# If set to NO only classes defined in header files are included.
-
-EXTRACT_LOCAL_CLASSES = YES
-
-# This flag is only useful for Objective-C code. When set to YES local
-# methods, which are defined in the implementation section but not in
-# the interface are included in the documentation.
-# If set to NO (the default) only methods in the interface are included.
-
-EXTRACT_LOCAL_METHODS = NO
-
-# If this flag is set to YES, the members of anonymous namespaces will be
-# extracted and appear in the documentation as a namespace called
-# 'anonymous_namespace{file}', where file will be replaced with the base
-# name of the file that contains the anonymous namespace. By default
-# anonymous namespaces are hidden.
-
-EXTRACT_ANON_NSPACES = NO
-
-# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all
-# undocumented members of documented classes, files or namespaces.
-# If set to NO (the default) these members will be included in the
-# various overviews, but no documentation section is generated.
-# This option has no effect if EXTRACT_ALL is enabled.
-
-HIDE_UNDOC_MEMBERS = NO
-
-# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all
-# undocumented classes that are normally visible in the class hierarchy.
-# If set to NO (the default) these classes will be included in the various
-# overviews. This option has no effect if EXTRACT_ALL is enabled.
-
-HIDE_UNDOC_CLASSES = NO
-
-# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all
-# friend (class|struct|union) declarations.
-# If set to NO (the default) these declarations will be included in the
-# documentation.
-
-HIDE_FRIEND_COMPOUNDS = NO
-
-# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any
-# documentation blocks found inside the body of a function.
-# If set to NO (the default) these blocks will be appended to the
-# function's detailed documentation block.
-
-HIDE_IN_BODY_DOCS = NO
-
-# The INTERNAL_DOCS tag determines if documentation
-# that is typed after a \internal command is included. If the tag is set
-# to NO (the default) then the documentation will be excluded.
-# Set it to YES to include the internal documentation.
-
-INTERNAL_DOCS = NO
-
-# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate
-# file names in lower-case letters. If set to YES upper-case letters are also
-# allowed. This is useful if you have classes or files whose names only differ
-# in case and if your file system supports case sensitive file names. Windows
-# and Mac users are advised to set this option to NO.
-
-CASE_SENSE_NAMES = YES
-
-# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen
-# will show members with their full class and namespace scopes in the
-# documentation. If set to YES the scope will be hidden.
-
-HIDE_SCOPE_NAMES = NO
-
-# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen
-# will put a list of the files that are included by a file in the documentation
-# of that file.
-
-SHOW_INCLUDE_FILES = YES
-
-# If the FORCE_LOCAL_INCLUDES tag is set to YES then Doxygen
-# will list include files with double quotes in the documentation
-# rather than with sharp brackets.
-
-FORCE_LOCAL_INCLUDES = NO
-
-# If the INLINE_INFO tag is set to YES (the default) then a tag [inline]
-# is inserted in the documentation for inline members.
-
-INLINE_INFO = YES
-
-# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen
-# will sort the (detailed) documentation of file and class members
-# alphabetically by member name. If set to NO the members will appear in
-# declaration order.
-
-SORT_MEMBER_DOCS = YES
-
-# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the
-# brief documentation of file, namespace and class members alphabetically
-# by member name. If set to NO (the default) the members will appear in
-# declaration order.
-
-SORT_BRIEF_DOCS = NO
-
-# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen
-# will sort the (brief and detailed) documentation of class members so that
-# constructors and destructors are listed first. If set to NO (the default)
-# the constructors will appear in the respective orders defined by
-# SORT_MEMBER_DOCS and SORT_BRIEF_DOCS.
-# This tag will be ignored for brief docs if SORT_BRIEF_DOCS is set to NO
-# and ignored for detailed docs if SORT_MEMBER_DOCS is set to NO.
-
-SORT_MEMBERS_CTORS_1ST = NO
-
-# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the
-# hierarchy of group names into alphabetical order. If set to NO (the default)
-# the group names will appear in their defined order.
-
-SORT_GROUP_NAMES = NO
-
-# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be
-# sorted by fully-qualified names, including namespaces. If set to
-# NO (the default), the class list will be sorted only by class name,
-# not including the namespace part.
-# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES.
-# Note: This option applies only to the class list, not to the
-# alphabetical list.
-
-SORT_BY_SCOPE_NAME = NO
-
-# If the STRICT_PROTO_MATCHING option is enabled and doxygen fails to
-# do proper type resolution of all parameters of a function it will reject a
-# match between the prototype and the implementation of a member function even
-# if there is only one candidate or it is obvious which candidate to choose
-# by doing a simple string match. By disabling STRICT_PROTO_MATCHING doxygen
-# will still accept a match between prototype and implementation in such cases.
-
-STRICT_PROTO_MATCHING = NO
-
-# The GENERATE_TODOLIST tag can be used to enable (YES) or
-# disable (NO) the todo list. This list is created by putting \todo
-# commands in the documentation.
-
-GENERATE_TODOLIST = YES
-
-# The GENERATE_TESTLIST tag can be used to enable (YES) or
-# disable (NO) the test list. This list is created by putting \test
-# commands in the documentation.
-
-GENERATE_TESTLIST = YES
-
-# The GENERATE_BUGLIST tag can be used to enable (YES) or
-# disable (NO) the bug list. This list is created by putting \bug
-# commands in the documentation.
-
-GENERATE_BUGLIST = YES
-
-# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or
-# disable (NO) the deprecated list. This list is created by putting
-# \deprecated commands in the documentation.
-
-GENERATE_DEPRECATEDLIST= YES
-
-# The ENABLED_SECTIONS tag can be used to enable conditional
-# documentation sections, marked by \if section-label ... \endif
-# and \cond section-label ... \endcond blocks.
-
-ENABLED_SECTIONS =
-
-# The MAX_INITIALIZER_LINES tag determines the maximum number of lines
-# the initial value of a variable or macro consists of for it to appear in
-# the documentation. If the initializer consists of more lines than specified
-# here it will be hidden. Use a value of 0 to hide initializers completely.
-# The appearance of the initializer of individual variables and macros in the
-# documentation can be controlled using \showinitializer or \hideinitializer
-# command in the documentation regardless of this setting.
-
MAX_INITIALIZER_LINES = 0
-
-# Set the SHOW_USED_FILES tag to NO to disable the list of files generated
-# at the bottom of the documentation of classes and structs. If set to YES the
-# list will mention the files that were used to generate the documentation.
-
-SHOW_USED_FILES = YES
-
-# Set the SHOW_FILES tag to NO to disable the generation of the Files page.
-# This will remove the Files entry from the Quick Index and from the
-# Folder Tree View (if specified). The default is YES.
-
-SHOW_FILES = YES
-
-# Set the SHOW_NAMESPACES tag to NO to disable the generation of the
-# Namespaces page.
-# This will remove the Namespaces entry from the Quick Index
-# and from the Folder Tree View (if specified). The default is YES.
-
-SHOW_NAMESPACES = YES
-
-# The FILE_VERSION_FILTER tag can be used to specify a program or script that
-# doxygen should invoke to get the current version for each file (typically from
-# the version control system). Doxygen will invoke the program by executing (via
-# popen()) the command <command> <input-file>, where <command> is the value of
-# the FILE_VERSION_FILTER tag, and <input-file> is the name of an input file
-# provided by doxygen. Whatever the program writes to standard output
-# is used as the file version. See the manual for examples.
-
-FILE_VERSION_FILTER =
-
-# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed
-# by doxygen. The layout file controls the global structure of the generated
-# output files in an output format independent way. To create the layout file
-# that represents doxygen's defaults, run doxygen with the -l option.
-# You can optionally specify a file name after the option, if omitted
-# DoxygenLayout.xml will be used as the name of the layout file.
-
-LAYOUT_FILE =
-
-# The CITE_BIB_FILES tag can be used to specify one or more bib files
-# containing the references data. This must be a list of .bib files. The
-# .bib extension is automatically appended if omitted. Using this command
-# requires the bibtex tool to be installed. See also
-# http://en.wikipedia.org/wiki/BibTeX for more info. For LaTeX the style
-# of the bibliography can be controlled using LATEX_BIB_STYLE. To use this
-# feature you need bibtex and perl available in the search path. Do not use
-# file names with spaces, bibtex cannot handle them.
-
-CITE_BIB_FILES =
-
-#---------------------------------------------------------------------------
-# configuration options related to warning and progress messages
-#---------------------------------------------------------------------------
-
-# The QUIET tag can be used to turn on/off the messages that are generated
-# by doxygen. Possible values are YES and NO. If left blank NO is used.
-
QUIET = YES
-
-# The WARNINGS tag can be used to turn on/off the warning messages that are
-# generated by doxygen. Possible values are YES and NO. If left blank
-# NO is used.
-
-WARNINGS = YES
-
-# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings
-# for undocumented members. If EXTRACT_ALL is set to YES then this flag will
-# automatically be disabled.
-
-WARN_IF_UNDOCUMENTED = YES
-
-# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for
-# potential errors in the documentation, such as not documenting some
-# parameters in a documented function, or documenting parameters that
-# don't exist or using markup commands wrongly.
-
-WARN_IF_DOC_ERROR = YES
-
-# The WARN_NO_PARAMDOC option can be enabled to get warnings for
-# functions that are documented, but have no documentation for their parameters
-# or return value. If set to NO (the default) doxygen will only warn about
-# wrong or incomplete parameter documentation, but not about the absence of
-# documentation.
-
-WARN_NO_PARAMDOC = NO
-
-# The WARN_FORMAT tag determines the format of the warning messages that
-# doxygen can produce. The string should contain the $file, $line, and $text
-# tags, which will be replaced by the file and line number from which the
-# warning originated and the warning text. Optionally the format may contain
-# $version, which will be replaced by the version of the file (if it could
-# be obtained via FILE_VERSION_FILTER)
-
-WARN_FORMAT = "$file:$line: $text"
-
-# The WARN_LOGFILE tag can be used to specify a file to which warning
-# and error messages should be written. If left blank the output is written
-# to stderr.
-
-WARN_LOGFILE =
-
-#---------------------------------------------------------------------------
-# configuration options related to the input files
-#---------------------------------------------------------------------------
-
-# The INPUT tag can be used to specify the files and/or directories that contain
-# documented source files. You may enter file names like "myfile.cpp" or
-# directories like "/usr/src/myproject". Separate the files or directories
-# with spaces.
-
INPUT = @top_srcdir@/libevdev/libevdev.h \
- @top_srcdir@/libevdev/libevdev-uinput.h
-
-# This tag can be used to specify the character encoding of the source files
-# that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is
-# also the default input encoding. Doxygen uses libiconv (or the iconv built
-# into libc) for the transcoding. See http://www.gnu.org/software/libiconv for
-# the list of possible encodings.
-
-INPUT_ENCODING = UTF-8
-
-# If the value of the INPUT tag contains directories, you can use the
-# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp
-# and *.h) to filter out the source-files in the directories. If left
-# blank the following patterns are tested:
-# *.c *.cc *.cxx *.cpp *.c++ *.d *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh
-# *.hxx *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.dox *.py
-# *.f90 *.f *.for *.vhd *.vhdl
-
-FILE_PATTERNS =
-
-# The RECURSIVE tag can be used to turn specify whether or not subdirectories
-# should be searched for input files as well. Possible values are YES and NO.
-# If left blank NO is used.
-
-RECURSIVE = NO
-
-# The EXCLUDE tag can be used to specify files and/or directories that should be
-# excluded from the INPUT source files. This way you can easily exclude a
-# subdirectory from a directory tree whose root is specified with the INPUT tag.
-# Note that relative paths are relative to the directory from which doxygen is
-# run.
-
-EXCLUDE =
-
-# The EXCLUDE_SYMLINKS tag can be used to select whether or not files or
-# directories that are symbolic links (a Unix file system feature) are excluded
-# from the input.
-
-EXCLUDE_SYMLINKS = NO
-
-# If the value of the INPUT tag contains directories, you can use the
-# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude
-# certain files from those directories. Note that the wildcards are matched
-# against the file with absolute path, so to exclude all test directories
-# for example use the pattern */test/*
-
-EXCLUDE_PATTERNS =
-
-# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names
-# (namespaces, classes, functions, etc.) that should be excluded from the
-# output. The symbol name can be a fully qualified name, a word, or if the
-# wildcard * is used, a substring. Examples: ANamespace, AClass,
-# AClass::ANamespace, ANamespace::*Test
-
-EXCLUDE_SYMBOLS =
-
-# The EXAMPLE_PATH tag can be used to specify one or more files or
-# directories that contain example code fragments that are included (see
-# the \include command).
-
+ @top_srcdir@/libevdev/libevdev-uinput.h
EXAMPLE_PATH = @top_srcdir@/include
-
-# If the value of the EXAMPLE_PATH tag contains directories, you can use the
-# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp
-# and *.h) to filter out the source-files in the directories. If left
-# blank all files are included.
-
-EXAMPLE_PATTERNS =
-
-# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be
-# searched for input files to be used with the \include or \dontinclude
-# commands irrespective of the value of the RECURSIVE tag.
-# Possible values are YES and NO. If left blank NO is used.
-
-EXAMPLE_RECURSIVE = NO
-
-# The IMAGE_PATH tag can be used to specify one or more files or
-# directories that contain image that are included in the documentation (see
-# the \image command).
-
-IMAGE_PATH =
-
-# The INPUT_FILTER tag can be used to specify a program that doxygen should
-# invoke to filter for each input file. Doxygen will invoke the filter program
-# by executing (via popen()) the command <filter> <input-file>, where <filter>
-# is the value of the INPUT_FILTER tag, and <input-file> is the name of an
-# input file. Doxygen will then use the output that the filter program writes
-# to standard output.
-# If FILTER_PATTERNS is specified, this tag will be
-# ignored.
-
-INPUT_FILTER =
-
-# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern
-# basis.
-# Doxygen will compare the file name with each pattern and apply the
-# filter if there is a match.
-# The filters are a list of the form:
-# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further
-# info on how filters are used. If FILTER_PATTERNS is empty or if
-# non of the patterns match the file name, INPUT_FILTER is applied.
-
-FILTER_PATTERNS =
-
-# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using
-# INPUT_FILTER) will be used to filter the input files when producing source
-# files to browse (i.e. when SOURCE_BROWSER is set to YES).
-
-FILTER_SOURCE_FILES = NO
-
-# The FILTER_SOURCE_PATTERNS tag can be used to specify source filters per file
-# pattern. A pattern will override the setting for FILTER_PATTERN (if any)
-# and it is also possible to disable source filtering for a specific pattern
-# using *.ext= (so without naming a filter). This option only has effect when
-# FILTER_SOURCE_FILES is enabled.
-
-FILTER_SOURCE_PATTERNS =
-
-# If the USE_MD_FILE_AS_MAINPAGE tag refers to the name of a markdown file that
-# is part of the input, its contents will be placed on the main page (index.html).
-# This can be useful if you have a project on for instance GitHub and want reuse
-# the introduction page also for the doxygen output.
-
-USE_MDFILE_AS_MAINPAGE =
-
-#---------------------------------------------------------------------------
-# configuration options related to source browsing
-#---------------------------------------------------------------------------
-
-# If the SOURCE_BROWSER tag is set to YES then a list of source files will
-# be generated. Documented entities will be cross-referenced with these sources.
-# Note: To get rid of all source code in the generated output, make sure also
-# VERBATIM_HEADERS is set to NO.
-
-SOURCE_BROWSER = NO
-
-# Setting the INLINE_SOURCES tag to YES will include the body
-# of functions and classes directly in the documentation.
-
-INLINE_SOURCES = NO
-
-# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct
-# doxygen to hide any special comment blocks from generated source code
-# fragments. Normal C, C++ and Fortran comments will always remain visible.
-
-STRIP_CODE_COMMENTS = YES
-
-# If the REFERENCED_BY_RELATION tag is set to YES
-# then for each documented function all documented
-# functions referencing it will be listed.
-
-REFERENCED_BY_RELATION = NO
-
-# If the REFERENCES_RELATION tag is set to YES
-# then for each documented function all documented entities
-# called/used by that function will be listed.
-
-REFERENCES_RELATION = NO
-
-# If the REFERENCES_LINK_SOURCE tag is set to YES (the default)
-# and SOURCE_BROWSER tag is set to YES, then the hyperlinks from
-# functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will
-# link to the source code.
-# Otherwise they will link to the documentation.
-
-REFERENCES_LINK_SOURCE = YES
-
-# If the USE_HTAGS tag is set to YES then the references to source code
-# will point to the HTML generated by the htags(1) tool instead of doxygen
-# built-in source browser. The htags tool is part of GNU's global source
-# tagging system (see http://www.gnu.org/software/global/global.html). You
-# will need version 4.8.6 or higher.
-
-USE_HTAGS = NO
-
-# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen
-# will generate a verbatim copy of the header file for each class for
-# which an include is specified. Set to NO to disable this.
-
-VERBATIM_HEADERS = YES
-
-#---------------------------------------------------------------------------
-# configuration options related to the alphabetical class index
-#---------------------------------------------------------------------------
-
-# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index
-# of all compounds will be generated. Enable this if the project
-# contains a lot of classes, structs, unions or interfaces.
-
-ALPHABETICAL_INDEX = YES
-
-# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then
-# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns
-# in which this list will be split (can be a number in the range [1..20])
-
-COLS_IN_ALPHA_INDEX = 5
-
-# In case all classes in a project start with a common prefix, all
-# classes will be put under the same header in the alphabetical index.
-# The IGNORE_PREFIX tag can be used to specify one or more prefixes that
-# should be ignored while generating the index headers.
-
-IGNORE_PREFIX =
-
-#---------------------------------------------------------------------------
-# configuration options related to the HTML output
-#---------------------------------------------------------------------------
-
-# If the GENERATE_HTML tag is set to YES (the default) Doxygen will
-# generate HTML output.
-
GENERATE_HTML = YES
-
-# The HTML_OUTPUT tag is used to specify where the HTML docs will be put.
-# If a relative path is entered the value of OUTPUT_DIRECTORY will be
-# put in front of it. If left blank `html' will be used as the default path.
-
-HTML_OUTPUT = html
-
-# The HTML_FILE_EXTENSION tag can be used to specify the file extension for
-# each generated HTML page (for example: .htm,.php,.asp). If it is left blank
-# doxygen will generate files with .html extension.
-
-HTML_FILE_EXTENSION = .html
-
-# The HTML_HEADER tag can be used to specify a personal HTML header for
-# each generated HTML page. If it is left blank doxygen will generate a
-# standard header. Note that when using a custom header you are responsible
-# for the proper inclusion of any scripts and style sheets that doxygen
-# needs, which is dependent on the configuration options used.
-# It is advised to generate a default header using "doxygen -w html
-# header.html footer.html stylesheet.css YourConfigFile" and then modify
-# that header. Note that the header is subject to change so you typically
-# have to redo this when upgrading to a newer version of doxygen or when
-# changing the value of configuration settings such as GENERATE_TREEVIEW!
-
-HTML_HEADER =
-
-# The HTML_FOOTER tag can be used to specify a personal HTML footer for
-# each generated HTML page. If it is left blank doxygen will generate a
-# standard footer.
-
-HTML_FOOTER =
-
-# The HTML_STYLESHEET tag can be used to specify a user-defined cascading
-# style sheet that is used by each HTML page. It can be used to
-# fine-tune the look of the HTML output. If left blank doxygen will
-# generate a default style sheet. Note that it is recommended to use
-# HTML_EXTRA_STYLESHEET instead of this one, as it is more robust and this
-# tag will in the future become obsolete.
-
-HTML_STYLESHEET =
-
-# The HTML_EXTRA_STYLESHEET tag can be used to specify an additional
-# user-defined cascading style sheet that is included after the standard
-# style sheets created by doxygen. Using this option one can overrule
-# certain style aspects. This is preferred over using HTML_STYLESHEET
-# since it does not replace the standard style sheet and is therefor more
-# robust against future updates. Doxygen will copy the style sheet file to
-# the output directory.
-
HTML_EXTRA_STYLESHEET = @srcdir@/libevdev.css
-
-# The HTML_EXTRA_FILES tag can be used to specify one or more extra images or
-# other source files which should be copied to the HTML output directory. Note
-# that these files will be copied to the base HTML output directory. Use the
-# $relpath$ marker in the HTML_HEADER and/or HTML_FOOTER files to load these
-# files. In the HTML_STYLESHEET file, use the file name only. Also note that
-# the files will be copied as-is; there are no commands or markers available.
-
-HTML_EXTRA_FILES =
-
-# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output.
-# Doxygen will adjust the colors in the style sheet and background images
-# according to this color. Hue is specified as an angle on a colorwheel,
-# see http://en.wikipedia.org/wiki/Hue for more information.
-# For instance the value 0 represents red, 60 is yellow, 120 is green,
-# 180 is cyan, 240 is blue, 300 purple, and 360 is red again.
-# The allowed range is 0 to 359.
-
-HTML_COLORSTYLE_HUE = 220
-
-# The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of
-# the colors in the HTML output. For a value of 0 the output will use
-# grayscales only. A value of 255 will produce the most vivid colors.
-
-HTML_COLORSTYLE_SAT = 100
-
-# The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to
-# the luminance component of the colors in the HTML output. Values below
-# 100 gradually make the output lighter, whereas values above 100 make
-# the output darker. The value divided by 100 is the actual gamma applied,
-# so 80 represents a gamma of 0.8, The value 220 represents a gamma of 2.2,
-# and 100 does not change the gamma.
-
-HTML_COLORSTYLE_GAMMA = 80
-
-# If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML
-# page will contain the date and time when the page was generated. Setting
-# this to NO can help when comparing the output of multiple runs.
-
HTML_TIMESTAMP = YES
-
-# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML
-# documentation will contain sections that can be hidden and shown after the
-# page has loaded.
-
-HTML_DYNAMIC_SECTIONS = NO
-
-# With HTML_INDEX_NUM_ENTRIES one can control the preferred number of
-# entries shown in the various tree structured indices initially; the user
-# can expand and collapse entries dynamically later on. Doxygen will expand
-# the tree to such a level that at most the specified number of entries are
-# visible (unless a fully collapsed tree already exceeds this amount).
-# So setting the number of entries 1 will produce a full collapsed tree by
-# default. 0 is a special value representing an infinite number of entries
-# and will result in a full expanded tree by default.
-
-HTML_INDEX_NUM_ENTRIES = 100
-
-# If the GENERATE_DOCSET tag is set to YES, additional index files
-# will be generated that can be used as input for Apple's Xcode 3
-# integrated development environment, introduced with OSX 10.5 (Leopard).
-# To create a documentation set, doxygen will generate a Makefile in the
-# HTML output directory. Running make will produce the docset in that
-# directory and running "make install" will install the docset in
-# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find
-# it at startup.
-# See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html
-# for more information.
-
-GENERATE_DOCSET = NO
-
-# When GENERATE_DOCSET tag is set to YES, this tag determines the name of the
-# feed. A documentation feed provides an umbrella under which multiple
-# documentation sets from a single provider (such as a company or product suite)
-# can be grouped.
-
-DOCSET_FEEDNAME = "Doxygen generated docs"
-
-# When GENERATE_DOCSET tag is set to YES, this tag specifies a string that
-# should uniquely identify the documentation set bundle. This should be a
-# reverse domain-name style string, e.g. com.mycompany.MyDocSet. Doxygen
-# will append .docset to the name.
-
-DOCSET_BUNDLE_ID = org.doxygen.Project
-
-# When GENERATE_PUBLISHER_ID tag specifies a string that should uniquely
-# identify the documentation publisher. This should be a reverse domain-name
-# style string, e.g. com.mycompany.MyDocSet.documentation.
-
-DOCSET_PUBLISHER_ID = org.doxygen.Publisher
-
-# The GENERATE_PUBLISHER_NAME tag identifies the documentation publisher.
-
-DOCSET_PUBLISHER_NAME = Publisher
-
-# If the GENERATE_HTMLHELP tag is set to YES, additional index files
-# will be generated that can be used as input for tools like the
-# Microsoft HTML help workshop to generate a compiled HTML help file (.chm)
-# of the generated HTML documentation.
-
-GENERATE_HTMLHELP = NO
-
-# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can
-# be used to specify the file name of the resulting .chm file. You
-# can add a path in front of the file if the result should not be
-# written to the html output directory.
-
-CHM_FILE =
-
-# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can
-# be used to specify the location (absolute path including file name) of
-# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run
-# the HTML help compiler on the generated index.hhp.
-
-HHC_LOCATION =
-
-# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag
-# controls if a separate .chi index file is generated (YES) or that
-# it should be included in the master .chm file (NO).
-
-GENERATE_CHI = NO
-
-# If the GENERATE_HTMLHELP tag is set to YES, the CHM_INDEX_ENCODING
-# is used to encode HtmlHelp index (hhk), content (hhc) and project file
-# content.
-
-CHM_INDEX_ENCODING =
-
-# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag
-# controls whether a binary table of contents is generated (YES) or a
-# normal table of contents (NO) in the .chm file.
-
-BINARY_TOC = NO
-
-# The TOC_EXPAND flag can be set to YES to add extra items for group members
-# to the contents of the HTML help documentation and to the tree view.
-
-TOC_EXPAND = NO
-
-# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and
-# QHP_VIRTUAL_FOLDER are set, an additional index file will be generated
-# that can be used as input for Qt's qhelpgenerator to generate a
-# Qt Compressed Help (.qch) of the generated HTML documentation.
-
-GENERATE_QHP = NO
-
-# If the QHG_LOCATION tag is specified, the QCH_FILE tag can
-# be used to specify the file name of the resulting .qch file.
-# The path specified is relative to the HTML output folder.
-
-QCH_FILE =
-
-# The QHP_NAMESPACE tag specifies the namespace to use when generating
-# Qt Help Project output. For more information please see
-# http://doc.trolltech.com/qthelpproject.html#namespace
-
-QHP_NAMESPACE = org.doxygen.Project
-
-# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating
-# Qt Help Project output. For more information please see
-# http://doc.trolltech.com/qthelpproject.html#virtual-folders
-
-QHP_VIRTUAL_FOLDER = doc
-
-# If QHP_CUST_FILTER_NAME is set, it specifies the name of a custom filter to
-# add. For more information please see
-# http://doc.trolltech.com/qthelpproject.html#custom-filters
-
-QHP_CUST_FILTER_NAME =
-
-# The QHP_CUST_FILT_ATTRS tag specifies the list of the attributes of the
-# custom filter to add. For more information please see
-# <a href="http://doc.trolltech.com/qthelpproject.html#custom-filters">
-# Qt Help Project / Custom Filters</a>.
-
-QHP_CUST_FILTER_ATTRS =
-
-# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this
-# project's
-# filter section matches.
-# <a href="http://doc.trolltech.com/qthelpproject.html#filter-attributes">
-# Qt Help Project / Filter Attributes</a>.
-
-QHP_SECT_FILTER_ATTRS =
-
-# If the GENERATE_QHP tag is set to YES, the QHG_LOCATION tag can
-# be used to specify the location of Qt's qhelpgenerator.
-# If non-empty doxygen will try to run qhelpgenerator on the generated
-# .qhp file.
-
-QHG_LOCATION =
-
-# If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files
-# will be generated, which together with the HTML files, form an Eclipse help
-# plugin. To install this plugin and make it available under the help contents
-# menu in Eclipse, the contents of the directory containing the HTML and XML
-# files needs to be copied into the plugins directory of eclipse. The name of
-# the directory within the plugins directory should be the same as
-# the ECLIPSE_DOC_ID value. After copying Eclipse needs to be restarted before
-# the help appears.
-
-GENERATE_ECLIPSEHELP = NO
-
-# A unique identifier for the eclipse help plugin. When installing the plugin
-# the directory name containing the HTML and XML files should also have
-# this name.
-
-ECLIPSE_DOC_ID = org.doxygen.Project
-
-# The DISABLE_INDEX tag can be used to turn on/off the condensed index (tabs)
-# at top of each HTML page. The value NO (the default) enables the index and
-# the value YES disables it. Since the tabs have the same information as the
-# navigation tree you can set this option to NO if you already set
-# GENERATE_TREEVIEW to YES.
-
-DISABLE_INDEX = NO
-
-# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index
-# structure should be generated to display hierarchical information.
-# If the tag value is set to YES, a side panel will be generated
-# containing a tree-like index structure (just like the one that
-# is generated for HTML Help). For this to work a browser that supports
-# JavaScript, DHTML, CSS and frames is required (i.e. any modern browser).
-# Windows users are probably better off using the HTML help feature.
-# Since the tree basically has the same information as the tab index you
-# could consider to set DISABLE_INDEX to NO when enabling this option.
-
-GENERATE_TREEVIEW = NO
-
-# The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values
-# (range [0,1..20]) that doxygen will group on one line in the generated HTML
-# documentation. Note that a value of 0 will completely suppress the enum
-# values from appearing in the overview section.
-
-ENUM_VALUES_PER_LINE = 4
-
-# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be
-# used to set the initial width (in pixels) of the frame in which the tree
-# is shown.
-
-TREEVIEW_WIDTH = 250
-
-# When the EXT_LINKS_IN_WINDOW option is set to YES doxygen will open
-# links to external symbols imported via tag files in a separate window.
-
-EXT_LINKS_IN_WINDOW = NO
-
-# Use this tag to change the font size of Latex formulas included
-# as images in the HTML documentation. The default is 10. Note that
-# when you change the font size after a successful doxygen run you need
-# to manually remove any form_*.png images from the HTML output directory
-# to force them to be regenerated.
-
-FORMULA_FONTSIZE = 10
-
-# Use the FORMULA_TRANPARENT tag to determine whether or not the images
-# generated for formulas are transparent PNGs. Transparent PNGs are
-# not supported properly for IE 6.0, but are supported on all modern browsers.
-# Note that when changing this option you need to delete any form_*.png files
-# in the HTML output before the changes have effect.
-
-FORMULA_TRANSPARENT = YES
-
-# Enable the USE_MATHJAX option to render LaTeX formulas using MathJax
-# (see http://www.mathjax.org) which uses client side Javascript for the
-# rendering instead of using prerendered bitmaps. Use this if you do not
-# have LaTeX installed or if you want to formulas look prettier in the HTML
-# output. When enabled you may also need to install MathJax separately and
-# configure the path to it using the MATHJAX_RELPATH option.
-
-USE_MATHJAX = NO
-
-# When MathJax is enabled you can set the default output format to be used for
-# thA MathJax output. Supported types are HTML-CSS, NativeMML (i.e. MathML) and
-# SVG. The default value is HTML-CSS, which is slower, but has the best
-# compatibility.
-
-MATHJAX_FORMAT = HTML-CSS
-
-# When MathJax is enabled you need to specify the location relative to the
-# HTML output directory using the MATHJAX_RELPATH option. The destination
-# directory should contain the MathJax.js script. For instance, if the mathjax
-# directory is located at the same level as the HTML output directory, then
-# MATHJAX_RELPATH should be ../mathjax. The default value points to
-# the MathJax Content Delivery Network so you can quickly see the result without
-# installing MathJax.
-# However, it is strongly recommended to install a local
-# copy of MathJax from http://www.mathjax.org before deployment.
-
-MATHJAX_RELPATH = http://cdn.mathjax.org/mathjax/latest
-
-# The MATHJAX_EXTENSIONS tag can be used to specify one or MathJax extension
-# names that should be enabled during MathJax rendering.
-
-MATHJAX_EXTENSIONS =
-
-# When the SEARCHENGINE tag is enabled doxygen will generate a search box
-# for the HTML output. The underlying search engine uses javascript
-# and DHTML and should work on any modern browser. Note that when using
-# HTML help (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets
-# (GENERATE_DOCSET) there is already a search function so this one should
-# typically be disabled. For large projects the javascript based search engine
-# can be slow, then enabling SERVER_BASED_SEARCH may provide a better solution.
-
-SEARCHENGINE = YES
-
-# When the SERVER_BASED_SEARCH tag is enabled the search engine will be
-# implemented using a web server instead of a web client using Javascript.
-# There are two flavours of web server based search depending on the
-# EXTERNAL_SEARCH setting. When disabled, doxygen will generate a PHP script for
-# searching and an index file used by the script. When EXTERNAL_SEARCH is
-# enabled the indexing and searching needs to be provided by external tools.
-# See the manual for details.
-
-SERVER_BASED_SEARCH = NO
-
-# When EXTERNAL_SEARCH is enabled doxygen will no longer generate the PHP
-# script for searching. Instead the search results are written to an XML file
-# which needs to be processed by an external indexer. Doxygen will invoke an
-# external search engine pointed to by the SEARCHENGINE_URL option to obtain
-# the search results. Doxygen ships with an example indexer (doxyindexer) and
-# search engine (doxysearch.cgi) which are based on the open source search engine
-# library Xapian. See the manual for configuration details.
-
-EXTERNAL_SEARCH = NO
-
-# The SEARCHENGINE_URL should point to a search engine hosted by a web server
-# which will returned the search results when EXTERNAL_SEARCH is enabled.
-# Doxygen ships with an example search engine (doxysearch) which is based on
-# the open source search engine library Xapian. See the manual for configuration
-# details.
-
-SEARCHENGINE_URL =
-
-# When SERVER_BASED_SEARCH and EXTERNAL_SEARCH are both enabled the unindexed
-# search data is written to a file for indexing by an external tool. With the
-# SEARCHDATA_FILE tag the name of this file can be specified.
-
-SEARCHDATA_FILE = searchdata.xml
-
-# When SERVER_BASED_SEARCH AND EXTERNAL_SEARCH are both enabled the
-# EXTERNAL_SEARCH_ID tag can be used as an identifier for the project. This is
-# useful in combination with EXTRA_SEARCH_MAPPINGS to search through multiple
-# projects and redirect the results back to the right project.
-
-EXTERNAL_SEARCH_ID =
-
-# The EXTRA_SEARCH_MAPPINGS tag can be used to enable searching through doxygen
-# projects other than the one defined by this configuration file, but that are
-# all added to the same external search index. Each project needs to have a
-# unique id set via EXTERNAL_SEARCH_ID. The search mapping then maps the id
-# of to a relative location where the documentation can be found.
-# The format is: EXTRA_SEARCH_MAPPINGS = id1=loc1 id2=loc2 ...
-
-EXTRA_SEARCH_MAPPINGS =
-
-#---------------------------------------------------------------------------
-# configuration options related to the LaTeX output
-#---------------------------------------------------------------------------
-
-# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will
-# generate Latex output.
-
GENERATE_LATEX = NO
-
-# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put.
-# If a relative path is entered the value of OUTPUT_DIRECTORY will be
-# put in front of it. If left blank `latex' will be used as the default path.
-
-LATEX_OUTPUT = latex
-
-# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be
-# invoked. If left blank `latex' will be used as the default command name.
-# Note that when enabling USE_PDFLATEX this option is only used for
-# generating bitmaps for formulas in the HTML output, but not in the
-# Makefile that is written to the output directory.
-
-LATEX_CMD_NAME = latex
-
-# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to
-# generate index for LaTeX. If left blank `makeindex' will be used as the
-# default command name.
-
-MAKEINDEX_CMD_NAME = makeindex
-
-# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact
-# LaTeX documents. This may be useful for small projects and may help to
-# save some trees in general.
-
-COMPACT_LATEX = NO
-
-# The PAPER_TYPE tag can be used to set the paper type that is used
-# by the printer. Possible values are: a4, letter, legal and
-# executive. If left blank a4wide will be used.
-
-PAPER_TYPE = a4
-
-# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX
-# packages that should be included in the LaTeX output.
-
-EXTRA_PACKAGES =
-
-# The LATEX_HEADER tag can be used to specify a personal LaTeX header for
-# the generated latex document. The header should contain everything until
-# the first chapter. If it is left blank doxygen will generate a
-# standard header. Notice: only use this tag if you know what you are doing!
-
-LATEX_HEADER =
-
-# The LATEX_FOOTER tag can be used to specify a personal LaTeX footer for
-# the generated latex document. The footer should contain everything after
-# the last chapter. If it is left blank doxygen will generate a
-# standard footer. Notice: only use this tag if you know what you are doing!
-
-LATEX_FOOTER =
-
-# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated
-# is prepared for conversion to pdf (using ps2pdf). The pdf file will
-# contain links (just like the HTML output) instead of page references
-# This makes the output suitable for online browsing using a pdf viewer.
-
-PDF_HYPERLINKS = YES
-
-# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of
-# plain latex in the generated Makefile. Set this option to YES to get a
-# higher quality PDF documentation.
-
-USE_PDFLATEX = YES
-
-# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode.
-# command to the generated LaTeX files. This will instruct LaTeX to keep
-# running if errors occur, instead of asking the user for help.
-# This option is also used when generating formulas in HTML.
-
-LATEX_BATCHMODE = NO
-
-# If LATEX_HIDE_INDICES is set to YES then doxygen will not
-# include the index chapters (such as File Index, Compound Index, etc.)
-# in the output.
-
-LATEX_HIDE_INDICES = NO
-
-# If LATEX_SOURCE_CODE is set to YES then doxygen will include
-# source code with syntax highlighting in the LaTeX output.
-# Note that which sources are shown also depends on other settings
-# such as SOURCE_BROWSER.
-
-LATEX_SOURCE_CODE = NO
-
-# The LATEX_BIB_STYLE tag can be used to specify the style to use for the
-# bibliography, e.g. plainnat, or ieeetr. The default style is "plain". See
-# http://en.wikipedia.org/wiki/BibTeX for more info.
-
-LATEX_BIB_STYLE = plain
-
-#---------------------------------------------------------------------------
-# configuration options related to the RTF output
-#---------------------------------------------------------------------------
-
-# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output
-# The RTF output is optimized for Word 97 and may not look very pretty with
-# other RTF readers or editors.
-
-GENERATE_RTF = NO
-
-# The RTF_OUTPUT tag is used to specify where the RTF docs will be put.
-# If a relative path is entered the value of OUTPUT_DIRECTORY will be
-# put in front of it. If left blank `rtf' will be used as the default path.
-
-RTF_OUTPUT = rtf
-
-# If the COMPACT_RTF tag is set to YES Doxygen generates more compact
-# RTF documents. This may be useful for small projects and may help to
-# save some trees in general.
-
-COMPACT_RTF = NO
-
-# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated
-# will contain hyperlink fields. The RTF file will
-# contain links (just like the HTML output) instead of page references.
-# This makes the output suitable for online browsing using WORD or other
-# programs which support those fields.
-# Note: wordpad (write) and others do not support links.
-
-RTF_HYPERLINKS = NO
-
-# Load style sheet definitions from file. Syntax is similar to doxygen's
-# config file, i.e. a series of assignments. You only have to provide
-# replacements, missing definitions are set to their default value.
-
-RTF_STYLESHEET_FILE =
-
-# Set optional variables used in the generation of an rtf document.
-# Syntax is similar to doxygen's config file.
-
-RTF_EXTENSIONS_FILE =
-
-#---------------------------------------------------------------------------
-# configuration options related to the man page output
-#---------------------------------------------------------------------------
-
-# If the GENERATE_MAN tag is set to YES (the default) Doxygen will
-# generate man pages
-
-GENERATE_MAN = NO
-
-# The MAN_OUTPUT tag is used to specify where the man pages will be put.
-# If a relative path is entered the value of OUTPUT_DIRECTORY will be
-# put in front of it. If left blank `man' will be used as the default path.
-
-MAN_OUTPUT = man
-
-# The MAN_EXTENSION tag determines the extension that is added to
-# the generated man pages (default is the subroutine's section .3)
-
-MAN_EXTENSION = .3
-
-# If the MAN_LINKS tag is set to YES and Doxygen generates man output,
-# then it will generate one additional man file for each entity
-# documented in the real man page(s). These additional files
-# only source the real man page, but without them the man command
-# would be unable to find the correct page. The default is NO.
-
-MAN_LINKS = NO
-
-#---------------------------------------------------------------------------
-# configuration options related to the XML output
-#---------------------------------------------------------------------------
-
-# If the GENERATE_XML tag is set to YES Doxygen will
-# generate an XML file that captures the structure of
-# the code including all documentation.
-
-GENERATE_XML = NO
-
-# The XML_OUTPUT tag is used to specify where the XML pages will be put.
-# If a relative path is entered the value of OUTPUT_DIRECTORY will be
-# put in front of it. If left blank `xml' will be used as the default path.
-
-XML_OUTPUT = xml
-
-# The XML_SCHEMA tag can be used to specify an XML schema,
-# which can be used by a validating XML parser to check the
-# syntax of the XML files.
-
-XML_SCHEMA =
-
-# The XML_DTD tag can be used to specify an XML DTD,
-# which can be used by a validating XML parser to check the
-# syntax of the XML files.
-
-XML_DTD =
-
-# If the XML_PROGRAMLISTING tag is set to YES Doxygen will
-# dump the program listings (including syntax highlighting
-# and cross-referencing information) to the XML output. Note that
-# enabling this will significantly increase the size of the XML output.
-
-XML_PROGRAMLISTING = YES
-
-#---------------------------------------------------------------------------
-# configuration options for the AutoGen Definitions output
-#---------------------------------------------------------------------------
-
-# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will
-# generate an AutoGen Definitions (see autogen.sf.net) file
-# that captures the structure of the code including all
-# documentation. Note that this feature is still experimental
-# and incomplete at the moment.
-
-GENERATE_AUTOGEN_DEF = NO
-
-#---------------------------------------------------------------------------
-# configuration options related to the Perl module output
-#---------------------------------------------------------------------------
-
-# If the GENERATE_PERLMOD tag is set to YES Doxygen will
-# generate a Perl module file that captures the structure of
-# the code including all documentation. Note that this
-# feature is still experimental and incomplete at the
-# moment.
-
-GENERATE_PERLMOD = NO
-
-# If the PERLMOD_LATEX tag is set to YES Doxygen will generate
-# the necessary Makefile rules, Perl scripts and LaTeX code to be able
-# to generate PDF and DVI output from the Perl module output.
-
-PERLMOD_LATEX = NO
-
-# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be
-# nicely formatted so it can be parsed by a human reader.
-# This is useful
-# if you want to understand what is going on.
-# On the other hand, if this
-# tag is set to NO the size of the Perl module output will be much smaller
-# and Perl will parse it just the same.
-
-PERLMOD_PRETTY = YES
-
-# The names of the make variables in the generated doxyrules.make file
-# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX.
-# This is useful so different doxyrules.make files included by the same
-# Makefile don't overwrite each other's variables.
-
-PERLMOD_MAKEVAR_PREFIX =
-
-#---------------------------------------------------------------------------
-# Configuration options related to the preprocessor
-#---------------------------------------------------------------------------
-
-# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will
-# evaluate all C-preprocessor directives found in the sources and include
-# files.
-
-ENABLE_PREPROCESSING = YES
-
-# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro
-# names in the source code. If set to NO (the default) only conditional
-# compilation will be performed. Macro expansion can be done in a controlled
-# way by setting EXPAND_ONLY_PREDEF to YES.
-
MACRO_EXPANSION = YES
-
-# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES
-# then the macro expansion is limited to the macros specified with the
-# PREDEFINED and EXPAND_AS_DEFINED tags.
-
EXPAND_ONLY_PREDEF = YES
-
-# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files
-# pointed to by INCLUDE_PATH will be searched when a #include is found.
-
-SEARCH_INCLUDES = YES
-
-# The INCLUDE_PATH tag can be used to specify one or more directories that
-# contain include files that are not input files but should be processed by
-# the preprocessor.
-
-INCLUDE_PATH =
-
-# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard
-# patterns (like *.h and *.hpp) to filter out the header-files in the
-# directories. If left blank, the patterns specified with FILE_PATTERNS will
-# be used.
-
-INCLUDE_FILE_PATTERNS =
-
-# The PREDEFINED tag can be used to specify one or more macro names that
-# are defined before the preprocessor is started (similar to the -D option of
-# gcc). The argument of the tag is a list of macros of the form: name
-# or name=definition (no spaces). If the definition and the = are
-# omitted =1 is assumed. To prevent a macro definition from being
-# undefined via #undef or recursively expanded use the := operator
-# instead of the = operator.
-
PREDEFINED = LIBEVDEV_ATTRIBUTE_PRINTF(f,a)=
-
-# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then
-# this tag can be used to specify a list of macro names that should be expanded.
-# The macro definition that is found in the sources will be used.
-# Use the PREDEFINED tag if you want to use a different macro definition that
-# overrules the definition found in the source code.
-
-EXPAND_AS_DEFINED =
-
-# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then
-# doxygen's preprocessor will remove all references to function-like macros
-# that are alone on a line, have an all uppercase name, and do not end with a
-# semicolon, because these will confuse the parser if not removed.
-
-SKIP_FUNCTION_MACROS = YES
-
-#---------------------------------------------------------------------------
-# Configuration::additions related to external references
-#---------------------------------------------------------------------------
-
-# The TAGFILES option can be used to specify one or more tagfiles. For each
-# tag file the location of the external documentation should be added. The
-# format of a tag file without this location is as follows:
-#
-# TAGFILES = file1 file2 ...
-# Adding location for the tag files is done as follows:
-#
-# TAGFILES = file1=loc1 "file2 = loc2" ...
-# where "loc1" and "loc2" can be relative or absolute paths
-# or URLs. Note that each tag file must have a unique name (where the name does
-# NOT include the path). If a tag file is not located in the directory in which
-# doxygen is run, you must also specify the path to the tagfile here.
-
-TAGFILES =
-
-# When a file name is specified after GENERATE_TAGFILE, doxygen will create
-# a tag file that is based on the input files it reads.
-
-GENERATE_TAGFILE =
-
-# If the ALLEXTERNALS tag is set to YES all external classes will be listed
-# in the class index. If set to NO only the inherited external classes
-# will be listed.
-
-ALLEXTERNALS = NO
-
-# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed
-# in the modules index. If set to NO, only the current project's groups will
-# be listed.
-
-EXTERNAL_GROUPS = YES
-
-# The PERL_PATH should be the absolute path and name of the perl script
-# interpreter (i.e. the result of `which perl').
-
-PERL_PATH = /usr/bin/perl
-
-#---------------------------------------------------------------------------
-# Configuration options related to the dot tool
-#---------------------------------------------------------------------------
-
-# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will
-# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base
-# or super classes. Setting the tag to NO turns the diagrams off. Note that
-# this option also works with HAVE_DOT disabled, but it is recommended to
-# install and use dot, since it yields more powerful graphs.
-
-CLASS_DIAGRAMS = YES
-
-# You can define message sequence charts within doxygen comments using the \msc
-# command. Doxygen will then run the mscgen tool (see
-# http://www.mcternan.me.uk/mscgen/) to produce the chart and insert it in the
-# documentation. The MSCGEN_PATH tag allows you to specify the directory where
-# the mscgen tool resides. If left empty the tool is assumed to be found in the
-# default search path.
-
-MSCGEN_PATH =
-
-# If set to YES, the inheritance and collaboration graphs will hide
-# inheritance and usage relations if the target is undocumented
-# or is not a class.
-
-HIDE_UNDOC_RELATIONS = YES
-
-# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is
-# available from the path. This tool is part of Graphviz, a graph visualization
-# toolkit from AT&T and Lucent Bell Labs. The other options in this section
-# have no effect if this option is set to NO (the default)
-
-HAVE_DOT = NO
-
-# The DOT_NUM_THREADS specifies the number of dot invocations doxygen is
-# allowed to run in parallel. When set to 0 (the default) doxygen will
-# base this on the number of processors available in the system. You can set it
-# explicitly to a value larger than 0 to get control over the balance
-# between CPU load and processing speed.
-
-DOT_NUM_THREADS = 0
-
-# By default doxygen will use the Helvetica font for all dot files that
-# doxygen generates. When you want a differently looking font you can specify
-# the font name using DOT_FONTNAME. You need to make sure dot is able to find
-# the font, which can be done by putting it in a standard location or by setting
-# the DOTFONTPATH environment variable or by setting DOT_FONTPATH to the
-# directory containing the font.
-
-DOT_FONTNAME = Helvetica
-
-# The DOT_FONTSIZE tag can be used to set the size of the font of dot graphs.
-# The default size is 10pt.
-
-DOT_FONTSIZE = 10
-
-# By default doxygen will tell dot to use the Helvetica font.
-# If you specify a different font using DOT_FONTNAME you can use DOT_FONTPATH to
-# set the path where dot can find it.
-
-DOT_FONTPATH =
-
-# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen
-# will generate a graph for each documented class showing the direct and
-# indirect inheritance relations. Setting this tag to YES will force the
-# CLASS_DIAGRAMS tag to NO.
-
-CLASS_GRAPH = YES
-
-# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen
-# will generate a graph for each documented class showing the direct and
-# indirect implementation dependencies (inheritance, containment, and
-# class references variables) of the class with other documented classes.
-
-COLLABORATION_GRAPH = YES
-
-# If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen
-# will generate a graph for groups, showing the direct groups dependencies
-
-GROUP_GRAPHS = YES
-
-# If the UML_LOOK tag is set to YES doxygen will generate inheritance and
-# collaboration diagrams in a style similar to the OMG's Unified Modeling
-# Language.
-
-UML_LOOK = NO
-
-# If the UML_LOOK tag is enabled, the fields and methods are shown inside
-# the class node. If there are many fields or methods and many nodes the
-# graph may become too big to be useful. The UML_LIMIT_NUM_FIELDS
-# threshold limits the number of items for each type to make the size more
-# managable. Set this to 0 for no limit. Note that the threshold may be
-# exceeded by 50% before the limit is enforced.
-
-UML_LIMIT_NUM_FIELDS = 10
-
-# If set to YES, the inheritance and collaboration graphs will show the
-# relations between templates and their instances.
-
-TEMPLATE_RELATIONS = NO
-
-# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT
-# tags are set to YES then doxygen will generate a graph for each documented
-# file showing the direct and indirect include dependencies of the file with
-# other documented files.
-
-INCLUDE_GRAPH = YES
-
-# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and
-# HAVE_DOT tags are set to YES then doxygen will generate a graph for each
-# documented header file showing the documented files that directly or
-# indirectly include this file.
-
-INCLUDED_BY_GRAPH = YES
-
-# If the CALL_GRAPH and HAVE_DOT options are set to YES then
-# doxygen will generate a call dependency graph for every global function
-# or class method. Note that enabling this option will significantly increase
-# the time of a run. So in most cases it will be better to enable call graphs
-# for selected functions only using the \callgraph command.
-
-CALL_GRAPH = NO
-
-# If the CALLER_GRAPH and HAVE_DOT tags are set to YES then
-# doxygen will generate a caller dependency graph for every global function
-# or class method. Note that enabling this option will significantly increase
-# the time of a run. So in most cases it will be better to enable caller
-# graphs for selected functions only using the \callergraph command.
-
-CALLER_GRAPH = NO
-
-# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen
-# will generate a graphical hierarchy of all classes instead of a textual one.
-
-GRAPHICAL_HIERARCHY = YES
-
-# If the DIRECTORY_GRAPH and HAVE_DOT tags are set to YES
-# then doxygen will show the dependencies a directory has on other directories
-# in a graphical way. The dependency relations are determined by the #include
-# relations between the files in the directories.
-
-DIRECTORY_GRAPH = YES
-
-# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images
-# generated by dot. Possible values are svg, png, jpg, or gif.
-# If left blank png will be used. If you choose svg you need to set
-# HTML_FILE_EXTENSION to xhtml in order to make the SVG files
-# visible in IE 9+ (other browsers do not have this requirement).
-
-DOT_IMAGE_FORMAT = png
-
-# If DOT_IMAGE_FORMAT is set to svg, then this option can be set to YES to
-# enable generation of interactive SVG images that allow zooming and panning.
-# Note that this requires a modern browser other than Internet Explorer.
-# Tested and working are Firefox, Chrome, Safari, and Opera. For IE 9+ you
-# need to set HTML_FILE_EXTENSION to xhtml in order to make the SVG files
-# visible. Older versions of IE do not have SVG support.
-
-INTERACTIVE_SVG = NO
-
-# The tag DOT_PATH can be used to specify the path where the dot tool can be
-# found. If left blank, it is assumed the dot tool can be found in the path.
-
-DOT_PATH =
-
-# The DOTFILE_DIRS tag can be used to specify one or more directories that
-# contain dot files that are included in the documentation (see the
-# \dotfile command).
-
-DOTFILE_DIRS =
-
-# The MSCFILE_DIRS tag can be used to specify one or more directories that
-# contain msc files that are included in the documentation (see the
-# \mscfile command).
-
-MSCFILE_DIRS =
-
-# The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of
-# nodes that will be shown in the graph. If the number of nodes in a graph
-# becomes larger than this value, doxygen will truncate the graph, which is
-# visualized by representing a node as a red box. Note that doxygen if the
-# number of direct children of the root node in a graph is already larger than
-# DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note
-# that the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH.
-
-DOT_GRAPH_MAX_NODES = 50
-
-# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the
-# graphs generated by dot. A depth value of 3 means that only nodes reachable
-# from the root by following a path via at most 3 edges will be shown. Nodes
-# that lay further from the root node will be omitted. Note that setting this
-# option to 1 or 2 may greatly reduce the computation time needed for large
-# code bases. Also note that the size of a graph can be further restricted by
-# DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction.
-
-MAX_DOT_GRAPH_DEPTH = 0
-
-# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent
-# background. This is disabled by default, because dot on Windows does not
-# seem to support this out of the box. Warning: Depending on the platform used,
-# enabling this option may lead to badly anti-aliased labels on the edges of
-# a graph (i.e. they become hard to read).
-
-DOT_TRANSPARENT = NO
-
-# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output
-# files in one run (i.e. multiple -o and -T options on the command line). This
-# makes dot run faster, but since only newer versions of dot (>1.8.10)
-# support this, this feature is disabled by default.
-
-DOT_MULTI_TARGETS = NO
-
-# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will
-# generate a legend page explaining the meaning of the various boxes and
-# arrows in the dot generated graphs.
-
-GENERATE_LEGEND = YES
-
-# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will
-# remove the intermediate dot files that are used to generate
-# the various graphs.
-
-DOT_CLEANUP = YES
--- /dev/null
+/*
+ * Input event codes
+ *
+ * *** IMPORTANT ***
+ * This file is not only included from C-code but also from devicetree source
+ * files. As such this file MUST only contain comments and defines.
+ *
+ * Copyright (c) 1999-2002 Vojtech Pavlik
+ * Copyright (c) 2015 Hans de Goede <hdegoede@redhat.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ */
+#ifndef _UAPI_INPUT_EVENT_CODES_H
+#define _UAPI_INPUT_EVENT_CODES_H
+
+/*
+ * Device properties and quirks
+ */
+
+#define INPUT_PROP_POINTER 0x00 /* needs a pointer */
+#define INPUT_PROP_DIRECT 0x01 /* direct input devices */
+#define INPUT_PROP_BUTTONPAD 0x02 /* has button(s) under pad */
+#define INPUT_PROP_SEMI_MT 0x03 /* touch rectangle only */
+#define INPUT_PROP_TOPBUTTONPAD 0x04 /* softbuttons at top of pad */
+#define INPUT_PROP_POINTING_STICK 0x05 /* is a pointing stick */
+#define INPUT_PROP_ACCELEROMETER 0x06 /* has accelerometer */
+
+#define INPUT_PROP_MAX 0x1f
+#define INPUT_PROP_CNT (INPUT_PROP_MAX + 1)
+
+/*
+ * Event types
+ */
+
+#define EV_SYN 0x00
+#define EV_KEY 0x01
+#define EV_REL 0x02
+#define EV_ABS 0x03
+#define EV_MSC 0x04
+#define EV_SW 0x05
+#define EV_LED 0x11
+#define EV_SND 0x12
+#define EV_REP 0x14
+#define EV_FF 0x15
+#define EV_PWR 0x16
+#define EV_FF_STATUS 0x17
+#define EV_MAX 0x1f
+#define EV_CNT (EV_MAX+1)
+
+/*
+ * Synchronization events.
+ */
+
+#define SYN_REPORT 0
+#define SYN_CONFIG 1
+#define SYN_MT_REPORT 2
+#define SYN_DROPPED 3
+#define SYN_MAX 0xf
+#define SYN_CNT (SYN_MAX+1)
+
+/*
+ * Keys and buttons
+ *
+ * Most of the keys/buttons are modeled after USB HUT 1.12
+ * (see http://www.usb.org/developers/hidpage).
+ * Abbreviations in the comments:
+ * AC - Application Control
+ * AL - Application Launch Button
+ * SC - System Control
+ */
+
+#define KEY_RESERVED 0
+#define KEY_ESC 1
+#define KEY_1 2
+#define KEY_2 3
+#define KEY_3 4
+#define KEY_4 5
+#define KEY_5 6
+#define KEY_6 7
+#define KEY_7 8
+#define KEY_8 9
+#define KEY_9 10
+#define KEY_0 11
+#define KEY_MINUS 12
+#define KEY_EQUAL 13
+#define KEY_BACKSPACE 14
+#define KEY_TAB 15
+#define KEY_Q 16
+#define KEY_W 17
+#define KEY_E 18
+#define KEY_R 19
+#define KEY_T 20
+#define KEY_Y 21
+#define KEY_U 22
+#define KEY_I 23
+#define KEY_O 24
+#define KEY_P 25
+#define KEY_LEFTBRACE 26
+#define KEY_RIGHTBRACE 27
+#define KEY_ENTER 28
+#define KEY_LEFTCTRL 29
+#define KEY_A 30
+#define KEY_S 31
+#define KEY_D 32
+#define KEY_F 33
+#define KEY_G 34
+#define KEY_H 35
+#define KEY_J 36
+#define KEY_K 37
+#define KEY_L 38
+#define KEY_SEMICOLON 39
+#define KEY_APOSTROPHE 40
+#define KEY_GRAVE 41
+#define KEY_LEFTSHIFT 42
+#define KEY_BACKSLASH 43
+#define KEY_Z 44
+#define KEY_X 45
+#define KEY_C 46
+#define KEY_V 47
+#define KEY_B 48
+#define KEY_N 49
+#define KEY_M 50
+#define KEY_COMMA 51
+#define KEY_DOT 52
+#define KEY_SLASH 53
+#define KEY_RIGHTSHIFT 54
+#define KEY_KPASTERISK 55
+#define KEY_LEFTALT 56
+#define KEY_SPACE 57
+#define KEY_CAPSLOCK 58
+#define KEY_F1 59
+#define KEY_F2 60
+#define KEY_F3 61
+#define KEY_F4 62
+#define KEY_F5 63
+#define KEY_F6 64
+#define KEY_F7 65
+#define KEY_F8 66
+#define KEY_F9 67
+#define KEY_F10 68
+#define KEY_NUMLOCK 69
+#define KEY_SCROLLLOCK 70
+#define KEY_KP7 71
+#define KEY_KP8 72
+#define KEY_KP9 73
+#define KEY_KPMINUS 74
+#define KEY_KP4 75
+#define KEY_KP5 76
+#define KEY_KP6 77
+#define KEY_KPPLUS 78
+#define KEY_KP1 79
+#define KEY_KP2 80
+#define KEY_KP3 81
+#define KEY_KP0 82
+#define KEY_KPDOT 83
+
+#define KEY_ZENKAKUHANKAKU 85
+#define KEY_102ND 86
+#define KEY_F11 87
+#define KEY_F12 88
+#define KEY_RO 89
+#define KEY_KATAKANA 90
+#define KEY_HIRAGANA 91
+#define KEY_HENKAN 92
+#define KEY_KATAKANAHIRAGANA 93
+#define KEY_MUHENKAN 94
+#define KEY_KPJPCOMMA 95
+#define KEY_KPENTER 96
+#define KEY_RIGHTCTRL 97
+#define KEY_KPSLASH 98
+#define KEY_SYSRQ 99
+#define KEY_RIGHTALT 100
+#define KEY_LINEFEED 101
+#define KEY_HOME 102
+#define KEY_UP 103
+#define KEY_PAGEUP 104
+#define KEY_LEFT 105
+#define KEY_RIGHT 106
+#define KEY_END 107
+#define KEY_DOWN 108
+#define KEY_PAGEDOWN 109
+#define KEY_INSERT 110
+#define KEY_DELETE 111
+#define KEY_MACRO 112
+#define KEY_MUTE 113
+#define KEY_VOLUMEDOWN 114
+#define KEY_VOLUMEUP 115
+#define KEY_POWER 116 /* SC System Power Down */
+#define KEY_KPEQUAL 117
+#define KEY_KPPLUSMINUS 118
+#define KEY_PAUSE 119
+#define KEY_SCALE 120 /* AL Compiz Scale (Expose) */
+
+#define KEY_KPCOMMA 121
+#define KEY_HANGEUL 122
+#define KEY_HANGUEL KEY_HANGEUL
+#define KEY_HANJA 123
+#define KEY_YEN 124
+#define KEY_LEFTMETA 125
+#define KEY_RIGHTMETA 126
+#define KEY_COMPOSE 127
+
+#define KEY_STOP 128 /* AC Stop */
+#define KEY_AGAIN 129
+#define KEY_PROPS 130 /* AC Properties */
+#define KEY_UNDO 131 /* AC Undo */
+#define KEY_FRONT 132
+#define KEY_COPY 133 /* AC Copy */
+#define KEY_OPEN 134 /* AC Open */
+#define KEY_PASTE 135 /* AC Paste */
+#define KEY_FIND 136 /* AC Search */
+#define KEY_CUT 137 /* AC Cut */
+#define KEY_HELP 138 /* AL Integrated Help Center */
+#define KEY_MENU 139 /* Menu (show menu) */
+#define KEY_CALC 140 /* AL Calculator */
+#define KEY_SETUP 141
+#define KEY_SLEEP 142 /* SC System Sleep */
+#define KEY_WAKEUP 143 /* System Wake Up */
+#define KEY_FILE 144 /* AL Local Machine Browser */
+#define KEY_SENDFILE 145
+#define KEY_DELETEFILE 146
+#define KEY_XFER 147
+#define KEY_PROG1 148
+#define KEY_PROG2 149
+#define KEY_WWW 150 /* AL Internet Browser */
+#define KEY_MSDOS 151
+#define KEY_COFFEE 152 /* AL Terminal Lock/Screensaver */
+#define KEY_SCREENLOCK KEY_COFFEE
+#define KEY_ROTATE_DISPLAY 153 /* Display orientation for e.g. tablets */
+#define KEY_DIRECTION KEY_ROTATE_DISPLAY
+#define KEY_CYCLEWINDOWS 154
+#define KEY_MAIL 155
+#define KEY_BOOKMARKS 156 /* AC Bookmarks */
+#define KEY_COMPUTER 157
+#define KEY_BACK 158 /* AC Back */
+#define KEY_FORWARD 159 /* AC Forward */
+#define KEY_CLOSECD 160
+#define KEY_EJECTCD 161
+#define KEY_EJECTCLOSECD 162
+#define KEY_NEXTSONG 163
+#define KEY_PLAYPAUSE 164
+#define KEY_PREVIOUSSONG 165
+#define KEY_STOPCD 166
+#define KEY_RECORD 167
+#define KEY_REWIND 168
+#define KEY_PHONE 169 /* Media Select Telephone */
+#define KEY_ISO 170
+#define KEY_CONFIG 171 /* AL Consumer Control Configuration */
+#define KEY_HOMEPAGE 172 /* AC Home */
+#define KEY_REFRESH 173 /* AC Refresh */
+#define KEY_EXIT 174 /* AC Exit */
+#define KEY_MOVE 175
+#define KEY_EDIT 176
+#define KEY_SCROLLUP 177
+#define KEY_SCROLLDOWN 178
+#define KEY_KPLEFTPAREN 179
+#define KEY_KPRIGHTPAREN 180
+#define KEY_NEW 181 /* AC New */
+#define KEY_REDO 182 /* AC Redo/Repeat */
+
+#define KEY_F13 183
+#define KEY_F14 184
+#define KEY_F15 185
+#define KEY_F16 186
+#define KEY_F17 187
+#define KEY_F18 188
+#define KEY_F19 189
+#define KEY_F20 190
+#define KEY_F21 191
+#define KEY_F22 192
+#define KEY_F23 193
+#define KEY_F24 194
+
+#define KEY_PLAYCD 200
+#define KEY_PAUSECD 201
+#define KEY_PROG3 202
+#define KEY_PROG4 203
+#define KEY_DASHBOARD 204 /* AL Dashboard */
+#define KEY_SUSPEND 205
+#define KEY_CLOSE 206 /* AC Close */
+#define KEY_PLAY 207
+#define KEY_FASTFORWARD 208
+#define KEY_BASSBOOST 209
+#define KEY_PRINT 210 /* AC Print */
+#define KEY_HP 211
+#define KEY_CAMERA 212
+#define KEY_SOUND 213
+#define KEY_QUESTION 214
+#define KEY_EMAIL 215
+#define KEY_CHAT 216
+#define KEY_SEARCH 217
+#define KEY_CONNECT 218
+#define KEY_FINANCE 219 /* AL Checkbook/Finance */
+#define KEY_SPORT 220
+#define KEY_SHOP 221
+#define KEY_ALTERASE 222
+#define KEY_CANCEL 223 /* AC Cancel */
+#define KEY_BRIGHTNESSDOWN 224
+#define KEY_BRIGHTNESSUP 225
+#define KEY_MEDIA 226
+
+#define KEY_SWITCHVIDEOMODE 227 /* Cycle between available video
+ outputs (Monitor/LCD/TV-out/etc) */
+#define KEY_KBDILLUMTOGGLE 228
+#define KEY_KBDILLUMDOWN 229
+#define KEY_KBDILLUMUP 230
+
+#define KEY_SEND 231 /* AC Send */
+#define KEY_REPLY 232 /* AC Reply */
+#define KEY_FORWARDMAIL 233 /* AC Forward Msg */
+#define KEY_SAVE 234 /* AC Save */
+#define KEY_DOCUMENTS 235
+
+#define KEY_BATTERY 236
+
+#define KEY_BLUETOOTH 237
+#define KEY_WLAN 238
+#define KEY_UWB 239
+
+#define KEY_UNKNOWN 240
+
+#define KEY_VIDEO_NEXT 241 /* drive next video source */
+#define KEY_VIDEO_PREV 242 /* drive previous video source */
+#define KEY_BRIGHTNESS_CYCLE 243 /* brightness up, after max is min */
+#define KEY_BRIGHTNESS_AUTO 244 /* Set Auto Brightness: manual
+ brightness control is off,
+ rely on ambient */
+#define KEY_BRIGHTNESS_ZERO KEY_BRIGHTNESS_AUTO
+#define KEY_DISPLAY_OFF 245 /* display device to off state */
+
+#define KEY_WWAN 246 /* Wireless WAN (LTE, UMTS, GSM, etc.) */
+#define KEY_WIMAX KEY_WWAN
+#define KEY_RFKILL 247 /* Key that controls all radios */
+
+#define KEY_MICMUTE 248 /* Mute / unmute the microphone */
+
+/* Code 255 is reserved for special needs of AT keyboard driver */
+
+#define BTN_MISC 0x100
+#define BTN_0 0x100
+#define BTN_1 0x101
+#define BTN_2 0x102
+#define BTN_3 0x103
+#define BTN_4 0x104
+#define BTN_5 0x105
+#define BTN_6 0x106
+#define BTN_7 0x107
+#define BTN_8 0x108
+#define BTN_9 0x109
+
+#define BTN_MOUSE 0x110
+#define BTN_LEFT 0x110
+#define BTN_RIGHT 0x111
+#define BTN_MIDDLE 0x112
+#define BTN_SIDE 0x113
+#define BTN_EXTRA 0x114
+#define BTN_FORWARD 0x115
+#define BTN_BACK 0x116
+#define BTN_TASK 0x117
+
+#define BTN_JOYSTICK 0x120
+#define BTN_TRIGGER 0x120
+#define BTN_THUMB 0x121
+#define BTN_THUMB2 0x122
+#define BTN_TOP 0x123
+#define BTN_TOP2 0x124
+#define BTN_PINKIE 0x125
+#define BTN_BASE 0x126
+#define BTN_BASE2 0x127
+#define BTN_BASE3 0x128
+#define BTN_BASE4 0x129
+#define BTN_BASE5 0x12a
+#define BTN_BASE6 0x12b
+#define BTN_DEAD 0x12f
+
+#define BTN_GAMEPAD 0x130
+#define BTN_SOUTH 0x130
+#define BTN_A BTN_SOUTH
+#define BTN_EAST 0x131
+#define BTN_B BTN_EAST
+#define BTN_C 0x132
+#define BTN_NORTH 0x133
+#define BTN_X BTN_NORTH
+#define BTN_WEST 0x134
+#define BTN_Y BTN_WEST
+#define BTN_Z 0x135
+#define BTN_TL 0x136
+#define BTN_TR 0x137
+#define BTN_TL2 0x138
+#define BTN_TR2 0x139
+#define BTN_SELECT 0x13a
+#define BTN_START 0x13b
+#define BTN_MODE 0x13c
+#define BTN_THUMBL 0x13d
+#define BTN_THUMBR 0x13e
+
+#define BTN_DIGI 0x140
+#define BTN_TOOL_PEN 0x140
+#define BTN_TOOL_RUBBER 0x141
+#define BTN_TOOL_BRUSH 0x142
+#define BTN_TOOL_PENCIL 0x143
+#define BTN_TOOL_AIRBRUSH 0x144
+#define BTN_TOOL_FINGER 0x145
+#define BTN_TOOL_MOUSE 0x146
+#define BTN_TOOL_LENS 0x147
+#define BTN_TOOL_QUINTTAP 0x148 /* Five fingers on trackpad */
+#define BTN_TOUCH 0x14a
+#define BTN_STYLUS 0x14b
+#define BTN_STYLUS2 0x14c
+#define BTN_TOOL_DOUBLETAP 0x14d
+#define BTN_TOOL_TRIPLETAP 0x14e
+#define BTN_TOOL_QUADTAP 0x14f /* Four fingers on trackpad */
+
+#define BTN_WHEEL 0x150
+#define BTN_GEAR_DOWN 0x150
+#define BTN_GEAR_UP 0x151
+
+#define KEY_OK 0x160
+#define KEY_SELECT 0x161
+#define KEY_GOTO 0x162
+#define KEY_CLEAR 0x163
+#define KEY_POWER2 0x164
+#define KEY_OPTION 0x165
+#define KEY_INFO 0x166 /* AL OEM Features/Tips/Tutorial */
+#define KEY_TIME 0x167
+#define KEY_VENDOR 0x168
+#define KEY_ARCHIVE 0x169
+#define KEY_PROGRAM 0x16a /* Media Select Program Guide */
+#define KEY_CHANNEL 0x16b
+#define KEY_FAVORITES 0x16c
+#define KEY_EPG 0x16d
+#define KEY_PVR 0x16e /* Media Select Home */
+#define KEY_MHP 0x16f
+#define KEY_LANGUAGE 0x170
+#define KEY_TITLE 0x171
+#define KEY_SUBTITLE 0x172
+#define KEY_ANGLE 0x173
+#define KEY_ZOOM 0x174
+#define KEY_MODE 0x175
+#define KEY_KEYBOARD 0x176
+#define KEY_SCREEN 0x177
+#define KEY_PC 0x178 /* Media Select Computer */
+#define KEY_TV 0x179 /* Media Select TV */
+#define KEY_TV2 0x17a /* Media Select Cable */
+#define KEY_VCR 0x17b /* Media Select VCR */
+#define KEY_VCR2 0x17c /* VCR Plus */
+#define KEY_SAT 0x17d /* Media Select Satellite */
+#define KEY_SAT2 0x17e
+#define KEY_CD 0x17f /* Media Select CD */
+#define KEY_TAPE 0x180 /* Media Select Tape */
+#define KEY_RADIO 0x181
+#define KEY_TUNER 0x182 /* Media Select Tuner */
+#define KEY_PLAYER 0x183
+#define KEY_TEXT 0x184
+#define KEY_DVD 0x185 /* Media Select DVD */
+#define KEY_AUX 0x186
+#define KEY_MP3 0x187
+#define KEY_AUDIO 0x188 /* AL Audio Browser */
+#define KEY_VIDEO 0x189 /* AL Movie Browser */
+#define KEY_DIRECTORY 0x18a
+#define KEY_LIST 0x18b
+#define KEY_MEMO 0x18c /* Media Select Messages */
+#define KEY_CALENDAR 0x18d
+#define KEY_RED 0x18e
+#define KEY_GREEN 0x18f
+#define KEY_YELLOW 0x190
+#define KEY_BLUE 0x191
+#define KEY_CHANNELUP 0x192 /* Channel Increment */
+#define KEY_CHANNELDOWN 0x193 /* Channel Decrement */
+#define KEY_FIRST 0x194
+#define KEY_LAST 0x195 /* Recall Last */
+#define KEY_AB 0x196
+#define KEY_NEXT 0x197
+#define KEY_RESTART 0x198
+#define KEY_SLOW 0x199
+#define KEY_SHUFFLE 0x19a
+#define KEY_BREAK 0x19b
+#define KEY_PREVIOUS 0x19c
+#define KEY_DIGITS 0x19d
+#define KEY_TEEN 0x19e
+#define KEY_TWEN 0x19f
+#define KEY_VIDEOPHONE 0x1a0 /* Media Select Video Phone */
+#define KEY_GAMES 0x1a1 /* Media Select Games */
+#define KEY_ZOOMIN 0x1a2 /* AC Zoom In */
+#define KEY_ZOOMOUT 0x1a3 /* AC Zoom Out */
+#define KEY_ZOOMRESET 0x1a4 /* AC Zoom */
+#define KEY_WORDPROCESSOR 0x1a5 /* AL Word Processor */
+#define KEY_EDITOR 0x1a6 /* AL Text Editor */
+#define KEY_SPREADSHEET 0x1a7 /* AL Spreadsheet */
+#define KEY_GRAPHICSEDITOR 0x1a8 /* AL Graphics Editor */
+#define KEY_PRESENTATION 0x1a9 /* AL Presentation App */
+#define KEY_DATABASE 0x1aa /* AL Database App */
+#define KEY_NEWS 0x1ab /* AL Newsreader */
+#define KEY_VOICEMAIL 0x1ac /* AL Voicemail */
+#define KEY_ADDRESSBOOK 0x1ad /* AL Contacts/Address Book */
+#define KEY_MESSENGER 0x1ae /* AL Instant Messaging */
+#define KEY_DISPLAYTOGGLE 0x1af /* Turn display (LCD) on and off */
+#define KEY_BRIGHTNESS_TOGGLE KEY_DISPLAYTOGGLE
+#define KEY_SPELLCHECK 0x1b0 /* AL Spell Check */
+#define KEY_LOGOFF 0x1b1 /* AL Logoff */
+
+#define KEY_DOLLAR 0x1b2
+#define KEY_EURO 0x1b3
+
+#define KEY_FRAMEBACK 0x1b4 /* Consumer - transport controls */
+#define KEY_FRAMEFORWARD 0x1b5
+#define KEY_CONTEXT_MENU 0x1b6 /* GenDesc - system context menu */
+#define KEY_MEDIA_REPEAT 0x1b7 /* Consumer - transport control */
+#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_DEL_EOL 0x1c0
+#define KEY_DEL_EOS 0x1c1
+#define KEY_INS_LINE 0x1c2
+#define KEY_DEL_LINE 0x1c3
+
+#define KEY_FN 0x1d0
+#define KEY_FN_ESC 0x1d1
+#define KEY_FN_F1 0x1d2
+#define KEY_FN_F2 0x1d3
+#define KEY_FN_F3 0x1d4
+#define KEY_FN_F4 0x1d5
+#define KEY_FN_F5 0x1d6
+#define KEY_FN_F6 0x1d7
+#define KEY_FN_F7 0x1d8
+#define KEY_FN_F8 0x1d9
+#define KEY_FN_F9 0x1da
+#define KEY_FN_F10 0x1db
+#define KEY_FN_F11 0x1dc
+#define KEY_FN_F12 0x1dd
+#define KEY_FN_1 0x1de
+#define KEY_FN_2 0x1df
+#define KEY_FN_D 0x1e0
+#define KEY_FN_E 0x1e1
+#define KEY_FN_F 0x1e2
+#define KEY_FN_S 0x1e3
+#define KEY_FN_B 0x1e4
+
+#define KEY_BRL_DOT1 0x1f1
+#define KEY_BRL_DOT2 0x1f2
+#define KEY_BRL_DOT3 0x1f3
+#define KEY_BRL_DOT4 0x1f4
+#define KEY_BRL_DOT5 0x1f5
+#define KEY_BRL_DOT6 0x1f6
+#define KEY_BRL_DOT7 0x1f7
+#define KEY_BRL_DOT8 0x1f8
+#define KEY_BRL_DOT9 0x1f9
+#define KEY_BRL_DOT10 0x1fa
+
+#define KEY_NUMERIC_0 0x200 /* used by phones, remote controls, */
+#define KEY_NUMERIC_1 0x201 /* and other keypads */
+#define KEY_NUMERIC_2 0x202
+#define KEY_NUMERIC_3 0x203
+#define KEY_NUMERIC_4 0x204
+#define KEY_NUMERIC_5 0x205
+#define KEY_NUMERIC_6 0x206
+#define KEY_NUMERIC_7 0x207
+#define KEY_NUMERIC_8 0x208
+#define KEY_NUMERIC_9 0x209
+#define KEY_NUMERIC_STAR 0x20a
+#define KEY_NUMERIC_POUND 0x20b
+#define KEY_NUMERIC_A 0x20c /* Phone key A - HUT Telephony 0xb9 */
+#define KEY_NUMERIC_B 0x20d
+#define KEY_NUMERIC_C 0x20e
+#define KEY_NUMERIC_D 0x20f
+
+#define KEY_CAMERA_FOCUS 0x210
+#define KEY_WPS_BUTTON 0x211 /* WiFi Protected Setup key */
+
+#define KEY_TOUCHPAD_TOGGLE 0x212 /* Request switch touchpad on or off */
+#define KEY_TOUCHPAD_ON 0x213
+#define KEY_TOUCHPAD_OFF 0x214
+
+#define KEY_CAMERA_ZOOMIN 0x215
+#define KEY_CAMERA_ZOOMOUT 0x216
+#define KEY_CAMERA_UP 0x217
+#define KEY_CAMERA_DOWN 0x218
+#define KEY_CAMERA_LEFT 0x219
+#define KEY_CAMERA_RIGHT 0x21a
+
+#define KEY_ATTENDANT_ON 0x21b
+#define KEY_ATTENDANT_OFF 0x21c
+#define KEY_ATTENDANT_TOGGLE 0x21d /* Attendant call on or off */
+#define KEY_LIGHTS_TOGGLE 0x21e /* Reading light on or off */
+
+#define BTN_DPAD_UP 0x220
+#define BTN_DPAD_DOWN 0x221
+#define BTN_DPAD_LEFT 0x222
+#define BTN_DPAD_RIGHT 0x223
+
+#define KEY_ALS_TOGGLE 0x230 /* Ambient light sensor */
+
+#define KEY_BUTTONCONFIG 0x240 /* AL Button Configuration */
+#define KEY_TASKMANAGER 0x241 /* AL Task/Project Manager */
+#define KEY_JOURNAL 0x242 /* AL Log/Journal/Timecard */
+#define KEY_CONTROLPANEL 0x243 /* AL Control Panel */
+#define KEY_APPSELECT 0x244 /* AL Select Task/Application */
+#define KEY_SCREENSAVER 0x245 /* AL Screen Saver */
+#define KEY_VOICECOMMAND 0x246 /* Listening Voice Command */
+
+#define KEY_BRIGHTNESS_MIN 0x250 /* Set Brightness to Minimum */
+#define KEY_BRIGHTNESS_MAX 0x251 /* Set Brightness to Maximum */
+
+#define KEY_KBDINPUTASSIST_PREV 0x260
+#define KEY_KBDINPUTASSIST_NEXT 0x261
+#define KEY_KBDINPUTASSIST_PREVGROUP 0x262
+#define KEY_KBDINPUTASSIST_NEXTGROUP 0x263
+#define KEY_KBDINPUTASSIST_ACCEPT 0x264
+#define KEY_KBDINPUTASSIST_CANCEL 0x265
+
+#define BTN_TRIGGER_HAPPY 0x2c0
+#define BTN_TRIGGER_HAPPY1 0x2c0
+#define BTN_TRIGGER_HAPPY2 0x2c1
+#define BTN_TRIGGER_HAPPY3 0x2c2
+#define BTN_TRIGGER_HAPPY4 0x2c3
+#define BTN_TRIGGER_HAPPY5 0x2c4
+#define BTN_TRIGGER_HAPPY6 0x2c5
+#define BTN_TRIGGER_HAPPY7 0x2c6
+#define BTN_TRIGGER_HAPPY8 0x2c7
+#define BTN_TRIGGER_HAPPY9 0x2c8
+#define BTN_TRIGGER_HAPPY10 0x2c9
+#define BTN_TRIGGER_HAPPY11 0x2ca
+#define BTN_TRIGGER_HAPPY12 0x2cb
+#define BTN_TRIGGER_HAPPY13 0x2cc
+#define BTN_TRIGGER_HAPPY14 0x2cd
+#define BTN_TRIGGER_HAPPY15 0x2ce
+#define BTN_TRIGGER_HAPPY16 0x2cf
+#define BTN_TRIGGER_HAPPY17 0x2d0
+#define BTN_TRIGGER_HAPPY18 0x2d1
+#define BTN_TRIGGER_HAPPY19 0x2d2
+#define BTN_TRIGGER_HAPPY20 0x2d3
+#define BTN_TRIGGER_HAPPY21 0x2d4
+#define BTN_TRIGGER_HAPPY22 0x2d5
+#define BTN_TRIGGER_HAPPY23 0x2d6
+#define BTN_TRIGGER_HAPPY24 0x2d7
+#define BTN_TRIGGER_HAPPY25 0x2d8
+#define BTN_TRIGGER_HAPPY26 0x2d9
+#define BTN_TRIGGER_HAPPY27 0x2da
+#define BTN_TRIGGER_HAPPY28 0x2db
+#define BTN_TRIGGER_HAPPY29 0x2dc
+#define BTN_TRIGGER_HAPPY30 0x2dd
+#define BTN_TRIGGER_HAPPY31 0x2de
+#define BTN_TRIGGER_HAPPY32 0x2df
+#define BTN_TRIGGER_HAPPY33 0x2e0
+#define BTN_TRIGGER_HAPPY34 0x2e1
+#define BTN_TRIGGER_HAPPY35 0x2e2
+#define BTN_TRIGGER_HAPPY36 0x2e3
+#define BTN_TRIGGER_HAPPY37 0x2e4
+#define BTN_TRIGGER_HAPPY38 0x2e5
+#define BTN_TRIGGER_HAPPY39 0x2e6
+#define BTN_TRIGGER_HAPPY40 0x2e7
+
+/* We avoid low common keys in module aliases so they don't get huge. */
+#define KEY_MIN_INTERESTING KEY_MUTE
+#define KEY_MAX 0x2ff
+#define KEY_CNT (KEY_MAX+1)
+
+/*
+ * Relative axes
+ */
+
+#define REL_X 0x00
+#define REL_Y 0x01
+#define REL_Z 0x02
+#define REL_RX 0x03
+#define REL_RY 0x04
+#define REL_RZ 0x05
+#define REL_HWHEEL 0x06
+#define REL_DIAL 0x07
+#define REL_WHEEL 0x08
+#define REL_MISC 0x09
+#define REL_MAX 0x0f
+#define REL_CNT (REL_MAX+1)
+
+/*
+ * Absolute axes
+ */
+
+#define ABS_X 0x00
+#define ABS_Y 0x01
+#define ABS_Z 0x02
+#define ABS_RX 0x03
+#define ABS_RY 0x04
+#define ABS_RZ 0x05
+#define ABS_THROTTLE 0x06
+#define ABS_RUDDER 0x07
+#define ABS_WHEEL 0x08
+#define ABS_GAS 0x09
+#define ABS_BRAKE 0x0a
+#define ABS_HAT0X 0x10
+#define ABS_HAT0Y 0x11
+#define ABS_HAT1X 0x12
+#define ABS_HAT1Y 0x13
+#define ABS_HAT2X 0x14
+#define ABS_HAT2Y 0x15
+#define ABS_HAT3X 0x16
+#define ABS_HAT3Y 0x17
+#define ABS_PRESSURE 0x18
+#define ABS_DISTANCE 0x19
+#define ABS_TILT_X 0x1a
+#define ABS_TILT_Y 0x1b
+#define ABS_TOOL_WIDTH 0x1c
+
+#define ABS_VOLUME 0x20
+
+#define ABS_MISC 0x28
+
+#define ABS_MT_SLOT 0x2f /* MT slot being modified */
+#define ABS_MT_TOUCH_MAJOR 0x30 /* Major axis of touching ellipse */
+#define ABS_MT_TOUCH_MINOR 0x31 /* Minor axis (omit if circular) */
+#define ABS_MT_WIDTH_MAJOR 0x32 /* Major axis of approaching ellipse */
+#define ABS_MT_WIDTH_MINOR 0x33 /* Minor axis (omit if circular) */
+#define ABS_MT_ORIENTATION 0x34 /* Ellipse orientation */
+#define ABS_MT_POSITION_X 0x35 /* Center X touch position */
+#define ABS_MT_POSITION_Y 0x36 /* Center Y touch position */
+#define ABS_MT_TOOL_TYPE 0x37 /* Type of touching device */
+#define ABS_MT_BLOB_ID 0x38 /* Group a set of packets as a blob */
+#define ABS_MT_TRACKING_ID 0x39 /* Unique ID of initiated contact */
+#define ABS_MT_PRESSURE 0x3a /* Pressure on contact area */
+#define ABS_MT_DISTANCE 0x3b /* Contact hover distance */
+#define ABS_MT_TOOL_X 0x3c /* Center X tool position */
+#define ABS_MT_TOOL_Y 0x3d /* Center Y tool position */
+
+#define ABS_MAX 0x3f
+#define ABS_CNT (ABS_MAX+1)
+
+/*
+ * Switch events
+ */
+
+#define SW_LID 0x00 /* set = lid shut */
+#define SW_TABLET_MODE 0x01 /* set = tablet mode */
+#define SW_HEADPHONE_INSERT 0x02 /* set = inserted */
+#define SW_RFKILL_ALL 0x03 /* rfkill master switch, type "any"
+ set = radio enabled */
+#define SW_RADIO SW_RFKILL_ALL /* deprecated */
+#define SW_MICROPHONE_INSERT 0x04 /* set = inserted */
+#define SW_DOCK 0x05 /* set = plugged into dock */
+#define SW_LINEOUT_INSERT 0x06 /* set = inserted */
+#define SW_JACK_PHYSICAL_INSERT 0x07 /* set = mechanical switch set */
+#define SW_VIDEOOUT_INSERT 0x08 /* set = inserted */
+#define SW_CAMERA_LENS_COVER 0x09 /* set = lens covered */
+#define SW_KEYPAD_SLIDE 0x0a /* set = keypad slide out */
+#define SW_FRONT_PROXIMITY 0x0b /* set = front proximity sensor active */
+#define SW_ROTATE_LOCK 0x0c /* set = rotate locked/disabled */
+#define SW_LINEIN_INSERT 0x0d /* set = inserted */
+#define SW_MUTE_DEVICE 0x0e /* set = device disabled */
+#define SW_MAX 0x0f
+#define SW_CNT (SW_MAX+1)
+
+/*
+ * Misc events
+ */
+
+#define MSC_SERIAL 0x00
+#define MSC_PULSELED 0x01
+#define MSC_GESTURE 0x02
+#define MSC_RAW 0x03
+#define MSC_SCAN 0x04
+#define MSC_TIMESTAMP 0x05
+#define MSC_MAX 0x07
+#define MSC_CNT (MSC_MAX+1)
+
+/*
+ * LEDs
+ */
+
+#define LED_NUML 0x00
+#define LED_CAPSL 0x01
+#define LED_SCROLLL 0x02
+#define LED_COMPOSE 0x03
+#define LED_KANA 0x04
+#define LED_SLEEP 0x05
+#define LED_SUSPEND 0x06
+#define LED_MUTE 0x07
+#define LED_MISC 0x08
+#define LED_MAIL 0x09
+#define LED_CHARGING 0x0a
+#define LED_MAX 0x0f
+#define LED_CNT (LED_MAX+1)
+
+/*
+ * Autorepeat values
+ */
+
+#define REP_DELAY 0x00
+#define REP_PERIOD 0x01
+#define REP_MAX 0x01
+#define REP_CNT (REP_MAX+1)
+
+/*
+ * Sounds
+ */
+
+#define SND_CLICK 0x00
+#define SND_BELL 0x01
+#define SND_TONE 0x02
+#define SND_MAX 0x07
+#define SND_CNT (SND_MAX+1)
+
+#endif
#include <sys/types.h>
#include <linux/types.h>
+#include "input-event-codes.h"
/*
* The event structure itself
__u8 scancode[32];
};
+struct input_mask {
+ __u32 type;
+ __u32 codes_size;
+ __u64 codes_ptr;
+};
+
#define EVIOCGVERSION _IOR('E', 0x01, int) /* get driver version */
#define EVIOCGID _IOR('E', 0x02, struct input_id) /* get device ID */
#define EVIOCGREP _IOR('E', 0x03, unsigned int[2]) /* get repeat settings */
#define EVIOCGABS(abs) _IOR('E', 0x40 + (abs), struct input_absinfo) /* get abs value/limits */
#define EVIOCSABS(abs) _IOW('E', 0xc0 + (abs), struct input_absinfo) /* set abs value/limits */
-#define EVIOCSFF _IOC(_IOC_WRITE, 'E', 0x80, sizeof(struct ff_effect)) /* send a force effect to a force feedback device */
+#define EVIOCSFF _IOW('E', 0x80, struct ff_effect) /* send a force effect to a force feedback device */
#define EVIOCRMFF _IOW('E', 0x81, int) /* Erase a force effect */
#define EVIOCGEFFECTS _IOR('E', 0x84, int) /* Report number of effects playable at the same time */
#define EVIOCGRAB _IOW('E', 0x90, int) /* Grab/Release device */
#define EVIOCREVOKE _IOW('E', 0x91, int) /* Revoke device access */
-#define EVIOCSCLOCKID _IOW('E', 0xa0, int) /* Set clockid to be used for timestamps */
-
-/*
- * Device properties and quirks
- */
-
-#define INPUT_PROP_POINTER 0x00 /* needs a pointer */
-#define INPUT_PROP_DIRECT 0x01 /* direct input devices */
-#define INPUT_PROP_BUTTONPAD 0x02 /* has button(s) under pad */
-#define INPUT_PROP_SEMI_MT 0x03 /* touch rectangle only */
-
-#define INPUT_PROP_MAX 0x1f
-#define INPUT_PROP_CNT (INPUT_PROP_MAX + 1)
-
-/*
- * Event types
- */
-
-#define EV_SYN 0x00
-#define EV_KEY 0x01
-#define EV_REL 0x02
-#define EV_ABS 0x03
-#define EV_MSC 0x04
-#define EV_SW 0x05
-#define EV_LED 0x11
-#define EV_SND 0x12
-#define EV_REP 0x14
-#define EV_FF 0x15
-#define EV_PWR 0x16
-#define EV_FF_STATUS 0x17
-#define EV_MAX 0x1f
-#define EV_CNT (EV_MAX+1)
-
-/*
- * Synchronization events.
- */
-
-#define SYN_REPORT 0
-#define SYN_CONFIG 1
-#define SYN_MT_REPORT 2
-#define SYN_DROPPED 3
-#define SYN_MAX 0xf
-#define SYN_CNT (SYN_MAX+1)
-
-/*
- * Keys and buttons
+/**
+ * EVIOCGMASK - Retrieve current event mask
*
- * Most of the keys/buttons are modeled after USB HUT 1.12
- * (see http://www.usb.org/developers/hidpage).
- * Abbreviations in the comments:
- * AC - Application Control
- * AL - Application Launch Button
- * SC - System Control
- */
-
-#define KEY_RESERVED 0
-#define KEY_ESC 1
-#define KEY_1 2
-#define KEY_2 3
-#define KEY_3 4
-#define KEY_4 5
-#define KEY_5 6
-#define KEY_6 7
-#define KEY_7 8
-#define KEY_8 9
-#define KEY_9 10
-#define KEY_0 11
-#define KEY_MINUS 12
-#define KEY_EQUAL 13
-#define KEY_BACKSPACE 14
-#define KEY_TAB 15
-#define KEY_Q 16
-#define KEY_W 17
-#define KEY_E 18
-#define KEY_R 19
-#define KEY_T 20
-#define KEY_Y 21
-#define KEY_U 22
-#define KEY_I 23
-#define KEY_O 24
-#define KEY_P 25
-#define KEY_LEFTBRACE 26
-#define KEY_RIGHTBRACE 27
-#define KEY_ENTER 28
-#define KEY_LEFTCTRL 29
-#define KEY_A 30
-#define KEY_S 31
-#define KEY_D 32
-#define KEY_F 33
-#define KEY_G 34
-#define KEY_H 35
-#define KEY_J 36
-#define KEY_K 37
-#define KEY_L 38
-#define KEY_SEMICOLON 39
-#define KEY_APOSTROPHE 40
-#define KEY_GRAVE 41
-#define KEY_LEFTSHIFT 42
-#define KEY_BACKSLASH 43
-#define KEY_Z 44
-#define KEY_X 45
-#define KEY_C 46
-#define KEY_V 47
-#define KEY_B 48
-#define KEY_N 49
-#define KEY_M 50
-#define KEY_COMMA 51
-#define KEY_DOT 52
-#define KEY_SLASH 53
-#define KEY_RIGHTSHIFT 54
-#define KEY_KPASTERISK 55
-#define KEY_LEFTALT 56
-#define KEY_SPACE 57
-#define KEY_CAPSLOCK 58
-#define KEY_F1 59
-#define KEY_F2 60
-#define KEY_F3 61
-#define KEY_F4 62
-#define KEY_F5 63
-#define KEY_F6 64
-#define KEY_F7 65
-#define KEY_F8 66
-#define KEY_F9 67
-#define KEY_F10 68
-#define KEY_NUMLOCK 69
-#define KEY_SCROLLLOCK 70
-#define KEY_KP7 71
-#define KEY_KP8 72
-#define KEY_KP9 73
-#define KEY_KPMINUS 74
-#define KEY_KP4 75
-#define KEY_KP5 76
-#define KEY_KP6 77
-#define KEY_KPPLUS 78
-#define KEY_KP1 79
-#define KEY_KP2 80
-#define KEY_KP3 81
-#define KEY_KP0 82
-#define KEY_KPDOT 83
-
-#define KEY_ZENKAKUHANKAKU 85
-#define KEY_102ND 86
-#define KEY_F11 87
-#define KEY_F12 88
-#define KEY_RO 89
-#define KEY_KATAKANA 90
-#define KEY_HIRAGANA 91
-#define KEY_HENKAN 92
-#define KEY_KATAKANAHIRAGANA 93
-#define KEY_MUHENKAN 94
-#define KEY_KPJPCOMMA 95
-#define KEY_KPENTER 96
-#define KEY_RIGHTCTRL 97
-#define KEY_KPSLASH 98
-#define KEY_SYSRQ 99
-#define KEY_RIGHTALT 100
-#define KEY_LINEFEED 101
-#define KEY_HOME 102
-#define KEY_UP 103
-#define KEY_PAGEUP 104
-#define KEY_LEFT 105
-#define KEY_RIGHT 106
-#define KEY_END 107
-#define KEY_DOWN 108
-#define KEY_PAGEDOWN 109
-#define KEY_INSERT 110
-#define KEY_DELETE 111
-#define KEY_MACRO 112
-#define KEY_MUTE 113
-#define KEY_VOLUMEDOWN 114
-#define KEY_VOLUMEUP 115
-#define KEY_POWER 116 /* SC System Power Down */
-#define KEY_KPEQUAL 117
-#define KEY_KPPLUSMINUS 118
-#define KEY_PAUSE 119
-#define KEY_SCALE 120 /* AL Compiz Scale (Expose) */
-
-#define KEY_KPCOMMA 121
-#define KEY_HANGEUL 122
-#define KEY_HANGUEL KEY_HANGEUL
-#define KEY_HANJA 123
-#define KEY_YEN 124
-#define KEY_LEFTMETA 125
-#define KEY_RIGHTMETA 126
-#define KEY_COMPOSE 127
-
-#define KEY_STOP 128 /* AC Stop */
-#define KEY_AGAIN 129
-#define KEY_PROPS 130 /* AC Properties */
-#define KEY_UNDO 131 /* AC Undo */
-#define KEY_FRONT 132
-#define KEY_COPY 133 /* AC Copy */
-#define KEY_OPEN 134 /* AC Open */
-#define KEY_PASTE 135 /* AC Paste */
-#define KEY_FIND 136 /* AC Search */
-#define KEY_CUT 137 /* AC Cut */
-#define KEY_HELP 138 /* AL Integrated Help Center */
-#define KEY_MENU 139 /* Menu (show menu) */
-#define KEY_CALC 140 /* AL Calculator */
-#define KEY_SETUP 141
-#define KEY_SLEEP 142 /* SC System Sleep */
-#define KEY_WAKEUP 143 /* System Wake Up */
-#define KEY_FILE 144 /* AL Local Machine Browser */
-#define KEY_SENDFILE 145
-#define KEY_DELETEFILE 146
-#define KEY_XFER 147
-#define KEY_PROG1 148
-#define KEY_PROG2 149
-#define KEY_WWW 150 /* AL Internet Browser */
-#define KEY_MSDOS 151
-#define KEY_COFFEE 152 /* AL Terminal Lock/Screensaver */
-#define KEY_SCREENLOCK KEY_COFFEE
-#define KEY_DIRECTION 153
-#define KEY_CYCLEWINDOWS 154
-#define KEY_MAIL 155
-#define KEY_BOOKMARKS 156 /* AC Bookmarks */
-#define KEY_COMPUTER 157
-#define KEY_BACK 158 /* AC Back */
-#define KEY_FORWARD 159 /* AC Forward */
-#define KEY_CLOSECD 160
-#define KEY_EJECTCD 161
-#define KEY_EJECTCLOSECD 162
-#define KEY_NEXTSONG 163
-#define KEY_PLAYPAUSE 164
-#define KEY_PREVIOUSSONG 165
-#define KEY_STOPCD 166
-#define KEY_RECORD 167
-#define KEY_REWIND 168
-#define KEY_PHONE 169 /* Media Select Telephone */
-#define KEY_ISO 170
-#define KEY_CONFIG 171 /* AL Consumer Control Configuration */
-#define KEY_HOMEPAGE 172 /* AC Home */
-#define KEY_REFRESH 173 /* AC Refresh */
-#define KEY_EXIT 174 /* AC Exit */
-#define KEY_MOVE 175
-#define KEY_EDIT 176
-#define KEY_SCROLLUP 177
-#define KEY_SCROLLDOWN 178
-#define KEY_KPLEFTPAREN 179
-#define KEY_KPRIGHTPAREN 180
-#define KEY_NEW 181 /* AC New */
-#define KEY_REDO 182 /* AC Redo/Repeat */
-
-#define KEY_F13 183
-#define KEY_F14 184
-#define KEY_F15 185
-#define KEY_F16 186
-#define KEY_F17 187
-#define KEY_F18 188
-#define KEY_F19 189
-#define KEY_F20 190
-#define KEY_F21 191
-#define KEY_F22 192
-#define KEY_F23 193
-#define KEY_F24 194
-
-#define KEY_PLAYCD 200
-#define KEY_PAUSECD 201
-#define KEY_PROG3 202
-#define KEY_PROG4 203
-#define KEY_DASHBOARD 204 /* AL Dashboard */
-#define KEY_SUSPEND 205
-#define KEY_CLOSE 206 /* AC Close */
-#define KEY_PLAY 207
-#define KEY_FASTFORWARD 208
-#define KEY_BASSBOOST 209
-#define KEY_PRINT 210 /* AC Print */
-#define KEY_HP 211
-#define KEY_CAMERA 212
-#define KEY_SOUND 213
-#define KEY_QUESTION 214
-#define KEY_EMAIL 215
-#define KEY_CHAT 216
-#define KEY_SEARCH 217
-#define KEY_CONNECT 218
-#define KEY_FINANCE 219 /* AL Checkbook/Finance */
-#define KEY_SPORT 220
-#define KEY_SHOP 221
-#define KEY_ALTERASE 222
-#define KEY_CANCEL 223 /* AC Cancel */
-#define KEY_BRIGHTNESSDOWN 224
-#define KEY_BRIGHTNESSUP 225
-#define KEY_MEDIA 226
-
-#define KEY_SWITCHVIDEOMODE 227 /* Cycle between available video
- outputs (Monitor/LCD/TV-out/etc) */
-#define KEY_KBDILLUMTOGGLE 228
-#define KEY_KBDILLUMDOWN 229
-#define KEY_KBDILLUMUP 230
-
-#define KEY_SEND 231 /* AC Send */
-#define KEY_REPLY 232 /* AC Reply */
-#define KEY_FORWARDMAIL 233 /* AC Forward Msg */
-#define KEY_SAVE 234 /* AC Save */
-#define KEY_DOCUMENTS 235
-
-#define KEY_BATTERY 236
-
-#define KEY_BLUETOOTH 237
-#define KEY_WLAN 238
-#define KEY_UWB 239
-
-#define KEY_UNKNOWN 240
-
-#define KEY_VIDEO_NEXT 241 /* drive next video source */
-#define KEY_VIDEO_PREV 242 /* drive previous video source */
-#define KEY_BRIGHTNESS_CYCLE 243 /* brightness up, after max is min */
-#define KEY_BRIGHTNESS_ZERO 244 /* brightness off, use ambient */
-#define KEY_DISPLAY_OFF 245 /* display device to off state */
-
-#define KEY_WWAN 246 /* Wireless WAN (LTE, UMTS, GSM, etc.) */
-#define KEY_WIMAX KEY_WWAN
-#define KEY_RFKILL 247 /* Key that controls all radios */
-
-#define KEY_MICMUTE 248 /* Mute / unmute the microphone */
-
-/* Code 255 is reserved for special needs of AT keyboard driver */
-
-#define BTN_MISC 0x100
-#define BTN_0 0x100
-#define BTN_1 0x101
-#define BTN_2 0x102
-#define BTN_3 0x103
-#define BTN_4 0x104
-#define BTN_5 0x105
-#define BTN_6 0x106
-#define BTN_7 0x107
-#define BTN_8 0x108
-#define BTN_9 0x109
-
-#define BTN_MOUSE 0x110
-#define BTN_LEFT 0x110
-#define BTN_RIGHT 0x111
-#define BTN_MIDDLE 0x112
-#define BTN_SIDE 0x113
-#define BTN_EXTRA 0x114
-#define BTN_FORWARD 0x115
-#define BTN_BACK 0x116
-#define BTN_TASK 0x117
-
-#define BTN_JOYSTICK 0x120
-#define BTN_TRIGGER 0x120
-#define BTN_THUMB 0x121
-#define BTN_THUMB2 0x122
-#define BTN_TOP 0x123
-#define BTN_TOP2 0x124
-#define BTN_PINKIE 0x125
-#define BTN_BASE 0x126
-#define BTN_BASE2 0x127
-#define BTN_BASE3 0x128
-#define BTN_BASE4 0x129
-#define BTN_BASE5 0x12a
-#define BTN_BASE6 0x12b
-#define BTN_DEAD 0x12f
-
-#define BTN_GAMEPAD 0x130
-#define BTN_SOUTH 0x130
-#define BTN_A BTN_SOUTH
-#define BTN_EAST 0x131
-#define BTN_B BTN_EAST
-#define BTN_C 0x132
-#define BTN_NORTH 0x133
-#define BTN_X BTN_NORTH
-#define BTN_WEST 0x134
-#define BTN_Y BTN_WEST
-#define BTN_Z 0x135
-#define BTN_TL 0x136
-#define BTN_TR 0x137
-#define BTN_TL2 0x138
-#define BTN_TR2 0x139
-#define BTN_SELECT 0x13a
-#define BTN_START 0x13b
-#define BTN_MODE 0x13c
-#define BTN_THUMBL 0x13d
-#define BTN_THUMBR 0x13e
-
-#define BTN_DIGI 0x140
-#define BTN_TOOL_PEN 0x140
-#define BTN_TOOL_RUBBER 0x141
-#define BTN_TOOL_BRUSH 0x142
-#define BTN_TOOL_PENCIL 0x143
-#define BTN_TOOL_AIRBRUSH 0x144
-#define BTN_TOOL_FINGER 0x145
-#define BTN_TOOL_MOUSE 0x146
-#define BTN_TOOL_LENS 0x147
-#define BTN_TOOL_QUINTTAP 0x148 /* Five fingers on trackpad */
-#define BTN_TOUCH 0x14a
-#define BTN_STYLUS 0x14b
-#define BTN_STYLUS2 0x14c
-#define BTN_TOOL_DOUBLETAP 0x14d
-#define BTN_TOOL_TRIPLETAP 0x14e
-#define BTN_TOOL_QUADTAP 0x14f /* Four fingers on trackpad */
-
-#define BTN_WHEEL 0x150
-#define BTN_GEAR_DOWN 0x150
-#define BTN_GEAR_UP 0x151
-
-#define KEY_OK 0x160
-#define KEY_SELECT 0x161
-#define KEY_GOTO 0x162
-#define KEY_CLEAR 0x163
-#define KEY_POWER2 0x164
-#define KEY_OPTION 0x165
-#define KEY_INFO 0x166 /* AL OEM Features/Tips/Tutorial */
-#define KEY_TIME 0x167
-#define KEY_VENDOR 0x168
-#define KEY_ARCHIVE 0x169
-#define KEY_PROGRAM 0x16a /* Media Select Program Guide */
-#define KEY_CHANNEL 0x16b
-#define KEY_FAVORITES 0x16c
-#define KEY_EPG 0x16d
-#define KEY_PVR 0x16e /* Media Select Home */
-#define KEY_MHP 0x16f
-#define KEY_LANGUAGE 0x170
-#define KEY_TITLE 0x171
-#define KEY_SUBTITLE 0x172
-#define KEY_ANGLE 0x173
-#define KEY_ZOOM 0x174
-#define KEY_MODE 0x175
-#define KEY_KEYBOARD 0x176
-#define KEY_SCREEN 0x177
-#define KEY_PC 0x178 /* Media Select Computer */
-#define KEY_TV 0x179 /* Media Select TV */
-#define KEY_TV2 0x17a /* Media Select Cable */
-#define KEY_VCR 0x17b /* Media Select VCR */
-#define KEY_VCR2 0x17c /* VCR Plus */
-#define KEY_SAT 0x17d /* Media Select Satellite */
-#define KEY_SAT2 0x17e
-#define KEY_CD 0x17f /* Media Select CD */
-#define KEY_TAPE 0x180 /* Media Select Tape */
-#define KEY_RADIO 0x181
-#define KEY_TUNER 0x182 /* Media Select Tuner */
-#define KEY_PLAYER 0x183
-#define KEY_TEXT 0x184
-#define KEY_DVD 0x185 /* Media Select DVD */
-#define KEY_AUX 0x186
-#define KEY_MP3 0x187
-#define KEY_AUDIO 0x188 /* AL Audio Browser */
-#define KEY_VIDEO 0x189 /* AL Movie Browser */
-#define KEY_DIRECTORY 0x18a
-#define KEY_LIST 0x18b
-#define KEY_MEMO 0x18c /* Media Select Messages */
-#define KEY_CALENDAR 0x18d
-#define KEY_RED 0x18e
-#define KEY_GREEN 0x18f
-#define KEY_YELLOW 0x190
-#define KEY_BLUE 0x191
-#define KEY_CHANNELUP 0x192 /* Channel Increment */
-#define KEY_CHANNELDOWN 0x193 /* Channel Decrement */
-#define KEY_FIRST 0x194
-#define KEY_LAST 0x195 /* Recall Last */
-#define KEY_AB 0x196
-#define KEY_NEXT 0x197
-#define KEY_RESTART 0x198
-#define KEY_SLOW 0x199
-#define KEY_SHUFFLE 0x19a
-#define KEY_BREAK 0x19b
-#define KEY_PREVIOUS 0x19c
-#define KEY_DIGITS 0x19d
-#define KEY_TEEN 0x19e
-#define KEY_TWEN 0x19f
-#define KEY_VIDEOPHONE 0x1a0 /* Media Select Video Phone */
-#define KEY_GAMES 0x1a1 /* Media Select Games */
-#define KEY_ZOOMIN 0x1a2 /* AC Zoom In */
-#define KEY_ZOOMOUT 0x1a3 /* AC Zoom Out */
-#define KEY_ZOOMRESET 0x1a4 /* AC Zoom */
-#define KEY_WORDPROCESSOR 0x1a5 /* AL Word Processor */
-#define KEY_EDITOR 0x1a6 /* AL Text Editor */
-#define KEY_SPREADSHEET 0x1a7 /* AL Spreadsheet */
-#define KEY_GRAPHICSEDITOR 0x1a8 /* AL Graphics Editor */
-#define KEY_PRESENTATION 0x1a9 /* AL Presentation App */
-#define KEY_DATABASE 0x1aa /* AL Database App */
-#define KEY_NEWS 0x1ab /* AL Newsreader */
-#define KEY_VOICEMAIL 0x1ac /* AL Voicemail */
-#define KEY_ADDRESSBOOK 0x1ad /* AL Contacts/Address Book */
-#define KEY_MESSENGER 0x1ae /* AL Instant Messaging */
-#define KEY_DISPLAYTOGGLE 0x1af /* Turn display (LCD) on and off */
-#define KEY_SPELLCHECK 0x1b0 /* AL Spell Check */
-#define KEY_LOGOFF 0x1b1 /* AL Logoff */
-
-#define KEY_DOLLAR 0x1b2
-#define KEY_EURO 0x1b3
-
-#define KEY_FRAMEBACK 0x1b4 /* Consumer - transport controls */
-#define KEY_FRAMEFORWARD 0x1b5
-#define KEY_CONTEXT_MENU 0x1b6 /* GenDesc - system context menu */
-#define KEY_MEDIA_REPEAT 0x1b7 /* Consumer - transport control */
-#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_DEL_EOL 0x1c0
-#define KEY_DEL_EOS 0x1c1
-#define KEY_INS_LINE 0x1c2
-#define KEY_DEL_LINE 0x1c3
-
-#define KEY_FN 0x1d0
-#define KEY_FN_ESC 0x1d1
-#define KEY_FN_F1 0x1d2
-#define KEY_FN_F2 0x1d3
-#define KEY_FN_F3 0x1d4
-#define KEY_FN_F4 0x1d5
-#define KEY_FN_F5 0x1d6
-#define KEY_FN_F6 0x1d7
-#define KEY_FN_F7 0x1d8
-#define KEY_FN_F8 0x1d9
-#define KEY_FN_F9 0x1da
-#define KEY_FN_F10 0x1db
-#define KEY_FN_F11 0x1dc
-#define KEY_FN_F12 0x1dd
-#define KEY_FN_1 0x1de
-#define KEY_FN_2 0x1df
-#define KEY_FN_D 0x1e0
-#define KEY_FN_E 0x1e1
-#define KEY_FN_F 0x1e2
-#define KEY_FN_S 0x1e3
-#define KEY_FN_B 0x1e4
-
-#define KEY_BRL_DOT1 0x1f1
-#define KEY_BRL_DOT2 0x1f2
-#define KEY_BRL_DOT3 0x1f3
-#define KEY_BRL_DOT4 0x1f4
-#define KEY_BRL_DOT5 0x1f5
-#define KEY_BRL_DOT6 0x1f6
-#define KEY_BRL_DOT7 0x1f7
-#define KEY_BRL_DOT8 0x1f8
-#define KEY_BRL_DOT9 0x1f9
-#define KEY_BRL_DOT10 0x1fa
-
-#define KEY_NUMERIC_0 0x200 /* used by phones, remote controls, */
-#define KEY_NUMERIC_1 0x201 /* and other keypads */
-#define KEY_NUMERIC_2 0x202
-#define KEY_NUMERIC_3 0x203
-#define KEY_NUMERIC_4 0x204
-#define KEY_NUMERIC_5 0x205
-#define KEY_NUMERIC_6 0x206
-#define KEY_NUMERIC_7 0x207
-#define KEY_NUMERIC_8 0x208
-#define KEY_NUMERIC_9 0x209
-#define KEY_NUMERIC_STAR 0x20a
-#define KEY_NUMERIC_POUND 0x20b
-
-#define KEY_CAMERA_FOCUS 0x210
-#define KEY_WPS_BUTTON 0x211 /* WiFi Protected Setup key */
-
-#define KEY_TOUCHPAD_TOGGLE 0x212 /* Request switch touchpad on or off */
-#define KEY_TOUCHPAD_ON 0x213
-#define KEY_TOUCHPAD_OFF 0x214
-
-#define KEY_CAMERA_ZOOMIN 0x215
-#define KEY_CAMERA_ZOOMOUT 0x216
-#define KEY_CAMERA_UP 0x217
-#define KEY_CAMERA_DOWN 0x218
-#define KEY_CAMERA_LEFT 0x219
-#define KEY_CAMERA_RIGHT 0x21a
-
-#define KEY_ATTENDANT_ON 0x21b
-#define KEY_ATTENDANT_OFF 0x21c
-#define KEY_ATTENDANT_TOGGLE 0x21d /* Attendant call on or off */
-#define KEY_LIGHTS_TOGGLE 0x21e /* Reading light on or off */
-
-#define BTN_DPAD_UP 0x220
-#define BTN_DPAD_DOWN 0x221
-#define BTN_DPAD_LEFT 0x222
-#define BTN_DPAD_RIGHT 0x223
-
-#define KEY_ALS_TOGGLE 0x230 /* Ambient light sensor */
-
-#define BTN_TRIGGER_HAPPY 0x2c0
-#define BTN_TRIGGER_HAPPY1 0x2c0
-#define BTN_TRIGGER_HAPPY2 0x2c1
-#define BTN_TRIGGER_HAPPY3 0x2c2
-#define BTN_TRIGGER_HAPPY4 0x2c3
-#define BTN_TRIGGER_HAPPY5 0x2c4
-#define BTN_TRIGGER_HAPPY6 0x2c5
-#define BTN_TRIGGER_HAPPY7 0x2c6
-#define BTN_TRIGGER_HAPPY8 0x2c7
-#define BTN_TRIGGER_HAPPY9 0x2c8
-#define BTN_TRIGGER_HAPPY10 0x2c9
-#define BTN_TRIGGER_HAPPY11 0x2ca
-#define BTN_TRIGGER_HAPPY12 0x2cb
-#define BTN_TRIGGER_HAPPY13 0x2cc
-#define BTN_TRIGGER_HAPPY14 0x2cd
-#define BTN_TRIGGER_HAPPY15 0x2ce
-#define BTN_TRIGGER_HAPPY16 0x2cf
-#define BTN_TRIGGER_HAPPY17 0x2d0
-#define BTN_TRIGGER_HAPPY18 0x2d1
-#define BTN_TRIGGER_HAPPY19 0x2d2
-#define BTN_TRIGGER_HAPPY20 0x2d3
-#define BTN_TRIGGER_HAPPY21 0x2d4
-#define BTN_TRIGGER_HAPPY22 0x2d5
-#define BTN_TRIGGER_HAPPY23 0x2d6
-#define BTN_TRIGGER_HAPPY24 0x2d7
-#define BTN_TRIGGER_HAPPY25 0x2d8
-#define BTN_TRIGGER_HAPPY26 0x2d9
-#define BTN_TRIGGER_HAPPY27 0x2da
-#define BTN_TRIGGER_HAPPY28 0x2db
-#define BTN_TRIGGER_HAPPY29 0x2dc
-#define BTN_TRIGGER_HAPPY30 0x2dd
-#define BTN_TRIGGER_HAPPY31 0x2de
-#define BTN_TRIGGER_HAPPY32 0x2df
-#define BTN_TRIGGER_HAPPY33 0x2e0
-#define BTN_TRIGGER_HAPPY34 0x2e1
-#define BTN_TRIGGER_HAPPY35 0x2e2
-#define BTN_TRIGGER_HAPPY36 0x2e3
-#define BTN_TRIGGER_HAPPY37 0x2e4
-#define BTN_TRIGGER_HAPPY38 0x2e5
-#define BTN_TRIGGER_HAPPY39 0x2e6
-#define BTN_TRIGGER_HAPPY40 0x2e7
-
-/* We avoid low common keys in module aliases so they don't get huge. */
-#define KEY_MIN_INTERESTING KEY_MUTE
-#define KEY_MAX 0x2ff
-#define KEY_CNT (KEY_MAX+1)
-
-/*
- * Relative axes
- */
-
-#define REL_X 0x00
-#define REL_Y 0x01
-#define REL_Z 0x02
-#define REL_RX 0x03
-#define REL_RY 0x04
-#define REL_RZ 0x05
-#define REL_HWHEEL 0x06
-#define REL_DIAL 0x07
-#define REL_WHEEL 0x08
-#define REL_MISC 0x09
-#define REL_MAX 0x0f
-#define REL_CNT (REL_MAX+1)
-
-/*
- * Absolute axes
- */
-
-#define ABS_X 0x00
-#define ABS_Y 0x01
-#define ABS_Z 0x02
-#define ABS_RX 0x03
-#define ABS_RY 0x04
-#define ABS_RZ 0x05
-#define ABS_THROTTLE 0x06
-#define ABS_RUDDER 0x07
-#define ABS_WHEEL 0x08
-#define ABS_GAS 0x09
-#define ABS_BRAKE 0x0a
-#define ABS_HAT0X 0x10
-#define ABS_HAT0Y 0x11
-#define ABS_HAT1X 0x12
-#define ABS_HAT1Y 0x13
-#define ABS_HAT2X 0x14
-#define ABS_HAT2Y 0x15
-#define ABS_HAT3X 0x16
-#define ABS_HAT3Y 0x17
-#define ABS_PRESSURE 0x18
-#define ABS_DISTANCE 0x19
-#define ABS_TILT_X 0x1a
-#define ABS_TILT_Y 0x1b
-#define ABS_TOOL_WIDTH 0x1c
-
-#define ABS_VOLUME 0x20
-
-#define ABS_MISC 0x28
-
-#define ABS_MT_SLOT 0x2f /* MT slot being modified */
-#define ABS_MT_TOUCH_MAJOR 0x30 /* Major axis of touching ellipse */
-#define ABS_MT_TOUCH_MINOR 0x31 /* Minor axis (omit if circular) */
-#define ABS_MT_WIDTH_MAJOR 0x32 /* Major axis of approaching ellipse */
-#define ABS_MT_WIDTH_MINOR 0x33 /* Minor axis (omit if circular) */
-#define ABS_MT_ORIENTATION 0x34 /* Ellipse orientation */
-#define ABS_MT_POSITION_X 0x35 /* Center X touch position */
-#define ABS_MT_POSITION_Y 0x36 /* Center Y touch position */
-#define ABS_MT_TOOL_TYPE 0x37 /* Type of touching device */
-#define ABS_MT_BLOB_ID 0x38 /* Group a set of packets as a blob */
-#define ABS_MT_TRACKING_ID 0x39 /* Unique ID of initiated contact */
-#define ABS_MT_PRESSURE 0x3a /* Pressure on contact area */
-#define ABS_MT_DISTANCE 0x3b /* Contact hover distance */
-#define ABS_MT_TOOL_X 0x3c /* Center X tool position */
-#define ABS_MT_TOOL_Y 0x3d /* Center Y tool position */
-
-
-#define ABS_MAX 0x3f
-#define ABS_CNT (ABS_MAX+1)
-
-/*
- * Switch events
- */
-
-#define SW_LID 0x00 /* set = lid shut */
-#define SW_TABLET_MODE 0x01 /* set = tablet mode */
-#define SW_HEADPHONE_INSERT 0x02 /* set = inserted */
-#define SW_RFKILL_ALL 0x03 /* rfkill master switch, type "any"
- set = radio enabled */
-#define SW_RADIO SW_RFKILL_ALL /* deprecated */
-#define SW_MICROPHONE_INSERT 0x04 /* set = inserted */
-#define SW_DOCK 0x05 /* set = plugged into dock */
-#define SW_LINEOUT_INSERT 0x06 /* set = inserted */
-#define SW_JACK_PHYSICAL_INSERT 0x07 /* set = mechanical switch set */
-#define SW_VIDEOOUT_INSERT 0x08 /* set = inserted */
-#define SW_CAMERA_LENS_COVER 0x09 /* set = lens covered */
-#define SW_KEYPAD_SLIDE 0x0a /* set = keypad slide out */
-#define SW_FRONT_PROXIMITY 0x0b /* set = front proximity sensor active */
-#define SW_ROTATE_LOCK 0x0c /* set = rotate locked/disabled */
-#define SW_LINEIN_INSERT 0x0d /* set = inserted */
-#define SW_MUTE_DEVICE 0x0e /* set = device disabled */
-#define SW_MAX 0x0f
-#define SW_CNT (SW_MAX+1)
-
-/*
- * Misc events
- */
-
-#define MSC_SERIAL 0x00
-#define MSC_PULSELED 0x01
-#define MSC_GESTURE 0x02
-#define MSC_RAW 0x03
-#define MSC_SCAN 0x04
-#define MSC_TIMESTAMP 0x05
-#define MSC_MAX 0x07
-#define MSC_CNT (MSC_MAX+1)
-
-/*
- * LEDs
- */
-
-#define LED_NUML 0x00
-#define LED_CAPSL 0x01
-#define LED_SCROLLL 0x02
-#define LED_COMPOSE 0x03
-#define LED_KANA 0x04
-#define LED_SLEEP 0x05
-#define LED_SUSPEND 0x06
-#define LED_MUTE 0x07
-#define LED_MISC 0x08
-#define LED_MAIL 0x09
-#define LED_CHARGING 0x0a
-#define LED_MAX 0x0f
-#define LED_CNT (LED_MAX+1)
-
-/*
- * Autorepeat values
+ * This ioctl allows user to retrieve the current event mask for specific
+ * event type. The argument must be of type "struct input_mask" and
+ * specifies the event type to query, the address of the receive buffer and
+ * the size of the receive buffer.
+ *
+ * The event mask is a per-client mask that specifies which events are
+ * forwarded to the client. Each event code is represented by a single bit
+ * in the event mask. If the bit is set, the event is passed to the client
+ * normally. Otherwise, the event is filtered and will never be queued on
+ * the client's receive buffer.
+ *
+ * Event masks do not affect global state of the input device. They only
+ * affect the file descriptor they are applied to.
+ *
+ * The default event mask for a client has all bits set, i.e. all events
+ * are forwarded to the client. If the kernel is queried for an unknown
+ * event type or if the receive buffer is larger than the number of
+ * event codes known to the kernel, the kernel returns all zeroes for those
+ * codes.
+ *
+ * At maximum, codes_size bytes are copied.
+ *
+ * This ioctl may fail with ENODEV in case the file is revoked, EFAULT
+ * if the receive-buffer points to invalid memory, or EINVAL if the kernel
+ * does not implement the ioctl.
*/
+#define EVIOCGMASK _IOR('E', 0x92, struct input_mask) /* Get event-masks */
-#define REP_DELAY 0x00
-#define REP_PERIOD 0x01
-#define REP_MAX 0x01
-#define REP_CNT (REP_MAX+1)
-
-/*
- * Sounds
+/**
+ * EVIOCSMASK - Set event mask
+ *
+ * This ioctl is the counterpart to EVIOCGMASK. Instead of receiving the
+ * current event mask, this changes the client's event mask for a specific
+ * type. See EVIOCGMASK for a description of event-masks and the
+ * argument-type.
+ *
+ * This ioctl provides full forward compatibility. If the passed event type
+ * is unknown to the kernel, or if the number of event codes specified in
+ * the mask is bigger than what is known to the kernel, the ioctl is still
+ * accepted and applied. However, any unknown codes are left untouched and
+ * stay cleared. That means, the kernel always filters unknown codes
+ * regardless of what the client requests. If the new mask doesn't cover
+ * all known event-codes, all remaining codes are automatically cleared and
+ * thus filtered.
+ *
+ * This ioctl may fail with ENODEV in case the file is revoked. EFAULT is
+ * returned if the receive-buffer points to invalid memory. EINVAL is returned
+ * if the kernel does not implement the ioctl.
*/
+#define EVIOCSMASK _IOW('E', 0x93, struct input_mask) /* Set event-masks */
-#define SND_CLICK 0x00
-#define SND_BELL 0x01
-#define SND_TONE 0x02
-#define SND_MAX 0x07
-#define SND_CNT (SND_MAX+1)
+#define EVIOCSCLOCKID _IOW('E', 0xa0, int) /* Set clockid to be used for timestamps */
/*
* IDs.
#define BUS_GSC 0x1A
#define BUS_ATARI 0x1B
#define BUS_SPI 0x1C
+#define BUS_RMI 0x1D
/*
* MT_TOOL types
*/
#define MT_TOOL_FINGER 0
#define MT_TOOL_PEN 1
-#define MT_TOOL_MAX 1
+#define MT_TOOL_PALM 2
+#define MT_TOOL_MAX 2
/*
* Values describing the status of a force-feedback effect
#define FF_GAIN 0x60
#define FF_AUTOCENTER 0x61
+/*
+ * ff->playback(effect_id = FF_GAIN) is the first effect_id to
+ * cause a collision with another ff method, in this case ff->set_gain().
+ * Therefore the greatest safe value for effect_id is FF_GAIN - 1,
+ * and thus the total number of effects should never exceed FF_GAIN.
+ */
+#define FF_MAX_EFFECTS FF_GAIN
+
#define FF_MAX 0x7f
#define FF_CNT (FF_MAX+1)
--- /dev/null
+/*
+ * User level driver support for input subsystem
+ *
+ * Heavily based on evdev.c by Vojtech Pavlik
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Author: Aristeu Sergio Rozanski Filho <aris@cathedrallabs.org>
+ *
+ * Changes/Revisions:
+ * 0.5 08/13/2015 (David Herrmann <dh.herrmann@gmail.com> &
+ * Benjamin Tissoires <benjamin.tissoires@redhat.com>)
+ * - add UI_DEV_SETUP ioctl
+ * - add UI_ABS_SETUP ioctl
+ * - add UI_GET_VERSION ioctl
+ * 0.4 01/09/2014 (Benjamin Tissoires <benjamin.tissoires@redhat.com>)
+ * - add UI_GET_SYSNAME ioctl
+ * 0.3 24/05/2006 (Anssi Hannula <anssi.hannulagmail.com>)
+ * - update ff support for the changes in kernel interface
+ * - add UINPUT_VERSION
+ * 0.2 16/10/2004 (Micah Dowty <micah@navi.cx>)
+ * - added force feedback support
+ * - added UI_SET_PHYS
+ * 0.1 20/06/2002
+ * - first public version
+ */
+#ifndef __UINPUT_H_
+#define __UINPUT_H_
+
+#include <linux/types.h>
+#include <linux/input.h>
+
+#define UINPUT_VERSION 5
+#define UINPUT_MAX_NAME_SIZE 80
+
+struct uinput_ff_upload {
+ __u32 request_id;
+ __s32 retval;
+ struct ff_effect effect;
+ struct ff_effect old;
+};
+
+struct uinput_ff_erase {
+ __u32 request_id;
+ __s32 retval;
+ __u32 effect_id;
+};
+
+/* ioctl */
+#define UINPUT_IOCTL_BASE 'U'
+#define UI_DEV_CREATE _IO(UINPUT_IOCTL_BASE, 1)
+#define UI_DEV_DESTROY _IO(UINPUT_IOCTL_BASE, 2)
+
+struct uinput_setup {
+ struct input_id id;
+ char name[UINPUT_MAX_NAME_SIZE];
+ __u32 ff_effects_max;
+};
+
+/**
+ * UI_DEV_SETUP - Set device parameters for setup
+ *
+ * This ioctl sets parameters for the input device to be created. It
+ * supersedes the old "struct uinput_user_dev" method, which wrote this data
+ * via write(). To actually set the absolute axes UI_ABS_SETUP should be
+ * used.
+ *
+ * The ioctl takes a "struct uinput_setup" object as argument. The fields of
+ * this object are as follows:
+ * id: See the description of "struct input_id". This field is
+ * copied unchanged into the new device.
+ * name: This is used unchanged as name for the new device.
+ * ff_effects_max: This limits the maximum numbers of force-feedback effects.
+ * See below for a description of FF with uinput.
+ *
+ * This ioctl can be called multiple times and will overwrite previous values.
+ * If this ioctl fails with -EINVAL, it is recommended to use the old
+ * "uinput_user_dev" method via write() as a fallback, in case you run on an
+ * old kernel that does not support this ioctl.
+ *
+ * This ioctl may fail with -EINVAL if it is not supported or if you passed
+ * incorrect values, -ENOMEM if the kernel runs out of memory or -EFAULT if the
+ * passed uinput_setup object cannot be read/written.
+ * If this call fails, partial data may have already been applied to the
+ * internal device.
+ */
+#define UI_DEV_SETUP _IOW(UINPUT_IOCTL_BASE, 3, struct uinput_setup)
+
+struct uinput_abs_setup {
+ __u16 code; /* axis code */
+ /* __u16 filler; */
+ struct input_absinfo absinfo;
+};
+
+/**
+ * UI_ABS_SETUP - Set absolute axis information for the device to setup
+ *
+ * This ioctl sets one absolute axis information for the input device to be
+ * created. It supersedes the old "struct uinput_user_dev" method, which wrote
+ * part of this data and the content of UI_DEV_SETUP via write().
+ *
+ * The ioctl takes a "struct uinput_abs_setup" object as argument. The fields
+ * of this object are as follows:
+ * code: The corresponding input code associated with this axis
+ * (ABS_X, ABS_Y, etc...)
+ * absinfo: See "struct input_absinfo" for a description of this field.
+ * This field is copied unchanged into the kernel for the
+ * specified axis. If the axis is not enabled via
+ * UI_SET_ABSBIT, this ioctl will enable it.
+ *
+ * This ioctl can be called multiple times and will overwrite previous values.
+ * If this ioctl fails with -EINVAL, it is recommended to use the old
+ * "uinput_user_dev" method via write() as a fallback, in case you run on an
+ * old kernel that does not support this ioctl.
+ *
+ * This ioctl may fail with -EINVAL if it is not supported or if you passed
+ * incorrect values, -ENOMEM if the kernel runs out of memory or -EFAULT if the
+ * passed uinput_setup object cannot be read/written.
+ * If this call fails, partial data may have already been applied to the
+ * internal device.
+ */
+#define UI_ABS_SETUP _IOW(UINPUT_IOCTL_BASE, 4, struct uinput_abs_setup)
+
+#define UI_SET_EVBIT _IOW(UINPUT_IOCTL_BASE, 100, int)
+#define UI_SET_KEYBIT _IOW(UINPUT_IOCTL_BASE, 101, int)
+#define UI_SET_RELBIT _IOW(UINPUT_IOCTL_BASE, 102, int)
+#define UI_SET_ABSBIT _IOW(UINPUT_IOCTL_BASE, 103, int)
+#define UI_SET_MSCBIT _IOW(UINPUT_IOCTL_BASE, 104, int)
+#define UI_SET_LEDBIT _IOW(UINPUT_IOCTL_BASE, 105, int)
+#define UI_SET_SNDBIT _IOW(UINPUT_IOCTL_BASE, 106, int)
+#define UI_SET_FFBIT _IOW(UINPUT_IOCTL_BASE, 107, int)
+#define UI_SET_PHYS _IOW(UINPUT_IOCTL_BASE, 108, char*)
+#define UI_SET_SWBIT _IOW(UINPUT_IOCTL_BASE, 109, int)
+#define UI_SET_PROPBIT _IOW(UINPUT_IOCTL_BASE, 110, int)
+
+#define UI_BEGIN_FF_UPLOAD _IOWR(UINPUT_IOCTL_BASE, 200, struct uinput_ff_upload)
+#define UI_END_FF_UPLOAD _IOW(UINPUT_IOCTL_BASE, 201, struct uinput_ff_upload)
+#define UI_BEGIN_FF_ERASE _IOWR(UINPUT_IOCTL_BASE, 202, struct uinput_ff_erase)
+#define UI_END_FF_ERASE _IOW(UINPUT_IOCTL_BASE, 203, struct uinput_ff_erase)
+
+/**
+ * UI_GET_SYSNAME - get the sysfs name of the created uinput device
+ *
+ * @return the sysfs name of the created virtual input device.
+ * The complete sysfs path is then /sys/devices/virtual/input/--NAME--
+ * Usually, it is in the form "inputN"
+ */
+#define UI_GET_SYSNAME(len) _IOC(_IOC_READ, UINPUT_IOCTL_BASE, 44, len)
+
+/**
+ * UI_GET_VERSION - Return version of uinput protocol
+ *
+ * This writes uinput protocol version implemented by the kernel into
+ * the integer pointed to by the ioctl argument. The protocol version
+ * is hard-coded in the kernel and is independent of the uinput device.
+ */
+#define UI_GET_VERSION _IOR(UINPUT_IOCTL_BASE, 45, unsigned int)
+
+/*
+ * To write a force-feedback-capable driver, the upload_effect
+ * and erase_effect callbacks in input_dev must be implemented.
+ * The uinput driver will generate a fake input event when one of
+ * these callbacks are invoked. The userspace code then uses
+ * ioctls to retrieve additional parameters and send the return code.
+ * The callback blocks until this return code is sent.
+ *
+ * The described callback mechanism is only used if ff_effects_max
+ * is set.
+ *
+ * To implement upload_effect():
+ * 1. Wait for an event with type == EV_UINPUT and code == UI_FF_UPLOAD.
+ * A request ID will be given in 'value'.
+ * 2. Allocate a uinput_ff_upload struct, fill in request_id with
+ * the 'value' from the EV_UINPUT event.
+ * 3. Issue a UI_BEGIN_FF_UPLOAD ioctl, giving it the
+ * uinput_ff_upload struct. It will be filled in with the
+ * ff_effects passed to upload_effect().
+ * 4. Perform the effect upload, and place a return code back into
+ the uinput_ff_upload struct.
+ * 5. Issue a UI_END_FF_UPLOAD ioctl, also giving it the
+ * uinput_ff_upload_effect struct. This will complete execution
+ * of our upload_effect() handler.
+ *
+ * To implement erase_effect():
+ * 1. Wait for an event with type == EV_UINPUT and code == UI_FF_ERASE.
+ * A request ID will be given in 'value'.
+ * 2. Allocate a uinput_ff_erase struct, fill in request_id with
+ * the 'value' from the EV_UINPUT event.
+ * 3. Issue a UI_BEGIN_FF_ERASE ioctl, giving it the
+ * uinput_ff_erase struct. It will be filled in with the
+ * effect ID passed to erase_effect().
+ * 4. Perform the effect erasure, and place a return code back
+ * into the uinput_ff_erase struct.
+ * 5. Issue a UI_END_FF_ERASE ioctl, also giving it the
+ * uinput_ff_erase_effect struct. This will complete execution
+ * of our erase_effect() handler.
+ */
+
+/*
+ * This is the new event type, used only by uinput.
+ * 'code' is UI_FF_UPLOAD or UI_FF_ERASE, and 'value'
+ * is the unique request ID. This number was picked
+ * arbitrarily, above EV_MAX (since the input system
+ * never sees it) but in the range of a 16-bit int.
+ */
+#define EV_UINPUT 0x0101
+#define UI_FF_UPLOAD 1
+#define UI_FF_ERASE 2
+
+struct uinput_user_dev {
+ char name[UINPUT_MAX_NAME_SIZE];
+ struct input_id id;
+ __u32 ff_effects_max;
+ __s32 absmax[ABS_CNT];
+ __s32 absmin[ABS_CNT];
+ __s32 absfuzz[ABS_CNT];
+ __s32 absflat[ABS_CNT];
+};
+#endif /* __UINPUT_H_ */
libevdev-uinput-int.h \
libevdev.c \
libevdev-names.c \
- ../include/linux/input.h
+ ../include/linux/input-event-codes.h \
+ ../include/linux/input.h \
+ ../include/linux/uinput.h
libevdev_la_LDFLAGS = \
-version-info $(LIBEVDEV_LT_VERSION) \
libevdevinclude_HEADERS = libevdev.h libevdev-uinput.h
event-names.h: Makefile make-event-names.py
- $(PYTHON) $(srcdir)/make-event-names.py $(top_srcdir)/include/linux/input.h > $@
+ $(CAT) $(top_srcdir)/include/linux/input.h $(top_srcdir)/include/linux/input-event-codes.h | $(PYTHON) $(srcdir)/make-event-names.py > $@
+
EXTRA_DIST = make-event-names.py libevdev.sym
CLEANFILES = event-names.h
int val[];
};
+/**
+ * Internal only: log data used to send messages to the respective log
+ * handler. We re-use the same struct for a global and inside
+ * struct libevdev.
+ * For the global, device_handler is NULL, for per-device instance
+ * global_handler is NULL.
+ */
+struct logdata {
+ enum libevdev_log_priority priority; /** minimum logging priority */
+ libevdev_log_func_t global_handler; /** global handler function */
+ libevdev_device_log_func_t device_handler; /** per-device handler function */
+ void *userdata; /** user-defined data pointer */
+};
+
struct libevdev {
int fd;
bool initialized;
unsigned long *tracking_id_changes;
size_t tracking_id_changes_sz; /* in bytes */
} mt_sync;
-};
-struct logdata {
- enum libevdev_log_priority priority; /** minimum logging priority */
- libevdev_log_func_t handler; /** handler function */
- void *userdata; /** user-defined data pointer */
+ struct logdata log;
};
-extern struct logdata log_data;
-#define log_msg_cond(priority, ...) \
+#define log_msg_cond(dev, priority, ...) \
do { \
- if (libevdev_get_log_priority() >= priority) \
- log_msg(priority, log_data.userdata, __FILE__, __LINE__, __func__, __VA_ARGS__); \
+ if (_libevdev_log_priority(dev) >= priority) \
+ _libevdev_log_msg(dev, priority, __FILE__, __LINE__, __func__, __VA_ARGS__); \
} while(0)
-#define log_error(...) log_msg_cond(LIBEVDEV_LOG_ERROR, __VA_ARGS__)
-#define log_info(...) log_msg_cond(LIBEVDEV_LOG_INFO, __VA_ARGS__)
-#define log_dbg(...) log_msg_cond(LIBEVDEV_LOG_DEBUG, __VA_ARGS__)
-#define log_bug(...) log_msg_cond(LIBEVDEV_LOG_ERROR, "BUG: "__VA_ARGS__)
+#define log_error(dev, ...) log_msg_cond(dev, LIBEVDEV_LOG_ERROR, __VA_ARGS__)
+#define log_info(dev, ...) log_msg_cond(dev, LIBEVDEV_LOG_INFO, __VA_ARGS__)
+#define log_dbg(dev, ...) log_msg_cond(dev, LIBEVDEV_LOG_DEBUG, __VA_ARGS__)
+#define log_bug(dev, ...) log_msg_cond(dev, LIBEVDEV_LOG_ERROR, "BUG: "__VA_ARGS__)
extern void
-log_msg(enum libevdev_log_priority priority,
- void *data,
- const char *file, int line, const char *func,
- const char *format, ...) LIBEVDEV_ATTRIBUTE_PRINTF(6, 7);
+_libevdev_log_msg(const struct libevdev *dev,
+ enum libevdev_log_priority priority,
+ const char *file, int line, const char *func,
+ const char *format, ...) LIBEVDEV_ATTRIBUTE_PRINTF(6, 7);
+extern enum libevdev_log_priority
+_libevdev_log_priority(const struct libevdev *dev);
/**
* @return a pointer to the next element in the queue, or NULL if the queue
return 0;
}
-
/**
* Shift the first n elements into ev and return the number of elements
* shifted.
static inline int
queue_shift_multiple(struct libevdev *dev, size_t n, struct input_event *ev)
{
- size_t i;
+ size_t remaining;
if (dev->queue_next == 0)
return 0;
- n = min(n, dev->queue_next);
+ remaining = dev->queue_next;
+ n = min(n, remaining);
+ remaining -= n;
- if (ev) {
- for (i = 0; i < n; i++)
- ev[i] = dev->queue[i];
- }
+ if (ev)
+ memcpy(ev, dev->queue, n * sizeof(*ev));
- for (i = 0; i < dev->queue_next - n; i++)
- dev->queue[i] = dev->queue[n + i];
+ memmove(dev->queue, &dev->queue[n], remaining * sizeof(*dev->queue));
- dev->queue_next -= n;
+ dev->queue_next = remaining;
return n;
}
max = libevdev_event_type_get_max(type); \
break;
-
static inline int
type_to_mask_const(const struct libevdev *dev, unsigned int type, const unsigned long **mask)
{
#undef max_mask
#endif
-
return entry ? (int)entry->value : -1;
}
+
+LIBEVDEV_EXPORT int
+libevdev_property_from_name(const char *name)
+{
+ return libevdev_property_from_name_n(name, strlen(name));
+}
+
+LIBEVDEV_EXPORT int
+libevdev_property_from_name_n(const char *name, size_t len)
+{
+ struct name_lookup lookup;
+ const struct name_entry *entry;
+
+ lookup.name = name;
+ lookup.len = len;
+
+ entry = lookup_name(prop_names, ARRAY_LENGTH(prop_names), &lookup);
+
+ return entry ? (int)entry->value : -1;
+}
* OF THIS SOFTWARE.
*/
-
struct libevdev_uinput {
int fd; /**< file descriptor to uinput */
int fd_is_managed; /**< do we need to close it? */
return uinput_dev;
}
+static inline int
+set_abs(const struct libevdev *dev, int fd, unsigned int code)
+{
+ const struct input_absinfo *abs = libevdev_get_abs_info(dev, code);
+ struct uinput_abs_setup abs_setup = {0};
+ int rc;
+
+ abs_setup.code = code;
+ abs_setup.absinfo = *abs;
+ rc = ioctl(fd, UI_ABS_SETUP, &abs_setup);
+ return rc;
+}
+
static int
set_evbits(const struct libevdev *dev, int fd, struct uinput_user_dev *uidev)
{
goto out;
if (type == EV_ABS) {
- const struct input_absinfo *abs = libevdev_get_abs_info(dev, code);
- uidev->absmin[code] = abs->minimum;
- uidev->absmax[code] = abs->maximum;
- uidev->absfuzz[code] = abs->fuzz;
- uidev->absflat[code] = abs->flat;
- /* uinput has no resolution in the device struct, this needs
- * to be fixed in the kernel */
+ if (uidev == NULL) {
+ rc = set_abs(dev, fd, code);
+ if (rc != 0)
+ goto out;
+ } else {
+ const struct input_absinfo *abs =
+ libevdev_get_abs_info(dev, code);
+
+ uidev->absmin[code] = abs->minimum;
+ uidev->absmax[code] = abs->maximum;
+ uidev->absfuzz[code] = abs->fuzz;
+ uidev->absflat[code] = abs->flat;
+ /* uinput has no resolution in the
+ * device struct */
+ }
}
}
}
static int
-set_props(const struct libevdev *dev, int fd, struct uinput_user_dev *uidev)
+set_props(const struct libevdev *dev, int fd)
{
unsigned int prop;
int rc = 0;
* ioctl is called on an already created device. The
* last two can't happen here.
*/
- if (errno == -EINVAL)
+ if (errno == EINVAL)
rc = 0;
break;
}
{
struct dirent **namelist;
int ndev, i;
-
- /* FIXME: use new ioctl() here once kernel supports it */
+ int rc;
+ char buf[sizeof(SYS_INPUT_DIR) + 64] = SYS_INPUT_DIR;
+
+ rc = ioctl(uinput_dev->fd,
+ UI_GET_SYSNAME(sizeof(buf) - strlen(SYS_INPUT_DIR)),
+ &buf[strlen(SYS_INPUT_DIR)]);
+ if (rc != -1) {
+ uinput_dev->syspath = strdup(buf);
+ uinput_dev->devnode = fetch_device_node(buf);
+ return 0;
+ }
ndev = scandir(SYS_INPUT_DIR, &namelist, is_input_device, alphasort);
if (ndev <= 0)
for (i = 0; i < ndev; i++) {
int fd, len;
- char buf[sizeof(SYS_INPUT_DIR) + 64];
struct stat st;
- strcpy(buf, SYS_INPUT_DIR);
- strcat(buf, namelist[i]->d_name);
-
- if (stat(buf, &st) == -1)
- continue;
-
- /* created before UI_DEV_CREATE, or after it finished */
- if (st.st_ctime < uinput_dev->ctime[0] ||
- st.st_ctime > uinput_dev->ctime[1])
+ rc = snprintf(buf, sizeof(buf), "%s%s/name",
+ SYS_INPUT_DIR,
+ namelist[i]->d_name);
+ if (rc < 0 || (size_t)rc >= sizeof(buf)) {
continue;
+ }
/* created within time frame */
- strcat(buf, "/name");
fd = open(buf, O_RDONLY);
if (fd < 0)
continue;
+ /* created before UI_DEV_CREATE, or after it finished */
+ if (fstat(fd, &st) == -1 ||
+ st.st_ctime < uinput_dev->ctime[0] ||
+ st.st_ctime > uinput_dev->ctime[1]) {
+ close(fd);
+ continue;
+ }
+
len = read(fd, buf, sizeof(buf));
close(fd);
if (len <= 0)
if (strcmp(buf, uinput_dev->name) == 0) {
if (uinput_dev->syspath) {
/* FIXME: could descend into bit comparison here */
- log_info("multiple identical devices found. syspath is unreliable\n");
+ log_info(NULL, "multiple identical devices found. syspath is unreliable\n");
break;
} else {
- strcpy(buf, SYS_INPUT_DIR);
- strcat(buf, namelist[i]->d_name);
+ rc = snprintf(buf, sizeof(buf), "%s%s",
+ SYS_INPUT_DIR,
+ namelist[i]->d_name);
+ if (rc < 0 || (size_t)rc >= sizeof(buf)) {
+ log_error(NULL, "Invalid syspath, syspath is unreliable\n");
+ break;
+ }
+
uinput_dev->syspath = strdup(buf);
uinput_dev->devnode = fetch_device_node(buf);
}
return uinput_dev->devnode ? 0 : -1;
}
+static int
+uinput_create_write(const struct libevdev *dev, int fd,
+ struct libevdev_uinput *new_device)
+{
+ int rc;
+ struct uinput_user_dev uidev;
+
+ memset(&uidev, 0, sizeof(uidev));
+
+ strncpy(uidev.name, libevdev_get_name(dev), UINPUT_MAX_NAME_SIZE - 1);
+ uidev.id.vendor = libevdev_get_id_vendor(dev);
+ uidev.id.product = libevdev_get_id_product(dev);
+ uidev.id.bustype = libevdev_get_id_bustype(dev);
+ uidev.id.version = libevdev_get_id_version(dev);
+
+ if (set_evbits(dev, fd, &uidev) != 0)
+ goto error;
+ if (set_props(dev, fd) != 0)
+ goto error;
+
+ rc = write(fd, &uidev, sizeof(uidev));
+ if (rc < 0)
+ goto error;
+ else if ((size_t)rc < sizeof(uidev)) {
+ errno = EINVAL;
+ goto error;
+ }
+
+ errno = 0;
+
+error:
+ return -errno;
+}
+
+static int
+uinput_create_DEV_SETUP(const struct libevdev *dev, int fd,
+ struct libevdev_uinput *new_device)
+{
+ int rc;
+ struct uinput_setup setup;
+
+ if (set_evbits(dev, fd, NULL) != 0)
+ goto error;
+ if (set_props(dev, fd) != 0)
+ goto error;
+ memset(&setup, 0, sizeof(setup));
+ strncpy(setup.name, libevdev_get_name(dev), UINPUT_MAX_NAME_SIZE - 1);
+ setup.id.vendor = libevdev_get_id_vendor(dev);
+ setup.id.product = libevdev_get_id_product(dev);
+ setup.id.bustype = libevdev_get_id_bustype(dev);
+ setup.id.version = libevdev_get_id_version(dev);
+ setup.ff_effects_max = libevdev_has_event_type(dev, EV_FF) ? 10 : 0;
+
+ rc = ioctl(fd, UI_DEV_SETUP, &setup);
+ if (rc == 0)
+ errno = 0;
+error:
+ return -errno;
+}
LIBEVDEV_EXPORT int
libevdev_uinput_create_from_device(const struct libevdev *dev, int fd, struct libevdev_uinput** uinput_dev)
{
int rc;
- struct uinput_user_dev uidev;
struct libevdev_uinput *new_device;
+ int close_fd_on_error = (fd == LIBEVDEV_UINPUT_OPEN_MANAGED);
+ unsigned int uinput_version = 0;
new_device = alloc_uinput_device(libevdev_get_name(dev));
if (!new_device)
new_device->fd_is_managed = 1;
} else if (fd < 0) {
- log_bug("Invalid fd %d\n", fd);
+ log_bug(NULL, "Invalid fd %d\n", fd);
errno = EBADF;
goto error;
}
- memset(&uidev, 0, sizeof(uidev));
-
- strncpy(uidev.name, libevdev_get_name(dev), UINPUT_MAX_NAME_SIZE - 1);
- uidev.id.vendor = libevdev_get_id_vendor(dev);
- uidev.id.product = libevdev_get_id_product(dev);
- uidev.id.bustype = libevdev_get_id_bustype(dev);
- uidev.id.version = libevdev_get_id_version(dev);
-
- if (set_evbits(dev, fd, &uidev) != 0)
- goto error;
- if (set_props(dev, fd, &uidev) != 0)
- goto error;
+ if (ioctl(fd, UI_GET_VERSION, &uinput_version) == 0 &&
+ uinput_version >= 5)
+ rc = uinput_create_DEV_SETUP(dev, fd, new_device);
+ else
+ rc = uinput_create_write(dev, fd, new_device);
- rc = write(fd, &uidev, sizeof(uidev));
- if (rc < 0)
- goto error;
- else if ((size_t)rc < sizeof(uidev)) {
- errno = EINVAL;
+ if (rc != 0)
goto error;
- }
/* ctime notes time before/after ioctl to help us filter out devices
when traversing /sys/devices/virtual/input to find the device
new_device->fd = fd;
if (fetch_syspath_and_devnode(new_device) == -1) {
- log_error("unable to fetch syspath or device node.\n");
+ log_error(NULL, "unable to fetch syspath or device node.\n");
errno = ENODEV;
goto error;
}
return 0;
error:
+ rc = -errno;
libevdev_uinput_destroy(new_device);
- return -errno;
+ if (fd != -1 && close_fd_on_error)
+ close(fd);
+ return rc;
}
LIBEVDEV_EXPORT void
if (!uinput_dev)
return;
- ioctl(uinput_dev->fd, UI_DEV_DESTROY, NULL);
- if (uinput_dev->fd_is_managed)
- close(uinput_dev->fd);
+ if (uinput_dev->fd >= 0) {
+ (void)ioctl(uinput_dev->fd, UI_DEV_DESTROY, NULL);
+ if (uinput_dev->fd_is_managed)
+ close(uinput_dev->fd);
+ }
free(uinput_dev->syspath);
free(uinput_dev->devnode);
free(uinput_dev->name);
* help to create uinput devices that emulate libevdev devices. In the simplest
* form it serves to duplicate an existing device:
*
- @code
- int err;
- int new_fd;
- struct libevdev *dev;
- struct libevdev_uinput *uidev;
- struct input_event ev[2];
-
- err = libevdev_new_from_fd(&dev, fd);
- if (err != 0)
- return err;
-
- uifd = open("/dev/uinput", O_RDWR);
- if (uidev < 0)
- return -errno;
-
- err = libevdev_uinput_create_from_device(dev, uifd, &uidev);
- if (err != 0)
- return err;
-
- // post a REL_X event
- 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);
- if (err != 0)
- return err;
-
- libevdev_uinput_destroy(uidev);
- close(uifd);
-
- @endcode
+ * @code
+ * int err;
+ * int fd, new_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;
+ *
+ * err = libevdev_new_from_fd(fd, &dev);
+ * if (err != 0)
+ * return err;
+ *
+ * uifd = open("/dev/uinput", O_RDWR);
+ * if (uidev < 0)
+ * return -errno;
+ *
+ * err = libevdev_uinput_create_from_device(dev, uifd, &uidev);
+ * if (err != 0)
+ * return err;
+ *
+ * // post a REL_X event
+ * 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);
+ * if (err != 0)
+ * return err;
+ *
+ * libevdev_uinput_destroy(uidev);
+ * libevdev_free(dev);
+ * close(uifd);
+ * close(fd);
+ *
+ * @endcode
*
* Alternatively, a device can be constructed from scratch:
*
- @code
- int err;
- struct libevdev *dev;
- struct libevdev_uinput *uidev;
-
- dev = libevdev_new();
- libevdev_set_name(dev, "test device");
- libevdev_enable_event_type(dev, EV_REL);
- libevdev_enable_event_code(dev, EV_REL, REL_X);
- libevdev_enable_event_code(dev, EV_REL, REL_Y);
- libevdev_enable_event_type(dev, EV_KEY);
- libevdev_enable_event_code(dev, EV_KEY, BTN_LEFT);
- libevdev_enable_event_code(dev, EV_KEY, BTN_MIDDLE);
- libevdev_enable_event_code(dev, EV_KEY, BTN_RIGHT);
-
- err = libevdev_uinput_create_from_device(dev,
- LIBEVDEV_UINPUT_OPEN_MANAGED,
- &uidev);
- if (err != 0)
- return err;
-
- // ... do something ...
-
- libevdev_uinput_destroy(uidev);
-
- @endcode
+ * @code
+ * int err;
+ * struct libevdev *dev;
+ * struct libevdev_uinput *uidev;
+ *
+ * dev = libevdev_new();
+ * libevdev_set_name(dev, "test device");
+ * 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_type(dev, EV_KEY);
+ * libevdev_enable_event_code(dev, EV_KEY, BTN_LEFT, NULL);
+ * libevdev_enable_event_code(dev, EV_KEY, BTN_MIDDLE, NULL);
+ * libevdev_enable_event_code(dev, EV_KEY, BTN_RIGHT, NULL);
+ *
+ * err = libevdev_uinput_create_from_device(dev,
+ * LIBEVDEV_UINPUT_OPEN_MANAGED,
+ * &uidev);
+ * if (err != 0)
+ * return err;
+ *
+ * // ... do something ...
+ *
+ * libevdev_uinput_destroy(uidev);
+ *
+ * @endcode
*/
enum libevdev_uinput_open_mode {
/**
* @ingroup uinput
*
- * Return the syspath representing this uinput device.
- * At the time of writing, the uinput kernel device does not
- * provide a way to get the syspath directly through uinput so libevdev must guess.
- * In some cases libevdev is unable to derive the syspath. If the running kernel
- * supports the UI_GET_SYSNAME ioctl, the syspath is retrieved through that and will
- * be reliable and not be NULL. The UI_GET_SYSNAME ioctl is currently
- * scheduled for 3.15.
- *
- * @note This function may return NULL. libevdev currently 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.
+ * 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.
+ *
+ * @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.
* @param uinput_dev A previously created uinput device.
* @return The syspath for this device, including the preceding /sys
*
* @see libevdev_uinput_get_devnode
*/
-const char*libevdev_uinput_get_syspath(struct libevdev_uinput *uinput_dev);
+const char* libevdev_uinput_get_syspath(struct libevdev_uinput *uinput_dev);
/**
* @ingroup uinput
* This relies on libevdev_uinput_get_syspath() to provide a valid syspath.
* See libevdev_uinput_get_syspath() for more details.
*
- * @note This function may return NULL. libevdev currently has to guess the
+ * @note This function may return NULL. libevdev may have to guess the
* syspath and the device node. See libevdev_uinput_get_syspath() for details.
* @param uinput_dev A previously created uinput device.
* @return The device node for this device, in the form of /dev/input/eventN
_a > _b ? _a : _b; \
})
-
static inline bool
startswith(const char *str, size_t len, const char *prefix, size_t plen)
{
#include <poll.h>
#include <stdlib.h>
#include <string.h>
+#include <limits.h>
#include <unistd.h>
#include <stdarg.h>
#include <stdbool.h>
slot_value(const struct libevdev *dev, int slot, int axis)
{
if (unlikely(slot > dev->num_slots)) {
- log_bug("Slot %d exceeds number of slots (%d)\n", slot, dev->num_slots);
+ log_bug(dev, "Slot %d exceeds number of slots (%d)\n", slot, dev->num_slots);
slot = 0;
}
if (unlikely(axis < ABS_MT_MIN || axis > ABS_MT_MAX)) {
- log_bug("MT axis %d is outside the valid range [%d,%d]\n",
+ log_bug(dev, "MT axis %d is outside the valid range [%d,%d]\n",
axis, ABS_MT_MIN, ABS_MT_MAX);
axis = ABS_MT_MIN;
}
/* count the number of axes, keys, etc. to get a better idea at how
many events per EV_SYN we could possibly get. That's the max we
may get during SYN_DROPPED too. Use double that, just so we have
- room for events while syncing an event.
+ room for events while syncing a device.
*/
for (type = EV_KEY; type < EV_MAX; type++) {
int max = libevdev_event_type_get_max(type);
if (nslots > 1) {
int num_mt_axes = 0;
- for (code = ABS_MT_SLOT; code < ABS_MAX; code++) {
+ for (code = ABS_MT_SLOT; code <= ABS_MAX; code++) {
if (libevdev_has_event_code(dev, EV_ABS, code))
num_mt_axes++;
}
vfprintf(stderr, format, args);
}
+static void
+fix_invalid_absinfo(const struct libevdev *dev,
+ int axis,
+ struct input_absinfo* abs_info)
+{
+ /*
+ * The reported absinfo for ABS_MT_TRACKING_ID is sometimes
+ * uninitialized for certain mtk-soc, due to init code mangling
+ * in the vendor kernel.
+ */
+ if (axis == ABS_MT_TRACKING_ID &&
+ abs_info->maximum == abs_info->minimum) {
+ abs_info->minimum = -1;
+ abs_info->maximum = 0xFFFF;
+ log_bug(dev,
+ "Device \"%s\" has invalid ABS_MT_TRACKING_ID range",
+ dev->name);
+ }
+}
+
/*
* Global logging settings.
*/
-struct logdata log_data = {
- LIBEVDEV_LOG_INFO,
- libevdev_dflt_log_func,
- NULL,
+static struct logdata log_data = {
+ .priority = LIBEVDEV_LOG_INFO,
+ .global_handler = libevdev_dflt_log_func,
+ .userdata = NULL,
};
void
-log_msg(enum libevdev_log_priority priority,
- void *data,
- const char *file, int line, const char *func,
- const char *format, ...)
+_libevdev_log_msg(const struct libevdev *dev,
+ enum libevdev_log_priority priority,
+ const char *file, int line, const char *func,
+ const char *format, ...)
{
va_list args;
- if (!log_data.handler || priority > log_data.priority)
+ if (dev && dev->log.device_handler) {
+ /**
+ * if both global handler and device handler are set
+ * we've set up the handlers wrong. And that means we'll
+ * likely get the printf args wrong and cause all sorts of
+ * mayhem. Seppuku is called for.
+ */
+ if (unlikely(dev->log.global_handler))
+ abort();
+
+ if (priority > dev->log.priority)
+ return;
+ } else if (!log_data.global_handler || priority > log_data.priority)
return;
+ else if (unlikely(log_data.device_handler))
+ abort(); /* Seppuku, see above */
va_start(args, format);
- log_data.handler(priority, data, file, line, func, format, args);
+ if (dev && dev->log.device_handler)
+ dev->log.device_handler(dev, priority, dev->log.userdata, file, line, func, format, args);
+ else
+ log_data.global_handler(priority, log_data.userdata, file, line, func, format, args);
va_end(args);
}
static void
libevdev_reset(struct libevdev *dev)
{
+ enum libevdev_log_priority pri = dev->log.priority;
+ libevdev_device_log_func_t handler = dev->log.device_handler;
+
free(dev->name);
free(dev->phys);
free(dev->uniq);
dev->current_slot = -1;
dev->grabbed = LIBEVDEV_UNGRAB;
dev->sync_state = SYNC_NONE;
+ dev->log.priority = pri;
+ dev->log.device_handler = handler;
libevdev_enable_event_type(dev, EV_SYN);
}
LIBEVDEV_EXPORT void
libevdev_set_log_function(libevdev_log_func_t logfunc, void *data)
{
- log_data.handler = logfunc;
+ log_data.global_handler = logfunc;
log_data.userdata = data;
}
return log_data.priority;
}
+LIBEVDEV_EXPORT void
+libevdev_set_device_log_function(struct libevdev *dev,
+ libevdev_device_log_func_t logfunc,
+ enum libevdev_log_priority priority,
+ void *data)
+{
+ if (!dev) {
+ log_bug(NULL, "device must not be NULL\n");
+ return;
+ }
+
+ dev->log.priority = priority;
+ dev->log.device_handler = logfunc;
+ dev->log.userdata = data;
+}
+
+enum libevdev_log_priority
+_libevdev_log_priority(const struct libevdev *dev)
+{
+ if (dev && dev->log.device_handler)
+ return dev->log.priority;
+ else
+ return libevdev_get_log_priority();
+}
+
LIBEVDEV_EXPORT int
libevdev_change_fd(struct libevdev *dev, int fd)
{
if (!dev->initialized) {
- log_bug("device not initialized. call libevdev_set_fd() first\n");
+ log_bug(dev, "device not initialized. call libevdev_set_fd() first\n");
return -1;
}
dev->fd = fd;
char buf[256];
if (dev->initialized) {
- log_bug("device already initialized.\n");
+ log_bug(dev, "device already initialized.\n");
return -EBADF;
} else if (fd < 0)
return -EBADF;
if (rc < 0)
goto out;
+ fix_invalid_absinfo(dev, i, &abs_info);
+
dev->abs_info[i] = abs_info;
}
}
set_bit(slot_update, AXISBIT(slot, ABS_MT_SLOT));
}
-
}
}
return;
if (rc < 0) {
- log_error("Failed to drain events before sync.\n");
+ log_error(dev, "Failed to drain events before sync.\n");
return;
}
we can drain them.
*/
if (iterations >= max_iterations)
- log_info("Unable to drain events, buffer size mismatch.\n");
+ log_info(dev, "Unable to drain events, buffer size mismatch.\n");
}
static int
struct input_event *ev,
enum SyncState sync_state)
{
+ if (!libevdev_has_event_code(dev, ev->type, ev->code))
+ return EVENT_FILTER_DISCARD;
+
if (unlikely(dev->num_slots > -1 &&
libevdev_event_is_code(ev, EV_ABS, ABS_MT_SLOT) &&
(ev->value < 0 || ev->value >= dev->num_slots))) {
- log_bug("Device \"%s\" received an invalid slot index %d."
+ log_bug(dev, "Device \"%s\" received an invalid slot index %d."
"Capping to announced max slot number %d.\n",
dev->name, ev->value, dev->num_slots - 1);
ev->value = dev->num_slots - 1;
*slot_value(dev, dev->current_slot, ABS_MT_TRACKING_ID) == -1) ||
(ev->value != -1 &&
*slot_value(dev, dev->current_slot, ABS_MT_TRACKING_ID) != -1)))) {
- log_bug("Device \"%s\" received a double tracking ID %d in slot %d.\n",
+ log_bug(dev, "Device \"%s\" received a double tracking ID %d in slot %d.\n",
dev->name, ev->value, dev->current_slot);
return EVENT_FILTER_DISCARD;
}
{
int rc = LIBEVDEV_READ_STATUS_SUCCESS;
enum event_filter_status filter_status;
+ const unsigned int valid_flags = LIBEVDEV_READ_FLAG_NORMAL |
+ LIBEVDEV_READ_FLAG_SYNC |
+ LIBEVDEV_READ_FLAG_FORCE_SYNC |
+ LIBEVDEV_READ_FLAG_BLOCKING;
if (!dev->initialized) {
- log_bug("device not initialized. call libevdev_set_fd() first\n");
+ log_bug(dev, "device not initialized. call libevdev_set_fd() first\n");
return -EBADF;
} else if (dev->fd < 0)
return -EBADF;
- if (!(flags & (LIBEVDEV_READ_FLAG_NORMAL|LIBEVDEV_READ_FLAG_SYNC|LIBEVDEV_READ_FLAG_FORCE_SYNC))) {
- log_bug("invalid flags %#x\n.\n", flags);
+ if ((flags & valid_flags) == 0) {
+ log_bug(dev, "invalid flags %#x.\n", flags);
return -EINVAL;
}
goto out;
}
-
if (queue_shift(dev, ev) != 0)
return -EAGAIN;
if (queue_peek(dev, 0, &next) == 0 &&
next.type == EV_SYN && next.code == SYN_DROPPED)
- log_info("SYN_DROPPED received after finished "
+ log_info(dev, "SYN_DROPPED received after finished "
"sync - you're not keeping up\n");
}
}
int rc;
if (!dev->initialized) {
- log_bug("device not initialized. call libevdev_set_fd() first\n");
+ log_bug(dev, "device not initialized. call libevdev_set_fd() first\n");
return -EBADF;
} else if (dev->fd < 0)
return -EBADF;
STRING_SETTER(phys)
STRING_SETTER(uniq)
-
#define PRODUCT_GETTER(name) \
LIBEVDEV_EXPORT int libevdev_get_id_##name(const struct libevdev *dev) \
{ \
int rc;
if (!dev->initialized) {
- log_bug("device not initialized. call libevdev_set_fd() first\n");
+ log_bug(dev, "device not initialized. call libevdev_set_fd() first\n");
return -EBADF;
} else if (dev->fd < 0)
return -EBADF;
int rc = 0;
if (!dev->initialized) {
- log_bug("device not initialized. call libevdev_set_fd() first\n");
+ log_bug(dev, "device not initialized. call libevdev_set_fd() first\n");
return -EBADF;
} else if (dev->fd < 0)
return -EBADF;
if (grab != LIBEVDEV_GRAB && grab != LIBEVDEV_UNGRAB) {
- log_bug("invalid grab parameter %#x\n", grab);
+ log_bug(dev, "invalid grab parameter %#x\n", grab);
return -EINVAL;
}
size_t nleds = 0;
if (!dev->initialized) {
- log_bug("device not initialized. call libevdev_set_fd() first\n");
+ log_bug(dev, "device not initialized. call libevdev_set_fd() first\n");
return -EBADF;
} else if (dev->fd < 0)
return -EBADF;
libevdev_set_clock_id(struct libevdev *dev, int clockid)
{
if (!dev->initialized) {
- log_bug("device not initialized. call libevdev_set_fd() first\n");
+ log_bug(dev, "device not initialized. call libevdev_set_fd() first\n");
return -EBADF;
} else if (dev->fd < 0)
return -EBADF;
*
* libevdev does not handle the file descriptors directly, it merely uses
* them. The caller is responsible for opening the file descriptors, setting
- * them to O_NONBLOCK and handling permissions.
+ * them to O_NONBLOCK and handling permissions. A caller should drain any
+ * events pending on the file descriptor before passing it to libevdev.
*
* Where does libevdev sit?
* ========================
* finds them monitors the device to print the event.
*
* @code
- struct libevdev *dev = NULL;
- int fd;
- int rc = 1;
-
- fd = open("/dev/input/event0", O_RDONLY|O_NONBLOCK);
- rc = libevdev_new_from_fd(fd, &dev);
- if (rc < 0) {
- fprintf(stderr, "Failed to init libevdev (%s)\n", strerror(-rc));
- exit(1);
- }
- printf("Input device name: \"%s\"\n", libevdev_get_name(dev));
- 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));
- if (!libevdev_has_event_type(dev, EV_REL) ||
- !libevdev_has_event_code(dev, EV_KEY, BTN_LEFT)) {
- printf("This device does not look like a mouse\n");
- exit(1);
- }
-
- do {
- struct input_event ev;
- rc = libevdev_next_event(dev, LIBEVDEV_READ_FLAG_NORMAL, &ev);
- if (rc == 0)
- printf("Event: %s %s %d\n",
- libevdev_get_event_type_name(ev.type),
- libevdev_get_event_code_name(ev.type, ev.code),
- ev.value);
- } while (rc == 1 || rc == 0 || rc == -EAGAIN);
- @endcode
+ * struct libevdev *dev = NULL;
+ * int fd;
+ * int rc = 1;
+ *
+ * fd = open("/dev/input/event0", O_RDONLY|O_NONBLOCK);
+ * rc = libevdev_new_from_fd(fd, &dev);
+ * if (rc < 0) {
+ * fprintf(stderr, "Failed to init libevdev (%s)\n", strerror(-rc));
+ * exit(1);
+ * }
+ * printf("Input device name: \"%s\"\n", libevdev_get_name(dev));
+ * 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));
+ * if (!libevdev_has_event_type(dev, EV_REL) ||
+ * !libevdev_has_event_code(dev, EV_KEY, BTN_LEFT)) {
+ * printf("This device does not look like a mouse\n");
+ * exit(1);
+ * }
+ *
+ * do {
+ * struct input_event ev;
+ * rc = libevdev_next_event(dev, LIBEVDEV_READ_FLAG_NORMAL, &ev);
+ * if (rc == 0)
+ * printf("Event: %s %s %d\n",
+ * libevdev_get_event_type_name(ev.type),
+ * libevdev_get_event_code_name(ev.type, ev.code),
+ * ev.value);
+ * } while (rc == 1 || rc == 0 || rc == -EAGAIN);
+ * @endcode
*
* A more complete example is available with the libevdev-events tool here:
* http://cgit.freedesktop.org/libevdev/tree/tools/libevdev-events.c
* events. The number of events between SYN_REPORT events is arbitrary and
* depends on the hardware. An example event sequence may look like this:
* @code
- EV_ABS ABS_X 9
- EV_ABS ABS_Y 8
- EV_SYN SYN_REPORT 0
- ------------------------
- EV_ABS ABS_X 10
- EV_ABS ABS_Y 10
- EV_KEY BTN_TOUCH 1
- EV_SYN SYN_REPORT 0
- ------------------------
- EV_ABS ABS_X 11
- EV_SYN SYN_REPORT 0
+ * EV_ABS ABS_X 9
+ * EV_ABS ABS_Y 8
+ * EV_SYN SYN_REPORT 0
+ * ------------------------
+ * EV_ABS ABS_X 10
+ * EV_ABS ABS_Y 10
+ * EV_KEY BTN_TOUCH 1
+ * EV_SYN SYN_REPORT 0
+ * ------------------------
+ * EV_ABS ABS_X 11
+ * EV_SYN SYN_REPORT 0
* @endcode
*
* Events are handed to the client buffer as they appear, the kernel adjusts
* the client that some events were lost. The above example event sequence
* may look like this (note the missing/repeated events):
* @code
- EV_ABS ABS_X 9
- EV_ABS ABS_Y 8
- EV_SYN SYN_REPORT 0
- ------------------------
- EV_ABS ABS_X 10
- EV_ABS ABS_Y 10
- EV_SYN SYN_DROPPED 0
- EV_ABS ABS_Y 15
- EV_SYN SYN_REPORT 0
- ------------------------
- EV_ABS ABS_X 11
- EV_KEY BTN_TOUCH 0
- EV_SYN SYN_REPORT 0
+ * EV_ABS ABS_X 9
+ * EV_ABS ABS_Y 8
+ * EV_SYN SYN_REPORT 0
+ * ------------------------
+ * EV_ABS ABS_X 10
+ * EV_ABS ABS_Y 10
+ * EV_SYN SYN_DROPPED 0
+ * EV_ABS ABS_Y 15
+ * EV_SYN SYN_REPORT 0
+ * ------------------------
+ * EV_ABS ABS_X 11
+ * EV_KEY BTN_TOUCH 0
+ * EV_SYN SYN_REPORT 0
* @endcode
*
* A SYN_DROPPED event may be recieved at any time in the event sequence.
* active slot.
* Thus, an event sequence from a slot-capable device may look like this:
* @code
- EV_ABS ABS_MT_POSITION_Y 10
- EV_ABS ABS_MT_SLOT 1
- EV_ABS ABS_MT_POSITION_X 100
- EV_ABS ABS_MT_POSITION_Y 80
- EV_SYN SYN_REPORT 0
+ * EV_ABS ABS_MT_POSITION_Y 10
+ * EV_ABS ABS_MT_SLOT 1
+ * EV_ABS ABS_MT_POSITION_X 100
+ * EV_ABS ABS_MT_POSITION_Y 80
+ * EV_SYN SYN_REPORT 0
* @endcode
* Note the lack of ABS_MT_SLOT: the first ABS_MT_POSITION_Y applies to
* a slot opened previously, and is the only axis that changed for that
*
* An example event sequence for such a sync may look like this:
* @code
- EV_ABS ABS_MT_SLOT 0
- EV_ABS ABS_MT_POSITION_Y 10
- EV_ABS ABS_MT_SLOT 1
- EV_ABS ABS_MT_POSITION_X 100
- EV_ABS ABS_MT_POSITION_Y 80
- EV_ABS ABS_MT_SLOT 2
- EV_ABS ABS_MT_POSITION_Y 8
- EV_ABS ABS_MT_PRESSURE 12
- EV_ABS ABS_MT_SLOT 1
- EV_SYN SYN_REPORT 0
+ * EV_ABS ABS_MT_SLOT 0
+ * EV_ABS ABS_MT_POSITION_Y 10
+ * EV_ABS ABS_MT_SLOT 1
+ * EV_ABS ABS_MT_POSITION_X 100
+ * EV_ABS ABS_MT_POSITION_Y 80
+ * EV_ABS ABS_MT_SLOT 2
+ * EV_ABS ABS_MT_POSITION_Y 8
+ * EV_ABS ABS_MT_PRESSURE 12
+ * EV_ABS ABS_MT_SLOT 1
+ * EV_SYN SYN_REPORT 0
* @endcode
* Note the terminating ABS_MT_SLOT event, this indicates that the kernel
* currently has slot 1 active.
*
* An example event sequence for such a sync may look like this:
* @code
- EV_ABS ABS_MT_SLOT 0
- EV_ABS ABS_MT_TRACKING_ID -1
- EV_ABS ABS_MT_SLOT 2
- EV_ABS ABS_MT_TRACKING_ID -1
- EV_SYN SYN_REPORT 0
- ------------------------
- EV_ABS ABS_MT_SLOT 1
- EV_ABS ABS_MT_POSITION_X 100
- EV_ABS ABS_MT_POSITION_Y 80
- EV_ABS ABS_MT_SLOT 2
- EV_ABS ABS_MT_TRACKING_ID 45
- EV_ABS ABS_MT_POSITION_Y 8
- EV_ABS ABS_MT_PRESSURE 12
- EV_ABS ABS_MT_SLOT 1
- EV_SYN SYN_REPORT 0
+ * EV_ABS ABS_MT_SLOT 0
+ * EV_ABS ABS_MT_TRACKING_ID -1
+ * EV_ABS ABS_MT_SLOT 2
+ * EV_ABS ABS_MT_TRACKING_ID -1
+ * EV_SYN SYN_REPORT 0
+ * ------------------------
+ * EV_ABS ABS_MT_SLOT 1
+ * EV_ABS ABS_MT_POSITION_X 100
+ * EV_ABS ABS_MT_POSITION_Y 80
+ * EV_ABS ABS_MT_SLOT 2
+ * EV_ABS ABS_MT_TRACKING_ID 45
+ * EV_ABS ABS_MT_POSITION_Y 8
+ * EV_ABS ABS_MT_PRESSURE 12
+ * EV_ABS ABS_MT_SLOT 1
+ * EV_SYN SYN_REPORT 0
* @endcode
* Note how the touchpoint in slot 0 was terminated, the touchpoint in slot
* 2 was terminated and then started with a new ABS_MT_TRACKING_ID. The touchpoint
* handles events again. The below example shows an example event sequence
* and what libevdev sees in the case of a SYN_DROPPED event:
* @code
-
- kernel | userspace
- |
- EV_ABS ABS_MT_SLOT 0 | EV_ABS ABS_MT_SLOT 0
- EV_ABS ABS_MT_TRACKING_ID -1 | EV_ABS ABS_MT_TRACKING_ID -1
- EV_SYN SYN_REPORT 0 | EV_SYN SYN_REPORT 0
- ------------------------ | ------------------------
- EV_ABS ABS_MT_TRACKING_ID 30 |
- EV_ABS ABS_MT_POSITION_X 100 |
- EV_ABS ABS_MT_POSITION_Y 80 |
- EV_SYN SYN_REPORT 0 | SYN_DROPPED
- ------------------------ |
- EV_ABS ABS_MT_TRACKING_ID -1 |
- EV_SYN SYN_REPORT 0 |
- ------------------------ | ------------------------
- EV_ABS ABS_MT_SLOT 1 | EV_ABS ABS_MT_SLOT 1
- EV_ABS ABS_MT_POSITION_X 90 | EV_ABS ABS_MT_POSITION_X 90
- EV_ABS ABS_MT_POSITION_Y 10 | EV_ABS ABS_MT_POSITION_Y 10
- EV_SYN SYN_REPORT 0 | EV_SYN SYN_REPORT 0
+ *
+ * kernel | userspace
+ * |
+ * EV_ABS ABS_MT_SLOT 0 | EV_ABS ABS_MT_SLOT 0
+ * EV_ABS ABS_MT_TRACKING_ID -1 | EV_ABS ABS_MT_TRACKING_ID -1
+ * EV_SYN SYN_REPORT 0 | EV_SYN SYN_REPORT 0
+ * ------------------------ | ------------------------
+ * EV_ABS ABS_MT_TRACKING_ID 30 |
+ * EV_ABS ABS_MT_POSITION_X 100 |
+ * EV_ABS ABS_MT_POSITION_Y 80 |
+ * EV_SYN SYN_REPORT 0 | SYN_DROPPED
+ * ------------------------ |
+ * EV_ABS ABS_MT_TRACKING_ID -1 |
+ * EV_SYN SYN_REPORT 0 |
+ * ------------------------ | ------------------------
+ * EV_ABS ABS_MT_SLOT 1 | EV_ABS ABS_MT_SLOT 1
+ * EV_ABS ABS_MT_POSITION_X 90 | EV_ABS ABS_MT_POSITION_X 90
+ * EV_ABS ABS_MT_POSITION_Y 10 | EV_ABS ABS_MT_POSITION_Y 10
+ * EV_SYN SYN_REPORT 0 | EV_SYN SYN_REPORT 0
* @endcode
* If such an event sequence occurs, libevdev will send all updated axes
* during the sync process. Axis events may thus be generated for devices
* without a currently valid ABS_MT_TRACKING_ID. Specifically for the above
* example, the client would receive the following event sequence:
* @code
- EV_ABS ABS_MT_SLOT 0 ← LIBEVDEV_READ_FLAG_NORMAL
- EV_ABS ABS_MT_TRACKING_ID -1
- EV_SYN SYN_REPORT 0
- ------------------------
- EV_SYN SYN_DROPPED 0 → LIBEVDEV_READ_STATUS_SYNC
- ------------------------
- EV_ABS ABS_MT_POSITION_X 100 ← LIBEVDEV_READ_FLAG_SYNC
- EV_ABS ABS_MT_POSITION_Y 80
- EV_SYN SYN_REPORT 0
- ----------------------------- → -EGAIN
- EV_ABS ABS_MT_SLOT 1 ← LIBEVDEV_READ_FLAG_NORMAL
- EV_ABS ABS_MT_POSITION_X 90
- EV_ABS ABS_MT_POSITION_Y 10
- EV_SYN SYN_REPORT 0
- -------------------
+ * EV_ABS ABS_MT_SLOT 0 ← LIBEVDEV_READ_FLAG_NORMAL
+ * EV_ABS ABS_MT_TRACKING_ID -1
+ * EV_SYN SYN_REPORT 0
+ * ------------------------
+ * EV_SYN SYN_DROPPED 0 → LIBEVDEV_READ_STATUS_SYNC
+ * ------------------------
+ * EV_ABS ABS_MT_POSITION_X 100 ← LIBEVDEV_READ_FLAG_SYNC
+ * EV_ABS ABS_MT_POSITION_Y 80
+ * EV_SYN SYN_REPORT 0
+ * ----------------------------- → -EGAIN
+ * EV_ABS ABS_MT_SLOT 1 ← LIBEVDEV_READ_FLAG_NORMAL
+ * EV_ABS ABS_MT_POSITION_X 90
+ * EV_ABS ABS_MT_POSITION_Y 10
+ * EV_SYN SYN_REPORT 0
+ * -------------------
* @endcode
* 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
* assume the buffer contains the following sequence:
*
* @code
- EV_SYN SYN_DROPPED
- EV_ABS ABS_X 1
- EV_SYN SYN_REPORT 0
- EV_ABS ABS_X 2
- EV_SYN SYN_REPORT 0
- EV_ABS ABS_X 3
- EV_SYN SYN_REPORT 0
- EV_ABS ABS_X 4
- EV_SYN SYN_REPORT 0
- EV_ABS ABS_X 5
- EV_SYN SYN_REPORT 0
- EV_ABS ABS_X 6
- EV_SYN SYN_REPORT 0
+ * EV_SYN SYN_DROPPED
+ * EV_ABS ABS_X 1
+ * EV_SYN SYN_REPORT 0
+ * EV_ABS ABS_X 2
+ * EV_SYN SYN_REPORT 0
+ * EV_ABS ABS_X 3
+ * EV_SYN SYN_REPORT 0
+ * EV_ABS ABS_X 4
+ * EV_SYN SYN_REPORT 0
+ * EV_ABS ABS_X 5
+ * EV_SYN SYN_REPORT 0
+ * EV_ABS ABS_X 6
+ * EV_SYN SYN_REPORT 0
* @endcode
* An ioctl at any time in this sequence will return a value of 6 for ABS_X.
*
* avoid spurious cursor movements. In the above example, the event sequence
* by libevdev is:
* @code
- EV_SYN SYN_DROPPED
- EV_ABS ABS_X 6
- EV_SYN SYN_REPORT 0
- @endcode
+ * EV_SYN SYN_DROPPED
+ * EV_ABS ABS_X 6
+ * EV_SYN SYN_REPORT 0
+ * @endcode
*/
/**
* @include linux/input.h
*/
+/**
+ * @page static_linking Statically linking libevdev
+ *
+ * Statically linking libevdev.a is not recommended. Symbol visibility is
+ * difficult to control in a static library, so extra care must be taken to
+ * only use symbols that are explicitly exported. libevdev's API stability
+ * guarantee only applies to those symbols.
+ *
+ * If you do link libevdev statically, note that in addition to the exported
+ * symbols, libevdev reserves the <b>_libevdev_*</b> namespace. Do not use
+ * or create symbols with that prefix, they are subject to change at any
+ * time.
+ */
+
/**
* @page testing libevdev-internal test suite
*
* before libevdev_set_fd() unless documented otherwise.
*/
+/**
+ * @defgroup logging Library logging facilities
+ *
+ * libevdev provides two methods of logging library-internal messages. The
+ * old method is to provide a global log handler in
+ * libevdev_set_log_function(). The new method is to provide a per-context
+ * log handler in libevdev_set_device_log_function(). Developers are encouraged
+ * to use the per-context logging facilities over the global log handler as
+ * it provides access to the libevdev instance that caused a message, and is
+ * more flexible when libevdev is used from within a shared library.
+ *
+ * If a caller sets both the global log handler and a per-context log
+ * handler, each device with a per-context log handler will only invoke that
+ * log handler.
+ *
+ * @note To set a context-specific log handler, a context is needed.
+ * Thus developers are discouraged from using libevdev_new_from_fd() as
+ * important messages from the device initialization process may get lost.
+ *
+ * @note A context-specific handler cannot be used for libevdev's uinput
+ * devices. @ref uinput must use the global log handler.
+ */
+
/**
* @defgroup bits Querying device capabilities
*
*
* This is a shortcut for
*
- @code
- int err;
- struct libevdev *dev = libevdev_new();
- err = libevdev_set_fd(dev, fd);
- @endcode
+ * @code
+ * int err;
+ * struct libevdev *dev = libevdev_new();
+ * err = libevdev_set_fd(dev, fd);
+ * @endcode
*
* @param fd A file descriptor to the device in O_RDWR or O_RDONLY mode.
* @param[out] dev The newly initialized evdev device.
* Clean up and free the libevdev struct. After completion, the <code>struct
* libevdev</code> is invalid and must not be used.
*
+ * Note that calling libevdev_free() does not close the file descriptor
+ * currently asssociated with this instance.
+ *
* @param dev The evdev device
*
* @note This function may be called before libevdev_set_fd().
void libevdev_free(struct libevdev *dev);
/**
- * @ingroup init
+ * @ingroup logging
*/
enum libevdev_log_priority {
LIBEVDEV_LOG_ERROR = 10, /**< critical errors and application bugs */
};
/**
- * @ingroup init
+ * @ingroup logging
*
* Logging function called by library-internal logging.
* This function is expected to treat its input like printf would.
LIBEVDEV_ATTRIBUTE_PRINTF(6, 0);
/**
- * @ingroup init
+ * @ingroup logging
*
* Set a printf-style logging handler for library-internal logging. The default
* logging function is to stdout.
*
+ * @note The global log handler is only called if no context-specific log
+ * handler has been set with libevdev_set_device_log_function().
+ *
* @param logfunc The logging function for this device. If NULL, the current
* logging function is unset and no logging is performed.
* @param data User-specific data passed to the log handler.
*
* @note This function may be called before libevdev_set_fd().
+ *
+ * @deprecated Use per-context logging instead, see
+ * libevdev_set_device_log_function().
*/
void libevdev_set_log_function(libevdev_log_func_t logfunc, void *data);
/**
- * @ingroup init
+ * @ingroup logging
*
* Define the minimum level to be printed to the log handler.
* Messages higher than this level are printed, others are discarded. This
*
* @param priority Minimum priority to be printed to the log.
*
+ * @deprecated Use per-context logging instead, see
+ * libevdev_set_device_log_function().
*/
void libevdev_set_log_priority(enum libevdev_log_priority priority);
/**
- * @ingroup init
+ * @ingroup logging
*
* Return the current log priority level. Messages higher than this level
* are printed, others are discarded. This is a global setting.
*
* @return the current log level
+ *
+ * @deprecated Use per-context logging instead, see
+ * libevdev_set_device_log_function().
*/
enum libevdev_log_priority libevdev_get_log_priority(void);
+/**
+ * @ingroup logging
+ *
+ * Logging function called by library-internal logging for a specific
+ * libevdev context. This function is expected to treat its input like
+ * printf would.
+ *
+ * @param dev The evdev device
+ * @param priority Log priority of this message
+ * @param data User-supplied data pointer (see libevdev_set_log_function())
+ * @param file libevdev source code file generating this message
+ * @param line libevdev source code line generating this message
+ * @param func libevdev source code function generating this message
+ * @param format printf-style format string
+ * @param args List of arguments
+ *
+ * @see libevdev_set_log_function
+ * @since 1.3
+ */
+typedef 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)
+ LIBEVDEV_ATTRIBUTE_PRINTF(7, 0);
+
+/**
+ * @ingroup logging
+ *
+ * Set a printf-style logging handler for library-internal logging for this
+ * device context. The default logging function is NULL, i.e. the global log
+ * handler is invoked. If a context-specific log handler is set, the global
+ * log handler is not invoked for this device.
+ *
+ * @note This log function applies for this device context only, even if
+ * another context exists for the same fd.
+ *
+ * @param dev The evdev device
+ * @param logfunc The logging function for this device. If NULL, the current
+ * logging function is unset and logging falls back to the global log
+ * handler, if any.
+ * @param priority Minimum priority to be printed to the log.
+ * @param data User-specific data passed to the log handler.
+ *
+ * @note This function may be called before libevdev_set_fd().
+ * @since 1.3
+ */
+void libevdev_set_device_log_function(struct libevdev *dev,
+ libevdev_device_log_func_t logfunc,
+ enum libevdev_log_priority priority,
+ void *data);
+
/**
* @ingroup init
*/
* you need to change the fd after closing and re-opening the same device, use
* libevdev_change_fd().
*
+ * A caller should ensure that any events currently pending on the fd are
+ * drained before the file descriptor is passed to libevdev for
+ * initialization. Due to how the kernel's ioctl handling works, the initial
+ * device state will reflect the current device state *after* applying all
+ * events currently pending on the fd. Thus, if the fd is not drained, the
+ * state visible to the caller will be inconsistent with the events
+ * immediately available on the device. This does not affect state-less
+ * events like EV_REL.
+ *
* Unless otherwise specified, libevdev function behavior is undefined until
* a successfull call to libevdev_set_fd().
*
* The example code below illustrates how to force a re-sync of the
* library-internal state. Note that this code doesn't handle the events in
* the caller, it merely forces an update of the internal library state.
- @code
- struct input_event ev;
- libevdev_change_fd(dev, new_fd);
- libevdev_next_event(dev, LIBEVDEV_READ_FLAG_FORCE_SYNC, &ev);
- while (libevdev_next_event(dev, LIBEVDEV_READ_FLAG_SYNC, &ev) == LIBEVDEV_READ_STATUS_SYNC)
- ; // noop
- @endcode
+ * @code
+ * struct input_event ev;
+ * libevdev_change_fd(dev, new_fd);
+ * libevdev_next_event(dev, LIBEVDEV_READ_FLAG_FORCE_SYNC, &ev);
+ * while (libevdev_next_event(dev, LIBEVDEV_READ_FLAG_SYNC, &ev) == LIBEVDEV_READ_STATUS_SYNC)
+ * ; // noop
+ * @endcode
*
* The fd may be open in O_RDONLY or O_RDWR.
*
*/
int libevdev_get_fd(const struct libevdev* dev);
-
/**
* @ingroup events
*/
*/
LIBEVDEV_READ_STATUS_SYNC = 1
};
+
/**
* @ingroup events
*
* @note This function is signal-safe.
*/
int libevdev_get_abs_minimum(const struct libevdev *dev, unsigned int code);
+
/**
* @ingroup bits
*
* @note This function is signal-safe.
*/
int libevdev_get_abs_maximum(const struct libevdev *dev, unsigned int code);
+
/**
* @ingroup bits
*
* @note This function is signal-safe.
*/
int libevdev_get_abs_fuzz(const struct libevdev *dev, unsigned int code);
+
/**
* @ingroup bits
*
* @note This function is signal-safe.
*/
int libevdev_get_abs_flat(const struct libevdev *dev, unsigned int code);
+
/**
* @ingroup bits
*
*
* Fetch the current value of the event type. This is a shortcut for
*
- @code
- if (libevdev_has_event_type(dev, t) && libevdev_has_event_code(dev, t, c))
- val = libevdev_get_event_value(dev, t, c);
- @endcode
+ * @code
+ * if (libevdev_has_event_type(dev, t) && libevdev_has_event_code(dev, t, c))
+ * val = libevdev_get_event_value(dev, t, c);
+ * @endcode
*
* @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.)
*
* Fetch the current value of the code for the given slot. This is a shortcut for
*
- @code
- if (libevdev_has_event_type(dev, EV_ABS) &&
- libevdev_has_event_code(dev, EV_ABS, c) &&
- slot < device->number_of_slots)
- val = libevdev_get_slot_value(dev, slot, c);
- @endcode
+ * @code
+ * if (libevdev_has_event_type(dev, EV_ABS) &&
+ * libevdev_has_event_code(dev, EV_ABS, c) &&
+ * slot < device->number_of_slots)
+ * val = libevdev_get_slot_value(dev, slot, c);
+ * @endcode
*
* @param dev The evdev device, already initialized with libevdev_set_fd()
* @param slot The numerical slot number, must be smaller than the total number
/**
* @ingroup kernel
*
- * Forcibly enable an event type on this device, even if the underlying
+ * Forcibly enable an event code on this device, even if the underlying
* device does not support it. While this cannot make the device actually
* report such events, it will now return true for libevdev_has_event_code().
*
* The last argument depends on the type and code:
* - If type is EV_ABS, data must be a pointer to a struct input_absinfo
* containing the data for this axis.
- * - If type is EV_REP, daat must be a pointer to a int containing the data
+ * - If type is EV_REP, data must be a pointer to a int containing the data
* for this axis
* - For all other types, the argument must be NULL.
*
* This is a local modification only affecting only this representation of
* this device.
*
- * Disabling EV_SYN will not work. Don't shoot yourself in the foot.
- * It hurts.
+ * Disabling codes of type EV_SYN will not work. Don't shoot yourself in the
+ * foot. It hurts.
*
* @param dev The evdev device, already initialized with libevdev_set_fd()
* @param type The event type to disable (EV_ABS, EV_KEY, ...)
*/
int libevdev_kernel_set_abs_info(struct libevdev *dev, unsigned int code, const struct input_absinfo *abs);
-
/**
* @ingroup kernel
*/
* of LED codes and values to set them to, terminated by a -1. For example, to
* switch the NumLock LED on but the CapsLock LED off, use:
*
- @code
- libevdev_kernel_set_led_values(dev, LED_NUML, LIBEVDEV_LED_ON,
- LED_CAPSL, LIBEVDEV_LED_OFF,
- -1);
- @endcode
+ * @code
+ * libevdev_kernel_set_led_values(dev, LED_NUML, LIBEVDEV_LED_ON,
+ * LED_CAPSL, LIBEVDEV_LED_OFF,
+ * -1);
+ * @endcode
*
* If any LED code or value is invalid, this function returns -EINVAL and no
* LEDs are modified.
int libevdev_event_code_from_name_n(unsigned int type, const char *name,
size_t len);
+/**
+ * @ingroup misc
+ *
+ * Look up an input property by its name. Properties start with the fixed
+ * prefix "INPUT_PROP_" followed by their name (eg., "INPUT_PROP_POINTER").
+ * The prefix must be included in the name. It returns the constant assigned
+ * to the property or -1 if not found.
+ *
+ * @param name A non-NULL string describing an input property
+ *
+ * @return The given code constant for the name or -1 if not found.
+ */
+int libevdev_property_from_name(const char *name);
+
+/**
+ * @ingroup misc
+ *
+ * Look up an input property by its name. Properties start with the fixed
+ * prefix "INPUT_PROP_" followed by their name (eg., "INPUT_PROP_POINTER").
+ * The prefix must be included in the name. It returns the constant assigned
+ * to the property or -1 if not found.
+ *
+ * @param name A non-NULL string describing an input property
+ * @param len The length of the string in @p name excluding any terminating 0
+ * character.
+ *
+ * @return The given code constant for the name or -1 if not found.
+ */
+int libevdev_property_from_name_n(const char *name, size_t len);
+
/**
* @ingroup bits
*
*/
int libevdev_get_repeat(const struct libevdev *dev, int *delay, int *period);
-
/********* DEPRECATED SECTION *********/
#if defined(__GNUC__) && __GNUC__ >= 4
#define LIBEVDEV_DEPRECATED __attribute__ ((deprecated))
local:
*;
};
+
+LIBEVDEV_1_3 {
+global:
+ libevdev_set_device_log_function;
+ libevdev_property_from_name;
+ libevdev_property_from_name_n;
+
+local:
+ *;
+} LIBEVDEV_1;
print("};")
print("")
+ print("#if __clang__")
+ print("#pragma clang diagnostic push")
+ print("#pragma clang diagnostic ignored \"-Winitializer-overrides\"")
+ print("#else")
print("#pragma GCC diagnostic push")
print("#pragma GCC diagnostic ignored \"-Woverride-init\"")
+ print("#endif")
print("static const int ev_max[EV_MAX + 1] = {")
print(" [0 ... EV_MAX] = -1,")
for prefix in prefixes:
continue
print(" [EV_%s] = %s_MAX," % (prefix[:-1], prefix[:-1]))
print("};")
+ print("#if __clang__")
+ print("#pragma clang diagnostic pop /* \"-Winitializer-overrides\" */")
+ print("#else")
print("#pragma GCC diagnostic pop /* \"-Woverride-init\" */")
+ print("#endif");
print("")
def print_python_map(bits):
print_lookup(bits, prefix[:-1].lower())
print("};")
print("")
-
+ print("static const struct name_entry prop_names[] = {")
+ print_lookup(bits, "input_prop")
+ print("};")
+ print("")
def print_mapping_table(bits):
print("/* THIS FILE IS GENERATED, DO NOT EDIT */")
return bits
def usage(prog):
- print("Usage: %s /path/to/linux/input.h" % prog)
+ print("Usage: cat <files> | %s" % prog)
if __name__ == "__main__":
- if len(sys.argv) != 2:
+ if len(sys.argv) != 1:
usage(sys.argv[0])
sys.exit(2)
- with open(sys.argv[1]) as f:
- bits = parse(f)
- print_mapping_table(bits)
+ bits = parse(sys.stdin)
+ print_mapping_table(bits)
dnl Other compilers don't support -Werror per se, but they support
dnl an equivalent flag:
dnl - Sun Studio compiler supports -errwarn=%all
+dnl we don't test for that, it gives us false positives when gcc doesn't
+dnl actually complain about it. If someone wants to compile this on sun, let
+dnl them fix it.
AC_DEFUN([CC_CHECK_WERROR], [
AC_CACHE_CHECK(
[for $CC way to treat warnings as errors],
[cc_cv_werror],
- [CC_CHECK_CFLAGS_SILENT([-Werror], [cc_cv_werror=-Werror],
- [CC_CHECK_CFLAGS_SILENT([-errwarn=%all], [cc_cv_werror=-errwarn=%all])])
- ])
+ [CC_CHECK_FLAG_APPEND([cc_cv_werror], [CFLAGS], [-Werror])])
])
AC_DEFUN([CC_CHECK_ATTRIBUTE], [
])
AC_DEFUN([CC_FLAG_VISIBILITY], [
- AC_REQUIRE([CC_CHECK_WERROR])
AC_CACHE_CHECK([if $CC supports -fvisibility=hidden],
[cc_cv_flag_visibility],
- [cc_flag_visibility_save_CFLAGS="$CFLAGS"
- CFLAGS="$CFLAGS $cc_cv_werror"
- CC_CHECK_CFLAGS_SILENT([-fvisibility=hidden],
- cc_cv_flag_visibility='yes',
- cc_cv_flag_visibility='no')
- CFLAGS="$cc_flag_visibility_save_CFLAGS"])
+ [CC_CHECK_FLAG_APPEND([cc_cv_flag_visibility], [CFLAGS], [-fvisibility=hidden])])
- AS_IF([test "x$cc_cv_flag_visibility" = "xyes"],
+ AS_IF([test "x$cc_cv_flag_visibility" != "x"],
[AC_DEFINE([SUPPORT_FLAG_VISIBILITY], 1,
[Define this if the compiler supports the -fvisibility flag])
$1],
Name: libevdev
-Version: 1.2.2
+Version: 1.5.4
Release: 0
License: MIT
Summary: wrapper library for evdev input devices
%manifest %{name}.manifest
%defattr(-,root,root)
%{TZ_SYS_RO_SHARE}/license/%{name}
-%{_bindir}/touchpad-edge-detector
+%{_bindir}/*
%{_libdir}/*.so.*
%{_datadir}/*
-if BUILD_TESTS
-run_tests = test-libevdev test-kernel
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 =
+clean_local_deps =
+
+if ENABLE_RUNTIME_TESTS
+run_tests = test-libevdev test-kernel
+
.NOTPARALLEL:
-noinst_PROGRAMS = $(run_tests) $(build_tests)
+noinst_PROGRAMS += $(run_tests)
TESTS = $(run_tests)
test-common.h
# include builddir for event-names.h
-AM_CPPFLAGS = -I$(top_srcdir) -I$(top_srcdir)/include -I$(top_builddir)/libevdev $(CHECK_CFLAGS) $(GCOV_CFLAGS)
+AM_CPPFLAGS += $(CHECK_CFLAGS) $(GCOV_CFLAGS)
+AM_LDFLAGS += $(GCOV_LDFLAGS)
test_libevdev_SOURCES = \
test-main.c \
test-uinput.c \
$(common_sources)
-test_libevdev_LDADD = $(CHECK_LIBS) $(GCOV_LDFLAGS)
-
-test_compile_pedantic_SOURCES = test-compile-pedantic.c
-test_compile_pedantic_CFLAGS = $(AM_CPPFLAGS) -pedantic -Werror -std=c90
-
-test_link_SOURCES = test-link.c
-test_link_CFLAGS = -I$(top_srcdir)
-test_link_LDADD = $(top_builddir)/libevdev/libevdev.la
+test_libevdev_LDADD = $(CHECK_LIBS)
test_kernel_SOURCES = \
test-kernel.c \
valgrind:
$(MAKE) check-TESTS LOG_COMPILER="$(VALGRIND)" LOG_FLAGS="$(VALGRIND_FLAGS)"
-check: valgrind
+check_local_deps += valgrind
endif
gcov: gcov-report.txt
@cat gcov-report.txt
-check-local: gcov
+check_local_deps += gcov
+clean_local_deps += gcov-clean
else
gcov-clean:
@true
-endif
+endif # HAVE_VALGRIND
.PHONY: gcov gcov-clean gcov-report.txt
-clean-local: gcov-clean
- rm -f *.gcno *.gcda
+endif # ENABLE_RUNTIME_TESTS
+
+if ENABLE_STATIC_SYMBOL_LEAKS_TEST
+# 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"
+static-symbol-leaks: test-static-link
+ $(AM_V_GEN)(\
+ $(NM) --extern-only $(builddir)/test-static-link | \
+ grep -o -e " T .*" | \
+ grep -v -e " main$$" \
+ -e " atexit" \
+ -e " *gcov.*" \
+ -e " _.*" \
+ -e " libevdev_*" && \
+ echo "Leaking symbols found" && \
+ exit 1 || exit 0 \
+ )
-endif
+check_local_deps += static-symbol-leaks
+endif # HAVE_NM
+
+check-local: $(check_local_deps)
+
+clean-local: $(clean_local_deps)
+ rm -f *.gcno *.gcda
return;
if (dev->uinput_fd != -1) {
- ioctl(dev->uinput_fd, UI_DEV_DESTROY, NULL);
+ (void)ioctl(dev->uinput_fd, UI_DEV_DESTROY, NULL);
close(dev->uinput_fd);
}
if (dev->dev_fd != -1)
#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);
{
}
-int test_create_device(struct uinput_device **uidev_return,
- struct libevdev **dev_return,
- ...)
+void test_create_device(struct uinput_device **uidev_return,
+ struct libevdev **dev_return,
+ ...)
{
int rc, fd;
struct uinput_device *uidev;
*uidev_return = uidev;
*dev_return = dev;
-
- return rc == 0 ? rc : -errno;
}
-int test_create_abs_device(struct uinput_device **uidev_return,
- struct libevdev **dev_return,
- int nabs,
- const struct input_absinfo *abs,
- ...)
+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;
*uidev_return = uidev;
*dev_return = dev;
-
- return rc == 0 ? rc : -errno;
}
#include "test-common-uinput.h"
-
-int test_create_device(struct uinput_device **uidev,
- struct libevdev **dev,
- ...);
-int test_create_abs_device(struct uinput_device **uidev,
- struct libevdev **dev,
- int nabs,
- const struct input_absinfo *abs,
- ...);
+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,
*/
#include <config.h>
-#include <libevdev/libevdev-int.h>
#include "test-common.h"
START_TEST(test_type_codes)
{
- ck_assert(libevdev_event_type_from_name("EV_SYN") == EV_SYN);
- ck_assert(libevdev_event_type_from_name("EV_KEY") == EV_KEY);
- ck_assert(libevdev_event_type_from_name("EV_REL") == EV_REL);
- ck_assert(libevdev_event_type_from_name("EV_ABS") == EV_ABS);
- ck_assert(libevdev_event_type_from_name("EV_MSC") == EV_MSC);
- ck_assert(libevdev_event_type_from_name("EV_SND") == EV_SND);
- ck_assert(libevdev_event_type_from_name("EV_SW") == EV_SW);
- ck_assert(libevdev_event_type_from_name("EV_LED") == EV_LED);
- ck_assert(libevdev_event_type_from_name("EV_REP") == EV_REP);
- ck_assert(libevdev_event_type_from_name("EV_FF") == EV_FF);
- ck_assert(libevdev_event_type_from_name("EV_FF_STATUS") == EV_FF_STATUS);
- ck_assert(libevdev_event_type_from_name("EV_MAX") == EV_MAX);
-
- ck_assert(libevdev_event_type_from_name_n("EV_SYNTAX", 6) == EV_SYN);
- ck_assert(libevdev_event_type_from_name_n("EV_REPTILE", 6) == EV_REP);
+ 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_invalid)
{
- ck_assert(libevdev_event_type_from_name("EV_Syn") == -1);
- ck_assert(libevdev_event_type_from_name("ev_SYN") == -1);
- ck_assert(libevdev_event_type_from_name("SYN") == -1);
- ck_assert(libevdev_event_type_from_name("EV_SYNTAX") == -1);
+ 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(libevdev_event_type_from_name_n("EV_SYN", 5) == -1);
- ck_assert(libevdev_event_type_from_name_n("EV_REPTILE", 7) == -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_key_codes)
{
- ck_assert(libevdev_event_code_from_name(EV_SYN, "SYN_REPORT") == SYN_REPORT);
- ck_assert(libevdev_event_code_from_name(EV_ABS, "ABS_X") == ABS_X);
- ck_assert(libevdev_event_code_from_name(EV_KEY, "BTN_A") == BTN_A);
- ck_assert(libevdev_event_code_from_name(EV_KEY, "KEY_A") == KEY_A);
- ck_assert(libevdev_event_code_from_name(EV_REL, "REL_X") == REL_X);
- ck_assert(libevdev_event_code_from_name(EV_MSC, "MSC_RAW") == MSC_RAW);
- ck_assert(libevdev_event_code_from_name(EV_LED, "LED_KANA") == LED_KANA);
- ck_assert(libevdev_event_code_from_name(EV_SND, "SND_BELL") == SND_BELL);
- ck_assert(libevdev_event_code_from_name(EV_REP, "REP_DELAY") == REP_DELAY);
- ck_assert(libevdev_event_code_from_name(EV_SYN, "SYN_DROPPED") == SYN_DROPPED);
- ck_assert(libevdev_event_code_from_name(EV_KEY, "KEY_RESERVED") == KEY_RESERVED);
- ck_assert(libevdev_event_code_from_name(EV_KEY, "BTN_0") == BTN_0);
- ck_assert(libevdev_event_code_from_name(EV_KEY, "KEY_0") == KEY_0);
- ck_assert(libevdev_event_code_from_name(EV_FF, "FF_GAIN") == FF_GAIN);
- ck_assert(libevdev_event_code_from_name(EV_FF_STATUS, "FF_STATUS_MAX") == FF_STATUS_MAX);
- ck_assert(libevdev_event_code_from_name(EV_SW, "SW_MAX") == SW_MAX);
-
- ck_assert(libevdev_event_code_from_name_n(EV_ABS, "ABS_YXZ", 5) == ABS_Y);
+ 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_MAX"), SW_MAX);
+
+ ck_assert_int_eq(libevdev_event_code_from_name_n(EV_ABS, "ABS_YXZ", 5), ABS_Y);
}
END_TEST
START_TEST(test_key_invalid)
{
- ck_assert(libevdev_event_code_from_name(EV_MAX, "MAX_FAKE") == -1);
- ck_assert(libevdev_event_code_from_name(EV_CNT, "CNT_FAKE") == -1);
- ck_assert(libevdev_event_code_from_name(EV_PWR, "PWR_SOMETHING") == -1);
- ck_assert(libevdev_event_code_from_name(EV_ABS, "EV_ABS") == -1);
- ck_assert(libevdev_event_code_from_name(EV_ABS, "ABS_XY") == -1);
- ck_assert(libevdev_event_code_from_name(EV_KEY, "BTN_GAMEPAD") == -1);
- ck_assert(libevdev_event_code_from_name(EV_KEY, "BUS_PCI") == -1);
- ck_assert(libevdev_event_code_from_name(EV_FF_STATUS, "FF_STATUS") == -1);
- ck_assert(libevdev_event_code_from_name(EV_FF_STATUS, "FF_STATUS_") == -1);
- ck_assert(libevdev_event_code_from_name(EV_FF, "FF_STATUS") == -1);
- ck_assert(libevdev_event_code_from_name(EV_FF, "FF_STATUS_") == -1);
- ck_assert(libevdev_event_code_from_name(EV_KEY, "ID_BUS") == -1);
- ck_assert(libevdev_event_code_from_name(EV_SND, "SND_CNT") == -1);
- ck_assert(libevdev_event_code_from_name(EV_SW, "SW_CNT") == -1);
-
- ck_assert(libevdev_event_code_from_name_n(EV_ABS, "ABS_X", 4) == -1);
+ 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_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
tcase_add_test(tc, test_key_invalid);
suite_add_tcase(s, tc);
+ tc = tcase_create("property tests");
+ tcase_add_test(tc, test_properties);
+ tcase_add_test(tc, test_properties_invalid);
+ suite_add_tcase(s, tc);
+
return s;
}
dev_fd = libevdev_get_fd(dev);
ck_assert_int_ge(dev_fd, 0);
rc = ioctl(dev_fd, EVIOCREVOKE, NULL);
- if (rc == -1 && errno == -EINVAL) {
+ if (rc == -1 && errno == EINVAL) {
fprintf(stderr, "WARNING: skipping EVIOCREVOKE test, not suported by current kernel\n");
goto out;
}
ck_assert_int_gt(fd, -1);
rc = ioctl(fd, EVIOCREVOKE, NULL);
- if (rc == -1 && errno == -EINVAL) {
+ if (rc == -1 && errno == EINVAL) {
fprintf(stderr, "WARNING: skipping EVIOCREVOKE test, not suported by current kernel\n");
goto out;
}
}
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);
+ ck_assert_int_eq(ev.type, EV_KEY);
+ ck_assert_int_eq(ev.code, BTN_LEFT);
+ ck_assert_int_eq(ev.value, 1);
+
+ libevdev_free(dev);
+ uinput_device_free(uidev);
+}
+END_TEST
+
START_TEST(test_syn_dropped_event)
{
struct uinput_device* 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;
abs[3].value = ABS_MT_POSITION_Y;
abs[3].maximum = 1000;
-
abs[4].value = ABS_MT_SLOT;
abs[4].maximum = 1;
abs[5].value = ABS_MT_TRACKING_ID;
abs[3].value = ABS_MT_POSITION_Y;
abs[3].maximum = 1000;
-
abs[4].value = ABS_MT_SLOT;
abs[4].maximum = 1;
abs[5].value = ABS_MT_TRACKING_ID;
}
}
-
/* Now we basically re-do the exact same test, just with the
tracking ID order inverted */
}
}
-
uinput_device_free(uidev);
libevdev_free(dev);
}
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);
abs[5].value = ABS_MT_TRACKING_ID;
abs[5].maximum = 500;
- rc = test_create_abs_device(&uidev, &dev,
- 6, abs,
- EV_SYN, SYN_REPORT,
- -1);
+ test_create_abs_device(&uidev, &dev,
+ 6, 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);
abs[5].value = ABS_MT_TRACKING_ID;
abs[5].maximum = 500;
- rc = test_create_abs_device(&uidev, &dev,
- 6, abs,
- EV_SYN, SYN_REPORT,
- -1);
+ test_create_abs_device(&uidev, &dev,
+ 6, 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);
TCase *tc = tcase_create("event polling");
tcase_add_test(tc, test_next_event);
+ tcase_add_test(tc, test_next_event_invalid_fd);
+ tcase_add_test(tc, test_next_event_blocking);
tcase_add_test(tc, test_syn_dropped_event);
tcase_add_test(tc, test_double_syn_dropped_event);
tcase_add_test(tc, test_event_type_filtered);
tcase_add_test(tc, test_event_code_filtered);
tcase_add_test(tc, test_has_event_pending);
+ tcase_add_test(tc, test_has_event_pending_invalid_fd);
suite_add_tcase(s, tc);
tc = tcase_create("SYN_DROPPED deltas");
return s;
}
-
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);
uidev = uinput_device_new(TEST_DEVICE_NAME);
ck_assert(uidev != NULL);
-
abs.minimum = 0;
abs.maximum = 1000;
abs.fuzz = 1;
}
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;
tcase_add_test(tc, test_device_disable_bit_invalid);
tcase_add_test(tc, test_device_kernel_change_axis);
tcase_add_test(tc, test_device_kernel_change_axis_invalid);
+ tcase_add_test(tc, test_device_kernel_set_abs_invalid_fd);
suite_add_tcase(s, tc);
tc = tcase_create("led manipulation");
return s;
}
-
}
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;
}
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_set_clock_id)
{
struct uinput_device* uidev;
}
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;
tcase_add_test(tc, test_log_set_get_priority);
tcase_add_test(tc, test_log_default_priority);
tcase_add_test(tc, test_log_data);
+ tcase_add_test(tc, test_device_log_init);
suite_add_tcase(s, tc);
tc = tcase_create("device fd init");
tc = tcase_create("device grab");
tcase_add_test(tc, test_device_grab);
+ tcase_add_test(tc, test_device_grab_invalid_fd);
suite_add_tcase(s, tc);
tc = tcase_create("clock id");
tcase_add_test(tc, test_set_clock_id);
+ tcase_add_test(tc, test_set_clock_id_invalid_fd);
tcase_add_test(tc, test_clock_id_events);
suite_add_tcase(s, tc);
Memcheck:Param
timer_create(evp)
fun:timer_create@@GLIBC_2.3.3
- fun:srunner_run
- fun:main
}
{
<ioctl_EVIOCGRAB_unaddressable_bytes>
libevdev-events
touchpad-edge-detector
+mouse-dpi-tool
+libevdev-tweak-device
noinst_PROGRAMS = libevdev-events
-bin_PROGRAMS = touchpad-edge-detector
+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
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)
+libevdev_tweak_device_MANS = libevdev-tweak-device.1
} 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));
+ fprintf(stderr, "Failed to handle events: %s\n", strerror(-rc));
rc = 0;
out:
--- /dev/null
+/*
+ * Copyright © 2014 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.
+ */
+
+#define _GNU_SOURCE
+#include <config.h>
+
+#include <getopt.h>
+#include <limits.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <assert.h>
+#include <linux/input.h>
+
+#include "libevdev.h"
+
+static void
+usage(void)
+{
+ printf("%s --abs <axis> [--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 <led> --on|--off /dev/input/eventXYZ\n"
+ "\tEnable or disable the named LED\n",
+ program_invocation_short_name,
+ program_invocation_short_name,
+ program_invocation_short_name);
+}
+
+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();
+ 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();
+ 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;
+}
--- /dev/null
+/*
+ * Copyright © 2014 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 Red Hat
+ * not be used in advertising or publicity pertaining to distribution
+ * of the software without specific, written prior permission. Red
+ * Hat makes no representations about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied
+ * warranty.
+ *
+ * THE AUTHORS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN
+ * NO EVENT SHALL THE AUTHORS 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <libevdev/libevdev.h>
+#include <sys/signalfd.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <limits.h>
+#include <poll.h>
+#include <signal.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+
+#define min(a, b) (((a) < (b)) ? (a) : (b))
+#define max(a, b) (((a) > (b)) ? (a) : (b))
+
+struct measurements {
+ int distance;
+ double frequency;
+ uint64_t us;
+};
+
+static int
+usage(void) {
+ printf("Usage: %s /dev/input/event0\n", program_invocation_short_name);
+ 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 uint64_t
+tv2us(const struct timeval *tv)
+{
+ return tv->tv_sec * 1000000 + tv->tv_usec;
+}
+
+static inline double
+get_frequency(double last, double current)
+{
+ return 1000000.0/(current - last);
+}
+
+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->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 = tv2us(&ev->time);
+
+ /* reset after pause */
+ if (last_us + idle_reset < m->us) {
+ m->frequency = 0.0;
+ m->distance = 0;
+ } else {
+ double freq = get_frequency(last_us, m->us);
+ m->frequency = max(freq, m->frequency);
+ return print_current_values(m);
+ }
+
+ return 0;
+ } else if (ev->type != EV_REL)
+ return 0;
+
+ switch(ev->code) {
+ case REL_X:
+ m->distance += ev->value;
+ break;
+ }
+
+ return 0;
+}
+
+static int
+mainloop(struct libevdev *dev, struct measurements *m) {
+ struct pollfd fds[2];
+ sigset_t mask;
+
+ fds[0].fd = libevdev_get_fd(dev);
+ fds[0].events = POLLIN;
+
+ sigemptyset(&mask);
+ sigaddset(&mask, SIGINT);
+ fds[1].fd = signalfd(-1, &mask, SFD_NONBLOCK);
+ fds[1].events = POLLIN;
+
+ sigprocmask(SIG_BLOCK, &mask, NULL);
+
+ while (poll(fds, 2, -1)) {
+ struct input_event ev;
+ int rc;
+
+ if (fds[1].revents)
+ 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;
+ } else if (rc != -EAGAIN && rc < 0) {
+ fprintf(stderr, "Error: %s\n", strerror(-rc));
+ return 1;
+ } else if (rc == LIBEVDEV_READ_STATUS_SUCCESS) {
+ handle_event(m, &ev);
+ }
+ } while (rc != -EAGAIN);
+ }
+
+ return 0;
+}
+
+static void
+print_summary(struct measurements *m)
+{
+ int res;
+
+ printf("Estimated sampling frequency: %dHz\n", (int)m->frequency);
+ 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);
+}
+
+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;
+}
+
+int
+main (int argc, char **argv) {
+ int rc;
+ int fd;
+ const char *path;
+ struct libevdev *dev;
+ struct measurements measurements = {0, 0, 0};
+
+ if (argc < 2)
+ return usage();
+
+ path = argv[1];
+ if (path[0] == '-')
+ return usage();
+
+ 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(&measurements);
+
+ 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)measurements.frequency);
+
+ libevdev_free(dev);
+ close(fd);
+
+ return rc;
+}
#include <errno.h>
#include <fcntl.h>
#include <limits.h>
+#include <math.h>
#include <poll.h>
#include <signal.h>
#include <stdint.h>
static int
usage(void) {
- printf("Usage: %s /dev/input/event0\n", program_invocation_short_name);
+ printf("Usage: %s 12x34 /dev/input/event0\n", program_invocation_short_name);
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 minimum and maximum for the x and y coordinates, respectively.\n"
+ "The first argument is the physical size of the touchpad in mm.\n");
return 1;
}
int top, bottom, left, right;
};
+struct size {
+ int w, h;
+};
+
static int
print_current_values(const struct dimensions *d)
{
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);
+
+ return;
+}
+
+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) {
+ printf("Touchpad size as listed by the kernel: %dx%dmm\n",
+ w/x->resolution, h/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("# <Laptop model description goes here>\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();
- if (argc < 2)
+ if (sscanf(argv[1], "%dx%d", &size.w, &size.h) != 2 ||
+ size.w <= 0 || size.h <= 0)
return usage();
- path = argv[1];
+ 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();
}
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;
setbuf(stdout, NULL);
rc = mainloop(dev, &dim);
+ printf("\n\n");
- printf("\n");
+ print_udev_override_rule(dev, &dim, &size);
+out:
libevdev_free(dev);
close(fd);
return rc;
}
-