mirror of
https://github.com/openharmony/third_party_libevdev.git
synced 2026-07-19 19:23:30 -04:00
update OpenHarmony 2.0 Canary
This commit is contained in:
@@ -0,0 +1,42 @@
|
||||
lib_LTLIBRARIES=libevdev.la
|
||||
|
||||
AM_CPPFLAGS = $(GCC_CFLAGS) $(GCOV_CFLAGS) -I$(top_srcdir)/include -I$(top_srcdir)
|
||||
AM_LDFLAGS = $(GCOV_LDFLAGS)
|
||||
|
||||
libevdev_la_SOURCES = \
|
||||
libevdev.h \
|
||||
libevdev-int.h \
|
||||
libevdev-util.h \
|
||||
libevdev-uinput.c \
|
||||
libevdev-uinput.h \
|
||||
libevdev-uinput-int.h \
|
||||
libevdev.c \
|
||||
libevdev-names.c \
|
||||
../include/linux/input.h \
|
||||
../include/linux/uinput.h \
|
||||
../include/linux/@OS@/input-event-codes.h \
|
||||
../include/linux/@OS@/input.h \
|
||||
../include/linux/@OS@/uinput.h
|
||||
|
||||
libevdev_la_LDFLAGS = \
|
||||
$(AM_LDFLAGS) \
|
||||
-version-info $(LIBEVDEV_LT_VERSION) \
|
||||
-Wl,--version-script="$(srcdir)/libevdev.sym" \
|
||||
$(GNU_LD_FLAGS)
|
||||
|
||||
EXTRA_libevdev_la_DEPENDENCIES = $(srcdir)/libevdev.sym
|
||||
|
||||
libevdevincludedir = $(includedir)/libevdev-1.0/libevdev
|
||||
libevdevinclude_HEADERS = libevdev.h libevdev-uinput.h
|
||||
|
||||
event-names.h: Makefile make-event-names.py
|
||||
$(PYTHON) $(srcdir)/make-event-names.py $(top_srcdir)/include/linux/@OS@/input.h $(top_srcdir)/include/linux/@OS@/input-event-codes.h > $@
|
||||
|
||||
|
||||
EXTRA_DIST = make-event-names.py libevdev.sym
|
||||
CLEANFILES = event-names.h
|
||||
BUILT_SOURCES = event-names.h
|
||||
|
||||
if GCOV_ENABLED
|
||||
CLEANFILES += *.gcno
|
||||
endif
|
||||
@@ -0,0 +1,749 @@
|
||||
# Makefile.in generated by automake 1.16.2 from Makefile.am.
|
||||
# @configure_input@
|
||||
|
||||
# Copyright (C) 1994-2020 Free Software Foundation, Inc.
|
||||
|
||||
# This Makefile.in is free software; the Free Software Foundation
|
||||
# gives unlimited permission to copy and/or distribute it,
|
||||
# with or without modifications, as long as this notice is preserved.
|
||||
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
|
||||
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
# PARTICULAR PURPOSE.
|
||||
|
||||
@SET_MAKE@
|
||||
|
||||
|
||||
VPATH = @srcdir@
|
||||
am__is_gnu_make = { \
|
||||
if test -z '$(MAKELEVEL)'; then \
|
||||
false; \
|
||||
elif test -n '$(MAKE_HOST)'; then \
|
||||
true; \
|
||||
elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
|
||||
true; \
|
||||
else \
|
||||
false; \
|
||||
fi; \
|
||||
}
|
||||
am__make_running_with_option = \
|
||||
case $${target_option-} in \
|
||||
?) ;; \
|
||||
*) echo "am__make_running_with_option: internal error: invalid" \
|
||||
"target option '$${target_option-}' specified" >&2; \
|
||||
exit 1;; \
|
||||
esac; \
|
||||
has_opt=no; \
|
||||
sane_makeflags=$$MAKEFLAGS; \
|
||||
if $(am__is_gnu_make); then \
|
||||
sane_makeflags=$$MFLAGS; \
|
||||
else \
|
||||
case $$MAKEFLAGS in \
|
||||
*\\[\ \ ]*) \
|
||||
bs=\\; \
|
||||
sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
|
||||
| sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \
|
||||
esac; \
|
||||
fi; \
|
||||
skip_next=no; \
|
||||
strip_trailopt () \
|
||||
{ \
|
||||
flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
|
||||
}; \
|
||||
for flg in $$sane_makeflags; do \
|
||||
test $$skip_next = yes && { skip_next=no; continue; }; \
|
||||
case $$flg in \
|
||||
*=*|--*) continue;; \
|
||||
-*I) strip_trailopt 'I'; skip_next=yes;; \
|
||||
-*I?*) strip_trailopt 'I';; \
|
||||
-*O) strip_trailopt 'O'; skip_next=yes;; \
|
||||
-*O?*) strip_trailopt 'O';; \
|
||||
-*l) strip_trailopt 'l'; skip_next=yes;; \
|
||||
-*l?*) strip_trailopt 'l';; \
|
||||
-[dEDm]) skip_next=yes;; \
|
||||
-[JT]) skip_next=yes;; \
|
||||
esac; \
|
||||
case $$flg in \
|
||||
*$$target_option*) has_opt=yes; break;; \
|
||||
esac; \
|
||||
done; \
|
||||
test $$has_opt = yes
|
||||
am__make_dryrun = (target_option=n; $(am__make_running_with_option))
|
||||
am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
|
||||
pkgdatadir = $(datadir)/@PACKAGE@
|
||||
pkgincludedir = $(includedir)/@PACKAGE@
|
||||
pkglibdir = $(libdir)/@PACKAGE@
|
||||
pkglibexecdir = $(libexecdir)/@PACKAGE@
|
||||
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
|
||||
install_sh_DATA = $(install_sh) -c -m 644
|
||||
install_sh_PROGRAM = $(install_sh) -c
|
||||
install_sh_SCRIPT = $(install_sh) -c
|
||||
INSTALL_HEADER = $(INSTALL_DATA)
|
||||
transform = $(program_transform_name)
|
||||
NORMAL_INSTALL = :
|
||||
PRE_INSTALL = :
|
||||
POST_INSTALL = :
|
||||
NORMAL_UNINSTALL = :
|
||||
PRE_UNINSTALL = :
|
||||
POST_UNINSTALL = :
|
||||
build_triplet = @build@
|
||||
host_triplet = @host@
|
||||
@GCOV_ENABLED_TRUE@am__append_1 = *.gcno
|
||||
subdir = libevdev
|
||||
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
|
||||
am__aclocal_m4_deps = $(top_srcdir)/m4/attributes.m4 \
|
||||
$(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \
|
||||
$(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \
|
||||
$(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac
|
||||
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
|
||||
$(ACLOCAL_M4)
|
||||
DIST_COMMON = $(srcdir)/Makefile.am $(libevdevinclude_HEADERS) \
|
||||
$(am__DIST_COMMON)
|
||||
mkinstalldirs = $(install_sh) -d
|
||||
CONFIG_HEADER = $(top_builddir)/config.h
|
||||
CONFIG_CLEAN_FILES =
|
||||
CONFIG_CLEAN_VPATH_FILES =
|
||||
am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
|
||||
am__vpath_adj = case $$p in \
|
||||
$(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
|
||||
*) f=$$p;; \
|
||||
esac;
|
||||
am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
|
||||
am__install_max = 40
|
||||
am__nobase_strip_setup = \
|
||||
srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
|
||||
am__nobase_strip = \
|
||||
for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
|
||||
am__nobase_list = $(am__nobase_strip_setup); \
|
||||
for p in $$list; do echo "$$p $$p"; done | \
|
||||
sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
|
||||
$(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
|
||||
if (++n[$$2] == $(am__install_max)) \
|
||||
{ print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
|
||||
END { for (dir in files) print dir, files[dir] }'
|
||||
am__base_list = \
|
||||
sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
|
||||
sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
|
||||
am__uninstall_files_from_dir = { \
|
||||
test -z "$$files" \
|
||||
|| { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
|
||||
|| { echo " ( cd '$$dir' && rm -f" $$files ")"; \
|
||||
$(am__cd) "$$dir" && rm -f $$files; }; \
|
||||
}
|
||||
am__installdirs = "$(DESTDIR)$(libdir)" \
|
||||
"$(DESTDIR)$(libevdevincludedir)"
|
||||
LTLIBRARIES = $(lib_LTLIBRARIES)
|
||||
libevdev_la_LIBADD =
|
||||
am_libevdev_la_OBJECTS = libevdev-uinput.lo libevdev.lo \
|
||||
libevdev-names.lo
|
||||
libevdev_la_OBJECTS = $(am_libevdev_la_OBJECTS)
|
||||
AM_V_lt = $(am__v_lt_@AM_V@)
|
||||
am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
|
||||
am__v_lt_0 = --silent
|
||||
am__v_lt_1 =
|
||||
libevdev_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
|
||||
$(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
|
||||
$(libevdev_la_LDFLAGS) $(LDFLAGS) -o $@
|
||||
AM_V_P = $(am__v_P_@AM_V@)
|
||||
am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
|
||||
am__v_P_0 = false
|
||||
am__v_P_1 = :
|
||||
AM_V_GEN = $(am__v_GEN_@AM_V@)
|
||||
am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
|
||||
am__v_GEN_0 = @echo " GEN " $@;
|
||||
am__v_GEN_1 =
|
||||
AM_V_at = $(am__v_at_@AM_V@)
|
||||
am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
|
||||
am__v_at_0 = @
|
||||
am__v_at_1 =
|
||||
DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
|
||||
depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp
|
||||
am__maybe_remake_depfiles = depfiles
|
||||
am__depfiles_remade = ./$(DEPDIR)/libevdev-names.Plo \
|
||||
./$(DEPDIR)/libevdev-uinput.Plo ./$(DEPDIR)/libevdev.Plo
|
||||
am__mv = mv -f
|
||||
COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
|
||||
$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
|
||||
LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
|
||||
$(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \
|
||||
$(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
|
||||
$(AM_CFLAGS) $(CFLAGS)
|
||||
AM_V_CC = $(am__v_CC_@AM_V@)
|
||||
am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@)
|
||||
am__v_CC_0 = @echo " CC " $@;
|
||||
am__v_CC_1 =
|
||||
CCLD = $(CC)
|
||||
LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
|
||||
$(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
|
||||
$(AM_LDFLAGS) $(LDFLAGS) -o $@
|
||||
AM_V_CCLD = $(am__v_CCLD_@AM_V@)
|
||||
am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@)
|
||||
am__v_CCLD_0 = @echo " CCLD " $@;
|
||||
am__v_CCLD_1 =
|
||||
SOURCES = $(libevdev_la_SOURCES)
|
||||
DIST_SOURCES = $(libevdev_la_SOURCES)
|
||||
am__can_run_installinfo = \
|
||||
case $$AM_UPDATE_INFO_DIR in \
|
||||
n|no|NO) false;; \
|
||||
*) (install-info --version) >/dev/null 2>&1;; \
|
||||
esac
|
||||
HEADERS = $(libevdevinclude_HEADERS)
|
||||
am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
|
||||
# Read a list of newline-separated strings from the standard input,
|
||||
# and print each of them once, without duplicates. Input order is
|
||||
# *not* preserved.
|
||||
am__uniquify_input = $(AWK) '\
|
||||
BEGIN { nonempty = 0; } \
|
||||
{ items[$$0] = 1; nonempty = 1; } \
|
||||
END { if (nonempty) { for (i in items) print i; }; } \
|
||||
'
|
||||
# Make sure the list of sources is unique. This is necessary because,
|
||||
# e.g., the same source file might be shared among _SOURCES variables
|
||||
# for different programs/libraries.
|
||||
am__define_uniq_tagged_files = \
|
||||
list='$(am__tagged_files)'; \
|
||||
unique=`for i in $$list; do \
|
||||
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
|
||||
done | $(am__uniquify_input)`
|
||||
ETAGS = etags
|
||||
CTAGS = ctags
|
||||
am__DIST_COMMON = $(srcdir)/Makefile.in \
|
||||
$(top_srcdir)/build-aux/depcomp
|
||||
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
|
||||
ACLOCAL = @ACLOCAL@
|
||||
AMTAR = @AMTAR@
|
||||
AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
|
||||
AR = @AR@
|
||||
AUTOCONF = @AUTOCONF@
|
||||
AUTOHEADER = @AUTOHEADER@
|
||||
AUTOMAKE = @AUTOMAKE@
|
||||
AWK = @AWK@
|
||||
CC = @CC@
|
||||
CCDEPMODE = @CCDEPMODE@
|
||||
CFLAGS = @CFLAGS@
|
||||
CHECK_CFLAGS = @CHECK_CFLAGS@
|
||||
CHECK_LIBS = @CHECK_LIBS@
|
||||
CPP = @CPP@
|
||||
CPPFLAGS = @CPPFLAGS@
|
||||
CYGPATH_W = @CYGPATH_W@
|
||||
DEFS = @DEFS@
|
||||
DEPDIR = @DEPDIR@
|
||||
DLLTOOL = @DLLTOOL@
|
||||
DOXYGEN = @DOXYGEN@
|
||||
DSYMUTIL = @DSYMUTIL@
|
||||
DUMPBIN = @DUMPBIN@
|
||||
ECHO_C = @ECHO_C@
|
||||
ECHO_N = @ECHO_N@
|
||||
ECHO_T = @ECHO_T@
|
||||
EGREP = @EGREP@
|
||||
EXEEXT = @EXEEXT@
|
||||
FGREP = @FGREP@
|
||||
GCC_CFLAGS = @GCC_CFLAGS@
|
||||
GCOV_CFLAGS = @GCOV_CFLAGS@
|
||||
GCOV_LDFLAGS = @GCOV_LDFLAGS@
|
||||
GNU_LD_FLAGS = @GNU_LD_FLAGS@
|
||||
GREP = @GREP@
|
||||
INSTALL = @INSTALL@
|
||||
INSTALL_DATA = @INSTALL_DATA@
|
||||
INSTALL_PROGRAM = @INSTALL_PROGRAM@
|
||||
INSTALL_SCRIPT = @INSTALL_SCRIPT@
|
||||
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
|
||||
LD = @LD@
|
||||
LDFLAGS = @LDFLAGS@
|
||||
LIBEVDEV_LT_VERSION = @LIBEVDEV_LT_VERSION@
|
||||
LIBOBJS = @LIBOBJS@
|
||||
LIBS = @LIBS@
|
||||
LIBTOOL = @LIBTOOL@
|
||||
LIPO = @LIPO@
|
||||
LN_S = @LN_S@
|
||||
LTLIBOBJS = @LTLIBOBJS@
|
||||
LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
|
||||
MAKEINFO = @MAKEINFO@
|
||||
MANIFEST_TOOL = @MANIFEST_TOOL@
|
||||
MKDIR_P = @MKDIR_P@
|
||||
NM = @NM@
|
||||
NMEDIT = @NMEDIT@
|
||||
OBJDUMP = @OBJDUMP@
|
||||
OBJEXT = @OBJEXT@
|
||||
OS = @OS@
|
||||
OTOOL = @OTOOL@
|
||||
OTOOL64 = @OTOOL64@
|
||||
PACKAGE = @PACKAGE@
|
||||
PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
|
||||
PACKAGE_NAME = @PACKAGE_NAME@
|
||||
PACKAGE_STRING = @PACKAGE_STRING@
|
||||
PACKAGE_TARNAME = @PACKAGE_TARNAME@
|
||||
PACKAGE_URL = @PACKAGE_URL@
|
||||
PACKAGE_VERSION = @PACKAGE_VERSION@
|
||||
PATH_SEPARATOR = @PATH_SEPARATOR@
|
||||
PKG_CONFIG = @PKG_CONFIG@
|
||||
PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
|
||||
PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
|
||||
PYTHON = @PYTHON@
|
||||
PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
|
||||
PYTHON_PLATFORM = @PYTHON_PLATFORM@
|
||||
PYTHON_PREFIX = @PYTHON_PREFIX@
|
||||
PYTHON_VERSION = @PYTHON_VERSION@
|
||||
RANLIB = @RANLIB@
|
||||
SED = @SED@
|
||||
SET_MAKE = @SET_MAKE@
|
||||
SHELL = @SHELL@
|
||||
STRIP = @STRIP@
|
||||
VALGRIND = @VALGRIND@
|
||||
VERSION = @VERSION@
|
||||
abs_builddir = @abs_builddir@
|
||||
abs_srcdir = @abs_srcdir@
|
||||
abs_top_builddir = @abs_top_builddir@
|
||||
abs_top_srcdir = @abs_top_srcdir@
|
||||
ac_ct_AR = @ac_ct_AR@
|
||||
ac_ct_CC = @ac_ct_CC@
|
||||
ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
|
||||
am__include = @am__include@
|
||||
am__leading_dot = @am__leading_dot@
|
||||
am__quote = @am__quote@
|
||||
am__tar = @am__tar@
|
||||
am__untar = @am__untar@
|
||||
bindir = @bindir@
|
||||
build = @build@
|
||||
build_alias = @build_alias@
|
||||
build_cpu = @build_cpu@
|
||||
build_os = @build_os@
|
||||
build_vendor = @build_vendor@
|
||||
builddir = @builddir@
|
||||
datadir = @datadir@
|
||||
datarootdir = @datarootdir@
|
||||
docdir = @docdir@
|
||||
dvidir = @dvidir@
|
||||
exec_prefix = @exec_prefix@
|
||||
host = @host@
|
||||
host_alias = @host_alias@
|
||||
host_cpu = @host_cpu@
|
||||
host_os = @host_os@
|
||||
host_vendor = @host_vendor@
|
||||
htmldir = @htmldir@
|
||||
includedir = @includedir@
|
||||
infodir = @infodir@
|
||||
install_sh = @install_sh@
|
||||
libdir = @libdir@
|
||||
libexecdir = @libexecdir@
|
||||
localedir = @localedir@
|
||||
localstatedir = @localstatedir@
|
||||
mandir = @mandir@
|
||||
mkdir_p = @mkdir_p@
|
||||
oldincludedir = @oldincludedir@
|
||||
pdfdir = @pdfdir@
|
||||
pkgpyexecdir = @pkgpyexecdir@
|
||||
pkgpythondir = @pkgpythondir@
|
||||
prefix = @prefix@
|
||||
program_transform_name = @program_transform_name@
|
||||
psdir = @psdir@
|
||||
pyexecdir = @pyexecdir@
|
||||
pythondir = @pythondir@
|
||||
sbindir = @sbindir@
|
||||
sharedstatedir = @sharedstatedir@
|
||||
srcdir = @srcdir@
|
||||
sysconfdir = @sysconfdir@
|
||||
target_alias = @target_alias@
|
||||
top_build_prefix = @top_build_prefix@
|
||||
top_builddir = @top_builddir@
|
||||
top_srcdir = @top_srcdir@
|
||||
lib_LTLIBRARIES = libevdev.la
|
||||
AM_CPPFLAGS = $(GCC_CFLAGS) $(GCOV_CFLAGS) -I$(top_srcdir)/include -I$(top_srcdir)
|
||||
AM_LDFLAGS = $(GCOV_LDFLAGS)
|
||||
libevdev_la_SOURCES = \
|
||||
libevdev.h \
|
||||
libevdev-int.h \
|
||||
libevdev-util.h \
|
||||
libevdev-uinput.c \
|
||||
libevdev-uinput.h \
|
||||
libevdev-uinput-int.h \
|
||||
libevdev.c \
|
||||
libevdev-names.c \
|
||||
../include/linux/input.h \
|
||||
../include/linux/uinput.h \
|
||||
../include/linux/@OS@/input-event-codes.h \
|
||||
../include/linux/@OS@/input.h \
|
||||
../include/linux/@OS@/uinput.h
|
||||
|
||||
libevdev_la_LDFLAGS = \
|
||||
$(AM_LDFLAGS) \
|
||||
-version-info $(LIBEVDEV_LT_VERSION) \
|
||||
-Wl,--version-script="$(srcdir)/libevdev.sym" \
|
||||
$(GNU_LD_FLAGS)
|
||||
|
||||
EXTRA_libevdev_la_DEPENDENCIES = $(srcdir)/libevdev.sym
|
||||
libevdevincludedir = $(includedir)/libevdev-1.0/libevdev
|
||||
libevdevinclude_HEADERS = libevdev.h libevdev-uinput.h
|
||||
EXTRA_DIST = make-event-names.py libevdev.sym
|
||||
CLEANFILES = event-names.h $(am__append_1)
|
||||
BUILT_SOURCES = event-names.h
|
||||
all: $(BUILT_SOURCES)
|
||||
$(MAKE) $(AM_MAKEFLAGS) all-am
|
||||
|
||||
.SUFFIXES:
|
||||
.SUFFIXES: .c .lo .o .obj
|
||||
$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
|
||||
@for dep in $?; do \
|
||||
case '$(am__configure_deps)' in \
|
||||
*$$dep*) \
|
||||
( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
|
||||
&& { if test -f $@; then exit 0; else break; fi; }; \
|
||||
exit 1;; \
|
||||
esac; \
|
||||
done; \
|
||||
echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign libevdev/Makefile'; \
|
||||
$(am__cd) $(top_srcdir) && \
|
||||
$(AUTOMAKE) --foreign libevdev/Makefile
|
||||
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
|
||||
@case '$?' in \
|
||||
*config.status*) \
|
||||
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
|
||||
*) \
|
||||
echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \
|
||||
cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \
|
||||
esac;
|
||||
|
||||
$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
|
||||
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
|
||||
|
||||
$(top_srcdir)/configure: $(am__configure_deps)
|
||||
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
|
||||
$(ACLOCAL_M4): $(am__aclocal_m4_deps)
|
||||
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
|
||||
$(am__aclocal_m4_deps):
|
||||
|
||||
install-libLTLIBRARIES: $(lib_LTLIBRARIES)
|
||||
@$(NORMAL_INSTALL)
|
||||
@list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \
|
||||
list2=; for p in $$list; do \
|
||||
if test -f $$p; then \
|
||||
list2="$$list2 $$p"; \
|
||||
else :; fi; \
|
||||
done; \
|
||||
test -z "$$list2" || { \
|
||||
echo " $(MKDIR_P) '$(DESTDIR)$(libdir)'"; \
|
||||
$(MKDIR_P) "$(DESTDIR)$(libdir)" || exit 1; \
|
||||
echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(libdir)'"; \
|
||||
$(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(libdir)"; \
|
||||
}
|
||||
|
||||
uninstall-libLTLIBRARIES:
|
||||
@$(NORMAL_UNINSTALL)
|
||||
@list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \
|
||||
for p in $$list; do \
|
||||
$(am__strip_dir) \
|
||||
echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$f'"; \
|
||||
$(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$f"; \
|
||||
done
|
||||
|
||||
clean-libLTLIBRARIES:
|
||||
-test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES)
|
||||
@list='$(lib_LTLIBRARIES)'; \
|
||||
locs=`for p in $$list; do echo $$p; done | \
|
||||
sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \
|
||||
sort -u`; \
|
||||
test -z "$$locs" || { \
|
||||
echo rm -f $${locs}; \
|
||||
rm -f $${locs}; \
|
||||
}
|
||||
|
||||
libevdev.la: $(libevdev_la_OBJECTS) $(libevdev_la_DEPENDENCIES) $(EXTRA_libevdev_la_DEPENDENCIES)
|
||||
$(AM_V_CCLD)$(libevdev_la_LINK) -rpath $(libdir) $(libevdev_la_OBJECTS) $(libevdev_la_LIBADD) $(LIBS)
|
||||
|
||||
mostlyclean-compile:
|
||||
-rm -f *.$(OBJEXT)
|
||||
|
||||
distclean-compile:
|
||||
-rm -f *.tab.c
|
||||
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libevdev-names.Plo@am__quote@ # am--include-marker
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libevdev-uinput.Plo@am__quote@ # am--include-marker
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libevdev.Plo@am__quote@ # am--include-marker
|
||||
|
||||
$(am__depfiles_remade):
|
||||
@$(MKDIR_P) $(@D)
|
||||
@echo '# dummy' >$@-t && $(am__mv) $@-t $@
|
||||
|
||||
am--depfiles: $(am__depfiles_remade)
|
||||
|
||||
.c.o:
|
||||
@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\
|
||||
@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
|
||||
@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po
|
||||
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
|
||||
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
|
||||
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $<
|
||||
|
||||
.c.obj:
|
||||
@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\
|
||||
@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\
|
||||
@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po
|
||||
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
|
||||
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
|
||||
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
|
||||
|
||||
.c.lo:
|
||||
@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\
|
||||
@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
|
||||
@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo
|
||||
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
|
||||
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
|
||||
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $<
|
||||
|
||||
mostlyclean-libtool:
|
||||
-rm -f *.lo
|
||||
|
||||
clean-libtool:
|
||||
-rm -rf .libs _libs
|
||||
install-libevdevincludeHEADERS: $(libevdevinclude_HEADERS)
|
||||
@$(NORMAL_INSTALL)
|
||||
@list='$(libevdevinclude_HEADERS)'; test -n "$(libevdevincludedir)" || list=; \
|
||||
if test -n "$$list"; then \
|
||||
echo " $(MKDIR_P) '$(DESTDIR)$(libevdevincludedir)'"; \
|
||||
$(MKDIR_P) "$(DESTDIR)$(libevdevincludedir)" || exit 1; \
|
||||
fi; \
|
||||
for p in $$list; do \
|
||||
if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
|
||||
echo "$$d$$p"; \
|
||||
done | $(am__base_list) | \
|
||||
while read files; do \
|
||||
echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(libevdevincludedir)'"; \
|
||||
$(INSTALL_HEADER) $$files "$(DESTDIR)$(libevdevincludedir)" || exit $$?; \
|
||||
done
|
||||
|
||||
uninstall-libevdevincludeHEADERS:
|
||||
@$(NORMAL_UNINSTALL)
|
||||
@list='$(libevdevinclude_HEADERS)'; test -n "$(libevdevincludedir)" || list=; \
|
||||
files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
|
||||
dir='$(DESTDIR)$(libevdevincludedir)'; $(am__uninstall_files_from_dir)
|
||||
|
||||
ID: $(am__tagged_files)
|
||||
$(am__define_uniq_tagged_files); mkid -fID $$unique
|
||||
tags: tags-am
|
||||
TAGS: tags
|
||||
|
||||
tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
|
||||
set x; \
|
||||
here=`pwd`; \
|
||||
$(am__define_uniq_tagged_files); \
|
||||
shift; \
|
||||
if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
|
||||
test -n "$$unique" || unique=$$empty_fix; \
|
||||
if test $$# -gt 0; then \
|
||||
$(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
|
||||
"$$@" $$unique; \
|
||||
else \
|
||||
$(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
|
||||
$$unique; \
|
||||
fi; \
|
||||
fi
|
||||
ctags: ctags-am
|
||||
|
||||
CTAGS: ctags
|
||||
ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
|
||||
$(am__define_uniq_tagged_files); \
|
||||
test -z "$(CTAGS_ARGS)$$unique" \
|
||||
|| $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
|
||||
$$unique
|
||||
|
||||
GTAGS:
|
||||
here=`$(am__cd) $(top_builddir) && pwd` \
|
||||
&& $(am__cd) $(top_srcdir) \
|
||||
&& gtags -i $(GTAGS_ARGS) "$$here"
|
||||
cscopelist: cscopelist-am
|
||||
|
||||
cscopelist-am: $(am__tagged_files)
|
||||
list='$(am__tagged_files)'; \
|
||||
case "$(srcdir)" in \
|
||||
[\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
|
||||
*) sdir=$(subdir)/$(srcdir) ;; \
|
||||
esac; \
|
||||
for i in $$list; do \
|
||||
if test -f "$$i"; then \
|
||||
echo "$(subdir)/$$i"; \
|
||||
else \
|
||||
echo "$$sdir/$$i"; \
|
||||
fi; \
|
||||
done >> $(top_builddir)/cscope.files
|
||||
|
||||
distclean-tags:
|
||||
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
|
||||
|
||||
distdir: $(BUILT_SOURCES)
|
||||
$(MAKE) $(AM_MAKEFLAGS) distdir-am
|
||||
|
||||
distdir-am: $(DISTFILES)
|
||||
@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
|
||||
topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
|
||||
list='$(DISTFILES)'; \
|
||||
dist_files=`for file in $$list; do echo $$file; done | \
|
||||
sed -e "s|^$$srcdirstrip/||;t" \
|
||||
-e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
|
||||
case $$dist_files in \
|
||||
*/*) $(MKDIR_P) `echo "$$dist_files" | \
|
||||
sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
|
||||
sort -u` ;; \
|
||||
esac; \
|
||||
for file in $$dist_files; do \
|
||||
if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
|
||||
if test -d $$d/$$file; then \
|
||||
dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
|
||||
if test -d "$(distdir)/$$file"; then \
|
||||
find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
|
||||
fi; \
|
||||
if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
|
||||
cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
|
||||
find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
|
||||
fi; \
|
||||
cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
|
||||
else \
|
||||
test -f "$(distdir)/$$file" \
|
||||
|| cp -p $$d/$$file "$(distdir)/$$file" \
|
||||
|| exit 1; \
|
||||
fi; \
|
||||
done
|
||||
check-am: all-am
|
||||
check: $(BUILT_SOURCES)
|
||||
$(MAKE) $(AM_MAKEFLAGS) check-am
|
||||
all-am: Makefile $(LTLIBRARIES) $(HEADERS)
|
||||
installdirs:
|
||||
for dir in "$(DESTDIR)$(libdir)" "$(DESTDIR)$(libevdevincludedir)"; do \
|
||||
test -z "$$dir" || $(MKDIR_P) "$$dir"; \
|
||||
done
|
||||
install: $(BUILT_SOURCES)
|
||||
$(MAKE) $(AM_MAKEFLAGS) install-am
|
||||
install-exec: install-exec-am
|
||||
install-data: install-data-am
|
||||
uninstall: uninstall-am
|
||||
|
||||
install-am: all-am
|
||||
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
|
||||
|
||||
installcheck: installcheck-am
|
||||
install-strip:
|
||||
if test -z '$(STRIP)'; then \
|
||||
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
|
||||
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
|
||||
install; \
|
||||
else \
|
||||
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
|
||||
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
|
||||
"INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
|
||||
fi
|
||||
mostlyclean-generic:
|
||||
|
||||
clean-generic:
|
||||
-test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
|
||||
|
||||
distclean-generic:
|
||||
-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
|
||||
-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
|
||||
|
||||
maintainer-clean-generic:
|
||||
@echo "This command is intended for maintainers to use"
|
||||
@echo "it deletes files that may require special tools to rebuild."
|
||||
-test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES)
|
||||
clean: clean-am
|
||||
|
||||
clean-am: clean-generic clean-libLTLIBRARIES clean-libtool \
|
||||
mostlyclean-am
|
||||
|
||||
distclean: distclean-am
|
||||
-rm -f ./$(DEPDIR)/libevdev-names.Plo
|
||||
-rm -f ./$(DEPDIR)/libevdev-uinput.Plo
|
||||
-rm -f ./$(DEPDIR)/libevdev.Plo
|
||||
-rm -f Makefile
|
||||
distclean-am: clean-am distclean-compile distclean-generic \
|
||||
distclean-tags
|
||||
|
||||
dvi: dvi-am
|
||||
|
||||
dvi-am:
|
||||
|
||||
html: html-am
|
||||
|
||||
html-am:
|
||||
|
||||
info: info-am
|
||||
|
||||
info-am:
|
||||
|
||||
install-data-am: install-libevdevincludeHEADERS
|
||||
|
||||
install-dvi: install-dvi-am
|
||||
|
||||
install-dvi-am:
|
||||
|
||||
install-exec-am: install-libLTLIBRARIES
|
||||
|
||||
install-html: install-html-am
|
||||
|
||||
install-html-am:
|
||||
|
||||
install-info: install-info-am
|
||||
|
||||
install-info-am:
|
||||
|
||||
install-man:
|
||||
|
||||
install-pdf: install-pdf-am
|
||||
|
||||
install-pdf-am:
|
||||
|
||||
install-ps: install-ps-am
|
||||
|
||||
install-ps-am:
|
||||
|
||||
installcheck-am:
|
||||
|
||||
maintainer-clean: maintainer-clean-am
|
||||
-rm -f ./$(DEPDIR)/libevdev-names.Plo
|
||||
-rm -f ./$(DEPDIR)/libevdev-uinput.Plo
|
||||
-rm -f ./$(DEPDIR)/libevdev.Plo
|
||||
-rm -f Makefile
|
||||
maintainer-clean-am: distclean-am maintainer-clean-generic
|
||||
|
||||
mostlyclean: mostlyclean-am
|
||||
|
||||
mostlyclean-am: mostlyclean-compile mostlyclean-generic \
|
||||
mostlyclean-libtool
|
||||
|
||||
pdf: pdf-am
|
||||
|
||||
pdf-am:
|
||||
|
||||
ps: ps-am
|
||||
|
||||
ps-am:
|
||||
|
||||
uninstall-am: uninstall-libLTLIBRARIES \
|
||||
uninstall-libevdevincludeHEADERS
|
||||
|
||||
.MAKE: all check install install-am install-strip
|
||||
|
||||
.PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \
|
||||
clean-generic clean-libLTLIBRARIES clean-libtool cscopelist-am \
|
||||
ctags ctags-am distclean distclean-compile distclean-generic \
|
||||
distclean-libtool distclean-tags distdir dvi dvi-am html \
|
||||
html-am info info-am install install-am install-data \
|
||||
install-data-am install-dvi install-dvi-am install-exec \
|
||||
install-exec-am install-html install-html-am install-info \
|
||||
install-info-am install-libLTLIBRARIES \
|
||||
install-libevdevincludeHEADERS install-man install-pdf \
|
||||
install-pdf-am install-ps install-ps-am install-strip \
|
||||
installcheck installcheck-am installdirs maintainer-clean \
|
||||
maintainer-clean-generic mostlyclean mostlyclean-compile \
|
||||
mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
|
||||
tags tags-am uninstall uninstall-am uninstall-libLTLIBRARIES \
|
||||
uninstall-libevdevincludeHEADERS
|
||||
|
||||
.PRECIOUS: Makefile
|
||||
|
||||
|
||||
event-names.h: Makefile make-event-names.py
|
||||
$(PYTHON) $(srcdir)/make-event-names.py $(top_srcdir)/include/linux/@OS@/input.h $(top_srcdir)/include/linux/@OS@/input-event-codes.h > $@
|
||||
|
||||
# Tell versions [3.59,3.63) of GNU make to not export all variables.
|
||||
# Otherwise a system limit (for SysV at least) may be exceeded.
|
||||
.NOEXPORT:
|
||||
@@ -0,0 +1,350 @@
|
||||
/*
|
||||
* Copyright © 2013 Red Hat, Inc.
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software and its
|
||||
* documentation for any purpose is hereby granted without fee, provided that
|
||||
* the above copyright notice appear in all copies and that both that copyright
|
||||
* notice and this permission notice appear in supporting documentation, and
|
||||
* that the name of the copyright holders not be used in advertising or
|
||||
* publicity pertaining to distribution of the software without specific,
|
||||
* written prior permission. The copyright holders make no representations
|
||||
* about the suitability of this software for any purpose. It is provided "as
|
||||
* is" without express or implied warranty.
|
||||
*
|
||||
* THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
|
||||
* EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
|
||||
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
|
||||
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
|
||||
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
|
||||
* OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef LIBEVDEV_INT_H
|
||||
#define LIBEVDEV_INT_H
|
||||
|
||||
#include "config.h"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdbool.h>
|
||||
#include <errno.h>
|
||||
#include "libevdev.h"
|
||||
#include "libevdev-util.h"
|
||||
|
||||
#define MAX_NAME 256
|
||||
#define ABS_MT_MIN ABS_MT_SLOT
|
||||
#define ABS_MT_MAX ABS_MT_TOOL_Y
|
||||
#define ABS_MT_CNT (ABS_MT_MAX - ABS_MT_MIN + 1)
|
||||
#define LIBEVDEV_EXPORT __attribute__((visibility("default")))
|
||||
#define ALIAS(_to) __attribute__((alias(#_to)))
|
||||
|
||||
/**
|
||||
* Sync state machine:
|
||||
* default state: SYNC_NONE
|
||||
*
|
||||
* SYNC_NONE → SYN_DROPPED or forced sync → SYNC_NEEDED
|
||||
* SYNC_NEEDED → libevdev_next_event(LIBEVDEV_READ_FLAG_SYNC) → SYNC_IN_PROGRESS
|
||||
* SYNC_NEEDED → libevdev_next_event(LIBEVDEV_READ_FLAG_SYNC_NONE) → SYNC_NONE
|
||||
* SYNC_IN_PROGRESS → libevdev_next_event(LIBEVDEV_READ_FLAG_SYNC_NONE) → SYNC_NONE
|
||||
* SYNC_IN_PROGRESS → no sync events left → SYNC_NONE
|
||||
*
|
||||
*/
|
||||
enum SyncState {
|
||||
SYNC_NONE,
|
||||
SYNC_NEEDED,
|
||||
SYNC_IN_PROGRESS,
|
||||
};
|
||||
|
||||
/**
|
||||
* 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;
|
||||
char *name;
|
||||
char *phys;
|
||||
char *uniq;
|
||||
struct input_id ids;
|
||||
int driver_version;
|
||||
unsigned long bits[NLONGS(EV_CNT)];
|
||||
unsigned long props[NLONGS(INPUT_PROP_CNT)];
|
||||
unsigned long key_bits[NLONGS(KEY_CNT)];
|
||||
unsigned long rel_bits[NLONGS(REL_CNT)];
|
||||
unsigned long abs_bits[NLONGS(ABS_CNT)];
|
||||
unsigned long led_bits[NLONGS(LED_CNT)];
|
||||
unsigned long msc_bits[NLONGS(MSC_CNT)];
|
||||
unsigned long sw_bits[NLONGS(SW_CNT)];
|
||||
unsigned long rep_bits[NLONGS(REP_CNT)]; /* convenience, always 1 */
|
||||
unsigned long ff_bits[NLONGS(FF_CNT)];
|
||||
unsigned long snd_bits[NLONGS(SND_CNT)];
|
||||
unsigned long key_values[NLONGS(KEY_CNT)];
|
||||
unsigned long led_values[NLONGS(LED_CNT)];
|
||||
unsigned long sw_values[NLONGS(SW_CNT)];
|
||||
struct input_absinfo abs_info[ABS_CNT];
|
||||
int *mt_slot_vals; /* [num_slots * ABS_MT_CNT] */
|
||||
int num_slots; /**< valid slots in mt_slot_vals */
|
||||
int current_slot;
|
||||
int rep_values[REP_CNT];
|
||||
|
||||
enum SyncState sync_state;
|
||||
enum libevdev_grab_mode grabbed;
|
||||
|
||||
struct input_event *queue;
|
||||
size_t queue_size; /**< size of queue in elements */
|
||||
size_t queue_next; /**< next event index */
|
||||
size_t queue_nsync; /**< number of sync events */
|
||||
|
||||
struct timeval last_event_time;
|
||||
|
||||
struct logdata log;
|
||||
};
|
||||
|
||||
#define log_msg_cond(dev, priority, ...) \
|
||||
do { \
|
||||
if (_libevdev_log_priority(dev) >= priority) \
|
||||
_libevdev_log_msg(dev, priority, __FILE__, __LINE__, __func__, __VA_ARGS__); \
|
||||
} while(0)
|
||||
|
||||
#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
|
||||
_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);
|
||||
|
||||
static inline void
|
||||
init_event(struct libevdev *dev, struct input_event *ev, int type, int code, int value)
|
||||
{
|
||||
ev->input_event_sec = dev->last_event_time.tv_sec;
|
||||
ev->input_event_usec = dev->last_event_time.tv_usec;
|
||||
ev->type = type;
|
||||
ev->code = code;
|
||||
ev->value = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return a pointer to the next element in the queue, or NULL if the queue
|
||||
* is full.
|
||||
*/
|
||||
static inline struct input_event*
|
||||
queue_push(struct libevdev *dev)
|
||||
{
|
||||
if (dev->queue_next >= dev->queue_size)
|
||||
return NULL;
|
||||
|
||||
return &dev->queue[dev->queue_next++];
|
||||
}
|
||||
|
||||
static inline bool
|
||||
queue_push_event(struct libevdev *dev, unsigned int type,
|
||||
unsigned int code, int value)
|
||||
{
|
||||
struct input_event *ev = queue_push(dev);
|
||||
|
||||
if (ev)
|
||||
init_event(dev, ev, type, code, value);
|
||||
|
||||
return ev != NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set ev to the last element in the queue, removing it from the queue.
|
||||
*
|
||||
* @return 0 on success, 1 if the queue is empty.
|
||||
*/
|
||||
static inline int
|
||||
queue_pop(struct libevdev *dev, struct input_event *ev)
|
||||
{
|
||||
if (dev->queue_next == 0)
|
||||
return 1;
|
||||
|
||||
*ev = dev->queue[--dev->queue_next];
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int
|
||||
queue_peek(struct libevdev *dev, size_t idx, struct input_event *ev)
|
||||
{
|
||||
if (dev->queue_next == 0 || idx > dev->queue_next)
|
||||
return 1;
|
||||
*ev = dev->queue[idx];
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Shift the first n elements into ev and return the number of elements
|
||||
* shifted.
|
||||
* ev must be large enough to store n elements.
|
||||
*
|
||||
* @param ev The buffer to copy into, or NULL
|
||||
* @return The number of elements in ev.
|
||||
*/
|
||||
static inline int
|
||||
queue_shift_multiple(struct libevdev *dev, size_t n, struct input_event *ev)
|
||||
{
|
||||
size_t remaining;
|
||||
|
||||
if (dev->queue_next == 0)
|
||||
return 0;
|
||||
|
||||
remaining = dev->queue_next;
|
||||
n = min(n, remaining);
|
||||
remaining -= n;
|
||||
|
||||
if (ev)
|
||||
memcpy(ev, dev->queue, n * sizeof(*ev));
|
||||
|
||||
memmove(dev->queue, &dev->queue[n], remaining * sizeof(*dev->queue));
|
||||
|
||||
dev->queue_next = remaining;
|
||||
return n;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set ev to the first element in the queue, shifting everything else
|
||||
* forward by one.
|
||||
*
|
||||
* @return 0 on success, 1 if the queue is empty.
|
||||
*/
|
||||
static inline int
|
||||
queue_shift(struct libevdev *dev, struct input_event *ev)
|
||||
{
|
||||
return queue_shift_multiple(dev, 1, ev) == 1 ? 0 : 1;
|
||||
}
|
||||
|
||||
static inline int
|
||||
queue_alloc(struct libevdev *dev, size_t size)
|
||||
{
|
||||
if (size == 0)
|
||||
return -ENOMEM;
|
||||
|
||||
dev->queue = calloc(size, sizeof(struct input_event));
|
||||
if (!dev->queue)
|
||||
return -ENOMEM;
|
||||
|
||||
dev->queue_size = size;
|
||||
dev->queue_next = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline void
|
||||
queue_free(struct libevdev *dev)
|
||||
{
|
||||
free(dev->queue);
|
||||
dev->queue_size = 0;
|
||||
dev->queue_next = 0;
|
||||
}
|
||||
|
||||
static inline size_t
|
||||
queue_num_elements(struct libevdev *dev)
|
||||
{
|
||||
return dev->queue_next;
|
||||
}
|
||||
|
||||
static inline size_t
|
||||
queue_size(struct libevdev *dev)
|
||||
{
|
||||
return dev->queue_size;
|
||||
}
|
||||
|
||||
static inline size_t
|
||||
queue_num_free_elements(struct libevdev *dev)
|
||||
{
|
||||
if (dev->queue_size == 0)
|
||||
return 0;
|
||||
|
||||
return dev->queue_size - dev->queue_next;
|
||||
}
|
||||
|
||||
static inline struct input_event *
|
||||
queue_next_element(struct libevdev *dev)
|
||||
{
|
||||
if (dev->queue_next == dev->queue_size)
|
||||
return NULL;
|
||||
|
||||
return &dev->queue[dev->queue_next];
|
||||
}
|
||||
|
||||
static inline int
|
||||
queue_set_num_elements(struct libevdev *dev, size_t nelem)
|
||||
{
|
||||
if (nelem > dev->queue_size)
|
||||
return 1;
|
||||
|
||||
dev->queue_next = nelem;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define max_mask(uc, lc) \
|
||||
case EV_##uc: \
|
||||
*mask = dev->lc##_bits; \
|
||||
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)
|
||||
{
|
||||
int max;
|
||||
|
||||
switch(type) {
|
||||
max_mask(ABS, abs);
|
||||
max_mask(REL, rel);
|
||||
max_mask(KEY, key);
|
||||
max_mask(LED, led);
|
||||
max_mask(MSC, msc);
|
||||
max_mask(SW, sw);
|
||||
max_mask(FF, ff);
|
||||
max_mask(REP, rep);
|
||||
max_mask(SND, snd);
|
||||
default:
|
||||
max = -1;
|
||||
break;
|
||||
}
|
||||
|
||||
return max;
|
||||
}
|
||||
|
||||
static inline int
|
||||
type_to_mask(struct libevdev *dev, unsigned int type, unsigned long **mask)
|
||||
{
|
||||
int max;
|
||||
|
||||
switch(type) {
|
||||
max_mask(ABS, abs);
|
||||
max_mask(REL, rel);
|
||||
max_mask(KEY, key);
|
||||
max_mask(LED, led);
|
||||
max_mask(MSC, msc);
|
||||
max_mask(SW, sw);
|
||||
max_mask(FF, ff);
|
||||
max_mask(REP, rep);
|
||||
max_mask(SND, snd);
|
||||
default:
|
||||
max = -1;
|
||||
break;
|
||||
}
|
||||
|
||||
return max;
|
||||
}
|
||||
|
||||
#undef max_mask
|
||||
#endif
|
||||
@@ -0,0 +1,230 @@
|
||||
/*
|
||||
* Copyright © 2013 David Herrmann <dh.herrmann@gmail.com>
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software and its
|
||||
* documentation for any purpose is hereby granted without fee, provided that
|
||||
* the above copyright notice appear in all copies and that both that copyright
|
||||
* notice and this permission notice appear in supporting documentation, and
|
||||
* that the name of the copyright holders not be used in advertising or
|
||||
* publicity pertaining to distribution of the software without specific,
|
||||
* written prior permission. The copyright holders make no representations
|
||||
* about the suitability of this software for any purpose. It is provided "as
|
||||
* is" without express or implied warranty.
|
||||
*
|
||||
* THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
|
||||
* EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
|
||||
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
|
||||
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
|
||||
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
|
||||
* OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <strings.h>
|
||||
|
||||
#include "libevdev-int.h"
|
||||
#include "libevdev-util.h"
|
||||
#include "libevdev.h"
|
||||
|
||||
#include "event-names.h"
|
||||
|
||||
struct name_lookup {
|
||||
const char *name;
|
||||
size_t len;
|
||||
};
|
||||
|
||||
static int cmp_entry(const void *vlookup, const void *ventry)
|
||||
{
|
||||
const struct name_lookup *lookup = vlookup;
|
||||
const struct name_entry *entry = ventry;
|
||||
int r;
|
||||
|
||||
r = strncmp(lookup->name, entry->name, lookup->len);
|
||||
if (!r) {
|
||||
if (entry->name[lookup->len])
|
||||
r = -1;
|
||||
else
|
||||
r = 0;
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
static const struct name_entry*
|
||||
lookup_name(const struct name_entry *array, size_t asize,
|
||||
struct name_lookup *lookup)
|
||||
{
|
||||
const struct name_entry *entry;
|
||||
|
||||
entry = bsearch(lookup, array, asize, sizeof(*array), cmp_entry);
|
||||
if (!entry)
|
||||
return NULL;
|
||||
|
||||
return entry;
|
||||
}
|
||||
|
||||
LIBEVDEV_EXPORT int
|
||||
libevdev_event_type_from_name(const char *name)
|
||||
{
|
||||
return libevdev_event_type_from_name_n(name, strlen(name));
|
||||
}
|
||||
|
||||
LIBEVDEV_EXPORT int
|
||||
libevdev_event_type_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(ev_names, ARRAY_LENGTH(ev_names), &lookup);
|
||||
|
||||
return entry ? (int)entry->value : -1;
|
||||
}
|
||||
|
||||
static int type_from_prefix(const char *name, ssize_t len)
|
||||
{
|
||||
const char *e;
|
||||
size_t i;
|
||||
ssize_t l;
|
||||
|
||||
/* MAX_ is not allowed, even though EV_MAX exists */
|
||||
if (startswith(name, len, "MAX_", 4))
|
||||
return -1;
|
||||
/* BTN_ is special as there is no EV_BTN type */
|
||||
if (startswith(name, len, "BTN_", 4))
|
||||
return EV_KEY;
|
||||
/* FF_STATUS_ is special as FF_ is a prefix of it, so test it first */
|
||||
if (startswith(name, len, "FF_STATUS_", 10))
|
||||
return EV_FF_STATUS;
|
||||
|
||||
for (i = 0; i < ARRAY_LENGTH(ev_names); ++i) {
|
||||
/* skip EV_ prefix so @e is suffix of [EV_]XYZ */
|
||||
e = &ev_names[i].name[3];
|
||||
l = strlen(e);
|
||||
|
||||
/* compare prefix and test for trailing _ */
|
||||
if (len > l && startswith(name, len, e, l) && name[l] == '_')
|
||||
return ev_names[i].value;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
LIBEVDEV_EXPORT int
|
||||
libevdev_event_code_from_name(unsigned int type, const char *name)
|
||||
{
|
||||
return libevdev_event_code_from_name_n(type, name, strlen(name));
|
||||
}
|
||||
|
||||
LIBEVDEV_EXPORT int
|
||||
libevdev_event_code_from_name_n(unsigned int type, const char *name, size_t len)
|
||||
{
|
||||
struct name_lookup lookup;
|
||||
const struct name_entry *entry;
|
||||
int real_type;
|
||||
|
||||
/* verify that @name is really of type @type */
|
||||
real_type = type_from_prefix(name, len);
|
||||
if (real_type < 0 || (unsigned int)real_type != type)
|
||||
return -1;
|
||||
|
||||
/* now look up the name @name and return the constant */
|
||||
lookup.name = name;
|
||||
lookup.len = len;
|
||||
|
||||
entry = lookup_name(code_names, ARRAY_LENGTH(code_names), &lookup);
|
||||
|
||||
return entry ? (int)entry->value : -1;
|
||||
}
|
||||
|
||||
LIBEVDEV_EXPORT int
|
||||
libevdev_event_value_from_name(unsigned int type, unsigned int code, const char *name)
|
||||
{
|
||||
return libevdev_event_value_from_name_n(type, code, name, strlen(name));
|
||||
}
|
||||
|
||||
LIBEVDEV_EXPORT int
|
||||
libevdev_event_value_from_name_n(unsigned int type, unsigned int code, const char *name, size_t len)
|
||||
{
|
||||
struct name_lookup lookup;
|
||||
const struct name_entry *entry;
|
||||
|
||||
if (type != EV_ABS || code != ABS_MT_TOOL_TYPE)
|
||||
return -1;
|
||||
|
||||
lookup.name = name;
|
||||
lookup.len = len;
|
||||
|
||||
entry = lookup_name(tool_type_names, ARRAY_LENGTH(tool_type_names), &lookup);
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
LIBEVDEV_EXPORT int
|
||||
libevdev_event_code_from_code_name(const char *name)
|
||||
{
|
||||
return libevdev_event_code_from_code_name_n(name, strlen(name));
|
||||
}
|
||||
|
||||
LIBEVDEV_EXPORT int
|
||||
libevdev_event_code_from_code_name_n(const char *name, size_t len)
|
||||
{
|
||||
const struct name_entry *entry;
|
||||
struct name_lookup lookup;
|
||||
|
||||
/* now look up the name @name and return the constant */
|
||||
lookup.name = name;
|
||||
lookup.len = len;
|
||||
|
||||
entry = lookup_name(code_names, ARRAY_LENGTH(code_names), &lookup);
|
||||
|
||||
return entry ? (int)entry->value : -1;
|
||||
}
|
||||
|
||||
LIBEVDEV_EXPORT int
|
||||
libevdev_event_type_from_code_name(const char *name)
|
||||
{
|
||||
return libevdev_event_type_from_code_name_n(name, strlen(name));
|
||||
}
|
||||
|
||||
LIBEVDEV_EXPORT int
|
||||
libevdev_event_type_from_code_name_n(const char *name, size_t len)
|
||||
{
|
||||
const struct name_entry *entry;
|
||||
struct name_lookup lookup;
|
||||
|
||||
/* First look up if the name exists, we dont' want to return a valid
|
||||
* type for an invalid code name */
|
||||
lookup.name = name;
|
||||
lookup.len = len;
|
||||
|
||||
entry = lookup_name(code_names, ARRAY_LENGTH(code_names), &lookup);
|
||||
|
||||
return entry ? type_from_prefix(name, len) : -1;
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
* Copyright © 2013 Red Hat, Inc.
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software and its
|
||||
* documentation for any purpose is hereby granted without fee, provided that
|
||||
* the above copyright notice appear in all copies and that both that copyright
|
||||
* notice and this permission notice appear in supporting documentation, and
|
||||
* that the name of the copyright holders not be used in advertising or
|
||||
* publicity pertaining to distribution of the software without specific,
|
||||
* written prior permission. The copyright holders make no representations
|
||||
* about the suitability of this software for any purpose. It is provided "as
|
||||
* is" without express or implied warranty.
|
||||
*
|
||||
* THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
|
||||
* EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
|
||||
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
|
||||
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
|
||||
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
|
||||
* OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
struct libevdev_uinput {
|
||||
int fd; /**< file descriptor to uinput */
|
||||
int fd_is_managed; /**< do we need to close it? */
|
||||
char *name; /**< device name */
|
||||
char *syspath; /**< /sys path */
|
||||
char *devnode; /**< device node */
|
||||
time_t ctime[2]; /**< before/after UI_DEV_CREATE */
|
||||
};
|
||||
@@ -0,0 +1,502 @@
|
||||
/*
|
||||
* Copyright © 2013 Red Hat, Inc.
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software and its
|
||||
* documentation for any purpose is hereby granted without fee, provided that
|
||||
* the above copyright notice appear in all copies and that both that copyright
|
||||
* notice and this permission notice appear in supporting documentation, and
|
||||
* that the name of the copyright holders not be used in advertising or
|
||||
* publicity pertaining to distribution of the software without specific,
|
||||
* written prior permission. The copyright holders make no representations
|
||||
* about the suitability of this software for any purpose. It is provided "as
|
||||
* is" without express or implied warranty.
|
||||
*
|
||||
* THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
|
||||
* EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
|
||||
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
|
||||
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
|
||||
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
|
||||
* OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include <dirent.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <linux/uinput.h>
|
||||
#include <poll.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <sys/stat.h>
|
||||
#include <time.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "libevdev-int.h"
|
||||
#include "libevdev-uinput-int.h"
|
||||
#include "libevdev-uinput.h"
|
||||
#include "libevdev-util.h"
|
||||
#include "libevdev.h"
|
||||
|
||||
#ifndef UINPUT_IOCTL_BASE
|
||||
#define UINPUT_IOCTL_BASE 'U'
|
||||
#endif
|
||||
|
||||
#ifndef UI_SET_PROPBIT
|
||||
#define UI_SET_PROPBIT _IOW(UINPUT_IOCTL_BASE, 110, int)
|
||||
#endif
|
||||
|
||||
static struct libevdev_uinput *
|
||||
alloc_uinput_device(const char *name)
|
||||
{
|
||||
struct libevdev_uinput *uinput_dev;
|
||||
|
||||
uinput_dev = calloc(1, sizeof(struct libevdev_uinput));
|
||||
if (uinput_dev) {
|
||||
uinput_dev->name = strdup(name);
|
||||
uinput_dev->fd = -1;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
int rc = 0;
|
||||
unsigned int type;
|
||||
|
||||
for (type = 0; type < EV_CNT; type++) {
|
||||
unsigned int code;
|
||||
int max;
|
||||
int uinput_bit;
|
||||
const unsigned long *mask;
|
||||
|
||||
if (!libevdev_has_event_type(dev, type))
|
||||
continue;
|
||||
|
||||
rc = ioctl(fd, UI_SET_EVBIT, type);
|
||||
if (rc == -1)
|
||||
break;
|
||||
|
||||
/* uinput can't set EV_REP */
|
||||
if (type == EV_REP)
|
||||
continue;
|
||||
|
||||
max = type_to_mask_const(dev, type, &mask);
|
||||
if (max == -1)
|
||||
continue;
|
||||
|
||||
switch(type) {
|
||||
case EV_KEY: uinput_bit = UI_SET_KEYBIT; break;
|
||||
case EV_REL: uinput_bit = UI_SET_RELBIT; break;
|
||||
case EV_ABS: uinput_bit = UI_SET_ABSBIT; break;
|
||||
case EV_MSC: uinput_bit = UI_SET_MSCBIT; break;
|
||||
case EV_LED: uinput_bit = UI_SET_LEDBIT; break;
|
||||
case EV_SND: uinput_bit = UI_SET_SNDBIT; break;
|
||||
case EV_FF: uinput_bit = UI_SET_FFBIT; break;
|
||||
case EV_SW: uinput_bit = UI_SET_SWBIT; break;
|
||||
default:
|
||||
rc = -1;
|
||||
errno = EINVAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
for (code = 0; code <= (unsigned int)max; code++) {
|
||||
if (!libevdev_has_event_code(dev, type, code))
|
||||
continue;
|
||||
|
||||
rc = ioctl(fd, uinput_bit, code);
|
||||
if (rc == -1)
|
||||
goto out;
|
||||
|
||||
if (type == EV_ABS) {
|
||||
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 */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
out:
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int
|
||||
set_props(const struct libevdev *dev, int fd)
|
||||
{
|
||||
unsigned int prop;
|
||||
int rc = 0;
|
||||
|
||||
for (prop = 0; prop <= INPUT_PROP_MAX; prop++) {
|
||||
if (!libevdev_has_property(dev, prop))
|
||||
continue;
|
||||
|
||||
rc = ioctl(fd, UI_SET_PROPBIT, prop);
|
||||
if (rc == -1) {
|
||||
/* If UI_SET_PROPBIT is not supported, treat -EINVAL
|
||||
* as success. The kernel only sends -EINVAL for an
|
||||
* invalid ioctl, invalid INPUT_PROP_MAX or if the
|
||||
* ioctl is called on an already created device. The
|
||||
* last two can't happen here.
|
||||
*/
|
||||
if (errno == EINVAL)
|
||||
rc = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
LIBEVDEV_EXPORT int
|
||||
libevdev_uinput_get_fd(const struct libevdev_uinput *uinput_dev)
|
||||
{
|
||||
return uinput_dev->fd;
|
||||
}
|
||||
|
||||
#ifdef __FreeBSD__
|
||||
/*
|
||||
* FreeBSD does not have anything similar to sysfs.
|
||||
* Set libevdev_uinput->syspath to NULL unconditionally.
|
||||
* Look up the device nodes directly instead of via sysfs, as this matches what
|
||||
* is returned by the UI_GET_SYSNAME ioctl() on FreeBSD.
|
||||
*/
|
||||
static int
|
||||
fetch_syspath_and_devnode(struct libevdev_uinput *uinput_dev)
|
||||
{
|
||||
#define DEV_INPUT_DIR "/dev/input/"
|
||||
int rc;
|
||||
char buf[sizeof(DEV_INPUT_DIR) + 64] = DEV_INPUT_DIR;
|
||||
|
||||
rc = ioctl(uinput_dev->fd,
|
||||
UI_GET_SYSNAME(sizeof(buf) - strlen(DEV_INPUT_DIR)),
|
||||
&buf[strlen(DEV_INPUT_DIR)]);
|
||||
if (rc == -1)
|
||||
return -1;
|
||||
|
||||
uinput_dev->syspath = NULL;
|
||||
uinput_dev->devnode = strdup(buf);
|
||||
|
||||
return 0;
|
||||
#undef DEV_INPUT_DIR
|
||||
}
|
||||
|
||||
#else /* !__FreeBSD__ */
|
||||
|
||||
static int is_event_device(const struct dirent *dent) {
|
||||
return strncmp("event", dent->d_name, 5) == 0;
|
||||
}
|
||||
|
||||
static char *
|
||||
fetch_device_node(const char *path)
|
||||
{
|
||||
char *devnode = NULL;
|
||||
struct dirent **namelist;
|
||||
int ndev, i;
|
||||
|
||||
ndev = scandir(path, &namelist, is_event_device, alphasort);
|
||||
if (ndev <= 0)
|
||||
return NULL;
|
||||
|
||||
/* ndev should only ever be 1 */
|
||||
|
||||
for (i = 0; i < ndev; i++) {
|
||||
if (!devnode && asprintf(&devnode, "/dev/input/%s", namelist[i]->d_name) == -1)
|
||||
devnode = NULL;
|
||||
free(namelist[i]);
|
||||
}
|
||||
|
||||
free(namelist);
|
||||
|
||||
return devnode;
|
||||
}
|
||||
|
||||
static int is_input_device(const struct dirent *dent) {
|
||||
return strncmp("input", dent->d_name, 5) == 0;
|
||||
}
|
||||
|
||||
static int
|
||||
fetch_syspath_and_devnode(struct libevdev_uinput *uinput_dev)
|
||||
{
|
||||
#define SYS_INPUT_DIR "/sys/devices/virtual/input/"
|
||||
struct dirent **namelist;
|
||||
int ndev, i;
|
||||
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)
|
||||
return -1;
|
||||
|
||||
for (i = 0; i < ndev; i++) {
|
||||
int fd, len;
|
||||
struct stat st;
|
||||
|
||||
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 */
|
||||
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)
|
||||
continue;
|
||||
|
||||
buf[len - 1] = '\0'; /* file contains \n */
|
||||
if (strcmp(buf, uinput_dev->name) == 0) {
|
||||
if (uinput_dev->syspath) {
|
||||
/* FIXME: could descend into bit comparison here */
|
||||
log_info(NULL, "multiple identical devices found. syspath is unreliable\n");
|
||||
break;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < ndev; i++)
|
||||
free(namelist[i]);
|
||||
free(namelist);
|
||||
|
||||
return uinput_dev->devnode ? 0 : -1;
|
||||
#undef SYS_INPUT_DIR
|
||||
}
|
||||
#endif /* __FreeBSD__*/
|
||||
|
||||
static int
|
||||
uinput_create_write(const struct libevdev *dev, int fd)
|
||||
{
|
||||
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 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)
|
||||
return -ENOMEM;
|
||||
|
||||
if (fd == LIBEVDEV_UINPUT_OPEN_MANAGED) {
|
||||
fd = open("/dev/uinput", O_RDWR|O_CLOEXEC);
|
||||
if (fd < 0)
|
||||
goto error;
|
||||
|
||||
new_device->fd_is_managed = 1;
|
||||
} else if (fd < 0) {
|
||||
log_bug(NULL, "Invalid fd %d\n", fd);
|
||||
errno = EBADF;
|
||||
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);
|
||||
|
||||
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
|
||||
node.
|
||||
|
||||
this is in seconds, so ctime[0]/[1] will almost always be
|
||||
identical but /sys doesn't give us sub-second ctime so...
|
||||
*/
|
||||
new_device->ctime[0] = time(NULL);
|
||||
|
||||
rc = ioctl(fd, UI_DEV_CREATE, NULL);
|
||||
if (rc == -1)
|
||||
goto error;
|
||||
|
||||
new_device->ctime[1] = time(NULL);
|
||||
new_device->fd = fd;
|
||||
|
||||
if (fetch_syspath_and_devnode(new_device) == -1) {
|
||||
log_error(NULL, "unable to fetch syspath or device node.\n");
|
||||
errno = ENODEV;
|
||||
goto error;
|
||||
}
|
||||
|
||||
*uinput_dev = new_device;
|
||||
|
||||
return 0;
|
||||
|
||||
error:
|
||||
rc = -errno;
|
||||
libevdev_uinput_destroy(new_device);
|
||||
if (fd != -1 && close_fd_on_error)
|
||||
close(fd);
|
||||
return rc;
|
||||
}
|
||||
|
||||
LIBEVDEV_EXPORT void
|
||||
libevdev_uinput_destroy(struct libevdev_uinput *uinput_dev)
|
||||
{
|
||||
if (!uinput_dev)
|
||||
return;
|
||||
|
||||
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);
|
||||
free(uinput_dev);
|
||||
}
|
||||
|
||||
LIBEVDEV_EXPORT const char*
|
||||
libevdev_uinput_get_syspath(struct libevdev_uinput *uinput_dev)
|
||||
{
|
||||
return uinput_dev->syspath;
|
||||
}
|
||||
|
||||
LIBEVDEV_EXPORT const char*
|
||||
libevdev_uinput_get_devnode(struct libevdev_uinput *uinput_dev)
|
||||
{
|
||||
return uinput_dev->devnode;
|
||||
}
|
||||
|
||||
LIBEVDEV_EXPORT int
|
||||
libevdev_uinput_write_event(const struct libevdev_uinput *uinput_dev,
|
||||
unsigned int type,
|
||||
unsigned int code,
|
||||
int value)
|
||||
{
|
||||
struct input_event ev = { {0,0}, type, code, value };
|
||||
int fd = libevdev_uinput_get_fd(uinput_dev);
|
||||
int rc, max;
|
||||
|
||||
if (type > EV_MAX)
|
||||
return -EINVAL;
|
||||
|
||||
max = libevdev_event_type_get_max(type);
|
||||
if (max == -1 || code > (unsigned int)max)
|
||||
return -EINVAL;
|
||||
|
||||
rc = write(fd, &ev, sizeof(ev));
|
||||
|
||||
return rc < 0 ? -errno : 0;
|
||||
}
|
||||
@@ -0,0 +1,255 @@
|
||||
/*
|
||||
* Copyright © 2013 Red Hat, Inc.
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software and its
|
||||
* documentation for any purpose is hereby granted without fee, provided that
|
||||
* the above copyright notice appear in all copies and that both that copyright
|
||||
* notice and this permission notice appear in supporting documentation, and
|
||||
* that the name of the copyright holders not be used in advertising or
|
||||
* publicity pertaining to distribution of the software without specific,
|
||||
* written prior permission. The copyright holders make no representations
|
||||
* about the suitability of this software for any purpose. It is provided "as
|
||||
* is" without express or implied warranty.
|
||||
*
|
||||
* THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
|
||||
* EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
|
||||
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
|
||||
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
|
||||
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
|
||||
* OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef LIBEVDEV_UINPUT_H
|
||||
#define LIBEVDEV_UINPUT_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <libevdev/libevdev.h>
|
||||
|
||||
struct libevdev_uinput;
|
||||
|
||||
/**
|
||||
* @defgroup uinput uinput device creation
|
||||
*
|
||||
* Creation of uinput devices based on existing libevdev devices. These functions
|
||||
* help to create uinput devices that emulate libevdev devices. In the simplest
|
||||
* form it serves to duplicate an existing device:
|
||||
*
|
||||
* @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 (uifd < 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, 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 {
|
||||
/* intentionally -2 to avoid to avoid code like the below from accidentally working:
|
||||
fd = open("/dev/uinput", O_RDWR); // fails, fd is -1
|
||||
libevdev_uinput_create_from_device(dev, fd, &uidev); // may hide the error */
|
||||
LIBEVDEV_UINPUT_OPEN_MANAGED = -2 /**< let libevdev open and close @c /dev/uinput */
|
||||
};
|
||||
|
||||
/**
|
||||
* @ingroup uinput
|
||||
*
|
||||
* Create a uinput device based on the given libevdev device. The uinput device
|
||||
* will be an exact copy of the libevdev device, minus the bits that uinput doesn't
|
||||
* allow to be set.
|
||||
*
|
||||
* If uinput_fd is @ref LIBEVDEV_UINPUT_OPEN_MANAGED, libevdev_uinput_create_from_device()
|
||||
* will open @c /dev/uinput in read/write mode and manage the file descriptor.
|
||||
* Otherwise, uinput_fd must be opened by the caller and opened with the
|
||||
* appropriate permissions.
|
||||
*
|
||||
* The device's lifetime is tied to the uinput file descriptor, closing it will
|
||||
* destroy the uinput device. You should call libevdev_uinput_destroy() before
|
||||
* closing the file descriptor to free allocated resources.
|
||||
* A file descriptor can only create one uinput device at a time; the second device
|
||||
* will fail with -EINVAL.
|
||||
*
|
||||
* You don't need to keep the file descriptor variable around,
|
||||
* libevdev_uinput_get_fd() will return it when needed.
|
||||
*
|
||||
* @note Due to limitations in the uinput kernel module, REP_DELAY and
|
||||
* REP_PERIOD will default to the kernel defaults, not to the ones set in the
|
||||
* source device.
|
||||
*
|
||||
* @note On FreeBSD, if the UI_GET_SYSNAME ioctl() fails, there is no other way
|
||||
* to get a device, and the function call will fail.
|
||||
*
|
||||
* @param dev The device to duplicate
|
||||
* @param uinput_fd @ref LIBEVDEV_UINPUT_OPEN_MANAGED or a file descriptor to @c /dev/uinput,
|
||||
* @param[out] uinput_dev The newly created libevdev device.
|
||||
*
|
||||
* @return 0 on success or a negative errno on failure. On failure, the value of
|
||||
* uinput_dev is unmodified.
|
||||
*
|
||||
* @see libevdev_uinput_destroy
|
||||
*/
|
||||
int libevdev_uinput_create_from_device(const struct libevdev *dev,
|
||||
int uinput_fd,
|
||||
struct libevdev_uinput **uinput_dev);
|
||||
|
||||
/**
|
||||
* @ingroup uinput
|
||||
*
|
||||
* Destroy a previously created uinput device and free associated memory.
|
||||
*
|
||||
* If the device was opened with @ref LIBEVDEV_UINPUT_OPEN_MANAGED,
|
||||
* libevdev_uinput_destroy() also closes the file descriptor. Otherwise, the
|
||||
* fd is left as-is and must be closed by the caller.
|
||||
*
|
||||
* @param uinput_dev A previously created uinput device.
|
||||
*/
|
||||
void libevdev_uinput_destroy(struct libevdev_uinput *uinput_dev);
|
||||
|
||||
/**
|
||||
* @ingroup uinput
|
||||
*
|
||||
* Return the file descriptor used to create this uinput device. This is the
|
||||
* fd pointing to <strong>/dev/uinput</strong>. This file descriptor may be used to write
|
||||
* events that are emitted by the uinput device.
|
||||
* Closing this file descriptor will destroy the uinput device, you should
|
||||
* call libevdev_uinput_destroy() first to free allocated resources.
|
||||
*
|
||||
* @param uinput_dev A previously created uinput device.
|
||||
*
|
||||
* @return The file descriptor used to create this device
|
||||
*/
|
||||
int libevdev_uinput_get_fd(const struct libevdev_uinput *uinput_dev);
|
||||
|
||||
/**
|
||||
* @ingroup uinput
|
||||
*
|
||||
* Return the syspath representing this uinput device. If the UI_GET_SYSNAME
|
||||
* ioctl not available, libevdev makes an educated guess.
|
||||
* The UI_GET_SYSNAME ioctl is available since Linux 3.15.
|
||||
*
|
||||
* The syspath returned is the one of the input node itself
|
||||
* (e.g. /sys/devices/virtual/input/input123), not the syspath of the device
|
||||
* node returned with libevdev_uinput_get_devnode().
|
||||
*
|
||||
* @note This function may return NULL if UI_GET_SYSNAME is not available.
|
||||
* In that case, libevdev uses ctime and the device name to guess devices.
|
||||
* To avoid false positives, wait at least wait at least 1.5s between
|
||||
* creating devices that have the same name.
|
||||
*
|
||||
* @note FreeBSD does not have sysfs, on FreeBSD this function always returns
|
||||
* NULL.
|
||||
*
|
||||
* @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);
|
||||
|
||||
/**
|
||||
* @ingroup uinput
|
||||
*
|
||||
* Return the device node representing this uinput device.
|
||||
*
|
||||
* 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 may have to guess the
|
||||
* syspath and the device node. See libevdev_uinput_get_syspath() for details.
|
||||
*
|
||||
* @note On FreeBSD, this function can not return NULL. libudev uses the
|
||||
* UI_GET_SYSNAME ioctl to get the device node on this platform and if that
|
||||
* fails, the call to libevdev_uinput_create_from_device() fails.
|
||||
*
|
||||
* @param uinput_dev A previously created uinput device.
|
||||
* @return The device node for this device, in the form of /dev/input/eventN
|
||||
*
|
||||
* @see libevdev_uinput_get_syspath
|
||||
*/
|
||||
const char* libevdev_uinput_get_devnode(struct libevdev_uinput *uinput_dev);
|
||||
|
||||
/**
|
||||
* @ingroup uinput
|
||||
*
|
||||
* Post an event through the uinput device. It is the caller's responsibility
|
||||
* that any event sequence is terminated with an EV_SYN/SYN_REPORT/0 event.
|
||||
* Otherwise, listeners on the device node will not see the events until the
|
||||
* next EV_SYN event is posted.
|
||||
*
|
||||
* @param uinput_dev A previously created uinput device.
|
||||
* @param type Event type (EV_ABS, EV_REL, etc.)
|
||||
* @param code Event code (ABS_X, REL_Y, etc.)
|
||||
* @param value The event value
|
||||
* @return 0 on success or a negative errno on error
|
||||
*/
|
||||
int libevdev_uinput_write_event(const struct libevdev_uinput *uinput_dev,
|
||||
unsigned int type,
|
||||
unsigned int code,
|
||||
int value);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* LIBEVDEV_UINPUT_H */
|
||||
@@ -0,0 +1,86 @@
|
||||
/*
|
||||
* Copyright © 2013 Red Hat, Inc.
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software and its
|
||||
* documentation for any purpose is hereby granted without fee, provided that
|
||||
* the above copyright notice appear in all copies and that both that copyright
|
||||
* notice and this permission notice appear in supporting documentation, and
|
||||
* that the name of the copyright holders not be used in advertising or
|
||||
* publicity pertaining to distribution of the software without specific,
|
||||
* written prior permission. The copyright holders make no representations
|
||||
* about the suitability of this software for any purpose. It is provided "as
|
||||
* is" without express or implied warranty.
|
||||
*
|
||||
* THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
|
||||
* EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
|
||||
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
|
||||
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
|
||||
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
|
||||
* OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef _UTIL_H_
|
||||
#define _UTIL_H_
|
||||
|
||||
#include "config.h"
|
||||
#include <stdbool.h>
|
||||
#include <string.h>
|
||||
|
||||
#define LONG_BITS (sizeof(long) * 8)
|
||||
#define NLONGS(x) (((x) + LONG_BITS - 1) / LONG_BITS)
|
||||
#define ARRAY_LENGTH(a) (sizeof(a) / (sizeof((a)[0])))
|
||||
#define unlikely(x) (__builtin_expect(!!(x),0))
|
||||
|
||||
#undef min
|
||||
#undef max
|
||||
#ifdef __GNUC__
|
||||
#define min(a,b) \
|
||||
({ __typeof__ (a) _a = (a); \
|
||||
__typeof__ (b) _b = (b); \
|
||||
_a > _b ? _b : _a; \
|
||||
})
|
||||
#define max(a,b) \
|
||||
({ __typeof__ (a) _a = (a); \
|
||||
__typeof__ (b) _b = (b); \
|
||||
_a > _b ? _a : _b; \
|
||||
})
|
||||
#else
|
||||
#define min(a,b) ((a) > (b) ? (b) : (a))
|
||||
#define max(a,b) ((a) > (b) ? (a) : (b))
|
||||
#endif
|
||||
|
||||
static inline bool
|
||||
startswith(const char *str, size_t len, const char *prefix, size_t plen)
|
||||
{
|
||||
return len >= plen && !strncmp(str, prefix, plen);
|
||||
}
|
||||
|
||||
static inline int
|
||||
bit_is_set(const unsigned long *array, int bit)
|
||||
{
|
||||
return !!(array[bit / LONG_BITS] & (1LL << (bit % LONG_BITS)));
|
||||
}
|
||||
|
||||
static inline void
|
||||
set_bit(unsigned long *array, int bit)
|
||||
{
|
||||
array[bit / LONG_BITS] |= (1LL << (bit % LONG_BITS));
|
||||
}
|
||||
|
||||
static inline void
|
||||
clear_bit(unsigned long *array, int bit)
|
||||
{
|
||||
array[bit / LONG_BITS] &= ~(1LL << (bit % LONG_BITS));
|
||||
}
|
||||
|
||||
static inline void
|
||||
set_bit_state(unsigned long *array, int bit, int state)
|
||||
{
|
||||
if (state)
|
||||
set_bit(array, bit);
|
||||
else
|
||||
clear_bit(array, bit);
|
||||
}
|
||||
|
||||
#endif
|
||||
+1887
File diff suppressed because it is too large
Load Diff
+2373
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,140 @@
|
||||
/*
|
||||
* Copyright (c) 2013 David Herrmann <dh.herrmann@gmail.com>
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software and its
|
||||
* documentation for any purpose is hereby granted without fee, provided that
|
||||
* the above copyright notice appear in all copies and that both that copyright
|
||||
* notice and this permission notice appear in supporting documentation, and
|
||||
* that the name of the copyright holders not be used in advertising or
|
||||
* publicity pertaining to distribution of the software without specific,
|
||||
* written prior permission. The copyright holders make no representations
|
||||
* about the suitability of this software for any purpose. It is provided "as
|
||||
* is" without express or implied warranty.
|
||||
*
|
||||
* THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
|
||||
* EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
|
||||
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
|
||||
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
|
||||
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
|
||||
* OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
LIBEVDEV_1 {
|
||||
global:
|
||||
libevdev_change_fd;
|
||||
libevdev_disable_event_code;
|
||||
libevdev_disable_event_type;
|
||||
libevdev_enable_event_code;
|
||||
libevdev_enable_event_type;
|
||||
libevdev_enable_property;
|
||||
libevdev_event_code_from_name;
|
||||
libevdev_event_code_from_name_n;
|
||||
libevdev_event_code_get_name;
|
||||
libevdev_event_is_code;
|
||||
libevdev_event_is_type;
|
||||
libevdev_event_type_from_name;
|
||||
libevdev_event_type_from_name_n;
|
||||
libevdev_event_type_get_max;
|
||||
libevdev_event_type_get_name;
|
||||
libevdev_fetch_event_value;
|
||||
libevdev_fetch_slot_value;
|
||||
libevdev_free;
|
||||
libevdev_get_abs_flat;
|
||||
libevdev_get_abs_fuzz;
|
||||
libevdev_get_abs_info;
|
||||
libevdev_get_abs_maximum;
|
||||
libevdev_get_abs_minimum;
|
||||
libevdev_get_abs_resolution;
|
||||
libevdev_get_current_slot;
|
||||
libevdev_get_driver_version;
|
||||
libevdev_get_event_value;
|
||||
libevdev_get_fd;
|
||||
libevdev_get_id_bustype;
|
||||
libevdev_get_id_product;
|
||||
libevdev_get_id_vendor;
|
||||
libevdev_get_id_version;
|
||||
libevdev_get_log_priority;
|
||||
libevdev_get_name;
|
||||
libevdev_get_num_slots;
|
||||
libevdev_get_phys;
|
||||
libevdev_get_repeat;
|
||||
libevdev_get_slot_value;
|
||||
libevdev_get_uniq;
|
||||
libevdev_grab;
|
||||
libevdev_has_event_code;
|
||||
libevdev_has_event_pending;
|
||||
libevdev_has_event_type;
|
||||
libevdev_has_property;
|
||||
libevdev_kernel_set_abs_info;
|
||||
libevdev_kernel_set_led_value;
|
||||
libevdev_kernel_set_led_values;
|
||||
libevdev_new;
|
||||
libevdev_new_from_fd;
|
||||
libevdev_next_event;
|
||||
libevdev_property_get_name;
|
||||
libevdev_set_abs_flat;
|
||||
libevdev_set_abs_fuzz;
|
||||
libevdev_set_abs_info;
|
||||
libevdev_set_abs_maximum;
|
||||
libevdev_set_abs_minimum;
|
||||
libevdev_set_abs_resolution;
|
||||
libevdev_set_clock_id;
|
||||
libevdev_set_event_value;
|
||||
libevdev_set_fd;
|
||||
libevdev_set_id_bustype;
|
||||
libevdev_set_id_product;
|
||||
libevdev_set_id_vendor;
|
||||
libevdev_set_id_version;
|
||||
libevdev_set_log_function;
|
||||
libevdev_set_log_priority;
|
||||
libevdev_set_name;
|
||||
libevdev_set_phys;
|
||||
libevdev_set_slot_value;
|
||||
libevdev_set_uniq;
|
||||
libevdev_uinput_create_from_device;
|
||||
libevdev_uinput_destroy;
|
||||
libevdev_uinput_get_devnode;
|
||||
libevdev_uinput_get_fd;
|
||||
libevdev_uinput_get_syspath;
|
||||
libevdev_uinput_write_event;
|
||||
|
||||
local:
|
||||
*;
|
||||
};
|
||||
|
||||
LIBEVDEV_1_3 {
|
||||
global:
|
||||
libevdev_set_device_log_function;
|
||||
libevdev_property_from_name;
|
||||
libevdev_property_from_name_n;
|
||||
|
||||
local:
|
||||
*;
|
||||
} LIBEVDEV_1;
|
||||
|
||||
LIBEVDEV_1_6 {
|
||||
global:
|
||||
libevdev_event_value_get_name;
|
||||
libevdev_event_value_from_name;
|
||||
libevdev_event_value_from_name_n;
|
||||
local:
|
||||
*;
|
||||
} LIBEVDEV_1_3;
|
||||
|
||||
LIBEVDEV_1_7 {
|
||||
global:
|
||||
libevdev_event_code_from_code_name;
|
||||
libevdev_event_code_from_code_name_n;
|
||||
libevdev_event_type_from_code_name;
|
||||
libevdev_event_type_from_code_name_n;
|
||||
local:
|
||||
*;
|
||||
} LIBEVDEV_1_6;
|
||||
|
||||
LIBEVDEV_1_10 {
|
||||
global:
|
||||
libevdev_disable_property;
|
||||
local:
|
||||
*;
|
||||
} LIBEVDEV_1_7;
|
||||
Executable
+231
@@ -0,0 +1,231 @@
|
||||
#!/usr/bin/env python3
|
||||
#
|
||||
# Parses linux/input.h scanning for #define KEY_FOO 134
|
||||
# Prints C header files or Python files that can be used as
|
||||
# mapping and lookup tables.
|
||||
#
|
||||
|
||||
import re
|
||||
import sys
|
||||
|
||||
|
||||
class Bits(object):
|
||||
def __init__(self):
|
||||
self.max_codes = {}
|
||||
|
||||
|
||||
prefixes = [
|
||||
"EV_",
|
||||
"REL_",
|
||||
"ABS_",
|
||||
"KEY_",
|
||||
"BTN_",
|
||||
"LED_",
|
||||
"SND_",
|
||||
"MSC_",
|
||||
"SW_",
|
||||
"FF_",
|
||||
"SYN_",
|
||||
"REP_",
|
||||
"INPUT_PROP_",
|
||||
"MT_TOOL_",
|
||||
]
|
||||
|
||||
duplicates = [
|
||||
"EV_VERSION",
|
||||
"BTN_MISC",
|
||||
"BTN_MOUSE",
|
||||
"BTN_JOYSTICK",
|
||||
"BTN_GAMEPAD",
|
||||
"BTN_DIGI",
|
||||
"BTN_WHEEL",
|
||||
"BTN_TRIGGER_HAPPY",
|
||||
"SW_MAX",
|
||||
"REP_MAX",
|
||||
]
|
||||
|
||||
btn_additional = [
|
||||
[0, "BTN_A"],
|
||||
[0, "BTN_B"],
|
||||
[0, "BTN_X"],
|
||||
[0, "BTN_Y"],
|
||||
]
|
||||
|
||||
code_prefixes = [
|
||||
"REL_",
|
||||
"ABS_",
|
||||
"KEY_",
|
||||
"BTN_",
|
||||
"LED_",
|
||||
"SND_",
|
||||
"MSC_",
|
||||
"SW_",
|
||||
"FF_",
|
||||
"SYN_",
|
||||
"REP_",
|
||||
]
|
||||
|
||||
|
||||
def print_bits(bits, prefix):
|
||||
if not hasattr(bits, prefix):
|
||||
return
|
||||
print("static const char * const %s_map[%s_MAX + 1] = {" % (prefix, prefix.upper()))
|
||||
for val, name in list(getattr(bits, prefix).items()):
|
||||
print(" [%s] = \"%s\"," % (name, name))
|
||||
if prefix == "key":
|
||||
for val, name in list(getattr(bits, "btn").items()):
|
||||
print(" [%s] = \"%s\"," % (name, name))
|
||||
print("};")
|
||||
print("")
|
||||
|
||||
|
||||
def print_map(bits):
|
||||
print("static const char * const * const event_type_map[EV_MAX + 1] = {")
|
||||
|
||||
for prefix in prefixes:
|
||||
if prefix in ["BTN_", "EV_", "INPUT_PROP_", "MT_TOOL_"]:
|
||||
continue
|
||||
print(" [EV_%s] = %s_map," % (prefix[:-1], prefix[:-1].lower()))
|
||||
|
||||
print("};")
|
||||
print("")
|
||||
|
||||
print("#if __clang__")
|
||||
print("#pragma clang diagnostic push")
|
||||
print("#pragma clang diagnostic ignored \"-Winitializer-overrides\"")
|
||||
print("#elif __GNUC__")
|
||||
print("#pragma GCC diagnostic push")
|
||||
print("#pragma GCC diagnostic ignored \"-Woverride-init\"")
|
||||
print("#endif")
|
||||
print("static const int ev_max[EV_MAX + 1] = {")
|
||||
for val in range(bits.max_codes["EV_MAX"] + 1):
|
||||
if val in bits.ev:
|
||||
prefix = bits.ev[val][3:]
|
||||
if prefix + "_" in prefixes:
|
||||
print(" %s_MAX," % prefix)
|
||||
continue
|
||||
print(" -1,")
|
||||
print("};")
|
||||
print("#if __clang__")
|
||||
print("#pragma clang diagnostic pop /* \"-Winitializer-overrides\" */")
|
||||
print("#elif __GNUC__")
|
||||
print("#pragma GCC diagnostic pop /* \"-Woverride-init\" */")
|
||||
print("#endif")
|
||||
print("")
|
||||
|
||||
|
||||
def print_lookup(bits, prefix):
|
||||
if not hasattr(bits, prefix):
|
||||
return
|
||||
|
||||
names = list(getattr(bits, prefix).items())
|
||||
if prefix == "btn":
|
||||
names = names + btn_additional
|
||||
|
||||
# We need to manually add the _MAX codes because some are
|
||||
# duplicates
|
||||
maxname = "%s_MAX" % (prefix.upper())
|
||||
if maxname in duplicates:
|
||||
names.append((bits.max_codes[maxname], maxname))
|
||||
|
||||
for val, name in sorted(names, key=lambda e: e[1]):
|
||||
print(" { .name = \"%s\", .value = %s }," % (name, name))
|
||||
|
||||
|
||||
def print_lookup_table(bits):
|
||||
print("struct name_entry {")
|
||||
print(" const char *name;")
|
||||
print(" unsigned int value;")
|
||||
print("};")
|
||||
print("")
|
||||
print("static const struct name_entry tool_type_names[] = {")
|
||||
print_lookup(bits, "mt_tool")
|
||||
print("};")
|
||||
print("")
|
||||
print("static const struct name_entry ev_names[] = {")
|
||||
print_lookup(bits, "ev")
|
||||
print("};")
|
||||
print("")
|
||||
|
||||
print("static const struct name_entry code_names[] = {")
|
||||
for prefix in sorted(code_prefixes, key=lambda e: e):
|
||||
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 */")
|
||||
print("")
|
||||
print("#ifndef EVENT_NAMES_H")
|
||||
print("#define EVENT_NAMES_H")
|
||||
print("")
|
||||
|
||||
for prefix in prefixes:
|
||||
if prefix == "BTN_":
|
||||
continue
|
||||
print_bits(bits, prefix[:-1].lower())
|
||||
|
||||
print_map(bits)
|
||||
print_lookup_table(bits)
|
||||
|
||||
print("#endif /* EVENT_NAMES_H */")
|
||||
|
||||
|
||||
def parse_define(bits, line):
|
||||
m = re.match(r"^#define\s+(\w+)\s+(\w+)", line)
|
||||
if m is None:
|
||||
return
|
||||
|
||||
name = m.group(1)
|
||||
|
||||
try:
|
||||
value = int(m.group(2), 0)
|
||||
except ValueError:
|
||||
return
|
||||
|
||||
for prefix in prefixes:
|
||||
if not name.startswith(prefix):
|
||||
continue
|
||||
|
||||
if name.endswith("_MAX"):
|
||||
bits.max_codes[name] = value
|
||||
|
||||
if name in duplicates:
|
||||
return
|
||||
|
||||
attrname = prefix[:-1].lower()
|
||||
|
||||
if not hasattr(bits, attrname):
|
||||
setattr(bits, attrname, {})
|
||||
b = getattr(bits, attrname)
|
||||
b[value] = name
|
||||
|
||||
|
||||
def parse(lines):
|
||||
bits = Bits()
|
||||
for line in lines:
|
||||
if not line.startswith("#define"):
|
||||
continue
|
||||
parse_define(bits, line)
|
||||
|
||||
return bits
|
||||
|
||||
|
||||
def usage(prog):
|
||||
print("Usage: %s <files>".format(prog))
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
if len(sys.argv) <= 1:
|
||||
usage(sys.argv[0])
|
||||
sys.exit(2)
|
||||
|
||||
from itertools import chain
|
||||
lines = chain(*[open(f).readlines() for f in sys.argv[1:]])
|
||||
bits = parse(lines)
|
||||
print_mapping_table(bits)
|
||||
Reference in New Issue
Block a user