xf86-input-synaptics-1.9.2/ 0000755 0143106 0000012 00000000000 14262661553 012471 5 0000000 0000000 xf86-input-synaptics-1.9.2/conf/ 0000755 0143106 0000012 00000000000 14262661553 013416 5 0000000 0000000 xf86-input-synaptics-1.9.2/conf/70-synaptics.conf 0000644 0143106 0000012 00000003331 14262661535 016446 0000000 0000000 # Example xorg.conf.d snippet that assigns the touchpad driver
# to all touchpads. See xorg.conf.d(5) for more information on
# InputClass.
# DO NOT EDIT THIS FILE, your distribution will likely overwrite
# it when updating. Copy (and rename) this file into
# /etc/X11/xorg.conf.d first.
# Additional options may be added in the form of
# Option "OptionName" "value"
#
Section "InputClass"
Identifier "touchpad catchall"
Driver "synaptics"
MatchIsTouchpad "on"
# This option is recommend on all Linux systems using evdev, but cannot be
# enabled by default. See the following link for details:
# http://who-t.blogspot.com/2010/11/how-to-ignore-configuration-errors.html
# MatchDevicePath "/dev/input/event*"
EndSection
Section "InputClass"
Identifier "touchpad ignore duplicates"
MatchIsTouchpad "on"
MatchOS "Linux"
MatchDevicePath "/dev/input/mouse*"
Option "Ignore" "on"
EndSection
# This option enables the bottom right corner to be a right button on clickpads
# and the right and middle top areas to be right / middle buttons on clickpads
# with a top button area.
# This option is only interpreted by clickpads.
Section "InputClass"
Identifier "Default clickpad buttons"
MatchDriver "synaptics"
Option "SoftButtonAreas" "50% 0 82% 0 0 0 0 0"
Option "SecondarySoftButtonAreas" "58% 0 0 15% 42% 58% 0 15%"
EndSection
# This option disables software buttons on Apple touchpads.
# This option is only interpreted by clickpads.
Section "InputClass"
Identifier "Disable clickpad buttons on Apple touchpads"
MatchProduct "Apple|bcm5974"
MatchDriver "synaptics"
Option "SoftButtonAreas" "0 0 0 0 0 0 0 0"
EndSection
xf86-input-synaptics-1.9.2/conf/Makefile.in 0000644 0143106 0000012 00000042264 14262661543 015412 0000000 0000000 # Makefile.in generated by automake 1.16.5 from Makefile.am.
# @configure_input@
# Copyright (C) 1994-2021 Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE.
@SET_MAKE@
# Copyright 2005 Adam Jackson.
#
# Permission is hereby granted, free of charge, to any person obtaining a
# copy of this software and associated documentation files (the "Software"),
# to deal in the Software without restriction, including without limitation
# on the rights to use, copy, modify, merge, publish, distribute, sub
# license, and/or sell copies of the Software, and to permit persons to whom
# the Software is furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice (including the next
# paragraph) shall be included in all copies or substantial portions of the
# Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
# ADAM JACKSON BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
VPATH = @srcdir@
am__is_gnu_make = { \
if test -z '$(MAKELEVEL)'; then \
false; \
elif test -n '$(MAKE_HOST)'; then \
true; \
elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
true; \
else \
false; \
fi; \
}
am__make_running_with_option = \
case $${target_option-} in \
?) ;; \
*) echo "am__make_running_with_option: internal error: invalid" \
"target option '$${target_option-}' specified" >&2; \
exit 1;; \
esac; \
has_opt=no; \
sane_makeflags=$$MAKEFLAGS; \
if $(am__is_gnu_make); then \
sane_makeflags=$$MFLAGS; \
else \
case $$MAKEFLAGS in \
*\\[\ \ ]*) \
bs=\\; \
sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
| sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \
esac; \
fi; \
skip_next=no; \
strip_trailopt () \
{ \
flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
}; \
for flg in $$sane_makeflags; do \
test $$skip_next = yes && { skip_next=no; continue; }; \
case $$flg in \
*=*|--*) continue;; \
-*I) strip_trailopt 'I'; skip_next=yes;; \
-*I?*) strip_trailopt 'I';; \
-*O) strip_trailopt 'O'; skip_next=yes;; \
-*O?*) strip_trailopt 'O';; \
-*l) strip_trailopt 'l'; skip_next=yes;; \
-*l?*) strip_trailopt 'l';; \
-[dEDm]) skip_next=yes;; \
-[JT]) skip_next=yes;; \
esac; \
case $$flg in \
*$$target_option*) has_opt=yes; break;; \
esac; \
done; \
test $$has_opt = yes
am__make_dryrun = (target_option=n; $(am__make_running_with_option))
am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
pkgdatadir = $(datadir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
pkglibexecdir = $(libexecdir)/@PACKAGE@
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
install_sh_DATA = $(install_sh) -c -m 644
install_sh_PROGRAM = $(install_sh) -c
install_sh_SCRIPT = $(install_sh) -c
INSTALL_HEADER = $(INSTALL_DATA)
transform = $(program_transform_name)
NORMAL_INSTALL = :
PRE_INSTALL = :
POST_INSTALL = :
NORMAL_UNINSTALL = :
PRE_UNINSTALL = :
POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
subdir = conf
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
DIST_COMMON = $(srcdir)/Makefile.am $(am__dist_config_DATA_DIST) \
$(am__dist_fdi_DATA_DIST) $(am__DIST_COMMON)
mkinstalldirs = $(install_sh) -d
CONFIG_HEADER = $(top_builddir)/config.h
CONFIG_CLEAN_FILES =
CONFIG_CLEAN_VPATH_FILES =
AM_V_P = $(am__v_P_@AM_V@)
am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
am__v_P_0 = false
am__v_P_1 = :
AM_V_GEN = $(am__v_GEN_@AM_V@)
am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
am__v_GEN_0 = @echo " GEN " $@;
am__v_GEN_1 =
AM_V_at = $(am__v_at_@AM_V@)
am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
am__v_at_0 = @
am__v_at_1 =
SOURCES =
DIST_SOURCES =
am__can_run_installinfo = \
case $$AM_UPDATE_INFO_DIR in \
n|no|NO) false;; \
*) (install-info --version) >/dev/null 2>&1;; \
esac
am__dist_config_DATA_DIST = 70-synaptics.conf
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)$(configdir)" "$(DESTDIR)$(fdidir)"
am__dist_fdi_DATA_DIST = 11-x11-synaptics.fdi
DATA = $(dist_config_DATA) $(dist_fdi_DATA)
am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
am__DIST_COMMON = $(srcdir)/Makefile.in
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
ACLOCAL = @ACLOCAL@
ADMIN_MAN_DIR = @ADMIN_MAN_DIR@
ADMIN_MAN_SUFFIX = @ADMIN_MAN_SUFFIX@
AMTAR = @AMTAR@
AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
APP_MAN_DIR = @APP_MAN_DIR@
APP_MAN_SUFFIX = @APP_MAN_SUFFIX@
AR = @AR@
AUTOCONF = @AUTOCONF@
AUTOHEADER = @AUTOHEADER@
AUTOMAKE = @AUTOMAKE@
AWK = @AWK@
BASE_CFLAGS = @BASE_CFLAGS@
CC = @CC@
CCDEPMODE = @CCDEPMODE@
CFLAGS = @CFLAGS@
CHANGELOG_CMD = @CHANGELOG_CMD@
CPPFLAGS = @CPPFLAGS@
CSCOPE = @CSCOPE@
CTAGS = @CTAGS@
CWARNFLAGS = @CWARNFLAGS@
CYGPATH_W = @CYGPATH_W@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
DLLTOOL = @DLLTOOL@
DRIVER_MAN_DIR = @DRIVER_MAN_DIR@
DRIVER_MAN_SUFFIX = @DRIVER_MAN_SUFFIX@
DSYMUTIL = @DSYMUTIL@
DUMPBIN = @DUMPBIN@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
EGREP = @EGREP@
ETAGS = @ETAGS@
EXEEXT = @EXEEXT@
FGREP = @FGREP@
FILECMD = @FILECMD@
FILE_MAN_DIR = @FILE_MAN_DIR@
FILE_MAN_SUFFIX = @FILE_MAN_SUFFIX@
GREP = @GREP@
INSTALL = @INSTALL@
INSTALL_CMD = @INSTALL_CMD@
INSTALL_DATA = @INSTALL_DATA@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
LD = @LD@
LDFLAGS = @LDFLAGS@
LIBEVDEV_CFLAGS = @LIBEVDEV_CFLAGS@
LIBEVDEV_LIBS = @LIBEVDEV_LIBS@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
LIBTOOL = @LIBTOOL@
LIB_MAN_DIR = @LIB_MAN_DIR@
LIB_MAN_SUFFIX = @LIB_MAN_SUFFIX@
LIPO = @LIPO@
LN_S = @LN_S@
LTLIBOBJS = @LTLIBOBJS@
LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
MAKEINFO = @MAKEINFO@
MANIFEST_TOOL = @MANIFEST_TOOL@
MAN_SUBSTS = @MAN_SUBSTS@
MISC_MAN_DIR = @MISC_MAN_DIR@
MISC_MAN_SUFFIX = @MISC_MAN_SUFFIX@
MKDIR_P = @MKDIR_P@
NM = @NM@
NMEDIT = @NMEDIT@
OBJDUMP = @OBJDUMP@
OBJEXT = @OBJEXT@
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@
RANLIB = @RANLIB@
SED = @SED@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
STRICT_CFLAGS = @STRICT_CFLAGS@
STRIP = @STRIP@
VERSION = @VERSION@
XI_CFLAGS = @XI_CFLAGS@
XI_LIBS = @XI_LIBS@
XORG_CFLAGS = @XORG_CFLAGS@
XORG_LIBS = @XORG_LIBS@
XORG_MALLOC_DEBUG_ENV = @XORG_MALLOC_DEBUG_ENV@
XORG_MAN_PAGE = @XORG_MAN_PAGE@
XTST_CFLAGS = @XTST_CFLAGS@
XTST_LIBS = @XTST_LIBS@
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@
configdir = @configdir@
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@
inputdir = @inputdir@
install_sh = @install_sh@
libdir = @libdir@
libexecdir = @libexecdir@
localedir = @localedir@
localstatedir = @localstatedir@
mandir = @mandir@
mkdir_p = @mkdir_p@
oldincludedir = @oldincludedir@
pdfdir = @pdfdir@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
runstatedir = @runstatedir@
sbindir = @sbindir@
sdkdir = @sdkdir@
sharedstatedir = @sharedstatedir@
srcdir = @srcdir@
sysconfdir = @sysconfdir@
target_alias = @target_alias@
top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
@HAS_XORG_CONF_DIR_TRUE@dist_config_DATA = 70-synaptics.conf
@HAS_XORG_CONF_DIR_FALSE@fdidir = $(datadir)/hal/fdi/policy/20thirdparty
@HAS_XORG_CONF_DIR_FALSE@dist_fdi_DATA = 11-x11-synaptics.fdi
all: all-am
.SUFFIXES:
$(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 conf/Makefile'; \
$(am__cd) $(top_srcdir) && \
$(AUTOMAKE) --foreign conf/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):
mostlyclean-libtool:
-rm -f *.lo
clean-libtool:
-rm -rf .libs _libs
install-dist_configDATA: $(dist_config_DATA)
@$(NORMAL_INSTALL)
@list='$(dist_config_DATA)'; test -n "$(configdir)" || list=; \
if test -n "$$list"; then \
echo " $(MKDIR_P) '$(DESTDIR)$(configdir)'"; \
$(MKDIR_P) "$(DESTDIR)$(configdir)" || exit 1; \
fi; \
for p in $$list; do \
if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
echo "$$d$$p"; \
done | $(am__base_list) | \
while read files; do \
echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(configdir)'"; \
$(INSTALL_DATA) $$files "$(DESTDIR)$(configdir)" || exit $$?; \
done
uninstall-dist_configDATA:
@$(NORMAL_UNINSTALL)
@list='$(dist_config_DATA)'; test -n "$(configdir)" || list=; \
files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
dir='$(DESTDIR)$(configdir)'; $(am__uninstall_files_from_dir)
install-dist_fdiDATA: $(dist_fdi_DATA)
@$(NORMAL_INSTALL)
@list='$(dist_fdi_DATA)'; test -n "$(fdidir)" || list=; \
if test -n "$$list"; then \
echo " $(MKDIR_P) '$(DESTDIR)$(fdidir)'"; \
$(MKDIR_P) "$(DESTDIR)$(fdidir)" || exit 1; \
fi; \
for p in $$list; do \
if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
echo "$$d$$p"; \
done | $(am__base_list) | \
while read files; do \
echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(fdidir)'"; \
$(INSTALL_DATA) $$files "$(DESTDIR)$(fdidir)" || exit $$?; \
done
uninstall-dist_fdiDATA:
@$(NORMAL_UNINSTALL)
@list='$(dist_fdi_DATA)'; test -n "$(fdidir)" || list=; \
files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
dir='$(DESTDIR)$(fdidir)'; $(am__uninstall_files_from_dir)
tags TAGS:
ctags CTAGS:
cscope cscopelist:
distdir: $(BUILT_SOURCES)
$(MAKE) $(AM_MAKEFLAGS) distdir-am
distdir-am: $(DISTFILES)
@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
list='$(DISTFILES)'; \
dist_files=`for file in $$list; do echo $$file; done | \
sed -e "s|^$$srcdirstrip/||;t" \
-e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
case $$dist_files in \
*/*) $(MKDIR_P) `echo "$$dist_files" | \
sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
sort -u` ;; \
esac; \
for file in $$dist_files; do \
if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
if test -d $$d/$$file; then \
dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
if test -d "$(distdir)/$$file"; then \
find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
fi; \
if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
fi; \
cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
else \
test -f "$(distdir)/$$file" \
|| cp -p $$d/$$file "$(distdir)/$$file" \
|| exit 1; \
fi; \
done
check-am: all-am
check: check-am
all-am: Makefile $(DATA)
installdirs:
for dir in "$(DESTDIR)$(configdir)" "$(DESTDIR)$(fdidir)"; do \
test -z "$$dir" || $(MKDIR_P) "$$dir"; \
done
install: install-am
install-exec: install-exec-am
install-data: install-data-am
uninstall: uninstall-am
install-am: all-am
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
installcheck: installcheck-am
install-strip:
if test -z '$(STRIP)'; then \
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
install; \
else \
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
"INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
fi
mostlyclean-generic:
clean-generic:
distclean-generic:
-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
maintainer-clean-generic:
@echo "This command is intended for maintainers to use"
@echo "it deletes files that may require special tools to rebuild."
clean: clean-am
clean-am: clean-generic clean-libtool mostlyclean-am
distclean: distclean-am
-rm -f Makefile
distclean-am: clean-am distclean-generic
dvi: dvi-am
dvi-am:
html: html-am
html-am:
info: info-am
info-am:
install-data-am: install-dist_configDATA install-dist_fdiDATA
install-dvi: install-dvi-am
install-dvi-am:
install-exec-am:
install-html: install-html-am
install-html-am:
install-info: install-info-am
install-info-am:
install-man:
install-pdf: install-pdf-am
install-pdf-am:
install-ps: install-ps-am
install-ps-am:
installcheck-am:
maintainer-clean: maintainer-clean-am
-rm -f Makefile
maintainer-clean-am: distclean-am maintainer-clean-generic
mostlyclean: mostlyclean-am
mostlyclean-am: mostlyclean-generic mostlyclean-libtool
pdf: pdf-am
pdf-am:
ps: ps-am
ps-am:
uninstall-am: uninstall-dist_configDATA uninstall-dist_fdiDATA
.MAKE: install-am install-strip
.PHONY: all all-am check check-am clean clean-generic clean-libtool \
cscopelist-am ctags-am distclean distclean-generic \
distclean-libtool distdir dvi dvi-am html html-am info info-am \
install install-am install-data install-data-am \
install-dist_configDATA install-dist_fdiDATA install-dvi \
install-dvi-am install-exec install-exec-am install-html \
install-html-am install-info install-info-am install-man \
install-pdf install-pdf-am install-ps install-ps-am \
install-strip installcheck installcheck-am installdirs \
maintainer-clean maintainer-clean-generic mostlyclean \
mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
tags-am uninstall uninstall-am uninstall-dist_configDATA \
uninstall-dist_fdiDATA
.PRECIOUS: Makefile
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:
xf86-input-synaptics-1.9.2/conf/11-x11-synaptics.fdi 0000644 0143106 0000012 00000003506 14262661535 016671 0000000 0000000
synaptics
50% 0 82% 0 0 0 0 0
58% 0 0 8% 42% 58% 0 8%
0 0 0 0 0 0 0 0
xf86-input-synaptics-1.9.2/conf/Makefile.am 0000644 0143106 0000012 00000002375 14262661535 015401 0000000 0000000 # Copyright 2005 Adam Jackson.
#
# Permission is hereby granted, free of charge, to any person obtaining a
# copy of this software and associated documentation files (the "Software"),
# to deal in the Software without restriction, including without limitation
# on the rights to use, copy, modify, merge, publish, distribute, sub
# license, and/or sell copies of the Software, and to permit persons to whom
# the Software is furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice (including the next
# paragraph) shall be included in all copies or substantial portions of the
# Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
# ADAM JACKSON BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
if HAS_XORG_CONF_DIR
dist_config_DATA = 70-synaptics.conf
else
fdidir = $(datadir)/hal/fdi/policy/20thirdparty
dist_fdi_DATA = 11-x11-synaptics.fdi
endif
xf86-input-synaptics-1.9.2/src/ 0000755 0143106 0000012 00000000000 14262661552 013257 5 0000000 0000000 xf86-input-synaptics-1.9.2/src/synproto.h 0000644 0143106 0000012 00000011513 14262661535 015247 0000000 0000000 /*
* Copyright © 2004 Peter Osterlund
*
* 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.
*
* Authors:
* Peter Osterlund (petero2@telia.com)
*/
#ifndef _SYNPROTO_H_
#define _SYNPROTO_H_
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include
#include
#include
#include
#include
#ifndef XI86_SERVER_FD
#define XI86_SERVER_FD 0x20
#endif
struct _SynapticsPrivateRec;
typedef struct _SynapticsPrivateRec SynapticsPrivate;
enum SynapticsSlotState {
SLOTSTATE_EMPTY = 0, /* no slot in this cycle */
SLOTSTATE_OPEN, /* tracking ID received */
SLOTSTATE_CLOSE, /* tracking ID -1 received */
SLOTSTATE_OPEN_EMPTY, /* previously had tracking id, no events in this read cycle */
SLOTSTATE_UPDATE, /* had tracking id, other events in this cycle */
};
/* used to mark emulated hw button state */
#define BTN_EMULATED_FLAG 0x80
/*
* A structure to describe the state of the touchpad hardware (buttons and pad)
*/
struct SynapticsHwState {
CARD32 millis; /* Timestamp in milliseconds */
int x; /* X position of finger */
int y; /* Y position of finger */
int z; /* Finger pressure */
int cumulative_dx; /* Cumulative delta X for clickpad dragging */
int cumulative_dy; /* Cumulative delta Y for clickpad dragging */
int numFingers;
int fingerWidth;
Bool left;
Bool right;
Bool up;
Bool down;
Bool multi[8];
Bool middle; /* Some ALPS touchpads have a middle button */
int num_mt_mask;
ValuatorMask **mt_mask;
enum SynapticsSlotState *slot_state;
};
struct CommData {
XISBuffer *buffer;
unsigned char protoBuf[6]; /* Buffer for Packet */
unsigned char lastByte; /* Last read byte. Use for reset sequence detection. */
int outOfSync; /* How many consecutive incorrect packets we
have received */
int protoBufTail;
/* Used for keeping track of partial HwState updates. */
struct SynapticsHwState *hwState;
Bool oneFinger;
Bool twoFingers;
Bool threeFingers;
};
struct _SynapticsParameters;
struct SynapticsProtocolOperations {
Bool (*DeviceOnHook) (InputInfoPtr pInfo,
struct _SynapticsParameters * para);
Bool (*DeviceOffHook) (InputInfoPtr pInfo);
Bool (*QueryHardware) (InputInfoPtr pInfo);
Bool (*ReadHwState) (InputInfoPtr pInfo,
struct CommData * comm,
struct SynapticsHwState * hwRet);
Bool (*AutoDevProbe) (InputInfoPtr pInfo, const char *device);
void (*ReadDevDimensions) (InputInfoPtr pInfo);
};
#ifdef BUILD_PS2COMM
extern struct SynapticsProtocolOperations psaux_proto_operations;
extern struct SynapticsProtocolOperations alps_proto_operations;
#endif /* BUILD_PS2COMM */
#ifdef BUILD_EVENTCOMM
extern struct SynapticsProtocolOperations event_proto_operations;
#endif /* BUILD_EVENTCOMM */
#ifdef BUILD_PSMCOMM
extern struct SynapticsProtocolOperations psm_proto_operations;
#endif /* BUILD_PSMCOMM */
extern struct SynapticsHwState *SynapticsHwStateAlloc(SynapticsPrivate * priv);
extern void SynapticsHwStateFree(struct SynapticsHwState **hw);
extern void SynapticsCopyHwState(struct SynapticsHwState *dst,
const struct SynapticsHwState *src);
extern void SynapticsResetHwState(struct SynapticsHwState *hw);
extern void SynapticsResetTouchHwState(struct SynapticsHwState *hw,
Bool set_slot_empty);
extern Bool SynapticsIsSoftButtonAreasValid(int *values);
#endif /* _SYNPROTO_H_ */
xf86-input-synaptics-1.9.2/src/eventcomm.c 0000644 0143106 0000012 00000104222 14262661535 015342 0000000 0000000 /*
* Copyright © 2004-2007 Peter Osterlund
* Copyright © 2008-2012 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.
*
* Authors:
* Peter Osterlund (petero2@telia.com)
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include
#include
#include "eventcomm.h"
#include
#include
#include
#include
#include
#include
#include
#include
#include "synproto.h"
#include "synapticsstr.h"
#include
#include
#ifndef INPUT_PROP_BUTTONPAD
#define INPUT_PROP_BUTTONPAD 0x02
#endif
#ifndef INPUT_PROP_SEMI_MT
#define INPUT_PROP_SEMI_MT 0x03
#endif
#ifndef INPUT_PROP_TOPBUTTONPAD
#define INPUT_PROP_TOPBUTTONPAD 0x04
#endif
#ifndef ABS_MT_TOOL_Y
#define ABS_MT_TOOL_Y 0x3d
#endif
#define SYSCALL(call) while (((call) == -1) && (errno == EINTR))
#define LONG_BITS (sizeof(long) * 8)
#define NBITS(x) (((x) + LONG_BITS - 1) / LONG_BITS)
#define OFF(x) ((x) % LONG_BITS)
#define LONG(x) ((x) / LONG_BITS)
#define TEST_BIT(bit, array) ((array[LONG(bit)] >> OFF(bit)) & 1)
#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)
/**
* Protocol-specific data.
*/
struct eventcomm_proto_data {
/**
* Do we need to grab the event device?
* Note that in the current flow, this variable is always false and
* exists for readability of the code.
*/
BOOL need_grab;
int st_to_mt_offset[2];
double st_to_mt_scale[2];
int axis_map[ABS_MT_CNT];
int cur_slot;
ValuatorMask **last_mt_vals;
int num_touches;
struct libevdev *evdev;
enum libevdev_read_flag read_flag;
int have_monotonic_clock;
};
#ifdef HAVE_LIBEVDEV_DEVICE_LOG_FUNCS
static void
libevdev_log_func(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)
_X_ATTRIBUTE_PRINTF(7, 0);
static void
libevdev_log_func(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)
{
int verbosity;
switch(priority) {
case LIBEVDEV_LOG_ERROR: verbosity = 0; break;
case LIBEVDEV_LOG_INFO: verbosity = 4; break;
case LIBEVDEV_LOG_DEBUG:
default:
verbosity = 10;
break;
}
LogVMessageVerbSigSafe(X_NOTICE, verbosity, format, args);
}
#endif
struct eventcomm_proto_data *
EventProtoDataAlloc(int fd)
{
struct eventcomm_proto_data *proto_data;
int rc;
proto_data = calloc(1, sizeof(struct eventcomm_proto_data));
if (!proto_data)
return NULL;
proto_data->st_to_mt_scale[0] = 1;
proto_data->st_to_mt_scale[1] = 1;
proto_data->evdev = libevdev_new();
if (!proto_data->evdev) {
rc = -1;
goto out;
}
#ifdef HAVE_LIBEVDEV_DEVICE_LOG_FUNCS
libevdev_set_device_log_function(proto_data->evdev, libevdev_log_func,
LIBEVDEV_LOG_DEBUG, NULL);
#endif
rc = libevdev_set_fd(proto_data->evdev, fd);
if (rc < 0) {
goto out;
}
proto_data->read_flag = LIBEVDEV_READ_FLAG_NORMAL;
out:
if (rc < 0) {
if (proto_data && proto_data->evdev)
libevdev_free(proto_data->evdev);
free(proto_data);
proto_data = NULL;
}
return proto_data;
}
static void
UninitializeTouch(InputInfoPtr pInfo)
{
SynapticsPrivate *priv = (SynapticsPrivate *) pInfo->private;
struct eventcomm_proto_data *proto_data =
(struct eventcomm_proto_data *) priv->proto_data;
if (!priv->has_touch)
return;
if (proto_data->last_mt_vals) {
int i;
for (i = 0; i < priv->num_slots; i++)
valuator_mask_free(&proto_data->last_mt_vals[i]);
free(proto_data->last_mt_vals);
proto_data->last_mt_vals = NULL;
}
proto_data->num_touches = 0;
}
static void
InitializeTouch(InputInfoPtr pInfo)
{
SynapticsPrivate *priv = (SynapticsPrivate *) pInfo->private;
struct eventcomm_proto_data *proto_data =
(struct eventcomm_proto_data *) priv->proto_data;
int i;
if (!priv->has_touch)
return;
proto_data->cur_slot = libevdev_get_current_slot(proto_data->evdev);
proto_data->num_touches = 0;
proto_data->last_mt_vals = calloc(priv->num_slots, sizeof(ValuatorMask *));
if (!proto_data->last_mt_vals) {
xf86IDrvMsg(pInfo, X_WARNING,
"failed to allocate MT last values mask array\n");
UninitializeTouch(pInfo);
return;
}
for (i = 0; i < priv->num_slots; i++) {
int j;
proto_data->last_mt_vals[i] = valuator_mask_new(4 + priv->num_mt_axes);
if (!proto_data->last_mt_vals[i]) {
xf86IDrvMsg(pInfo, X_WARNING,
"failed to allocate MT last values mask\n");
UninitializeTouch(pInfo);
return;
}
/* Axes 0-4 are for X, Y, and scrolling. num_mt_axes does not include X
* and Y. */
valuator_mask_set(proto_data->last_mt_vals[i], 0, 0);
valuator_mask_set(proto_data->last_mt_vals[i], 1, 0);
for (j = 0; j < priv->num_mt_axes; j++)
valuator_mask_set(proto_data->last_mt_vals[i], 4 + j, 0);
}
}
static Bool
EventDeviceOnHook(InputInfoPtr pInfo, SynapticsParameters * para)
{
SynapticsPrivate *priv = (SynapticsPrivate *) pInfo->private;
struct eventcomm_proto_data *proto_data =
(struct eventcomm_proto_data *) priv->proto_data;
int ret;
if (libevdev_get_fd(proto_data->evdev) != -1) {
struct input_event ev;
libevdev_change_fd(proto_data->evdev, pInfo->fd);
/* re-sync libevdev's state, but we don't care about the actual
events here */
libevdev_next_event(proto_data->evdev, LIBEVDEV_READ_FLAG_FORCE_SYNC, &ev);
while (libevdev_next_event(proto_data->evdev,
LIBEVDEV_READ_FLAG_SYNC, &ev) == LIBEVDEV_READ_STATUS_SYNC)
;
} else
libevdev_set_fd(proto_data->evdev, pInfo->fd);
if (para->grab_event_device) {
/* Try to grab the event device so that data don't leak to /dev/input/mice */
ret = libevdev_grab(proto_data->evdev, LIBEVDEV_GRAB);
if (ret < 0) {
xf86IDrvMsg(pInfo, X_WARNING, "can't grab event device, errno=%d\n",
-ret);
return FALSE;
}
}
proto_data->need_grab = FALSE;
ret = libevdev_set_clock_id(proto_data->evdev, CLOCK_MONOTONIC);
proto_data->have_monotonic_clock = (ret == 0);
InitializeTouch(pInfo);
return TRUE;
}
static Bool
EventDeviceOffHook(InputInfoPtr pInfo)
{
SynapticsPrivate *priv = (SynapticsPrivate *) pInfo->private;
struct eventcomm_proto_data *proto_data = priv->proto_data;
UninitializeTouch(pInfo);
libevdev_grab(proto_data->evdev, LIBEVDEV_UNGRAB);
libevdev_set_log_function(NULL, NULL);
libevdev_set_log_priority(LIBEVDEV_LOG_INFO); /* reset to default */
return Success;
}
/**
* Test if the device on the file descriptor is recognized as touchpad
* device. Required bits for touchpad recognition are:
* - ABS_X + ABS_Y for absolute axes
* - ABS_PRESSURE or BTN_TOUCH
* - BTN_TOOL_FINGER
* - BTN_TOOL_PEN is _not_ set
*
* @param evdev Libevdev handle
*
* @return TRUE if the device is a touchpad or FALSE otherwise.
*/
static Bool
event_query_is_touchpad(struct libevdev *evdev)
{
/* Check for ABS_X, ABS_Y, ABS_PRESSURE and BTN_TOOL_FINGER */
if (!libevdev_has_event_type(evdev, EV_SYN) ||
!libevdev_has_event_type(evdev, EV_ABS) ||
!libevdev_has_event_type(evdev, EV_KEY))
return FALSE;
if (!libevdev_has_event_code(evdev, EV_ABS, ABS_X) ||
!libevdev_has_event_code(evdev, EV_ABS, ABS_Y))
return FALSE;
/* we expect touchpad either report raw pressure or touches */
if (!libevdev_has_event_code(evdev, EV_KEY, BTN_TOUCH) &&
!libevdev_has_event_code(evdev, EV_ABS, ABS_PRESSURE))
return FALSE;
/* all Synaptics-like touchpad report BTN_TOOL_FINGER */
if (!libevdev_has_event_code(evdev, EV_KEY, BTN_TOOL_FINGER) ||
libevdev_has_event_code(evdev, EV_ABS, BTN_TOOL_PEN)) /* Don't match wacom tablets */
return FALSE;
if (libevdev_has_event_code(evdev, EV_ABS, ABS_MT_SLOT)) {
if (libevdev_get_num_slots(evdev) == -1)
return FALSE; /* Ignore fake MT devices */
if (!libevdev_has_event_code(evdev, EV_ABS, ABS_MT_POSITION_X) ||
!libevdev_has_event_code(evdev, EV_ABS, ABS_MT_POSITION_Y))
return FALSE;
}
return TRUE;
}
#define PRODUCT_ANY 0x0000
struct model_lookup_t {
short vendor;
short product_start;
short product_end;
enum TouchpadModel model;
};
static struct model_lookup_t model_lookup_table[] = {
{0x0002, 0x0007, 0x0007, MODEL_SYNAPTICS},
{0x0002, 0x0008, 0x0008, MODEL_ALPS},
{0x05ac, PRODUCT_ANY, 0x222, MODEL_APPLETOUCH},
{0x05ac, 0x223, 0x228, MODEL_UNIBODY_MACBOOK},
{0x05ac, 0x229, 0x22b, MODEL_APPLETOUCH},
{0x05ac, 0x22c, PRODUCT_ANY, MODEL_UNIBODY_MACBOOK},
{0x0002, 0x000e, 0x000e, MODEL_ELANTECH},
{0x0, 0x0, 0x0, 0x0}
};
/**
* Check for the vendor/product id on the file descriptor and compare
* with the built-in model LUT. This information is used in synaptics.c to
* initialize model-specific dimensions.
*
* @param fd The file descriptor to a event device.
* @param[out] model_out The type of touchpad model detected.
*
* @return TRUE on success or FALSE otherwise.
*/
static Bool
event_query_model(struct libevdev *evdev, enum TouchpadModel *model_out,
unsigned short *vendor_id, unsigned short *product_id)
{
int vendor, product;
struct model_lookup_t *model_lookup;
vendor = libevdev_get_id_vendor(evdev);
product = libevdev_get_id_product(evdev);
for (model_lookup = model_lookup_table; model_lookup->vendor;
model_lookup++) {
if (model_lookup->vendor == vendor &&
(model_lookup->product_start == PRODUCT_ANY ||
model_lookup->product_start <= product) &&
(model_lookup->product_end == PRODUCT_ANY ||
model_lookup->product_end >= product))
*model_out = model_lookup->model;
}
*vendor_id = vendor;
*product_id = product;
return TRUE;
}
/**
* Get absinfo information from the given file descriptor for the given
* ABS_FOO code and store the information in min, max, fuzz and res.
*
* @param fd File descriptor to an event device
* @param code Event code (e.g. ABS_X)
* @param[out] min Minimum axis range
* @param[out] max Maximum axis range
* @param[out] fuzz Fuzz of this axis. If NULL, fuzz is ignored.
* @param[out] res Axis resolution. If NULL or the current kernel does not
* support the resolution field, res is ignored
*
* @return Zero on success, or errno otherwise.
*/
static int
event_get_abs(struct libevdev *evdev, int code,
int *min, int *max, int *fuzz, int *res)
{
const struct input_absinfo *abs;
abs = libevdev_get_abs_info(evdev, code);
*min = abs->minimum;
*max = abs->maximum;
/* We don't trust a zero fuzz as it probably is just a lazy value */
if (fuzz && abs->fuzz > 0)
*fuzz = abs->fuzz;
#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,30)
if (res)
*res = abs->resolution;
#endif
return 0;
}
/* Query device for axis ranges */
static void
event_query_axis_ranges(InputInfoPtr pInfo)
{
SynapticsPrivate *priv = (SynapticsPrivate *) pInfo->private;
struct eventcomm_proto_data *proto_data = priv->proto_data;
char buf[256] = { 0 };
/* The kernel's fuzziness concept seems a bit weird, but it can more or
* less be applied as hysteresis directly, i.e. no factor here. */
event_get_abs(proto_data->evdev, ABS_X, &priv->minx, &priv->maxx,
&priv->synpara.hyst_x, &priv->resx);
event_get_abs(proto_data->evdev, ABS_Y, &priv->miny, &priv->maxy,
&priv->synpara.hyst_y, &priv->resy);
if (priv->minx == priv->maxx || priv->miny == priv->maxy) {
xf86IDrvMsg(pInfo, X_ERROR, "Kernel bug: min == max on ABS_X/Y\n");
return;
}
priv->has_pressure = libevdev_has_event_code(proto_data->evdev, EV_ABS, ABS_PRESSURE);
priv->has_width = libevdev_has_event_code(proto_data->evdev, EV_ABS, ABS_TOOL_WIDTH);
if (priv->has_pressure)
event_get_abs(proto_data->evdev, ABS_PRESSURE, &priv->minp, &priv->maxp,
NULL, NULL);
if (priv->has_width)
event_get_abs(proto_data->evdev, ABS_TOOL_WIDTH,
&priv->minw, &priv->maxw, NULL, NULL);
if (priv->has_touch) {
int st_minx = priv->minx;
int st_maxx = priv->maxx;
int st_miny = priv->miny;
int st_maxy = priv->maxy;
event_get_abs(proto_data->evdev, ABS_MT_POSITION_X, &priv->minx,
&priv->maxx, &priv->synpara.hyst_x, &priv->resx);
event_get_abs(proto_data->evdev, ABS_MT_POSITION_Y, &priv->miny,
&priv->maxy, &priv->synpara.hyst_y, &priv->resy);
if (priv->minx == priv->maxx || priv->miny == priv->maxy) {
xf86IDrvMsg(pInfo, X_ERROR, "Kernel bug: min == max on ABS_MT_POSITION_X/Y\n");
return;
}
proto_data->st_to_mt_offset[0] = priv->minx - st_minx;
proto_data->st_to_mt_scale[0] =
(priv->maxx - priv->minx) / (st_maxx - st_minx);
proto_data->st_to_mt_offset[1] = priv->miny - st_miny;
proto_data->st_to_mt_scale[1] =
(priv->maxy - priv->miny) / (st_maxy - st_miny);
}
priv->has_left = libevdev_has_event_code(proto_data->evdev, EV_KEY, BTN_LEFT);
priv->has_right = libevdev_has_event_code(proto_data->evdev, EV_KEY, BTN_RIGHT);
priv->has_middle = libevdev_has_event_code(proto_data->evdev, EV_KEY, BTN_MIDDLE);
priv->has_double = libevdev_has_event_code(proto_data->evdev, EV_KEY, BTN_TOOL_DOUBLETAP);
priv->has_triple = libevdev_has_event_code(proto_data->evdev, EV_KEY, BTN_TOOL_TRIPLETAP);
if (libevdev_has_event_code(proto_data->evdev, EV_KEY, BTN_0) ||
libevdev_has_event_code(proto_data->evdev, EV_KEY, BTN_1) ||
libevdev_has_event_code(proto_data->evdev, EV_KEY, BTN_2) ||
libevdev_has_event_code(proto_data->evdev, EV_KEY, BTN_3))
priv->has_scrollbuttons = 1;
/* Now print the device information */
xf86IDrvMsg(pInfo, X_PROBED, "x-axis range %d - %d (res %d)\n",
priv->minx, priv->maxx, priv->resx);
xf86IDrvMsg(pInfo, X_PROBED, "y-axis range %d - %d (res %d)\n",
priv->miny, priv->maxy, priv->resy);
if (priv->has_pressure)
xf86IDrvMsg(pInfo, X_PROBED, "pressure range %d - %d\n",
priv->minp, priv->maxp);
else
xf86IDrvMsg(pInfo, X_INFO,
"device does not report pressure, will use touch data.\n");
if (priv->has_width)
xf86IDrvMsg(pInfo, X_PROBED, "finger width range %d - %d\n",
priv->minw, priv->maxw);
else
xf86IDrvMsg(pInfo, X_INFO, "device does not report finger width.\n");
if (priv->has_left)
strcat(buf, " left");
if (priv->has_right)
strcat(buf, " right");
if (priv->has_middle)
strcat(buf, " middle");
if (priv->has_double)
strcat(buf, " double");
if (priv->has_triple)
strcat(buf, " triple");
if (priv->has_scrollbuttons)
strcat(buf, " scroll-buttons");
xf86IDrvMsg(pInfo, X_PROBED, "buttons:%s\n", buf);
}
static Bool
EventQueryHardware(InputInfoPtr pInfo)
{
SynapticsPrivate *priv = (SynapticsPrivate *) pInfo->private;
struct eventcomm_proto_data *proto_data = priv->proto_data;
if (!event_query_is_touchpad(proto_data->evdev))
return FALSE;
xf86IDrvMsg(pInfo, X_PROBED, "touchpad found\n");
return TRUE;
}
static Bool
SynapticsReadEvent(InputInfoPtr pInfo, struct input_event *ev)
{
SynapticsPrivate *priv = (SynapticsPrivate *) pInfo->private;
struct eventcomm_proto_data *proto_data = priv->proto_data;
int rc;
static struct timeval last_event_time;
rc = libevdev_next_event(proto_data->evdev, proto_data->read_flag, ev);
if (rc < 0) {
if (rc != -EAGAIN) {
LogMessageVerbSigSafe(X_ERROR, 0, "%s: Read error %d\n", pInfo->name,
errno);
xf86RemoveEnabledDevice(pInfo);
} else if (proto_data->read_flag == LIBEVDEV_READ_FLAG_SYNC) {
proto_data->read_flag = LIBEVDEV_READ_FLAG_NORMAL;
return SynapticsReadEvent(pInfo, ev);
}
return FALSE;
}
/* SYN_DROPPED received in normal mode. Create a normal EV_SYN
so we process what's in the queue atm, then ensure we sync
next time */
if (rc == LIBEVDEV_READ_STATUS_SYNC &&
proto_data->read_flag == LIBEVDEV_READ_FLAG_NORMAL) {
proto_data->read_flag = LIBEVDEV_READ_FLAG_SYNC;
ev->type = EV_SYN;
ev->code = SYN_REPORT;
ev->value = 0;
ev->input_event_sec = last_event_time.tv_sec;
ev->input_event_usec = last_event_time.tv_usec;
} else if (ev->type == EV_SYN) {
last_event_time.tv_sec = ev->input_event_sec;
last_event_time.tv_usec = ev->input_event_usec;
}
return TRUE;
}
static Bool
EventTouchSlotPreviouslyOpen(SynapticsPrivate * priv, int slot)
{
int i;
for (i = 0; i < priv->num_active_touches; i++)
if (priv->open_slots[i] == slot)
return TRUE;
return FALSE;
}
static void
EventProcessTouchEvent(InputInfoPtr pInfo, struct SynapticsHwState *hw,
struct input_event *ev)
{
SynapticsPrivate *priv = (SynapticsPrivate *) pInfo->private;
struct eventcomm_proto_data *proto_data = priv->proto_data;
if (!priv->has_touch)
return;
if (ev->code == ABS_MT_SLOT) {
proto_data->cur_slot = ev->value;
}
else {
int slot_index = proto_data->cur_slot;
if (slot_index < 0)
return;
if (hw->slot_state[slot_index] == SLOTSTATE_OPEN_EMPTY)
hw->slot_state[slot_index] = SLOTSTATE_UPDATE;
if (ev->code == ABS_MT_TRACKING_ID) {
if (ev->value >= 0) {
hw->slot_state[slot_index] = SLOTSTATE_OPEN;
proto_data->num_touches++;
valuator_mask_copy(hw->mt_mask[slot_index],
proto_data->last_mt_vals[slot_index]);
}
else if (hw->slot_state[slot_index] != SLOTSTATE_EMPTY) {
hw->slot_state[slot_index] = SLOTSTATE_CLOSE;
proto_data->num_touches--;
}
/* When there are no fingers on the touchpad, set width and
* pressure to zero as ABS_MT_TOUCH_MAJOR and ABS_MT_PRESSURE
* are not zero when fingers are released. */
if (proto_data->num_touches == 0) {
hw->fingerWidth = 0;
hw->z = 0;
}
}
else {
ValuatorMask *mask = proto_data->last_mt_vals[slot_index];
int map = proto_data->axis_map[ev->code - ABS_MT_TOUCH_MAJOR];
int last_val = valuator_mask_get(mask, map);
valuator_mask_set(hw->mt_mask[slot_index], map, ev->value);
if (EventTouchSlotPreviouslyOpen(priv, slot_index)) {
if (ev->code == ABS_MT_POSITION_X)
hw->cumulative_dx += ev->value - last_val;
else if (ev->code == ABS_MT_POSITION_Y)
hw->cumulative_dy += ev->value - last_val;
else if (ev->code == ABS_MT_TOUCH_MAJOR &&
priv->has_mt_palm_detect)
hw->fingerWidth = ev->value;
else if (ev->code == ABS_MT_PRESSURE &&
priv->has_mt_palm_detect)
hw->z = ev->value;
}
valuator_mask_set(mask, map, ev->value);
}
}
}
/**
* Count the number of fingers based on the CommData information.
* The CommData struct contains the event information based on previous
* struct input_events, now we're just counting based on that.
*
* @param comm Assembled information from previous events.
* @return The number of fingers currently set.
*/
static int
count_fingers(InputInfoPtr pInfo, const struct CommData *comm)
{
SynapticsPrivate *priv = (SynapticsPrivate *) pInfo->private;
struct eventcomm_proto_data *proto_data = priv->proto_data;
int fingers = 0;
if (comm->oneFinger)
fingers = 1;
else if (comm->twoFingers)
fingers = 2;
else if (comm->threeFingers)
fingers = 3;
if (priv->has_touch && proto_data->num_touches > fingers)
fingers = proto_data->num_touches;
return fingers;
}
static inline double
apply_st_scaling(struct eventcomm_proto_data *proto_data, int value, int axis)
{
return value * proto_data->st_to_mt_scale[axis] +
proto_data->st_to_mt_offset[axis];
}
Bool
EventReadHwState(InputInfoPtr pInfo,
struct CommData *comm, struct SynapticsHwState *hwRet)
{
struct input_event ev;
Bool v;
struct SynapticsHwState *hw = comm->hwState;
SynapticsPrivate *priv = (SynapticsPrivate *) pInfo->private;
SynapticsParameters *para = &priv->synpara;
struct eventcomm_proto_data *proto_data = priv->proto_data;
Bool sync_cumulative = FALSE;
SynapticsResetTouchHwState(hw, FALSE);
/* Reset cumulative values if buttons were not previously pressed and no
* two-finger scrolling is ongoing, or no finger was previously present. */
if (((!hw->left && !hw->right && !hw->middle) &&
!(priv->vert_scroll_twofinger_on || priv->horiz_scroll_twofinger_on)) ||
hw->z < para->finger_low) {
hw->cumulative_dx = hw->x;
hw->cumulative_dy = hw->y;
sync_cumulative = TRUE;
}
while (SynapticsReadEvent(pInfo, &ev)) {
switch (ev.type) {
case EV_SYN:
switch (ev.code) {
case SYN_REPORT:
hw->numFingers = count_fingers(pInfo, comm);
if (proto_data->have_monotonic_clock)
hw->millis = 1000 * ev.input_event_sec + ev.input_event_usec / 1000;
else
hw->millis = GetTimeInMillis();
SynapticsCopyHwState(hwRet, hw);
return TRUE;
}
break;
case EV_KEY:
/* ignore hw repeat events */
if (ev.value > 1)
break;
v = (ev.value ? TRUE : FALSE);
switch (ev.code) {
case BTN_LEFT:
hw->left = v;
break;
case BTN_RIGHT:
hw->right = v;
break;
case BTN_MIDDLE:
hw->middle = v;
break;
case BTN_FORWARD:
hw->up = v;
break;
case BTN_BACK:
hw->down = v;
break;
case BTN_0:
hw->multi[0] = v;
break;
case BTN_1:
hw->multi[1] = v;
break;
case BTN_2:
hw->multi[2] = v;
break;
case BTN_3:
hw->multi[3] = v;
break;
case BTN_4:
hw->multi[4] = v;
break;
case BTN_5:
hw->multi[5] = v;
break;
case BTN_6:
hw->multi[6] = v;
break;
case BTN_7:
hw->multi[7] = v;
break;
case BTN_TOOL_FINGER:
comm->oneFinger = v;
break;
case BTN_TOOL_DOUBLETAP:
comm->twoFingers = v;
break;
case BTN_TOOL_TRIPLETAP:
comm->threeFingers = v;
break;
case BTN_TOUCH:
if (!priv->has_pressure)
hw->z = v ? para->finger_high + 1 : 0;
break;
}
break;
case EV_ABS:
if (ev.code < ABS_MT_SLOT) {
switch (ev.code) {
case ABS_X:
hw->x = apply_st_scaling(proto_data, ev.value, 0);
if (sync_cumulative)
hw->cumulative_dx = hw->x;
break;
case ABS_Y:
hw->y = apply_st_scaling(proto_data, ev.value, 1);
if (sync_cumulative)
hw->cumulative_dy = hw->y;
break;
case ABS_PRESSURE:
hw->z = ev.value;
break;
case ABS_TOOL_WIDTH:
hw->fingerWidth = ev.value;
break;
}
}
else
EventProcessTouchEvent(pInfo, hw, &ev);
break;
}
}
return FALSE;
}
/* filter for the AutoDevProbe scandir on /dev/input */
static int
EventDevOnly(const struct dirent *dir)
{
return strncmp(EVENT_DEV_NAME, dir->d_name, 5) == 0;
}
static void
event_query_touch(InputInfoPtr pInfo)
{
SynapticsPrivate *priv = (SynapticsPrivate *) pInfo->private;
SynapticsParameters *para = &priv->synpara;
struct eventcomm_proto_data *proto_data = priv->proto_data;
struct libevdev *dev = proto_data->evdev;
int axis;
priv->max_touches = 0;
priv->num_mt_axes = 0;
#ifdef EVIOCGPROP
if (libevdev_has_property(dev, INPUT_PROP_SEMI_MT)) {
xf86IDrvMsg(pInfo, X_INFO,
"ignoring touch events for semi-multitouch device\n");
priv->has_semi_mt = TRUE;
}
if (libevdev_has_property(dev, INPUT_PROP_BUTTONPAD)) {
xf86IDrvMsg(pInfo, X_INFO, "found clickpad property\n");
para->clickpad = TRUE;
}
if (libevdev_has_property(dev, INPUT_PROP_TOPBUTTONPAD)) {
xf86IDrvMsg(pInfo, X_INFO, "found top buttonpad property\n");
para->has_secondary_buttons = TRUE;
}
#endif
if (libevdev_has_event_code(dev, EV_ABS, ABS_MT_SLOT)) {
for (axis = ABS_MT_SLOT + 1; axis <= ABS_MT_MAX; axis++) {
if (!libevdev_has_event_code(dev, EV_ABS, axis))
continue;
priv->has_touch = TRUE;
/* X and Y axis info is handled by synaptics already and we don't
expose the tracking ID */
if (axis == ABS_MT_POSITION_X ||
axis == ABS_MT_POSITION_Y ||
axis == ABS_MT_TRACKING_ID)
continue;
priv->num_mt_axes++;
}
}
if (priv->has_touch) {
int axnum;
static const char *labels[ABS_MT_MAX] = {
AXIS_LABEL_PROP_ABS_MT_TOUCH_MAJOR,
AXIS_LABEL_PROP_ABS_MT_TOUCH_MINOR,
AXIS_LABEL_PROP_ABS_MT_WIDTH_MAJOR,
AXIS_LABEL_PROP_ABS_MT_WIDTH_MINOR,
AXIS_LABEL_PROP_ABS_MT_ORIENTATION,
AXIS_LABEL_PROP_ABS_MT_POSITION_X,
AXIS_LABEL_PROP_ABS_MT_POSITION_Y,
AXIS_LABEL_PROP_ABS_MT_TOOL_TYPE,
AXIS_LABEL_PROP_ABS_MT_BLOB_ID,
AXIS_LABEL_PROP_ABS_MT_TRACKING_ID,
AXIS_LABEL_PROP_ABS_MT_PRESSURE,
AXIS_LABEL_PROP_ABS_MT_DISTANCE,
AXIS_LABEL_PROP_ABS_MT_TOOL_X,
AXIS_LABEL_PROP_ABS_MT_TOOL_Y,
};
priv->max_touches = libevdev_get_num_slots(dev);
priv->touch_axes = malloc(priv->num_mt_axes *
sizeof(SynapticsTouchAxisRec));
if (!priv->touch_axes) {
priv->has_touch = FALSE;
return;
}
if (libevdev_has_event_code(dev, EV_ABS, ABS_MT_TOUCH_MAJOR) &&
libevdev_has_event_code(dev, EV_ABS, ABS_MT_PRESSURE))
priv->has_mt_palm_detect = TRUE;
axnum = 0;
for (axis = ABS_MT_SLOT + 1; axis <= ABS_MT_MAX; axis++) {
int axis_idx = axis - ABS_MT_TOUCH_MAJOR;
if (!libevdev_has_event_code(dev, EV_ABS, axis))
continue;
switch (axis) {
/* X and Y axis info is handled by synaptics already, we just
* need to map the evdev codes to the valuator numbers */
case ABS_MT_POSITION_X:
proto_data->axis_map[axis_idx] = 0;
break;
case ABS_MT_POSITION_Y:
proto_data->axis_map[axis_idx] = 1;
break;
/* Skip tracking ID info */
case ABS_MT_TRACKING_ID:
break;
default:
if (axis_idx >= sizeof(labels)/sizeof(labels[0])) {
xf86IDrvMsg(pInfo, X_ERROR,
"Axis %d out of label range. This is a bug\n",
axis);
priv->touch_axes[axnum].label = NULL;
} else
priv->touch_axes[axnum].label = labels[axis_idx];
priv->touch_axes[axnum].min = libevdev_get_abs_minimum(dev, axis);
priv->touch_axes[axnum].max = libevdev_get_abs_maximum(dev, axis);
/* Kernel provides units/mm, X wants units/m */
priv->touch_axes[axnum].res = libevdev_get_abs_resolution(dev, axis) * 1000;
/* Valuators 0-3 are used for X, Y, and scrolling */
proto_data->axis_map[axis_idx] = 4 + axnum;
axnum++;
break;
}
}
}
}
/**
* Probe the open device for dimensions.
*/
static void
EventReadDevDimensions(InputInfoPtr pInfo)
{
SynapticsPrivate *priv = (SynapticsPrivate *) pInfo->private;
struct eventcomm_proto_data *proto_data = priv->proto_data;
int i;
proto_data = EventProtoDataAlloc(pInfo->fd);
priv->proto_data = proto_data;
for (i = 0; i < ABS_MT_CNT; i++)
proto_data->axis_map[i] = -1;
proto_data->cur_slot = -1;
if (event_query_is_touchpad(proto_data->evdev)) {
event_query_touch(pInfo);
event_query_axis_ranges(pInfo);
}
event_query_model(proto_data->evdev, &priv->model, &priv->id_vendor,
&priv->id_product);
xf86IDrvMsg(pInfo, X_PROBED, "Vendor %#hx Product %#hx\n",
priv->id_vendor, priv->id_product);
}
static Bool
EventAutoDevProbe(InputInfoPtr pInfo, const char *device)
{
/* We are trying to find the right eventX device or fall back to
the psaux protocol and the given device from XF86Config */
int i;
Bool touchpad_found = FALSE;
struct dirent **namelist;
if (device) {
int fd = -1;
if (pInfo->flags & XI86_SERVER_FD)
fd = pInfo->fd;
else
SYSCALL(fd = open(device, O_RDONLY));
if (fd >= 0) {
int rc;
struct libevdev *evdev;
rc = libevdev_new_from_fd(fd, &evdev);
if (rc >= 0) {
touchpad_found = event_query_is_touchpad(evdev);
libevdev_free(evdev);
}
if (!(pInfo->flags & XI86_SERVER_FD))
SYSCALL(close(fd));
}
/* if a device is set and not a touchpad (or already grabbed),
* we must return FALSE. Otherwise, we'll add a device that
* wasn't requested for and repeat
* f5687a6741a19ef3081e7fd83ac55f6df8bcd5c2. */
return touchpad_found;
}
i = scandir(DEV_INPUT_EVENT, &namelist, EventDevOnly, alphasort);
if (i < 0) {
xf86IDrvMsg(pInfo, X_ERROR, "Couldn't open %s\n", DEV_INPUT_EVENT);
return FALSE;
}
else if (i == 0) {
xf86IDrvMsg(pInfo, X_ERROR,
"The /dev/input/event* device nodes seem to be missing\n");
free(namelist);
return FALSE;
}
while (i--) {
char fname[64];
int fd = -1;
if (!touchpad_found) {
int rc;
struct libevdev *evdev;
sprintf(fname, "%s/%s", DEV_INPUT_EVENT, namelist[i]->d_name);
SYSCALL(fd = open(fname, O_RDONLY));
if (fd < 0)
continue;
rc = libevdev_new_from_fd(fd, &evdev);
if (rc >= 0) {
touchpad_found = event_query_is_touchpad(evdev);
libevdev_free(evdev);
if (touchpad_found) {
xf86IDrvMsg(pInfo, X_PROBED, "auto-dev sets device to %s\n",
fname);
pInfo->options = xf86ReplaceStrOption(pInfo->options,
"Device",
fname);
}
}
SYSCALL(close(fd));
}
free(namelist[i]);
}
free(namelist);
if (!touchpad_found) {
xf86IDrvMsg(pInfo, X_ERROR, "no synaptics event device found\n");
return FALSE;
}
return TRUE;
}
struct SynapticsProtocolOperations event_proto_operations = {
EventDeviceOnHook,
EventDeviceOffHook,
EventQueryHardware,
EventReadHwState,
EventAutoDevProbe,
EventReadDevDimensions
};
xf86-input-synaptics-1.9.2/src/psmcomm.c 0000644 0143106 0000012 00000012531 14262661535 015021 0000000 0000000 /*
* Copyright © 1997 C. Scott Ananian
* Copyright © 1998-2000 Bruce Kalk
* Copyright © 2001 Stefan Gmeiner
* Copyright © 2002 Linuxcare Inc. David Kennedy
* Copyright © 2003 Fred Hucht
* Copyright © 2004 Arne Schwabe
*
* 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.
*
* Authors:
* Stefan Gmeiner (riddlebox@freesurf.ch)
* C. Scott Ananian (cananian@alumni.priceton.edu)
* Bruce Kalk (kall@compass.com)
* Linuxcare Inc. David Kennedy (dkennedy@linuxcare.com)
* Fred Hucht (fred@thp.Uni-Duisburg.de)
* Arne Schwabe
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include
#include
#include
#include
#include
#include
#include "synproto.h"
#include "synapticsstr.h"
#include "ps2comm.h" /* ps2_print_ident() */
#include
#define SYSCALL(call) while (((call) == -1) && (errno == EINTR))
/*
* Identify Touchpad
* See also the SYN_ID_* macros
*/
static Bool
psm_synaptics_identify(int fd, synapticshw_t * ident)
{
int ret;
SYSCALL(ret = ioctl(fd, MOUSE_SYN_GETHWINFO, ident));
if (ret == 0)
return TRUE;
else
return FALSE;
}
/* This define is used in a ioctl but not in mouse.h :/ */
#define PSM_LEVEL_NATIVE 2
static Bool
PSMQueryIsSynaptics(InputInfoPtr pInfo)
{
int ret;
int level = PSM_LEVEL_NATIVE;
mousehw_t mhw;
/* Put the device in native protocol mode to be sure
* Otherwise HWINFO will not return the right id
* And we will need native mode anyway ...
*/
SYSCALL(ret = ioctl(pInfo->fd, MOUSE_SETLEVEL, &level));
if (ret != 0) {
xf86IDrvMsg(pInfo, X_ERROR, "%s Can't set native mode\n", pInfo->name);
return FALSE;
}
SYSCALL(ret = ioctl(pInfo->fd, MOUSE_GETHWINFO, &mhw));
if (ret != 0) {
xf86IDrvMsg(pInfo, X_ERROR, "%s Can't get hardware info\n",
pInfo->name);
return FALSE;
}
if (mhw.model == MOUSE_MODEL_SYNAPTICS) {
return TRUE;
}
else {
xf86IDrvMsg(pInfo, X_ERROR,
"%s Found no Synaptics, found Mouse model %d instead\n",
pInfo->name, mhw.model);
return FALSE;
}
}
static void
convert_hw_info(const synapticshw_t * psm_ident,
struct PS2SynapticsHwInfo *synhw)
{
memset(synhw, 0, sizeof(*synhw));
synhw->model_id = ((psm_ident->infoRot180 << 23) |
(psm_ident->infoPortrait << 22) |
(psm_ident->infoSensor << 16) |
(psm_ident->infoHardware << 9) |
(psm_ident->infoNewAbs << 7) |
(psm_ident->capPen << 6) |
(psm_ident->infoSimplC << 5) |
(psm_ident->infoGeometry));
synhw->capabilities = ((psm_ident->capExtended << 23) |
(psm_ident->capPassthrough << 7) |
(psm_ident->capSleep << 4) |
(psm_ident->capFourButtons << 3) |
(psm_ident->capMultiFinger << 1) |
(psm_ident->capPalmDetect));
synhw->ext_cap = 0;
synhw->identity = ((psm_ident->infoMajor) |
(0x47 << 8) | (psm_ident->infoMinor << 16));
}
static Bool
PSMQueryHardware(InputInfoPtr pInfo)
{
synapticshw_t psm_ident;
struct PS2SynapticsHwInfo *synhw;
SynapticsPrivate *priv;
priv = (SynapticsPrivate *) pInfo->private;
if (!priv->proto_data)
priv->proto_data = calloc(1, sizeof(struct PS2SynapticsHwInfo));
synhw = (struct PS2SynapticsHwInfo *) priv->proto_data;
/* is the synaptics touchpad active? */
if (!PSMQueryIsSynaptics(pInfo))
return FALSE;
xf86IDrvMsg(pInfo, X_PROBED, "synaptics touchpad found\n");
if (!psm_synaptics_identify(pInfo->fd, &psm_ident))
return FALSE;
convert_hw_info(&psm_ident, synhw);
ps2_print_ident(pInfo, synhw);
return TRUE;
}
static Bool
PSMReadHwState(InputInfoPtr pInfo,
struct CommData *comm, struct SynapticsHwState *hwRet)
{
return PS2ReadHwStateProto(pInfo, &psm_proto_operations, comm, hwRet);
}
struct SynapticsProtocolOperations psm_proto_operations = {
NULL,
NULL,
PSMQueryHardware,
PSMReadHwState,
NULL,
NULL
};
xf86-input-synaptics-1.9.2/src/ps2comm.c 0000644 0143106 0000012 00000047771 14262661535 014744 0000000 0000000 /*
* Copyright © 1997 C. Scott Ananian
* Copyright © 1998-2000 Bruce Kalk
* Copyright © 2001 Stefan Gmeiner
* Copyright © 2002 Linuxcare Inc. David Kennedy
* Copyright © 2003 Fred Hucht
*
* 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.
*
* Authors:
* Stefan Gmeiner (riddlebox@freesurf.ch)
* C. Scott Ananian (cananian@alumni.priceton.edu)
* Bruce Kalk (kall@compass.com)
* Linuxcare Inc. David Kennedy (dkennedy@linuxcare.com)
* Fred Hucht (fred@thp.Uni-Duisburg.de)
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include
#include "synproto.h"
#include "synapticsstr.h"
#include "ps2comm.h"
#include
#define MAX_UNSYNC_PACKETS 10 /* i.e. 10 to 60 bytes */
/*
* The x/y limits are taken from the Synaptics TouchPad interfacing Guide,
* section 2.3.2, which says that they should be valid regardless of the
* actual size of the sensor.
*/
#define XMIN_NOMINAL 1472
#define XMAX_NOMINAL 5472
#define YMIN_NOMINAL 1408
#define YMAX_NOMINAL 4448
#define XMAX_VALID 6143
/* synaptics queries */
#define SYN_QUE_IDENTIFY 0x00
#define SYN_QUE_MODES 0x01
#define SYN_QUE_CAPABILITIES 0x02
#define SYN_QUE_MODEL 0x03
#define SYN_QUE_SERIAL_NUMBER_PREFIX 0x06
#define SYN_QUE_SERIAL_NUMBER_SUFFIX 0x07
#define SYN_QUE_RESOLUTION 0x08
#define SYN_QUE_EXT_CAPAB 0x09
/* status request response bits (PS2_CMD_STATUS_REQUEST) */
#define PS2_RES_REMOTE(r) ((r) & (1 << 22))
#define PS2_RES_ENABLE(r) ((r) & (1 << 21))
#define PS2_RES_SCALING(r) ((r) & (1 << 20))
#define PS2_RES_LEFT(r) ((r) & (1 << 18))
#define PS2_RES_MIDDLE(r) ((r) & (1 << 17))
#define PS2_RES_RIGHT(r) ((r) & (1 << 16))
#define PS2_RES_RESOLUTION(r) (((r) >> 8) & 0x03)
#define PS2_RES_SAMPLE_RATE(r) ((r) & 0xff)
#ifdef DEBUG
#define PS2DBG(...) ErrorF(__VA_ARGS__)
#else
#define PS2DBG(...)
#endif
/*****************************************************************************
* PS/2 Utility functions.
* Many parts adapted from tpconfig.c by C. Scott Ananian
****************************************************************************/
/*
* Read a byte from the ps/2 port
*/
static Bool
ps2_getbyte(int fd, byte * b)
{
if (xf86WaitForInput(fd, 50000) > 0) {
if (xf86ReadSerial(fd, b, 1) != 1) {
PS2DBG("ps2_getbyte: No byte read\n");
return FALSE;
}
PS2DBG("ps2_getbyte: byte %02X read\n", *b);
return TRUE;
}
PS2DBG("ps2_getbyte: timeout xf86WaitForInput\n");
return FALSE;
}
/*
* Write a byte to the ps/2 port, wait for ACK
*/
Bool
ps2_putbyte(int fd, byte b)
{
byte ack;
if (xf86WriteSerial(fd, &b, 1) != 1) {
PS2DBG("ps2_putbyte: error xf86WriteSerial\n");
return FALSE;
}
PS2DBG("ps2_putbyte: byte %02X send\n", b);
/* wait for an ACK */
if (!ps2_getbyte(fd, &ack)) {
return FALSE;
}
if (ack != PS2_ACK) {
PS2DBG("ps2_putbyte: wrong acknowledge 0x%02x\n", ack);
return FALSE;
}
return TRUE;
}
/*
* Use the Synaptics extended ps/2 syntax to write a special command byte. Needed by
* ps2_send_cmd and ps2_set_mode.
* special command: 0xE8 rr 0xE8 ss 0xE8 tt 0xE8 uu where (rr*64)+(ss*16)+(tt*4)+uu
* is the command. A 0xF3 or 0xE9 must follow (see ps2_send_cmd, ps2_set_mode)
*/
static Bool
ps2_special_cmd(int fd, byte cmd)
{
int i;
/* initialize with 'inert' command */
if (!ps2_putbyte(fd, PS2_CMD_SET_SCALING_1_1))
return FALSE;
/* send 4x 2-bits with set resolution command */
for (i = 0; i < 4; i++) {
if (!ps2_putbyte(fd, PS2_CMD_SET_RESOLUTION) ||
!ps2_putbyte(fd, (cmd >> 6) & 0x3))
return FALSE;
cmd <<= 2;
}
return TRUE;
}
/*
* Send a command to the synpatics touchpad by special commands
*/
static Bool
ps2_send_cmd(int fd, byte c)
{
PS2DBG("send command: 0x%02X\n", c);
return (ps2_special_cmd(fd, c) && ps2_putbyte(fd, PS2_CMD_STATUS_REQUEST));
}
/*****************************************************************************
* Synaptics communications functions
****************************************************************************/
/*
* Set the synaptics touchpad mode byte by special commands
*/
static Bool
ps2_synaptics_set_mode(int fd, byte mode)
{
PS2DBG("set mode byte to: 0x%02X\n", mode);
return (ps2_special_cmd(fd, mode) &&
ps2_putbyte(fd, PS2_CMD_SET_SAMPLE_RATE) && ps2_putbyte(fd, 0x14));
}
/*
* reset the touchpad
*/
static Bool
ps2_synaptics_reset(int fd)
{
byte r[2];
xf86FlushInput(fd);
PS2DBG("Reset the Touchpad...\n");
if (!ps2_putbyte(fd, PS2_CMD_RESET)) {
PS2DBG("...failed\n");
return FALSE;
}
xf86WaitForInput(fd, 4000000);
if (ps2_getbyte(fd, &r[0]) && ps2_getbyte(fd, &r[1])) {
if (r[0] == 0xAA && r[1] == 0x00) {
PS2DBG("...done\n");
return TRUE;
}
else {
PS2DBG("...failed. Wrong reset ack 0x%02x, 0x%02x\n", r[0], r[1]);
return FALSE;
}
}
PS2DBG("...failed\n");
return FALSE;
}
/*
* Read the model-id bytes from the touchpad
* see also SYN_MODEL_* macros
*/
static Bool
ps2_synaptics_model_id(int fd, struct PS2SynapticsHwInfo *synhw)
{
byte mi[3];
PS2DBG("Read mode id...\n");
synhw->model_id = 0;
if (ps2_send_cmd(fd, SYN_QUE_MODEL) &&
ps2_getbyte(fd, &mi[0]) &&
ps2_getbyte(fd, &mi[1]) && ps2_getbyte(fd, &mi[2])) {
synhw->model_id = (mi[0] << 16) | (mi[1] << 8) | mi[2];
PS2DBG("model-id %06X\n", synhw->model_id);
PS2DBG("...done.\n");
return TRUE;
}
PS2DBG("...failed.\n");
return FALSE;
}
/*
* Read the capability-bits from the touchpad
* see also the SYN_CAP_* macros
*/
static Bool
ps2_synaptics_capability(int fd, struct PS2SynapticsHwInfo *synhw)
{
byte cap[3];
PS2DBG("Read capabilites...\n");
synhw->capabilities = 0;
synhw->ext_cap = 0;
if (ps2_send_cmd(fd, SYN_QUE_CAPABILITIES) &&
ps2_getbyte(fd, &cap[0]) &&
ps2_getbyte(fd, &cap[1]) && ps2_getbyte(fd, &cap[2])) {
synhw->capabilities = (cap[0] << 16) | (cap[1] << 8) | cap[2];
PS2DBG("capabilities %06X\n", synhw->capabilities);
if (SYN_CAP_VALID(synhw)) {
if (SYN_EXT_CAP_REQUESTS(synhw)) {
if (ps2_send_cmd(fd, SYN_QUE_EXT_CAPAB) &&
ps2_getbyte(fd, &cap[0]) &&
ps2_getbyte(fd, &cap[1]) && ps2_getbyte(fd, &cap[2])) {
synhw->ext_cap = (cap[0] << 16) | (cap[1] << 8) | cap[2];
PS2DBG("ext-capability %06X\n", synhw->ext_cap);
}
else {
PS2DBG("synaptics says, that it has extended-capabilities, "
"but I cannot read them.");
}
}
PS2DBG("...done.\n");
return TRUE;
}
}
PS2DBG("...failed.\n");
return FALSE;
}
/*
* Identify Touchpad
* See also the SYN_ID_* macros
*/
static Bool
ps2_synaptics_identify(int fd, struct PS2SynapticsHwInfo *synhw)
{
byte id[3];
PS2DBG("Identify Touchpad...\n");
synhw->identity = 0;
if (ps2_send_cmd(fd, SYN_QUE_IDENTIFY) &&
ps2_getbyte(fd, &id[0]) &&
ps2_getbyte(fd, &id[1]) && ps2_getbyte(fd, &id[2])) {
synhw->identity = (id[0] << 16) | (id[1] << 8) | id[2];
PS2DBG("ident %06X\n", synhw->identity);
if (SYN_ID_IS_SYNAPTICS(synhw)) {
PS2DBG("...done.\n");
return TRUE;
}
}
PS2DBG("...failed.\n");
return FALSE;
}
static Bool
ps2_synaptics_enable_device(int fd)
{
return ps2_putbyte(fd, PS2_CMD_ENABLE);
}
static Bool
ps2_synaptics_disable_device(int fd)
{
xf86FlushInput(fd);
return ps2_putbyte(fd, PS2_CMD_DISABLE);
}
static Bool
ps2_query_is_synaptics(InputInfoPtr pInfo, int fd,
struct PS2SynapticsHwInfo *synhw)
{
int i;
for (i = 0; i < 3; i++) {
if (ps2_synaptics_disable_device(fd))
break;
}
xf86WaitForInput(fd, 20000);
xf86FlushInput(fd);
if (ps2_synaptics_identify(fd, synhw)) {
return TRUE;
}
else {
xf86IDrvMsg(pInfo, X_ERROR, "Query no Synaptics: %06X\n",
synhw->identity);
return FALSE;
}
}
void
ps2_print_ident(InputInfoPtr pInfo, const struct PS2SynapticsHwInfo *synhw)
{
xf86IDrvMsg(pInfo, X_PROBED, " Synaptics Touchpad, model: %d\n",
SYN_ID_MODEL(synhw));
xf86IDrvMsg(pInfo, X_PROBED, " Firmware: %d.%d\n", SYN_ID_MAJOR(synhw),
SYN_ID_MINOR(synhw));
if (SYN_MODEL_ROT180(synhw))
xf86IDrvMsg(pInfo, X_PROBED, " 180 degree mounted touchpad\n");
if (SYN_MODEL_PORTRAIT(synhw))
xf86IDrvMsg(pInfo, X_PROBED, " portrait touchpad\n");
xf86IDrvMsg(pInfo, X_PROBED, " Sensor: %d\n", SYN_MODEL_SENSOR(synhw));
if (SYN_MODEL_NEWABS(synhw))
xf86IDrvMsg(pInfo, X_PROBED, " new absolute packet format\n");
if (SYN_MODEL_PEN(synhw))
xf86IDrvMsg(pInfo, X_PROBED, " pen detection\n");
if (SYN_CAP_EXTENDED(synhw)) {
xf86IDrvMsg(pInfo, X_PROBED,
" Touchpad has extended capability bits\n");
if (SYN_CAP_MULTI_BUTTON_NO(synhw))
xf86IDrvMsg(pInfo, X_PROBED,
" -> %d multi buttons, i.e. besides standard buttons\n",
(int) (SYN_CAP_MULTI_BUTTON_NO(synhw)));
if (SYN_CAP_MIDDLE_BUTTON(synhw))
xf86IDrvMsg(pInfo, X_PROBED, " -> middle button\n");
if (SYN_CAP_FOUR_BUTTON(synhw))
xf86IDrvMsg(pInfo, X_PROBED, " -> four buttons\n");
if (SYN_CAP_MULTIFINGER(synhw))
xf86IDrvMsg(pInfo, X_PROBED, " -> multifinger detection\n");
if (SYN_CAP_PALMDETECT(synhw))
xf86IDrvMsg(pInfo, X_PROBED, " -> palm detection\n");
if (SYN_CAP_PASSTHROUGH(synhw))
xf86IDrvMsg(pInfo, X_PROBED, " -> pass-through port\n");
}
}
static Bool
PS2DeviceOffHook(InputInfoPtr pInfo)
{
ps2_synaptics_reset(pInfo->fd);
ps2_synaptics_enable_device(pInfo->fd);
return TRUE;
}
static Bool
PS2QueryHardware(InputInfoPtr pInfo)
{
int mode;
SynapticsPrivate *priv = (SynapticsPrivate *) pInfo->private;
struct PS2SynapticsHwInfo *synhw;
if (!priv->proto_data)
priv->proto_data = calloc(1, sizeof(struct PS2SynapticsHwInfo));
synhw = (struct PS2SynapticsHwInfo *) priv->proto_data;
/* is the synaptics touchpad active? */
if (!ps2_query_is_synaptics(pInfo, pInfo->fd, synhw))
return FALSE;
xf86IDrvMsg(pInfo, X_PROBED, "synaptics touchpad found\n");
if (!ps2_synaptics_reset(pInfo->fd))
xf86IDrvMsg(pInfo, X_ERROR, "reset failed\n");
if (!ps2_synaptics_identify(pInfo->fd, synhw))
return FALSE;
if (!ps2_synaptics_model_id(pInfo->fd, synhw))
return FALSE;
if (!ps2_synaptics_capability(pInfo->fd, synhw))
return FALSE;
mode = SYN_BIT_ABSOLUTE_MODE | SYN_BIT_HIGH_RATE;
if (SYN_ID_MAJOR(synhw) >= 4)
mode |= SYN_BIT_DISABLE_GESTURE;
if (SYN_CAP_EXTENDED(synhw))
mode |= SYN_BIT_W_MODE;
if (!ps2_synaptics_set_mode(pInfo->fd, mode))
return FALSE;
ps2_synaptics_enable_device(pInfo->fd);
ps2_print_ident(pInfo, synhw);
return TRUE;
}
/*
* Decide if the current packet stored in priv->protoBuf is valid.
*/
static Bool
ps2_packet_ok(struct PS2SynapticsHwInfo *synhw, struct CommData *comm)
{
unsigned char *buf = comm->protoBuf;
int newabs = SYN_MODEL_NEWABS(synhw);
if (newabs ? ((buf[0] & 0xC0) != 0x80) : ((buf[0] & 0xC0) != 0xC0)) {
PS2DBG("Synaptics driver lost sync at 1st byte\n");
return FALSE;
}
if (!newabs && ((buf[1] & 0x60) != 0x00)) {
PS2DBG("Synaptics driver lost sync at 2nd byte\n");
return FALSE;
}
if ((newabs ? ((buf[3] & 0xC0) != 0xC0) : ((buf[3] & 0xC0) != 0x80))) {
PS2DBG("Synaptics driver lost sync at 4th byte\n");
return FALSE;
}
if (!newabs && ((buf[4] & 0x60) != 0x00)) {
PS2DBG("Synaptics driver lost sync at 5th byte\n");
return FALSE;
}
return TRUE;
}
static Bool
ps2_synaptics_get_packet(InputInfoPtr pInfo, struct PS2SynapticsHwInfo *synhw,
struct SynapticsProtocolOperations *proto_ops,
struct CommData *comm)
{
int count = 0;
int c;
unsigned char u;
while ((c = XisbRead(comm->buffer)) >= 0) {
u = (unsigned char) c;
/* test if there is a reset sequence received */
if ((c == 0x00) && (comm->lastByte == 0xAA)) {
if (xf86WaitForInput(pInfo->fd, 50000) == 0) {
PS2DBG("Reset received\n");
proto_ops->QueryHardware(pInfo);
}
else
PS2DBG("faked reset received\n");
}
comm->lastByte = u;
/* to avoid endless loops */
if (count++ > 30) {
LogMessageVerbSigSafe(X_ERROR, 0,
"Synaptics driver lost sync... got gigantic packet!\n");
return FALSE;
}
comm->protoBuf[comm->protoBufTail++] = u;
/* Check that we have a valid packet. If not, we are out of sync,
so we throw away the first byte in the packet. */
if (comm->protoBufTail >= 6) {
if (!ps2_packet_ok(synhw, comm)) {
int i;
for (i = 0; i < comm->protoBufTail - 1; i++)
comm->protoBuf[i] = comm->protoBuf[i + 1];
comm->protoBufTail--;
comm->outOfSync++;
if (comm->outOfSync > MAX_UNSYNC_PACKETS) {
comm->outOfSync = 0;
PS2DBG("Synaptics synchronization lost too long -> reset touchpad.\n");
proto_ops->QueryHardware(pInfo); /* including a reset */
continue;
}
}
}
if (comm->protoBufTail >= 6) { /* Full packet received */
if (comm->outOfSync > 0) {
comm->outOfSync = 0;
PS2DBG("Synaptics driver resynced.\n");
}
comm->protoBufTail = 0;
return TRUE;
}
}
return FALSE;
}
Bool
PS2ReadHwStateProto(InputInfoPtr pInfo,
struct SynapticsProtocolOperations *proto_ops,
struct CommData *comm, struct SynapticsHwState *hwRet)
{
unsigned char *buf = comm->protoBuf;
struct SynapticsHwState *hw = comm->hwState;
SynapticsPrivate *priv = (SynapticsPrivate *) pInfo->private;
SynapticsParameters *para = &priv->synpara;
struct PS2SynapticsHwInfo *synhw;
int newabs;
int w, i;
synhw = (struct PS2SynapticsHwInfo *) priv->proto_data;
if (!synhw) {
LogMessageVerbSigSafe(X_ERROR, 0,
"PS2ReadHwState, synhw is NULL. This is a bug.\n");
return FALSE;
}
newabs = SYN_MODEL_NEWABS(synhw);
if (!ps2_synaptics_get_packet(pInfo, synhw, proto_ops, comm))
return FALSE;
/* Handle normal packets */
hw->x = hw->y = hw->z = hw->numFingers = hw->fingerWidth = 0;
hw->left = hw->right = hw->up = hw->down = hw->middle = FALSE;
for (i = 0; i < 8; i++)
hw->multi[i] = FALSE;
if (newabs) { /* newer protos... */
PS2DBG("using new protocols\n");
hw->x = (((buf[3] & 0x10) << 8) | ((buf[1] & 0x0f) << 8) | buf[4]);
hw->y = (((buf[3] & 0x20) << 7) | ((buf[1] & 0xf0) << 4) | buf[5]);
hw->z = buf[2];
w = (((buf[0] & 0x30) >> 2) |
((buf[0] & 0x04) >> 1) | ((buf[3] & 0x04) >> 2));
hw->left = (buf[0] & 0x01) ? 1 : 0;
hw->right = (buf[0] & 0x02) ? 1 : 0;
if (SYN_CAP_EXTENDED(synhw)) {
if (SYN_CAP_MIDDLE_BUTTON(synhw)) {
hw->middle = ((buf[0] ^ buf[3]) & 0x01) ? 1 : 0;
}
if (SYN_CAP_FOUR_BUTTON(synhw)) {
hw->up = ((buf[3] & 0x01)) ? 1 : 0;
if (hw->left)
hw->up = !hw->up;
hw->down = ((buf[3] & 0x02)) ? 1 : 0;
if (hw->right)
hw->down = !hw->down;
}
if (SYN_CAP_MULTI_BUTTON_NO(synhw)) {
if ((buf[3] & 2) ? !hw->right : hw->right) {
switch (SYN_CAP_MULTI_BUTTON_NO(synhw) & ~0x01) {
default:
break;
case 8:
hw->multi[7] = ((buf[5] & 0x08)) ? 1 : 0;
hw->multi[6] = ((buf[4] & 0x08)) ? 1 : 0;
/* fallthrough */
case 6:
hw->multi[5] = ((buf[5] & 0x04)) ? 1 : 0;
hw->multi[4] = ((buf[4] & 0x04)) ? 1 : 0;
/* fallthrough */
case 4:
hw->multi[3] = ((buf[5] & 0x02)) ? 1 : 0;
hw->multi[2] = ((buf[4] & 0x02)) ? 1 : 0;
/* fallthrough */
case 2:
hw->multi[1] = ((buf[5] & 0x01)) ? 1 : 0;
hw->multi[0] = ((buf[4] & 0x01)) ? 1 : 0;
}
}
}
}
}
else { /* old proto... */
PS2DBG("using old protocol\n");
hw->x = (((buf[1] & 0x1F) << 8) | buf[2]);
hw->y = (((buf[4] & 0x1F) << 8) | buf[5]);
hw->z = (((buf[0] & 0x30) << 2) | (buf[3] & 0x3F));
w = (((buf[1] & 0x80) >> 4) | ((buf[0] & 0x04) >> 1));
hw->left = (buf[0] & 0x01) ? 1 : 0;
hw->right = (buf[0] & 0x02) ? 1 : 0;
}
hw->y = YMAX_NOMINAL + YMIN_NOMINAL - hw->y;
if (hw->z >= para->finger_high) {
int w_ok = 0;
/*
* Use capability bits to decide if the w value is valid.
* If not, set it to 5, which corresponds to a finger of
* normal width.
*/
if (SYN_CAP_EXTENDED(synhw)) {
if ((w >= 0) && (w <= 1)) {
w_ok = SYN_CAP_MULTIFINGER(synhw);
}
else if (w == 2) {
w_ok = SYN_MODEL_PEN(synhw);
}
else if ((w >= 4) && (w <= 15)) {
w_ok = SYN_CAP_PALMDETECT(synhw);
}
}
if (!w_ok)
w = 5;
switch (w) {
case 0:
hw->numFingers = 2;
hw->fingerWidth = 5;
break;
case 1:
hw->numFingers = 3;
hw->fingerWidth = 5;
break;
default:
hw->numFingers = 1;
hw->fingerWidth = w;
break;
}
}
hw->millis = GetTimeInMillis();
SynapticsCopyHwState(hwRet, hw);
return TRUE;
}
static Bool
PS2ReadHwState(InputInfoPtr pInfo,
struct CommData *comm, struct SynapticsHwState *hwRet)
{
return PS2ReadHwStateProto(pInfo, &psaux_proto_operations, comm, hwRet);
}
struct SynapticsProtocolOperations psaux_proto_operations = {
NULL,
PS2DeviceOffHook,
PS2QueryHardware,
PS2ReadHwState,
NULL,
NULL
};
xf86-input-synaptics-1.9.2/src/synapticsstr.h 0000644 0143106 0000012 00000037731 14262661535 016132 0000000 0000000 /*
* 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.
*/
#ifndef _SYNAPTICSSTR_H_
#define _SYNAPTICSSTR_H_
#include "synproto.h"
#if GET_ABI_MAJOR(ABI_XINPUT_VERSION) < 18
#define LogMessageVerbSigSafe xf86MsgVerb
#endif
#if GET_ABI_MAJOR(ABI_XINPUT_VERSION) > 19
#define NO_DRIVER_SCALING 1
#elif GET_ABI_MAJOR(ABI_XINPUT_VERSION) == 19 && GET_ABI_MINOR(ABI_XINPUT_VERSION) >= 2
/* as of 19.2, the server takes device resolution into account when scaling
relative events from abs device, so we must not scale in synaptics. */
#define NO_DRIVER_SCALING 1
#endif
#if GET_ABI_MAJOR(ABI_XINPUT_VERSION) >= 23
#define HAVE_THREADED_INPUT 1
#endif
#ifdef DBG
#undef DBG
#endif
#ifdef DEBUG
#define DBG(verb, ...) \
xf86MsgVerb(X_INFO, verb, __VA_ARGS__)
#else
#define DBG(verb, msg, ...) /* */
#endif
/******************************************************************************
* Definitions
* structs, typedefs, #defines, enums
*****************************************************************************/
#define SYNAPTICS_MOVE_HISTORY 5
#define SYNAPTICS_MAX_TOUCHES 10
#define SYN_MAX_BUTTONS 12 /* Max number of mouse buttons */
/* Minimum and maximum values for scroll_button_repeat */
#define SBR_MIN 10
#define SBR_MAX 1000
enum OffState {
TOUCHPAD_ON = 0,
TOUCHPAD_OFF = 1,
TOUCHPAD_TAP_OFF = 2,
};
enum TapEvent {
RT_TAP = 0, /* Right top corner */
RB_TAP, /* Right bottom corner */
LT_TAP, /* Left top corner */
LB_TAP, /* Left bottom corner */
F1_TAP, /* Non-corner tap, one finger */
F2_TAP, /* Non-corner tap, two fingers */
F3_TAP, /* Non-corner tap, three fingers */
MAX_TAP
};
enum ClickFingerEvent {
F1_CLICK1 = 0, /* Click left, one finger */
F2_CLICK1, /* Click left, two fingers */
F3_CLICK1, /* Click left, three fingers */
MAX_CLICK
};
typedef struct _SynapticsMoveHist {
int x, y;
CARD32 millis;
} SynapticsMoveHistRec;
typedef struct _SynapticsTouchAxis {
const char *label;
int min;
int max;
int res;
} SynapticsTouchAxisRec;
enum FingerState { /* Note! The order matters. Compared with < operator. */
FS_BLOCKED = -1,
FS_UNTOUCHED = 0, /* this is 0 so it's the initialized value. */
FS_TOUCHED = 1,
FS_PRESSED = 2,
};
enum MovingState {
MS_FALSE,
MS_TOUCHPAD_RELATIVE,
};
enum MidButtonEmulation {
MBE_OFF, /* No button pressed */
MBE_LEFT, /* Left button pressed, waiting for right button or timeout */
MBE_RIGHT, /* Right button pressed, waiting for left button or timeout */
MBE_MID, /* Left and right buttons pressed, waiting for both buttons
to be released */
MBE_TIMEOUT, /* Waiting for both buttons to be released. */
MBE_LEFT_CLICK, /* Emulate left button click. */
MBE_RIGHT_CLICK, /* Emulate right button click. */
};
/* See docs/tapndrag.dia for a state machine diagram */
enum TapState {
TS_START, /* No tap/drag in progress */
TS_1, /* After first touch */
TS_MOVE, /* Pointer movement enabled */
TS_2A, /* After first release */
TS_2B, /* After second/third/... release */
TS_SINGLETAP, /* After timeout after first release */
TS_3, /* After second touch */
TS_DRAG, /* Pointer drag enabled */
TS_4, /* After release when "locked drags" enabled */
TS_5, /* After touch when "locked drags" enabled */
TS_CLICKPAD_MOVE, /* After left button press on a clickpad */
};
enum TapButtonState {
TBS_BUTTON_UP, /* "Virtual tap button" is up */
TBS_BUTTON_DOWN, /* "Virtual tap button" is down */
};
enum TouchpadModel {
MODEL_UNKNOWN = 0,
MODEL_SYNAPTICS,
MODEL_ALPS,
MODEL_APPLETOUCH,
MODEL_ELANTECH,
MODEL_UNIBODY_MACBOOK
};
enum SoftButtonAreas {
NO_BUTTON_AREA = -1,
BOTTOM_BUTTON_AREA = 0,
BOTTOM_RIGHT_BUTTON_AREA = 0,
BOTTOM_MIDDLE_BUTTON_AREA = 1,
TOP_BUTTON_AREA = 2,
TOP_RIGHT_BUTTON_AREA = 2,
TOP_MIDDLE_BUTTON_AREA = 3
};
enum SoftButtonAreaEdges {
LEFT = 0,
RIGHT = 1,
TOP = 2,
BOTTOM = 3
};
typedef struct _SynapticsParameters {
/* Parameter data */
int left_edge, right_edge, top_edge, bottom_edge; /* edge coordinates absolute */
int finger_low, finger_high, finger_press; /* finger detection values in Z-values */
int tap_time;
int tap_move; /* max. tapping time and movement in packets and coord. */
int single_tap_timeout; /* timeout to recognize a single tap */
int tap_time_2; /* max. tapping time for double taps */
int click_time; /* The duration of a single click */
Bool clickpad; /* Device is a has integrated buttons */
Bool has_secondary_buttons; /* Device has a top soft-button area */
int clickpad_ignore_motion_time; /* Ignore motion for X ms after a click */
int emulate_mid_button_time; /* Max time between left and right button presses to
emulate a middle button press. */
int emulate_twofinger_z; /* pressure threshold to emulate two finger touch (for Alps) */
int emulate_twofinger_w; /* Finger width threshold to emulate two finger touch */
int scroll_dist_vert; /* Scrolling distance in absolute coordinates */
int scroll_dist_horiz; /* Scrolling distance in absolute coordinates */
Bool scroll_edge_vert; /* Enable/disable vertical scrolling on right edge */
Bool scroll_edge_horiz; /* Enable/disable horizontal scrolling on left edge */
Bool scroll_edge_corner; /* Enable/disable continuous edge scrolling when in the corner */
Bool scroll_twofinger_vert; /* Enable/disable vertical two-finger scrolling */
Bool scroll_twofinger_horiz; /* Enable/disable horizontal two-finger scrolling */
double min_speed, max_speed, accl; /* movement parameters */
Bool updown_button_scrolling; /* Up/Down-Button scrolling or middle/double-click */
Bool leftright_button_scrolling; /* Left/right-button scrolling, or two lots of middle button */
Bool updown_button_repeat; /* If up/down button being used to scroll, auto-repeat? */
Bool leftright_button_repeat; /* If left/right button being used to scroll, auto-repeat? */
int scroll_button_repeat; /* time, in milliseconds, between scroll events being
* sent when holding down scroll buttons */
int touchpad_off; /* Switches the touchpad off
* 0 : Not off
* 1 : Off
* 2 : Only tapping and scrolling off
*/
Bool locked_drags; /* Enable locked drags */
int locked_drag_time; /* timeout for locked drags */
int tap_action[MAX_TAP]; /* Button to report on tap events */
int click_action[MAX_CLICK]; /* Button to report on click with fingers */
Bool circular_scrolling; /* Enable circular scrolling */
double scroll_dist_circ; /* Scrolling angle radians */
int circular_trigger; /* Trigger area for circular scrolling */
Bool circular_pad; /* Edge has an oval or circular shape */
Bool palm_detect; /* Enable Palm Detection */
int palm_min_width; /* Palm detection width */
int palm_min_z; /* Palm detection depth */
double coasting_speed; /* Coasting threshold scrolling speed in scrolls/s */
double coasting_friction; /* Number of scrolls per second per second to change coasting speed */
int press_motion_min_z; /* finger pressure at which minimum pressure motion factor is applied */
int press_motion_max_z; /* finger pressure at which maximum pressure motion factor is applied */
double press_motion_min_factor; /* factor applied on speed when finger pressure is at minimum */
double press_motion_max_factor; /* factor applied on speed when finger pressure is at minimum */
Bool grab_event_device; /* grab event device for exclusive use? */
Bool tap_and_drag_gesture; /* Switches the tap-and-drag gesture on/off */
unsigned int resolution_horiz; /* horizontal resolution of touchpad in units/mm */
unsigned int resolution_vert; /* vertical resolution of touchpad in units/mm */
int area_left_edge, area_right_edge, area_top_edge, area_bottom_edge; /* area coordinates absolute */
int softbutton_areas[4][4]; /* soft button area coordinates, 0 => right, 1 => middle , 2 => secondary right, 3 => secondary middle button */
int hyst_x, hyst_y; /* x and y width of hysteresis box */
int maxDeltaMM; /* maximum delta movement (vector length) in mm */
} SynapticsParameters;
struct _SynapticsPrivateRec {
SynapticsParameters synpara; /* Default parameter settings, read from
the X config file */
struct SynapticsProtocolOperations *proto_ops;
void *proto_data; /* protocol-specific data */
struct SynapticsHwState *hwState;
const char *device; /* device node */
CARD32 timer_time; /* when timer last fired */
OsTimerPtr timer; /* for up/down-button repeat, tap processing, etc */
struct CommData comm;
struct SynapticsHwState *local_hw_state; /* used in place of local hw state variables */
SynapticsMoveHistRec move_hist[SYNAPTICS_MOVE_HISTORY]; /* movement history */
int hist_index; /* Last added entry in move_hist[] */
int hyst_center_x; /* center x of hysteresis */
int hyst_center_y; /* center y of hysteresis */
struct {
int last_x; /* last x-scroll position */
int last_y; /* last y-scroll position */
double delta_x; /* accumulated horiz scroll delta */
double delta_y; /* accumulated vert scroll delta */
double last_a; /* last angle-scroll position */
CARD32 last_millis; /* time last scroll event posted */
double coast_speed_x; /* Horizontal coasting speed in scrolls/s */
double coast_speed_y; /* Vertical coasting speed in scrolls/s */
double coast_delta_x; /* Accumulated horizontal coast delta */
double coast_delta_y; /* Accumulated vertical coast delta */
int packets_this_scroll; /* Events received for this scroll */
} scroll;
int count_packet_finger; /* packet counter with finger on the touchpad */
int button_delay_millis; /* button delay for 3rd button emulation */
Bool prev_up; /* Previous up button value, for double click emulation */
enum FingerState finger_state; /* previous finger state */
CARD32 last_motion_millis; /* time of the last motion */
enum SoftButtonAreas last_button_area; /* Last button area we were in */
int clickpad_click_millis; /* Time of last clickpad click */
enum TapState tap_state; /* State of tap processing */
int tap_max_fingers; /* Max number of fingers seen since entering start state */
int tap_button; /* Which button started the tap processing */
enum TapButtonState tap_button_state; /* Current tap action */
SynapticsMoveHistRec touch_on; /* data when the touchpad is touched/released */
enum MovingState moving_state; /* previous moving state */
Bool vert_scroll_edge_on; /* Keeps track of currently active scroll modes */
Bool horiz_scroll_edge_on; /* Keeps track of currently active scroll modes */
Bool vert_scroll_twofinger_on; /* Keeps track of currently active scroll modes */
Bool horiz_scroll_twofinger_on; /* Keeps track of currently active scroll modes */
Bool circ_scroll_on; /* Keeps track of currently active scroll modes */
Bool circ_scroll_vert; /* True: Generate vertical scroll events
False: Generate horizontal events */
enum MidButtonEmulation mid_emu_state; /* emulated 3rd button */
int repeatButtons; /* buttons for repeat */
int nextRepeat; /* Time when to trigger next auto repeat event */
int lastButtons; /* last state of the buttons */
int prev_z; /* previous z value, for palm detection */
int prevFingers; /* previous numFingers, for transition detection */
int avg_width; /* weighted average of previous fingerWidth values */
#ifndef NO_DRIVER_SCALING
double horiz_coeff; /* normalization factor for x coordinates */
double vert_coeff; /* normalization factor for y coordinates */
#endif
int minx, maxx, miny, maxy; /* min/max dimensions as detected */
int minp, maxp, minw, maxw; /* min/max pressure and finger width as detected */
int resx, resy; /* resolution of coordinates as detected in units/mm */
Bool has_left; /* left button detected for this device */
Bool has_right; /* right button detected for this device */
Bool has_middle; /* middle button detected for this device */
Bool has_double; /* double click detected for this device */
Bool has_triple; /* triple click detected for this device */
Bool has_pressure; /* device reports pressure */
Bool has_width; /* device reports finger width */
Bool has_scrollbuttons; /* device has physical scrollbuttons */
Bool has_semi_mt; /* device is only semi-multitouch capable */
Bool has_mt_palm_detect; /* device reports per finger width and pressure */
enum TouchpadModel model; /* The detected model */
unsigned short id_vendor; /* vendor id */
unsigned short id_product; /* product id */
int scroll_axis_horiz; /* Horizontal smooth-scrolling axis */
int scroll_axis_vert; /* Vertical smooth-scrolling axis */
ValuatorMask *scroll_events_mask; /* ValuatorMask for smooth-scrolling */
Bool has_touch; /* Device has multitouch capabilities */
int max_touches; /* Number of touches supported */
int num_mt_axes; /* Number of multitouch axes other than X, Y */
SynapticsTouchAxisRec *touch_axes; /* Touch axis information other than X, Y */
int num_slots; /* Number of touch slots allocated */
int *open_slots; /* Array of currently open touch slots */
int num_active_touches; /* Number of active touches on device */
};
#endif /* _SYNAPTICSSTR_H_ */
xf86-input-synaptics-1.9.2/src/synproto.c 0000644 0143106 0000012 00000011156 14262661535 015245 0000000 0000000 /*
* Copyright © 2012 Canonical, Ltd.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice (including the next
* paragraph) shall be included in all copies or substantial portions of the
* Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
#include "synproto.h"
#include "synapticsstr.h"
static int
HwStateAllocTouch(struct SynapticsHwState *hw, SynapticsPrivate * priv)
{
int num_vals;
int i = 0;
hw->num_mt_mask = priv->num_slots;
hw->mt_mask = malloc(hw->num_mt_mask * sizeof(ValuatorMask *));
if (!hw->mt_mask)
goto fail;
num_vals = 2; /* x and y */
num_vals += 2; /* scroll axes */
num_vals += priv->num_mt_axes;
for (; i < hw->num_mt_mask; i++) {
hw->mt_mask[i] = valuator_mask_new(num_vals);
if (!hw->mt_mask[i])
goto fail;
}
hw->slot_state = calloc(hw->num_mt_mask, sizeof(enum SynapticsSlotState));
if (!hw->slot_state)
goto fail;
return Success;
fail:
for (i--; i >= 0; i--)
valuator_mask_free(&hw->mt_mask[i]);
free(hw->mt_mask);
hw->mt_mask = NULL;
return BadAlloc;
}
struct SynapticsHwState *
SynapticsHwStateAlloc(SynapticsPrivate * priv)
{
struct SynapticsHwState *hw;
hw = calloc(1, sizeof(struct SynapticsHwState));
if (!hw)
return NULL;
if (HwStateAllocTouch(hw, priv) != Success) {
free(hw);
return NULL;
}
return hw;
}
void
SynapticsHwStateFree(struct SynapticsHwState **hw)
{
int i;
if (!*hw)
return;
free((*hw)->slot_state);
for (i = 0; i < (*hw)->num_mt_mask; i++)
valuator_mask_free(&(*hw)->mt_mask[i]);
free((*hw)->mt_mask);
free(*hw);
*hw = NULL;
}
void
SynapticsCopyHwState(struct SynapticsHwState *dst,
const struct SynapticsHwState *src)
{
int i;
dst->millis = src->millis;
dst->x = src->x;
dst->y = src->y;
dst->z = src->z;
dst->cumulative_dx = src->cumulative_dx;
dst->cumulative_dy = src->cumulative_dy;
dst->numFingers = src->numFingers;
dst->fingerWidth = src->fingerWidth;
dst->left = src->left & BTN_EMULATED_FLAG ? 0 : src->left;
dst->right = src->right & BTN_EMULATED_FLAG ? 0 : src->right;
dst->up = src->up;
dst->down = src->down;
memcpy(dst->multi, src->multi, sizeof(dst->multi));
dst->middle = src->middle & BTN_EMULATED_FLAG ? 0 : src->middle;
for (i = 0; i < dst->num_mt_mask && i < src->num_mt_mask; i++)
valuator_mask_copy(dst->mt_mask[i], src->mt_mask[i]);
memcpy(dst->slot_state, src->slot_state,
dst->num_mt_mask * sizeof(enum SynapticsSlotState));
}
void
SynapticsResetHwState(struct SynapticsHwState *hw)
{
hw->millis = 0;
hw->x = INT_MIN;
hw->y = INT_MIN;
hw->z = 0;
hw->cumulative_dx = 0;
hw->cumulative_dy = 0;
hw->numFingers = 0;
hw->fingerWidth = 0;
hw->left = 0;
hw->right = 0;
hw->up = 0;
hw->down = 0;
hw->middle = 0;
memset(hw->multi, 0, sizeof(hw->multi));
SynapticsResetTouchHwState(hw, TRUE);
}
void
SynapticsResetTouchHwState(struct SynapticsHwState *hw, Bool set_slot_empty)
{
int i;
for (i = 0; i < hw->num_mt_mask; i++) {
int j;
/* Leave x and y valuators in case we need to restart touch */
for (j = 2; j < valuator_mask_num_valuators(hw->mt_mask[i]); j++)
valuator_mask_unset(hw->mt_mask[i], j);
switch (hw->slot_state[i]) {
case SLOTSTATE_OPEN:
case SLOTSTATE_OPEN_EMPTY:
case SLOTSTATE_UPDATE:
hw->slot_state[i] =
set_slot_empty ? SLOTSTATE_EMPTY : SLOTSTATE_OPEN_EMPTY;
break;
default:
hw->slot_state[i] = SLOTSTATE_EMPTY;
break;
}
}
}
xf86-input-synaptics-1.9.2/src/eventcomm.h 0000644 0143106 0000012 00000003525 14262661535 015353 0000000 0000000 /*
* Copyright © 2004 Peter Osterlund
*
* 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.
*
* Authors:
* Peter Osterlund (petero2@telia.com)
*/
#ifndef _EVENTCOMM_H_
#define _EVENTCOMM_H_
#include
#include
#include
#include
#include "synproto.h"
#ifndef input_event_sec
#define input_event_sec time.tv_sec
#endif
#ifndef input_event_usec
#define input_event_usec time.tv_usec
#endif
/* for auto-dev: */
#define DEV_INPUT_EVENT "/dev/input"
#define EVENT_DEV_NAME "event"
struct eventcomm_proto_data;
extern struct eventcomm_proto_data *EventProtoDataAlloc(int fd);
extern Bool
EventReadHwState(InputInfoPtr pInfo,
struct CommData *comm, struct SynapticsHwState *hwRet);
#endif /* _EVENTCOMM_H_ */
xf86-input-synaptics-1.9.2/src/Makefile.in 0000644 0143106 0000012 00000061523 14262661544 015254 0000000 0000000 # Makefile.in generated by automake 1.16.5 from Makefile.am.
# @configure_input@
# Copyright (C) 1994-2021 Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE.
@SET_MAKE@
# Copyright 2005 Adam Jackson.
#
# Permission is hereby granted, free of charge, to any person obtaining a
# copy of this software and associated documentation files (the "Software"),
# to deal in the Software without restriction, including without limitation
# on the rights to use, copy, modify, merge, publish, distribute, sub
# license, and/or sell copies of the Software, and to permit persons to whom
# the Software is furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice (including the next
# paragraph) shall be included in all copies or substantial portions of the
# Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
# ADAM JACKSON BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
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@
@BUILD_PS2COMM_TRUE@am__append_1 = \
@BUILD_PS2COMM_TRUE@ alpscomm.c \
@BUILD_PS2COMM_TRUE@ ps2comm.c ps2comm.h
@BUILD_EVENTCOMM_TRUE@am__append_2 = \
@BUILD_EVENTCOMM_TRUE@ eventcomm.c eventcomm.h
@BUILD_EVENTCOMM_TRUE@am__append_3 = $(LIBEVDEV_CFLAGS)
@BUILD_PSMCOMM_TRUE@am__append_4 = \
@BUILD_PSMCOMM_TRUE@ psmcomm.c
subdir = src
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON)
mkinstalldirs = $(install_sh) -d
CONFIG_HEADER = $(top_builddir)/config.h
CONFIG_CLEAN_FILES =
CONFIG_CLEAN_VPATH_FILES =
am__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)$(synaptics_drv_ladir)"
LTLIBRARIES = $(synaptics_drv_la_LTLIBRARIES)
am__DEPENDENCIES_1 =
@BUILD_EVENTCOMM_TRUE@synaptics_drv_la_DEPENDENCIES = \
@BUILD_EVENTCOMM_TRUE@ $(am__DEPENDENCIES_1)
am__synaptics_drv_la_SOURCES_DIST = synaptics.c synapticsstr.h \
synproto.c synproto.h properties.c alpscomm.c ps2comm.c \
ps2comm.h eventcomm.c eventcomm.h psmcomm.c
@BUILD_PS2COMM_TRUE@am__objects_1 = alpscomm.lo ps2comm.lo
@BUILD_EVENTCOMM_TRUE@am__objects_2 = eventcomm.lo
@BUILD_PSMCOMM_TRUE@am__objects_3 = psmcomm.lo
am_synaptics_drv_la_OBJECTS = synaptics.lo synproto.lo properties.lo \
$(am__objects_1) $(am__objects_2) $(am__objects_3)
synaptics_drv_la_OBJECTS = $(am_synaptics_drv_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 =
synaptics_drv_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \
$(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \
$(AM_CFLAGS) $(CFLAGS) $(synaptics_drv_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)/depcomp
am__maybe_remake_depfiles = depfiles
am__depfiles_remade = ./$(DEPDIR)/alpscomm.Plo \
./$(DEPDIR)/eventcomm.Plo ./$(DEPDIR)/properties.Plo \
./$(DEPDIR)/ps2comm.Plo ./$(DEPDIR)/psmcomm.Plo \
./$(DEPDIR)/synaptics.Plo ./$(DEPDIR)/synproto.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 = $(synaptics_drv_la_SOURCES)
DIST_SOURCES = $(am__synaptics_drv_la_SOURCES_DIST)
am__can_run_installinfo = \
case $$AM_UPDATE_INFO_DIR in \
n|no|NO) false;; \
*) (install-info --version) >/dev/null 2>&1;; \
esac
am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
# Read a list of newline-separated strings from the standard input,
# and print each of them once, without duplicates. Input order is
# *not* preserved.
am__uniquify_input = $(AWK) '\
BEGIN { nonempty = 0; } \
{ items[$$0] = 1; nonempty = 1; } \
END { if (nonempty) { for (i in items) print i; }; } \
'
# Make sure the list of sources is unique. This is necessary because,
# e.g., the same source file might be shared among _SOURCES variables
# for different programs/libraries.
am__define_uniq_tagged_files = \
list='$(am__tagged_files)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | $(am__uniquify_input)`
am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
ACLOCAL = @ACLOCAL@
ADMIN_MAN_DIR = @ADMIN_MAN_DIR@
ADMIN_MAN_SUFFIX = @ADMIN_MAN_SUFFIX@
AMTAR = @AMTAR@
AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
APP_MAN_DIR = @APP_MAN_DIR@
APP_MAN_SUFFIX = @APP_MAN_SUFFIX@
AR = @AR@
AUTOCONF = @AUTOCONF@
AUTOHEADER = @AUTOHEADER@
AUTOMAKE = @AUTOMAKE@
AWK = @AWK@
BASE_CFLAGS = @BASE_CFLAGS@
CC = @CC@
CCDEPMODE = @CCDEPMODE@
CFLAGS = @CFLAGS@
CHANGELOG_CMD = @CHANGELOG_CMD@
CPPFLAGS = @CPPFLAGS@
CSCOPE = @CSCOPE@
CTAGS = @CTAGS@
CWARNFLAGS = @CWARNFLAGS@
CYGPATH_W = @CYGPATH_W@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
DLLTOOL = @DLLTOOL@
DRIVER_MAN_DIR = @DRIVER_MAN_DIR@
DRIVER_MAN_SUFFIX = @DRIVER_MAN_SUFFIX@
DSYMUTIL = @DSYMUTIL@
DUMPBIN = @DUMPBIN@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
EGREP = @EGREP@
ETAGS = @ETAGS@
EXEEXT = @EXEEXT@
FGREP = @FGREP@
FILECMD = @FILECMD@
FILE_MAN_DIR = @FILE_MAN_DIR@
FILE_MAN_SUFFIX = @FILE_MAN_SUFFIX@
GREP = @GREP@
INSTALL = @INSTALL@
INSTALL_CMD = @INSTALL_CMD@
INSTALL_DATA = @INSTALL_DATA@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
LD = @LD@
LDFLAGS = @LDFLAGS@
LIBEVDEV_CFLAGS = @LIBEVDEV_CFLAGS@
LIBEVDEV_LIBS = @LIBEVDEV_LIBS@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
LIBTOOL = @LIBTOOL@
LIB_MAN_DIR = @LIB_MAN_DIR@
LIB_MAN_SUFFIX = @LIB_MAN_SUFFIX@
LIPO = @LIPO@
LN_S = @LN_S@
LTLIBOBJS = @LTLIBOBJS@
LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
MAKEINFO = @MAKEINFO@
MANIFEST_TOOL = @MANIFEST_TOOL@
MAN_SUBSTS = @MAN_SUBSTS@
MISC_MAN_DIR = @MISC_MAN_DIR@
MISC_MAN_SUFFIX = @MISC_MAN_SUFFIX@
MKDIR_P = @MKDIR_P@
NM = @NM@
NMEDIT = @NMEDIT@
OBJDUMP = @OBJDUMP@
OBJEXT = @OBJEXT@
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@
RANLIB = @RANLIB@
SED = @SED@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
STRICT_CFLAGS = @STRICT_CFLAGS@
STRIP = @STRIP@
VERSION = @VERSION@
XI_CFLAGS = @XI_CFLAGS@
XI_LIBS = @XI_LIBS@
XORG_CFLAGS = @XORG_CFLAGS@
XORG_LIBS = @XORG_LIBS@
XORG_MALLOC_DEBUG_ENV = @XORG_MALLOC_DEBUG_ENV@
XORG_MAN_PAGE = @XORG_MAN_PAGE@
XTST_CFLAGS = @XTST_CFLAGS@
XTST_LIBS = @XTST_LIBS@
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@
configdir = @configdir@
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@
inputdir = @inputdir@
install_sh = @install_sh@
libdir = @libdir@
libexecdir = @libexecdir@
localedir = @localedir@
localstatedir = @localstatedir@
mandir = @mandir@
mkdir_p = @mkdir_p@
oldincludedir = @oldincludedir@
pdfdir = @pdfdir@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
runstatedir = @runstatedir@
sbindir = @sbindir@
sdkdir = @sdkdir@
sharedstatedir = @sharedstatedir@
srcdir = @srcdir@
sysconfdir = @sysconfdir@
target_alias = @target_alias@
top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
# this is obnoxious:
# -module lets us name the module exactly how we want
# -avoid-version prevents gratuitous .0.0.0 version numbers on the end
# _ladir passes a dummy rpath to libtool so the thing will actually link
# TODO: -nostdlib/-Bstatic/-lgcc platform magic, not installing the .a, etc.
synaptics_drv_la_LTLIBRARIES = synaptics_drv.la
synaptics_drv_la_LDFLAGS = -module -avoid-version
synaptics_drv_ladir = @inputdir@
AM_CPPFLAGS = -I$(top_srcdir)/include $(am__append_3)
AM_CFLAGS = $(XORG_CFLAGS)
synaptics_drv_la_SOURCES = synaptics.c synapticsstr.h synproto.c \
synproto.h properties.c $(am__append_1) $(am__append_2) \
$(am__append_4)
@BUILD_EVENTCOMM_TRUE@synaptics_drv_la_LIBADD = \
@BUILD_EVENTCOMM_TRUE@ $(LIBEVDEV_LIBS)
all: all-am
.SUFFIXES:
.SUFFIXES: .c .lo .o .obj
$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
@for dep in $?; do \
case '$(am__configure_deps)' in \
*$$dep*) \
( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
&& { if test -f $@; then exit 0; else break; fi; }; \
exit 1;; \
esac; \
done; \
echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign src/Makefile'; \
$(am__cd) $(top_srcdir) && \
$(AUTOMAKE) --foreign src/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-synaptics_drv_laLTLIBRARIES: $(synaptics_drv_la_LTLIBRARIES)
@$(NORMAL_INSTALL)
@list='$(synaptics_drv_la_LTLIBRARIES)'; test -n "$(synaptics_drv_ladir)" || 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)$(synaptics_drv_ladir)'"; \
$(MKDIR_P) "$(DESTDIR)$(synaptics_drv_ladir)" || exit 1; \
echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(synaptics_drv_ladir)'"; \
$(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(synaptics_drv_ladir)"; \
}
uninstall-synaptics_drv_laLTLIBRARIES:
@$(NORMAL_UNINSTALL)
@list='$(synaptics_drv_la_LTLIBRARIES)'; test -n "$(synaptics_drv_ladir)" || list=; \
for p in $$list; do \
$(am__strip_dir) \
echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(synaptics_drv_ladir)/$$f'"; \
$(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(synaptics_drv_ladir)/$$f"; \
done
clean-synaptics_drv_laLTLIBRARIES:
-test -z "$(synaptics_drv_la_LTLIBRARIES)" || rm -f $(synaptics_drv_la_LTLIBRARIES)
@list='$(synaptics_drv_la_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}; \
}
synaptics_drv.la: $(synaptics_drv_la_OBJECTS) $(synaptics_drv_la_DEPENDENCIES) $(EXTRA_synaptics_drv_la_DEPENDENCIES)
$(AM_V_CCLD)$(synaptics_drv_la_LINK) -rpath $(synaptics_drv_ladir) $(synaptics_drv_la_OBJECTS) $(synaptics_drv_la_LIBADD) $(LIBS)
mostlyclean-compile:
-rm -f *.$(OBJEXT)
distclean-compile:
-rm -f *.tab.c
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/alpscomm.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eventcomm.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/properties.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ps2comm.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/psmcomm.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/synaptics.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/synproto.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)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.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)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.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)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.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
ID: $(am__tagged_files)
$(am__define_uniq_tagged_files); mkid -fID $$unique
tags: tags-am
TAGS: tags
tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
set x; \
here=`pwd`; \
$(am__define_uniq_tagged_files); \
shift; \
if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
test -n "$$unique" || unique=$$empty_fix; \
if test $$# -gt 0; then \
$(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
"$$@" $$unique; \
else \
$(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
$$unique; \
fi; \
fi
ctags: ctags-am
CTAGS: ctags
ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
$(am__define_uniq_tagged_files); \
test -z "$(CTAGS_ARGS)$$unique" \
|| $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
$$unique
GTAGS:
here=`$(am__cd) $(top_builddir) && pwd` \
&& $(am__cd) $(top_srcdir) \
&& gtags -i $(GTAGS_ARGS) "$$here"
cscopelist: cscopelist-am
cscopelist-am: $(am__tagged_files)
list='$(am__tagged_files)'; \
case "$(srcdir)" in \
[\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
*) sdir=$(subdir)/$(srcdir) ;; \
esac; \
for i in $$list; do \
if test -f "$$i"; then \
echo "$(subdir)/$$i"; \
else \
echo "$$sdir/$$i"; \
fi; \
done >> $(top_builddir)/cscope.files
distclean-tags:
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
distdir: $(BUILT_SOURCES)
$(MAKE) $(AM_MAKEFLAGS) distdir-am
distdir-am: $(DISTFILES)
@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
list='$(DISTFILES)'; \
dist_files=`for file in $$list; do echo $$file; done | \
sed -e "s|^$$srcdirstrip/||;t" \
-e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
case $$dist_files in \
*/*) $(MKDIR_P) `echo "$$dist_files" | \
sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
sort -u` ;; \
esac; \
for file in $$dist_files; do \
if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
if test -d $$d/$$file; then \
dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
if test -d "$(distdir)/$$file"; then \
find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
fi; \
if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
fi; \
cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
else \
test -f "$(distdir)/$$file" \
|| cp -p $$d/$$file "$(distdir)/$$file" \
|| exit 1; \
fi; \
done
check-am: all-am
check: check-am
all-am: Makefile $(LTLIBRARIES)
installdirs:
for dir in "$(DESTDIR)$(synaptics_drv_ladir)"; do \
test -z "$$dir" || $(MKDIR_P) "$$dir"; \
done
install: install-am
install-exec: install-exec-am
install-data: install-data-am
uninstall: uninstall-am
install-am: all-am
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
installcheck: installcheck-am
install-strip:
if test -z '$(STRIP)'; then \
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
install; \
else \
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
"INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
fi
mostlyclean-generic:
clean-generic:
distclean-generic:
-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
maintainer-clean-generic:
@echo "This command is intended for maintainers to use"
@echo "it deletes files that may require special tools to rebuild."
clean: clean-am
clean-am: clean-generic clean-libtool \
clean-synaptics_drv_laLTLIBRARIES mostlyclean-am
distclean: distclean-am
-rm -f ./$(DEPDIR)/alpscomm.Plo
-rm -f ./$(DEPDIR)/eventcomm.Plo
-rm -f ./$(DEPDIR)/properties.Plo
-rm -f ./$(DEPDIR)/ps2comm.Plo
-rm -f ./$(DEPDIR)/psmcomm.Plo
-rm -f ./$(DEPDIR)/synaptics.Plo
-rm -f ./$(DEPDIR)/synproto.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-synaptics_drv_laLTLIBRARIES
install-dvi: install-dvi-am
install-dvi-am:
install-exec-am:
install-html: install-html-am
install-html-am:
install-info: install-info-am
install-info-am:
install-man:
install-pdf: install-pdf-am
install-pdf-am:
install-ps: install-ps-am
install-ps-am:
installcheck-am:
maintainer-clean: maintainer-clean-am
-rm -f ./$(DEPDIR)/alpscomm.Plo
-rm -f ./$(DEPDIR)/eventcomm.Plo
-rm -f ./$(DEPDIR)/properties.Plo
-rm -f ./$(DEPDIR)/ps2comm.Plo
-rm -f ./$(DEPDIR)/psmcomm.Plo
-rm -f ./$(DEPDIR)/synaptics.Plo
-rm -f ./$(DEPDIR)/synproto.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-synaptics_drv_laLTLIBRARIES
.MAKE: install-am install-strip
.PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \
clean-generic clean-libtool clean-synaptics_drv_laLTLIBRARIES \
cscopelist-am ctags ctags-am distclean distclean-compile \
distclean-generic distclean-libtool distclean-tags distdir dvi \
dvi-am html html-am info info-am install install-am \
install-data install-data-am install-dvi install-dvi-am \
install-exec install-exec-am install-html install-html-am \
install-info install-info-am install-man install-pdf \
install-pdf-am install-ps install-ps-am install-strip \
install-synaptics_drv_laLTLIBRARIES 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-synaptics_drv_laLTLIBRARIES
.PRECIOUS: Makefile
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:
xf86-input-synaptics-1.9.2/src/synaptics.c 0000644 0143106 0000012 00000315053 14262661535 015370 0000000 0000000 /*
* Copyright © 1999 Henry Davies
* Copyright © 2001 Stefan Gmeiner
* Copyright © 2002 S. Lehner
* Copyright © 2002 Peter Osterlund
* Copyright © 2002 Linuxcare Inc. David Kennedy
* Copyright © 2003 Hartwig Felger
* Copyright © 2003 Jörg Bösner
* Copyright © 2003 Fred Hucht
* Copyright © 2004 Alexei Gilchrist
* Copyright © 2004 Matthias Ihmig
* Copyright © 2006 Stefan Bethge
* Copyright © 2006 Christian Thaeter
* Copyright © 2007 Joseph P. Skudlarek
* Copyright © 2008 Fedor P. Goncharov
* Copyright © 2008-2012 Red Hat, Inc.
* Copyright © 2011 The Chromium OS Authors
*
* 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.
*
* Authors:
* Joseph P. Skudlarek
* Christian Thaeter
* Stefan Bethge
* Matthias Ihmig
* Alexei Gilchrist
* Jörg Bösner
* Hartwig Felger
* Peter Osterlund
* S. Lehner
* Stefan Gmeiner
* Henry Davies for the
* Linuxcare Inc. David Kennedy
* Fred Hucht
* Fedor P. Goncharov
* Simon Thum
*
* Trademarks are the property of their respective owners.
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include "synapticsstr.h"
#include "synaptics-properties.h"
enum EdgeType {
NO_EDGE = 0,
BOTTOM_EDGE = 1,
TOP_EDGE = 2,
LEFT_EDGE = 4,
RIGHT_EDGE = 8,
LEFT_BOTTOM_EDGE = BOTTOM_EDGE | LEFT_EDGE,
RIGHT_BOTTOM_EDGE = BOTTOM_EDGE | RIGHT_EDGE,
RIGHT_TOP_EDGE = TOP_EDGE | RIGHT_EDGE,
LEFT_TOP_EDGE = TOP_EDGE | LEFT_EDGE
};
/*
* We expect to be receiving a steady 80 packets/sec (which gives 40
* reports/sec with more than one finger on the pad, as Advanced Gesture Mode
* requires two PS/2 packets per report). Instead of a random scattering of
* magic 13 and 20ms numbers scattered throughout the driver, introduce
* POLL_MS as 14ms, which is slightly less than 80Hz. 13ms is closer to
* 80Hz, but if the kernel event reporting was even slightly delayed,
* we would produce synthetic motion followed immediately by genuine
* motion, so use 14.
*
* We use this to call back at a constant rate to at least produce the
* illusion of smooth motion. It works a lot better than you'd expect.
*/
#define POLL_MS 14
#define MAX(a, b) (((a)>(b))?(a):(b))
#define MIN(a, b) (((a)<(b))?(a):(b))
#define TIME_DIFF(a, b) ((int)((a)-(b)))
#define SQR(x) ((x) * (x))
#ifndef M_PI
#define M_PI 3.14159265358979323846
#endif
#define INPUT_BUFFER_SIZE 200
/*****************************************************************************
* Forward declaration
****************************************************************************/
static int SynapticsPreInit(InputDriverPtr drv, InputInfoPtr pInfo, int flags);
static void SynapticsUnInit(InputDriverPtr drv, InputInfoPtr pInfo, int flags);
static Bool DeviceControl(DeviceIntPtr, int);
static void ReadInput(InputInfoPtr);
static int HandleState(InputInfoPtr, struct SynapticsHwState *, CARD32 now,
Bool from_timer);
static int ControlProc(InputInfoPtr, xDeviceCtl *);
static int SwitchMode(ClientPtr, DeviceIntPtr, int);
static int DeviceInit(DeviceIntPtr);
static int DeviceOn(DeviceIntPtr);
static int DeviceOff(DeviceIntPtr);
static int DeviceClose(DeviceIntPtr);
static Bool QueryHardware(InputInfoPtr);
static void ReadDevDimensions(InputInfoPtr);
#ifndef NO_DRIVER_SCALING
static void ScaleCoordinates(SynapticsPrivate * priv,
struct SynapticsHwState *hw);
static void CalculateScalingCoeffs(SynapticsPrivate * priv);
#endif
static void SanitizeDimensions(InputInfoPtr pInfo);
void InitDeviceProperties(InputInfoPtr pInfo);
int SetProperty(DeviceIntPtr dev, Atom property, XIPropertyValuePtr prop,
BOOL checkonly);
const static struct {
const char *name;
struct SynapticsProtocolOperations *proto_ops;
} protocols[] = {
#ifdef BUILD_EVENTCOMM
{ "event", &event_proto_operations },
#endif
#ifdef BUILD_PSMCOMM
{ "psm", &psm_proto_operations },
#endif
#ifdef BUILD_PS2COMM
{ "psaux", &psaux_proto_operations },
{ "alps", &alps_proto_operations },
#endif
{ NULL, NULL }
};
InputDriverRec SYNAPTICS = {
1,
"synaptics",
NULL,
SynapticsPreInit,
SynapticsUnInit,
NULL,
NULL,
#ifdef XI86_DRV_CAP_SERVER_FD
XI86_DRV_CAP_SERVER_FD
#endif
};
static XF86ModuleVersionInfo VersionRec = {
"synaptics",
MODULEVENDORSTRING,
MODINFOSTRING1,
MODINFOSTRING2,
XORG_VERSION_CURRENT,
PACKAGE_VERSION_MAJOR, PACKAGE_VERSION_MINOR, PACKAGE_VERSION_PATCHLEVEL,
ABI_CLASS_XINPUT,
ABI_XINPUT_VERSION,
MOD_CLASS_XINPUT,
{0, 0, 0, 0}
};
static pointer
SetupProc(pointer module, pointer options, int *errmaj, int *errmin)
{
xf86AddInputDriver(&SYNAPTICS, module, 0);
return module;
}
_X_EXPORT XF86ModuleData synapticsModuleData = {
&VersionRec,
&SetupProc,
NULL
};
/*****************************************************************************
* Function Definitions
****************************************************************************/
static inline void
SynapticsCloseFd(InputInfoPtr pInfo)
{
if (pInfo->fd > -1 && !(pInfo->flags & XI86_SERVER_FD)) {
xf86CloseSerial(pInfo->fd);
pInfo->fd = -1;
}
}
/**
* Fill in default dimensions for backends that cannot query the hardware.
* Eventually, we want the edges to be 1900/5400 for x, 1900/4000 for y.
* These values are based so that calculate_edge_widths() will give us the
* right values.
*
* The default values 1900, etc. come from the dawn of time, when men where
* men, or possibly apes.
*/
static void
SanitizeDimensions(InputInfoPtr pInfo)
{
SynapticsPrivate *priv = (SynapticsPrivate *) pInfo->private;
if (priv->minx >= priv->maxx) {
priv->minx = 1615;
priv->maxx = 5685;
priv->resx = 0;
xf86IDrvMsg(pInfo, X_PROBED,
"invalid x-axis range. defaulting to %d - %d\n",
priv->minx, priv->maxx);
}
if (priv->miny >= priv->maxy) {
priv->miny = 1729;
priv->maxy = 4171;
priv->resy = 0;
xf86IDrvMsg(pInfo, X_PROBED,
"invalid y-axis range. defaulting to %d - %d\n",
priv->miny, priv->maxy);
}
if (priv->minp >= priv->maxp) {
priv->minp = 0;
priv->maxp = 255;
xf86IDrvMsg(pInfo, X_PROBED,
"invalid pressure range. defaulting to %d - %d\n",
priv->minp, priv->maxp);
}
if (priv->minw >= priv->maxw) {
priv->minw = 0;
priv->maxw = 15;
xf86IDrvMsg(pInfo, X_PROBED,
"invalid finger width range. defaulting to %d - %d\n",
priv->minw, priv->maxw);
}
}
static Bool
SetDeviceAndProtocol(InputInfoPtr pInfo)
{
SynapticsPrivate *priv = pInfo->private;
char *proto, *device;
int i;
proto = xf86SetStrOption(pInfo->options, "Protocol", NULL);
device = xf86SetStrOption(pInfo->options, "Device", NULL);
/* If proto is auto-dev, unset and let the code do the rest */
if (proto && !strcmp(proto, "auto-dev")) {
free(proto);
proto = NULL;
}
for (i = 0; protocols[i].name; i++) {
if ((!device || !proto) &&
protocols[i].proto_ops->AutoDevProbe &&
protocols[i].proto_ops->AutoDevProbe(pInfo, device))
break;
else if (proto && !strcmp(proto, protocols[i].name))
break;
}
free(proto);
free(device);
priv->proto_ops = protocols[i].proto_ops;
return (priv->proto_ops != NULL);
}
static void
calculate_edge_widths(SynapticsPrivate * priv, int *l, int *r, int *t, int *b)
{
int width, height;
int ewidth, eheight; /* edge width/height */
width = abs(priv->maxx - priv->minx);
height = abs(priv->maxy - priv->miny);
if (priv->model == MODEL_SYNAPTICS) {
ewidth = width * .07;
eheight = height * .07;
}
else if (priv->model == MODEL_ALPS) {
ewidth = width * .15;
eheight = height * .15;
}
else if (priv->model == MODEL_APPLETOUCH ||
priv->model == MODEL_UNIBODY_MACBOOK) {
ewidth = width * .085;
eheight = height * .085;
}
else {
ewidth = width * .04;
eheight = height * .054;
}
*l = priv->minx + ewidth;
*r = priv->maxx - ewidth;
*t = priv->miny + eheight;
*b = priv->maxy - eheight;
}
static void
calculate_tap_hysteresis(SynapticsPrivate * priv, int range,
int *fingerLow, int *fingerHigh)
{
switch (priv->model) {
case MODEL_ELANTECH:
/* All Elantech touchpads don't need the Z filtering to get the
* number of fingers correctly. See Documentation/elantech.txt
* in the kernel.
*/
*fingerLow = priv->minp + 1;
*fingerHigh = priv->minp + 1;
break;
case MODEL_UNIBODY_MACBOOK:
*fingerLow = 70;
*fingerHigh = 75;
break;
default:
*fingerLow = priv->minp + range * (25.0 / 256);
*fingerHigh = priv->minp + range * (30.0 / 256);
break;
}
}
/* Area options support both percent values and absolute values. This is
* awkward. The xf86Set* calls will print to the log, but they'll
* also print an error if we request a percent value but only have an
* int. So - check first for percent, then call xf86Set* again to get
* the log message.
*/
static int
set_percent_option(pointer options, const char *optname,
const int range, const int offset, const int default_value)
{
int result;
double percent = xf86CheckPercentOption(options, optname, -1);
if (percent >= 0.0) {
percent = xf86SetPercentOption(options, optname, -1);
result = percent / 100.0 * range + offset;
} else
result = xf86SetIntOption(options, optname, default_value);
return result;
}
Bool
SynapticsIsSoftButtonAreasValid(int *values)
{
Bool right_disabled = FALSE;
Bool middle_disabled = FALSE;
enum {
/* right button left, right, top, bottom */
RBL = 0,
RBR = 1,
RBT = 2,
RBB = 3,
/* middle button left, right, top, bottom */
MBL = 4,
MBR = 5,
MBT = 6,
MBB = 7,
};
/* Check right button area */
if ((((values[RBL] != 0) && (values[RBR] != 0)) && (values[RBL] > values[RBR])) ||
(((values[RBT] != 0) && (values[RBB] != 0)) && (values[RBT] > values[RBB])))
return FALSE;
/* Check middle button area */
if ((((values[MBL] != 0) && (values[MBR] != 0)) && (values[MBL] > values[MBR])) ||
(((values[MBT] != 0) && (values[MBB] != 0)) && (values[MBT] > values[MBB])))
return FALSE;
if (values[RBL] == 0 && values[RBR] == 0 && values[RBT] == 0 && values[RBB] == 0)
right_disabled = TRUE;
if (values[MBL] == 0 && values[MBR] == 0 && values[MBT] == 0 && values[MBB] == 0)
middle_disabled = TRUE;
if (!right_disabled &&
((values[RBL] && values[RBL] == values[RBR]) ||
(values[RBT] && values[RBT] == values[RBB])))
return FALSE;
if (!middle_disabled &&
((values[MBL] && values[MBL] == values[MBR]) ||
(values[MBT] && values[MBT] == values[MBB])))
return FALSE;
/* Check for overlapping button areas */
if (!right_disabled && !middle_disabled) {
int right_left = values[RBL] ? values[RBL] : INT_MIN;
int right_right = values[RBR] ? values[RBR] : INT_MAX;
int right_top = values[RBT] ? values[RBT] : INT_MIN;
int right_bottom = values[RBB] ? values[RBB] : INT_MAX;
int middle_left = values[MBL] ? values[MBL] : INT_MIN;
int middle_right = values[MBR] ? values[MBR] : INT_MAX;
int middle_top = values[MBT] ? values[MBT] : INT_MIN;
int middle_bottom = values[MBB] ? values[MBB] : INT_MAX;
/* If areas overlap in the Y axis */
if ((right_bottom <= middle_bottom && right_bottom >= middle_top) ||
(right_top <= middle_bottom && right_top >= middle_top)) {
/* Check for overlapping left edges */
if ((right_left < middle_left && right_right > middle_left) ||
(middle_left < right_left && middle_right > right_left))
return FALSE;
/* Check for overlapping right edges */
if ((right_right > middle_right && right_left < middle_right) ||
(middle_right > right_right && middle_left < right_right))
return FALSE;
}
/* If areas overlap in the X axis */
if ((right_left >= middle_left && right_left <= middle_right) ||
(right_right >= middle_left && right_right <= middle_right)) {
/* Check for overlapping top edges */
if ((right_top < middle_top && right_bottom > middle_top) ||
(middle_top < right_top && middle_bottom > right_top))
return FALSE;
/* Check for overlapping bottom edges */
if ((right_bottom > middle_bottom && right_top < middle_bottom) ||
(middle_bottom > right_bottom && middle_top < right_bottom))
return FALSE;
}
}
return TRUE;
}
static void
set_softbutton_areas_option(InputInfoPtr pInfo, char *option_name, int offset)
{
SynapticsPrivate *priv = pInfo->private;
SynapticsParameters *pars = &priv->synpara;
int values[8];
int in_percent = 0; /* bitmask for which ones are in % */
char *option_string;
char *next_num;
char *end_str;
int i;
int width, height;
if (!pars->clickpad)
return;
option_string = xf86SetStrOption(pInfo->options, option_name, NULL);
if (!option_string)
return;
next_num = option_string;
for (i = 0; i < 8 && *next_num != '\0'; i++) {
long int value = strtol(next_num, &end_str, 0);
if (value > INT_MAX || value < -INT_MAX)
goto fail;
values[i] = value;
if (next_num != end_str) {
if (*end_str == '%') {
in_percent |= 1 << i;
end_str++;
}
next_num = end_str;
}
else
goto fail;
}
if (i < 8 || *next_num != '\0')
goto fail;
width = priv->maxx - priv->minx;
height = priv->maxy - priv->miny;
for (i = 0; in_percent && i < 8; i++) {
int base, size;
if ((in_percent & (1 << i)) == 0 || values[i] == 0)
continue;
size = ((i % 4) < 2) ? width : height;
base = ((i % 4) < 2) ? priv->minx : priv->miny;
values[i] = base + size * values[i] / 100.0;
}
if (!SynapticsIsSoftButtonAreasValid(values))
goto fail;
memcpy(pars->softbutton_areas[offset], values, 4 * sizeof(int));
memcpy(pars->softbutton_areas[offset + 1], values + 4, 4 * sizeof(int));
free(option_string);
return;
fail:
xf86IDrvMsg(pInfo, X_ERROR,
"invalid %s value '%s', keeping defaults\n",
option_name, option_string);
free(option_string);
}
static void
set_primary_softbutton_areas_option(InputInfoPtr pInfo)
{
set_softbutton_areas_option(pInfo, "SoftButtonAreas", BOTTOM_BUTTON_AREA);
}
static void
set_secondary_softbutton_areas_option(InputInfoPtr pInfo)
{
set_softbutton_areas_option(pInfo, "SecondarySoftButtonAreas", TOP_BUTTON_AREA);
}
static void
set_default_parameters(InputInfoPtr pInfo)
{
SynapticsPrivate *priv = pInfo->private; /* read-only */
pointer opts = pInfo->options; /* read-only */
SynapticsParameters *pars = &priv->synpara; /* modified */
int horizScrollDelta, vertScrollDelta; /* pixels */
int tapMove; /* pixels */
int l, r, t, b; /* left, right, top, bottom */
double accelFactor; /* 1/pixels */
int fingerLow, fingerHigh; /* pressure */
int emulateTwoFingerMinZ; /* pressure */
int emulateTwoFingerMinW; /* width */
int pressureMotionMinZ, pressureMotionMaxZ; /* pressure */
int palmMinWidth, palmMinZ; /* pressure */
int tapButton1, tapButton2, tapButton3;
int clickFinger1, clickFinger2, clickFinger3;
Bool vertEdgeScroll, horizEdgeScroll;
Bool vertTwoFingerScroll, horizTwoFingerScroll;
int horizResolution = 1;
int vertResolution = 1;
int width, height, diag, range;
int horizHyst, vertHyst;
int middle_button_timeout;
int grab_event_device = 0;
const char *source;
/* The synaptics specs specify typical edge widths of 4% on x, and 5.4% on
* y (page 7) [Synaptics TouchPad Interfacing Guide, 510-000080 - A
* Second Edition, http://www.synaptics.com/support/dev_support.cfm, 8 Sep
* 2008]. We use 7% for both instead for synaptics devices, and 15% for
* ALPS models.
* http://bugs.freedesktop.org/show_bug.cgi?id=21214
*
* If the range was autodetected, apply these edge widths to all four
* sides.
*/
width = abs(priv->maxx - priv->minx);
height = abs(priv->maxy - priv->miny);
diag = sqrt(width * width + height * height);
calculate_edge_widths(priv, &l, &r, &t, &b);
/* Again, based on typical x/y range and defaults */
horizScrollDelta = diag * .020;
vertScrollDelta = diag * .020;
tapMove = diag * .044;
accelFactor = 200.0 / diag; /* trial-and-error */
/* hysteresis, assume >= 0 is a detected value (e.g. evdev fuzz) */
horizHyst = pars->hyst_x >= 0 ? pars->hyst_x : diag * 0.005;
vertHyst = pars->hyst_y >= 0 ? pars->hyst_y : diag * 0.005;
range = priv->maxp - priv->minp + 1;
calculate_tap_hysteresis(priv, range, &fingerLow, &fingerHigh);
/* scaling based on defaults and a pressure of 256 */
emulateTwoFingerMinZ = priv->minp + range * (282.0 / 256);
pressureMotionMinZ = priv->minp + range * (30.0 / 256);
pressureMotionMaxZ = priv->minp + range * (160.0 / 256);
palmMinZ = priv->minp + range * (200.0 / 256);
range = priv->maxw - priv->minw + 1;
/* scaling based on defaults below and a tool width of 16 */
palmMinWidth = priv->minw + range * (10.0 / 16);
emulateTwoFingerMinW = priv->minw + range * (7.0 / 16);
/* Enable tap if we don't have a phys left button */
tapButton1 = priv->has_left ? 0 : 1;
tapButton2 = priv->has_left ? 0 : 3;
tapButton3 = priv->has_left ? 0 : 2;
/* Enable multifinger-click if only have one physical button,
otherwise clickFinger is always button 1. */
clickFinger1 = 1;
clickFinger2 = (priv->has_right || priv->has_middle) ? 1 : 3;
clickFinger3 = (priv->has_right || priv->has_middle) ? 1 : 2;
/* Enable vert edge scroll if we can't detect doubletap */
vertEdgeScroll = priv->has_double ? FALSE : TRUE;
horizEdgeScroll = FALSE;
/* Enable twofinger scroll if we can detect doubletap */
vertTwoFingerScroll = priv->has_double ? TRUE : FALSE;
horizTwoFingerScroll = FALSE;
/* Use resolution reported by hardware if available */
if ((priv->resx > 0) && (priv->resy > 0)) {
horizResolution = priv->resx;
vertResolution = priv->resy;
}
/* set the parameters */
pars->left_edge = xf86SetIntOption(opts, "LeftEdge", l);
pars->right_edge = xf86SetIntOption(opts, "RightEdge", r);
pars->top_edge = xf86SetIntOption(opts, "TopEdge", t);
pars->bottom_edge = xf86SetIntOption(opts, "BottomEdge", b);
pars->area_top_edge =
set_percent_option(opts, "AreaTopEdge", height, priv->miny, 0);
pars->area_bottom_edge =
set_percent_option(opts, "AreaBottomEdge", height, priv->miny, 0);
pars->area_left_edge =
set_percent_option(opts, "AreaLeftEdge", width, priv->minx, 0);
pars->area_right_edge =
set_percent_option(opts, "AreaRightEdge", width, priv->minx, 0);
pars->hyst_x =
set_percent_option(opts, "HorizHysteresis", width, 0, horizHyst);
pars->hyst_y =
set_percent_option(opts, "VertHysteresis", height, 0, vertHyst);
pars->finger_low = xf86SetIntOption(opts, "FingerLow", fingerLow);
pars->finger_high = xf86SetIntOption(opts, "FingerHigh", fingerHigh);
pars->tap_time = xf86SetIntOption(opts, "MaxTapTime", 180);
pars->tap_move = xf86SetIntOption(opts, "MaxTapMove", tapMove);
pars->tap_time_2 = xf86SetIntOption(opts, "MaxDoubleTapTime", 180);
pars->click_time = xf86SetIntOption(opts, "ClickTime", 100);
pars->clickpad = xf86SetBoolOption(opts, "ClickPad", pars->clickpad); /* Probed */
if (pars->clickpad)
pars->has_secondary_buttons = xf86SetBoolOption(opts,
"HasSecondarySoftButtons",
pars->has_secondary_buttons);
pars->clickpad_ignore_motion_time = 100; /* ms */
/* middle mouse button emulation on a clickpad? nah, you're joking */
middle_button_timeout = pars->clickpad ? 0 : 75;
pars->emulate_mid_button_time =
xf86SetIntOption(opts, "EmulateMidButtonTime", middle_button_timeout);
pars->emulate_twofinger_z =
xf86SetIntOption(opts, "EmulateTwoFingerMinZ", emulateTwoFingerMinZ);
pars->emulate_twofinger_w =
xf86SetIntOption(opts, "EmulateTwoFingerMinW", emulateTwoFingerMinW);
pars->scroll_dist_vert =
xf86SetIntOption(opts, "VertScrollDelta", vertScrollDelta);
pars->scroll_dist_horiz =
xf86SetIntOption(opts, "HorizScrollDelta", horizScrollDelta);
pars->scroll_edge_vert =
xf86SetBoolOption(opts, "VertEdgeScroll", vertEdgeScroll);
pars->scroll_edge_horiz =
xf86SetBoolOption(opts, "HorizEdgeScroll", horizEdgeScroll);
pars->scroll_edge_corner = xf86SetBoolOption(opts, "CornerCoasting", FALSE);
pars->scroll_twofinger_vert =
xf86SetBoolOption(opts, "VertTwoFingerScroll", vertTwoFingerScroll);
pars->scroll_twofinger_horiz =
xf86SetBoolOption(opts, "HorizTwoFingerScroll", horizTwoFingerScroll);
pars->touchpad_off = xf86SetIntOption(opts, "TouchpadOff", TOUCHPAD_ON);
if (priv->has_scrollbuttons) {
pars->updown_button_scrolling =
xf86SetBoolOption(opts, "UpDownScrolling", TRUE);
pars->leftright_button_scrolling =
xf86SetBoolOption(opts, "LeftRightScrolling", TRUE);
pars->updown_button_repeat =
xf86SetBoolOption(opts, "UpDownScrollRepeat", TRUE);
pars->leftright_button_repeat =
xf86SetBoolOption(opts, "LeftRightScrollRepeat", TRUE);
}
pars->scroll_button_repeat =
xf86SetIntOption(opts, "ScrollButtonRepeat", 100);
pars->locked_drags = xf86SetBoolOption(opts, "LockedDrags", FALSE);
pars->locked_drag_time = xf86SetIntOption(opts, "LockedDragTimeout", 5000);
pars->tap_action[RT_TAP] = xf86SetIntOption(opts, "RTCornerButton", 0);
pars->tap_action[RB_TAP] = xf86SetIntOption(opts, "RBCornerButton", 0);
pars->tap_action[LT_TAP] = xf86SetIntOption(opts, "LTCornerButton", 0);
pars->tap_action[LB_TAP] = xf86SetIntOption(opts, "LBCornerButton", 0);
pars->tap_action[F1_TAP] = xf86SetIntOption(opts, "TapButton1", tapButton1);
pars->tap_action[F2_TAP] = xf86SetIntOption(opts, "TapButton2", tapButton2);
pars->tap_action[F3_TAP] = xf86SetIntOption(opts, "TapButton3", tapButton3);
pars->click_action[F1_CLICK1] =
xf86SetIntOption(opts, "ClickFinger1", clickFinger1);
pars->click_action[F2_CLICK1] =
xf86SetIntOption(opts, "ClickFinger2", clickFinger2);
pars->click_action[F3_CLICK1] =
xf86SetIntOption(opts, "ClickFinger3", clickFinger3);
pars->circular_scrolling =
xf86SetBoolOption(opts, "CircularScrolling", FALSE);
pars->circular_trigger = xf86SetIntOption(opts, "CircScrollTrigger", 0);
pars->circular_pad = xf86SetBoolOption(opts, "CircularPad", FALSE);
pars->palm_detect = xf86SetBoolOption(opts, "PalmDetect", FALSE);
pars->palm_min_width = xf86SetIntOption(opts, "PalmMinWidth", palmMinWidth);
pars->palm_min_z = xf86SetIntOption(opts, "PalmMinZ", palmMinZ);
pars->single_tap_timeout = xf86SetIntOption(opts, "SingleTapTimeout", 180);
pars->press_motion_min_z =
xf86SetIntOption(opts, "PressureMotionMinZ", pressureMotionMinZ);
pars->press_motion_max_z =
xf86SetIntOption(opts, "PressureMotionMaxZ", pressureMotionMaxZ);
pars->min_speed = xf86SetRealOption(opts, "MinSpeed", 0.4);
pars->max_speed = xf86SetRealOption(opts, "MaxSpeed", 0.7);
pars->accl = xf86SetRealOption(opts, "AccelFactor", accelFactor);
pars->scroll_dist_circ = xf86SetRealOption(opts, "CircScrollDelta", 0.1);
pars->coasting_speed = xf86SetRealOption(opts, "CoastingSpeed", 20.0);
pars->coasting_friction = xf86SetRealOption(opts, "CoastingFriction", 50);
pars->press_motion_min_factor =
xf86SetRealOption(opts, "PressureMotionMinFactor", 1.0);
pars->press_motion_max_factor =
xf86SetRealOption(opts, "PressureMotionMaxFactor", 1.0);
/* Only grab the device by default if it's not coming from a config
backend. This way we avoid the device being added twice and sending
duplicate events.
*/
source = xf86CheckStrOption(opts, "_source", NULL);
if (source == NULL || strncmp(source, "server/", 7) != 0)
grab_event_device = TRUE;
pars->grab_event_device = xf86SetBoolOption(opts, "GrabEventDevice", grab_event_device);
pars->tap_and_drag_gesture =
xf86SetBoolOption(opts, "TapAndDragGesture", TRUE);
pars->resolution_horiz =
xf86SetIntOption(opts, "HorizResolution", horizResolution);
pars->resolution_vert =
xf86SetIntOption(opts, "VertResolution", vertResolution);
if (pars->resolution_horiz <= 0) {
xf86IDrvMsg(pInfo, X_ERROR,
"Invalid X resolution, using 1 instead.\n");
pars->resolution_horiz = 1;
}
if (pars->resolution_vert <= 0) {
xf86IDrvMsg(pInfo, X_ERROR,
"Invalid Y resolution, using 1 instead.\n");
pars->resolution_vert = 1;
}
/* Touchpad sampling rate is too low to detect all movements.
A user may lift one finger and put another one down within the same
EV_SYN or even between samplings so the driver doesn't notice at all.
We limit the movement to 20 mm within one event, that is more than
recordings showed is needed (17mm on a T440).
*/
if (pars->resolution_horiz > 1 &&
pars->resolution_vert > 1)
pars->maxDeltaMM = 20;
else {
/* on devices without resolution set the vector length to 0.25 of
the touchpad diagonal */
pars->maxDeltaMM = diag * 0.25;
}
/* Warn about (and fix) incorrectly configured TopEdge/BottomEdge parameters */
if (pars->top_edge > pars->bottom_edge) {
int tmp = pars->top_edge;
pars->top_edge = pars->bottom_edge;
pars->bottom_edge = tmp;
xf86IDrvMsg(pInfo, X_WARNING,
"TopEdge is bigger than BottomEdge. Fixing.\n");
}
set_primary_softbutton_areas_option(pInfo);
if (pars->has_secondary_buttons)
set_secondary_softbutton_areas_option(pInfo);
}
static double
SynapticsAccelerationProfile(DeviceIntPtr dev,
DeviceVelocityPtr vel,
double velocity, double thr, double acc)
{
InputInfoPtr pInfo = dev->public.devicePrivate;
SynapticsPrivate *priv = (SynapticsPrivate *) (pInfo->private);
SynapticsParameters *para = &priv->synpara;
double accelfct;
/*
* synaptics accel was originally base on device coordinate based
* velocity, which we recover this way so para->accl retains its scale.
*/
velocity /= vel->const_acceleration;
/* speed up linear with finger velocity */
accelfct = velocity * para->accl;
/* clip acceleration factor */
if (accelfct > para->max_speed * acc)
accelfct = para->max_speed * acc;
else if (accelfct < para->min_speed)
accelfct = para->min_speed;
/* modify speed according to pressure */
if (priv->moving_state == MS_TOUCHPAD_RELATIVE) {
int minZ = para->press_motion_min_z;
int maxZ = para->press_motion_max_z;
double minFctr = para->press_motion_min_factor;
double maxFctr = para->press_motion_max_factor;
if (priv->hwState->z <= minZ) {
accelfct *= minFctr;
}
else if (priv->hwState->z >= maxZ) {
accelfct *= maxFctr;
}
else {
accelfct *=
minFctr + (priv->hwState->z - minZ) * (maxFctr -
minFctr) / (maxZ - minZ);
}
}
return accelfct;
}
static int
SynapticsPreInit(InputDriverPtr drv, InputInfoPtr pInfo, int flags)
{
SynapticsPrivate *priv;
/* allocate memory for SynapticsPrivateRec */
priv = calloc(1, sizeof(SynapticsPrivate));
if (!priv)
return BadAlloc;
pInfo->type_name = XI_TOUCHPAD;
pInfo->device_control = DeviceControl;
pInfo->read_input = ReadInput;
pInfo->control_proc = ControlProc;
pInfo->switch_mode = SwitchMode;
pInfo->private = priv;
/* allocate now so we don't allocate in the signal handler */
priv->timer = TimerSet(NULL, 0, 0, NULL, NULL);
if (!priv->timer) {
free(priv);
return BadAlloc;
}
/* may change pInfo->options */
if (!SetDeviceAndProtocol(pInfo)) {
xf86IDrvMsg(pInfo, X_ERROR,
"Synaptics driver unable to detect protocol\n");
goto SetupProc_fail;
}
priv->device = xf86FindOptionValue(pInfo->options, "Device");
/* open the touchpad device */
pInfo->fd = xf86OpenSerial(pInfo->options);
if (pInfo->fd == -1) {
xf86IDrvMsg(pInfo, X_ERROR, "Synaptics driver unable to open device\n");
goto SetupProc_fail;
}
xf86ErrorFVerb(6, "port opened successfully\n");
/* initialize variables */
priv->repeatButtons = 0;
priv->nextRepeat = 0;
priv->count_packet_finger = 0;
priv->tap_state = TS_START;
priv->tap_button = 0;
priv->tap_button_state = TBS_BUTTON_UP;
priv->touch_on.millis = 0;
priv->synpara.hyst_x = -1;
priv->synpara.hyst_y = -1;
/* read hardware dimensions */
ReadDevDimensions(pInfo);
set_default_parameters(pInfo);
#ifndef NO_DRIVER_SCALING
CalculateScalingCoeffs(priv);
#endif
priv->comm.buffer = XisbNew(pInfo->fd, INPUT_BUFFER_SIZE);
if (!QueryHardware(pInfo)) {
xf86IDrvMsg(pInfo, X_ERROR,
"Unable to query/initialize Synaptics hardware.\n");
goto SetupProc_fail;
}
xf86ProcessCommonOptions(pInfo, pInfo->options);
if (priv->comm.buffer) {
XisbFree(priv->comm.buffer);
priv->comm.buffer = NULL;
}
SynapticsCloseFd(pInfo);
return Success;
SetupProc_fail:
SynapticsCloseFd(pInfo);
if (priv->comm.buffer)
XisbFree(priv->comm.buffer);
free(priv->proto_data);
free(priv->timer);
free(priv);
pInfo->private = NULL;
return BadAlloc;
}
/*
* Uninitialize the device.
*/
static void
SynapticsUnInit(InputDriverPtr drv, InputInfoPtr pInfo, int flags)
{
SynapticsPrivate *priv = ((SynapticsPrivate *) pInfo->private);
if (priv && priv->timer)
free(priv->timer);
if (priv && priv->proto_data)
free(priv->proto_data);
if (priv && priv->scroll_events_mask)
valuator_mask_free(&priv->scroll_events_mask);
if (priv && priv->open_slots)
free(priv->open_slots);
free(pInfo->private);
pInfo->private = NULL;
xf86DeleteInput(pInfo, 0);
}
/*
* Alter the control parameters for the mouse. Note that all special
* protocol values are handled by dix.
*/
static void
SynapticsCtrl(DeviceIntPtr device, PtrCtrl * ctrl)
{
}
static int
DeviceControl(DeviceIntPtr dev, int mode)
{
Bool RetValue;
switch (mode) {
case DEVICE_INIT:
RetValue = DeviceInit(dev);
break;
case DEVICE_ON:
RetValue = DeviceOn(dev);
break;
case DEVICE_OFF:
RetValue = DeviceOff(dev);
break;
case DEVICE_CLOSE:
RetValue = DeviceClose(dev);
break;
default:
RetValue = BadValue;
}
return RetValue;
}
static int
DeviceOn(DeviceIntPtr dev)
{
InputInfoPtr pInfo = dev->public.devicePrivate;
SynapticsPrivate *priv = (SynapticsPrivate *) (pInfo->private);
DBG(3, "Synaptics DeviceOn called\n");
pInfo->fd = xf86OpenSerial(pInfo->options);
if (pInfo->fd == -1) {
xf86IDrvMsg(pInfo, X_WARNING, "cannot open input device\n");
return !Success;
}
if (priv->proto_ops->DeviceOnHook &&
!priv->proto_ops->DeviceOnHook(pInfo, &priv->synpara))
goto error;
priv->comm.buffer = XisbNew(pInfo->fd, INPUT_BUFFER_SIZE);
if (!priv->comm.buffer)
goto error;
xf86FlushInput(pInfo->fd);
/* reinit the pad */
if (!QueryHardware(pInfo))
goto error;
xf86AddEnabledDevice(pInfo);
dev->public.on = TRUE;
return Success;
error:
if (priv->comm.buffer) {
XisbFree(priv->comm.buffer);
priv->comm.buffer = NULL;
}
SynapticsCloseFd(pInfo);
return !Success;
}
static void
SynapticsReset(SynapticsPrivate * priv)
{
int i;
SynapticsResetHwState(priv->hwState);
SynapticsResetHwState(priv->local_hw_state);
SynapticsResetHwState(priv->comm.hwState);
memset(priv->move_hist, 0, sizeof(priv->move_hist));
priv->hyst_center_x = 0;
priv->hyst_center_y = 0;
memset(&priv->scroll, 0, sizeof(priv->scroll));
priv->count_packet_finger = 0;
priv->finger_state = FS_UNTOUCHED;
priv->last_motion_millis = 0;
priv->clickpad_click_millis = 0;
priv->last_button_area = NO_BUTTON_AREA;
priv->tap_state = TS_START;
priv->tap_button = 0;
priv->tap_button_state = TBS_BUTTON_UP;
priv->moving_state = MS_FALSE;
priv->vert_scroll_edge_on = FALSE;
priv->horiz_scroll_edge_on = FALSE;
priv->vert_scroll_twofinger_on = FALSE;
priv->horiz_scroll_twofinger_on = FALSE;
priv->circ_scroll_on = FALSE;
priv->circ_scroll_vert = FALSE;
priv->mid_emu_state = MBE_OFF;
priv->nextRepeat = 0;
priv->lastButtons = 0;
priv->prev_z = 0;
priv->prevFingers = 0;
priv->num_active_touches = 0;
for (i = 0; i < priv->num_slots; i++)
priv->open_slots[i] = -1;
}
static int
DeviceOff(DeviceIntPtr dev)
{
InputInfoPtr pInfo = dev->public.devicePrivate;
SynapticsPrivate *priv = (SynapticsPrivate *) (pInfo->private);
Bool rc = Success;
DBG(3, "Synaptics DeviceOff called\n");
if (pInfo->fd != -1) {
TimerCancel(priv->timer);
xf86RemoveEnabledDevice(pInfo);
SynapticsReset(priv);
if (priv->proto_ops->DeviceOffHook &&
!priv->proto_ops->DeviceOffHook(pInfo))
rc = !Success;
if (priv->comm.buffer) {
XisbFree(priv->comm.buffer);
priv->comm.buffer = NULL;
}
SynapticsCloseFd(pInfo);
}
dev->public.on = FALSE;
return rc;
}
static int
DeviceClose(DeviceIntPtr dev)
{
Bool RetValue;
InputInfoPtr pInfo = dev->public.devicePrivate;
SynapticsPrivate *priv = (SynapticsPrivate *) pInfo->private;
RetValue = DeviceOff(dev);
TimerFree(priv->timer);
priv->timer = NULL;
free(priv->touch_axes);
priv->touch_axes = NULL;
SynapticsHwStateFree(&priv->hwState);
SynapticsHwStateFree(&priv->local_hw_state);
SynapticsHwStateFree(&priv->comm.hwState);
return RetValue;
}
static void
InitAxesLabels(Atom *labels, int nlabels, const SynapticsPrivate * priv)
{
int i;
memset(labels, 0, nlabels * sizeof(Atom));
switch (nlabels) {
default:
case 4:
labels[3] = XIGetKnownProperty(AXIS_LABEL_PROP_REL_VSCROLL);
case 3:
labels[2] = XIGetKnownProperty(AXIS_LABEL_PROP_REL_HSCROLL);
case 2:
labels[1] = XIGetKnownProperty(AXIS_LABEL_PROP_REL_Y);
case 1:
labels[0] = XIGetKnownProperty(AXIS_LABEL_PROP_REL_X);
break;
}
for (i = 0; i < priv->num_mt_axes; i++) {
SynapticsTouchAxisRec *axis = &priv->touch_axes[i];
int axnum = nlabels - priv->num_mt_axes + i;
labels[axnum] = XIGetKnownProperty(axis->label);
}
}
static void
InitButtonLabels(Atom *labels, int nlabels)
{
memset(labels, 0, nlabels * sizeof(Atom));
switch (nlabels) {
default:
case 7:
labels[6] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_HWHEEL_RIGHT);
case 6:
labels[5] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_HWHEEL_LEFT);
case 5:
labels[4] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_WHEEL_DOWN);
case 4:
labels[3] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_WHEEL_UP);
case 3:
labels[2] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_RIGHT);
case 2:
labels[1] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_MIDDLE);
case 1:
labels[0] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_LEFT);
break;
}
}
static void
DeviceInitTouch(DeviceIntPtr dev, Atom *axes_labels)
{
InputInfoPtr pInfo = dev->public.devicePrivate;
SynapticsPrivate *priv = (SynapticsPrivate *) (pInfo->private);
if (!priv->has_touch)
return;
priv->num_slots =
priv->max_touches ? priv->max_touches : SYNAPTICS_MAX_TOUCHES;
priv->open_slots = malloc(priv->num_slots * sizeof(int));
if (!priv->open_slots) {
xf86IDrvMsg(pInfo, X_ERROR,
"failed to allocate open touch slots array\n");
priv->has_touch = 0;
priv->num_slots = 0;
}
}
static int
DeviceInit(DeviceIntPtr dev)
{
InputInfoPtr pInfo = dev->public.devicePrivate;
SynapticsPrivate *priv = (SynapticsPrivate *) (pInfo->private);
Atom float_type, prop;
float tmpf;
unsigned char map[SYN_MAX_BUTTONS + 1];
int i;
int min, max;
int num_axes = 2;
Atom btn_labels[SYN_MAX_BUTTONS] = { 0 };
Atom *axes_labels;
DeviceVelocityPtr pVel;
num_axes += 2;
num_axes += priv->num_mt_axes;
axes_labels = calloc(num_axes, sizeof(Atom));
if (!axes_labels) {
xf86IDrvMsg(pInfo, X_ERROR, "failed to allocate axis labels\n");
return !Success;
}
InitAxesLabels(axes_labels, num_axes, priv);
InitButtonLabels(btn_labels, SYN_MAX_BUTTONS);
DBG(3, "Synaptics DeviceInit called\n");
for (i = 0; i <= SYN_MAX_BUTTONS; i++)
map[i] = i;
dev->public.on = FALSE;
InitPointerDeviceStruct((DevicePtr) dev, map,
SYN_MAX_BUTTONS,
btn_labels,
SynapticsCtrl,
GetMotionHistorySize(), num_axes, axes_labels);
/*
* setup dix acceleration to match legacy synaptics settings, and
* etablish a device-specific profile to do stuff like pressure-related
* acceleration.
*/
if (NULL != (pVel = GetDevicePredictableAccelData(dev))) {
SetDeviceSpecificAccelerationProfile(pVel,
SynapticsAccelerationProfile);
/* float property type */
float_type = XIGetKnownProperty(XATOM_FLOAT);
/* translate MinAcc to constant deceleration.
* May be overridden in xf86InitValuatorDefaults */
tmpf = 1.0 / priv->synpara.min_speed;
xf86IDrvMsg(pInfo, X_CONFIG,
"(accel) MinSpeed is now constant deceleration " "%.1f\n",
tmpf);
prop = XIGetKnownProperty(ACCEL_PROP_CONSTANT_DECELERATION);
XIChangeDeviceProperty(dev, prop, float_type, 32,
PropModeReplace, 1, &tmpf, FALSE);
/* adjust accordingly */
priv->synpara.max_speed /= priv->synpara.min_speed;
priv->synpara.min_speed = 1.0;
/* synaptics seems to report 80 packet/s, but dix scales for
* 100 packet/s by default. */
pVel->corr_mul = 12.5f; /*1000[ms]/80[/s] = 12.5 */
xf86IDrvMsg(pInfo, X_CONFIG, "(accel) MaxSpeed is now %.2f\n",
priv->synpara.max_speed);
xf86IDrvMsg(pInfo, X_CONFIG, "(accel) AccelFactor is now %.3f\n",
priv->synpara.accl);
prop = XIGetKnownProperty(ACCEL_PROP_PROFILE_NUMBER);
i = AccelProfileDeviceSpecific;
XIChangeDeviceProperty(dev, prop, XA_INTEGER, 32,
PropModeReplace, 1, &i, FALSE);
}
/* X valuator */
if (priv->minx < priv->maxx) {
min = priv->minx;
max = priv->maxx;
}
else {
min = 0;
max = -1;
}
xf86InitValuatorAxisStruct(dev, 0, axes_labels[0], min, max,
priv->resx * 1000, 0, priv->resx * 1000,
Relative);
xf86InitValuatorDefaults(dev, 0);
/* Y valuator */
if (priv->miny < priv->maxy) {
min = priv->miny;
max = priv->maxy;
}
else {
min = 0;
max = -1;
}
xf86InitValuatorAxisStruct(dev, 1, axes_labels[1], min, max,
priv->resy * 1000, 0, priv->resy * 1000,
Relative);
xf86InitValuatorDefaults(dev, 1);
xf86InitValuatorAxisStruct(dev, 2, axes_labels[2], 0, -1, 0, 0, 0,
Relative);
priv->scroll_axis_horiz = 2;
xf86InitValuatorAxisStruct(dev, 3, axes_labels[3], 0, -1, 0, 0, 0,
Relative);
priv->scroll_axis_vert = 3;
priv->scroll_events_mask = valuator_mask_new(MAX_VALUATORS);
if (!priv->scroll_events_mask) {
free(axes_labels);
return !Success;
}
SetScrollValuator(dev, priv->scroll_axis_horiz, SCROLL_TYPE_HORIZONTAL,
priv->synpara.scroll_dist_horiz, 0);
SetScrollValuator(dev, priv->scroll_axis_vert, SCROLL_TYPE_VERTICAL,
priv->synpara.scroll_dist_vert, 0);
DeviceInitTouch(dev, axes_labels);
free(axes_labels);
priv->hwState = SynapticsHwStateAlloc(priv);
if (!priv->hwState)
goto fail;
priv->local_hw_state = SynapticsHwStateAlloc(priv);
if (!priv->local_hw_state)
goto fail;
priv->comm.hwState = SynapticsHwStateAlloc(priv);
InitDeviceProperties(pInfo);
XIRegisterPropertyHandler(pInfo->dev, SetProperty, NULL, NULL);
SynapticsReset(priv);
return Success;
fail:
free(priv->local_hw_state);
free(priv->hwState);
free(priv->open_slots);
return !Success;
}
/*
* Convert from absolute X/Y coordinates to a coordinate system where
* -1 corresponds to the left/upper edge and +1 corresponds to the
* right/lower edge.
*/
static void
relative_coords(SynapticsPrivate * priv, int x, int y,
double *relX, double *relY)
{
int minX = priv->synpara.left_edge;
int maxX = priv->synpara.right_edge;
int minY = priv->synpara.top_edge;
int maxY = priv->synpara.bottom_edge;
double xCenter = (minX + maxX) / 2.0;
double yCenter = (minY + maxY) / 2.0;
if ((maxX - xCenter > 0) && (maxY - yCenter > 0)) {
*relX = (x - xCenter) / (maxX - xCenter);
*relY = (y - yCenter) / (maxY - yCenter);
}
else {
*relX = 0;
*relY = 0;
}
}
/* return angle of point relative to center */
static double
angle(SynapticsPrivate * priv, int x, int y)
{
double xCenter = (priv->synpara.left_edge + priv->synpara.right_edge) / 2.0;
double yCenter = (priv->synpara.top_edge + priv->synpara.bottom_edge) / 2.0;
return atan2(-(y - yCenter), x - xCenter);
}
/* return angle difference */
static double
diffa(double a1, double a2)
{
double da = fmod(a2 - a1, 2 * M_PI);
if (da < 0)
da += 2 * M_PI;
if (da > M_PI)
da -= 2 * M_PI;
return da;
}
static enum EdgeType
circular_edge_detection(SynapticsPrivate * priv, int x, int y)
{
enum EdgeType edge = 0;
double relX, relY, relR;
relative_coords(priv, x, y, &relX, &relY);
relR = SQR(relX) + SQR(relY);
if (relR > 1) {
/* we are outside the ellipse enclosed by the edge parameters */
if (relX > M_SQRT1_2)
edge |= RIGHT_EDGE;
else if (relX < -M_SQRT1_2)
edge |= LEFT_EDGE;
if (relY < -M_SQRT1_2)
edge |= TOP_EDGE;
else if (relY > M_SQRT1_2)
edge |= BOTTOM_EDGE;
}
return edge;
}
static enum EdgeType
edge_detection(SynapticsPrivate * priv, int x, int y)
{
enum EdgeType edge = NO_EDGE;
if (priv->synpara.circular_pad)
return circular_edge_detection(priv, x, y);
if (x > priv->synpara.right_edge)
edge |= RIGHT_EDGE;
else if (x < priv->synpara.left_edge)
edge |= LEFT_EDGE;
if (y < priv->synpara.top_edge)
edge |= TOP_EDGE;
else if (y > priv->synpara.bottom_edge)
edge |= BOTTOM_EDGE;
return edge;
}
/* Checks whether coordinates are in the Synaptics Area
* or not. If no Synaptics Area is defined (i.e. if
* priv->synpara.area_{left|right|top|bottom}_edge are
* all set to zero), the function returns TRUE.
*/
static Bool
is_inside_active_area(SynapticsPrivate * priv, int x, int y)
{
Bool inside_area = TRUE;
/* If a finger is down, then it must have started inside the active_area,
allow the motion to complete using the entire area */
if (priv->finger_state >= FS_TOUCHED)
return TRUE;
if ((priv->synpara.area_left_edge != 0) &&
(x < priv->synpara.area_left_edge))
inside_area = FALSE;
else if ((priv->synpara.area_right_edge != 0) &&
(x > priv->synpara.area_right_edge))
inside_area = FALSE;
if ((priv->synpara.area_top_edge != 0) && (y < priv->synpara.area_top_edge))
inside_area = FALSE;
else if ((priv->synpara.area_bottom_edge != 0) &&
(y > priv->synpara.area_bottom_edge))
inside_area = FALSE;
return inside_area;
}
static Bool
is_inside_button_area(SynapticsParameters * para, int which, int x, int y)
{
Bool inside_area = TRUE;
if (para->softbutton_areas[which][LEFT] == 0 &&
para->softbutton_areas[which][RIGHT] == 0 &&
para->softbutton_areas[which][TOP] == 0 &&
para->softbutton_areas[which][BOTTOM] == 0)
return FALSE;
if (para->softbutton_areas[which][LEFT] &&
x < para->softbutton_areas[which][LEFT])
inside_area = FALSE;
else if (para->softbutton_areas[which][RIGHT] &&
x > para->softbutton_areas[which][RIGHT])
inside_area = FALSE;
else if (para->softbutton_areas[which][TOP] &&
y < para->softbutton_areas[which][TOP])
inside_area = FALSE;
else if (para->softbutton_areas[which][BOTTOM] &&
y > para->softbutton_areas[which][BOTTOM])
inside_area = FALSE;
return inside_area;
}
static Bool
is_inside_rightbutton_area(SynapticsParameters * para, int x, int y)
{
return is_inside_button_area(para, BOTTOM_RIGHT_BUTTON_AREA, x, y);
}
static Bool
is_inside_middlebutton_area(SynapticsParameters * para, int x, int y)
{
return is_inside_button_area(para, BOTTOM_MIDDLE_BUTTON_AREA, x, y);
}
static Bool
is_inside_sec_rightbutton_area(SynapticsParameters * para, int x, int y)
{
return is_inside_button_area(para, TOP_RIGHT_BUTTON_AREA, x, y);
}
static Bool
is_inside_sec_middlebutton_area(SynapticsParameters * para, int x, int y)
{
return is_inside_button_area(para, TOP_MIDDLE_BUTTON_AREA, x, y);
}
static Bool
is_inside_top_or_bottom_button_area(SynapticsParameters * para, int offset,
int x, int y)
{
Bool inside_area = TRUE;
Bool right_valid, middle_valid;
int top, bottom;
/* We don't have a left button area, so we only check the y axis */
right_valid = para->softbutton_areas[offset][TOP] ||
para->softbutton_areas[offset][BOTTOM];
middle_valid = para->softbutton_areas[offset + 1][TOP] ||
para->softbutton_areas[offset + 1][BOTTOM];
if (!right_valid && !middle_valid)
return FALSE;
/* Check both buttons are horizontally aligned */
if (right_valid && middle_valid && (
para->softbutton_areas[offset][TOP] !=
para->softbutton_areas[offset + 1][TOP] ||
para->softbutton_areas[offset][BOTTOM] !=
para->softbutton_areas[offset + 1][BOTTOM]))
return FALSE;
if (right_valid) {
top = para->softbutton_areas[offset][TOP];
bottom = para->softbutton_areas[offset][BOTTOM];
}
else {
top = para->softbutton_areas[offset + 1][TOP];
bottom = para->softbutton_areas[offset + 1][BOTTOM];
}
if (top && y < top)
inside_area = FALSE;
else if (bottom && y > bottom)
inside_area = FALSE;
return inside_area;
}
static enum SoftButtonAreas
current_button_area(SynapticsParameters * para, int x, int y)
{
if (is_inside_top_or_bottom_button_area(para, BOTTOM_BUTTON_AREA, x, y))
return BOTTOM_BUTTON_AREA;
else if (is_inside_top_or_bottom_button_area(para, TOP_BUTTON_AREA, x, y))
return TOP_BUTTON_AREA;
else
return NO_BUTTON_AREA;
}
static CARD32
timerFunc(OsTimerPtr timer, CARD32 now, pointer arg)
{
InputInfoPtr pInfo = arg;
SynapticsPrivate *priv = (SynapticsPrivate *) (pInfo->private);
struct SynapticsHwState *hw = priv->local_hw_state;
int delay;
#if !HAVE_THREADED_INPUT
int sigstate = xf86BlockSIGIO();
#else
input_lock();
#endif
priv->hwState->millis += now - priv->timer_time;
SynapticsCopyHwState(hw, priv->hwState);
SynapticsResetTouchHwState(hw, FALSE);
delay = HandleState(pInfo, hw, hw->millis, TRUE);
priv->timer_time = now;
priv->timer = TimerSet(priv->timer, 0, delay, timerFunc, pInfo);
#if !HAVE_THREADED_INPUT
xf86UnblockSIGIO(sigstate);
#else
input_unlock();
#endif
return 0;
}
static int
clamp(int val, int min, int max)
{
if (val < min)
return min;
else if (val < max)
return val;
else
return max;
}
static Bool
SynapticsGetHwState(InputInfoPtr pInfo, SynapticsPrivate * priv,
struct SynapticsHwState *hw)
{
return priv->proto_ops->ReadHwState(pInfo, &priv->comm, hw);
}
/*
* called for each full received packet from the touchpad
*/
static void
ReadInput(InputInfoPtr pInfo)
{
SynapticsPrivate *priv = (SynapticsPrivate *) (pInfo->private);
struct SynapticsHwState *hw = priv->local_hw_state;
int delay = 0;
Bool newDelay = FALSE;
SynapticsResetTouchHwState(hw, FALSE);
while (SynapticsGetHwState(pInfo, priv, hw)) {
/* Semi-mt device touch slots do not track touches. When there is a
* change in the number of touches, we must disregard the temporary
* motion changes. */
if (priv->has_semi_mt && hw->numFingers != priv->hwState->numFingers) {
hw->cumulative_dx = priv->hwState->cumulative_dx;
hw->cumulative_dy = priv->hwState->cumulative_dy;
}
/* timer may cause actual events to lag behind (#48777) */
if (priv->hwState->millis > hw->millis)
hw->millis = priv->hwState->millis;
SynapticsCopyHwState(priv->hwState, hw);
delay = HandleState(pInfo, hw, hw->millis, FALSE);
newDelay = TRUE;
}
if (newDelay) {
priv->timer_time = GetTimeInMillis();
priv->timer = TimerSet(priv->timer, 0, delay, timerFunc, pInfo);
}
}
static int
HandleMidButtonEmulation(SynapticsPrivate * priv, struct SynapticsHwState *hw,
CARD32 now, int *delay)
{
SynapticsParameters *para = &priv->synpara;
Bool done = FALSE;
int timeleft;
int mid = 0;
if (para->emulate_mid_button_time <= 0)
return mid;
while (!done) {
switch (priv->mid_emu_state) {
case MBE_LEFT_CLICK:
case MBE_RIGHT_CLICK:
case MBE_OFF:
priv->button_delay_millis = now;
if (hw->left) {
priv->mid_emu_state = MBE_LEFT;
}
else if (hw->right) {
priv->mid_emu_state = MBE_RIGHT;
}
else {
done = TRUE;
}
break;
case MBE_LEFT:
timeleft =
TIME_DIFF(priv->button_delay_millis +
para->emulate_mid_button_time, now);
if (timeleft > 0)
*delay = MIN(*delay, timeleft);
/* timeout, but within the same ReadInput cycle! */
if ((timeleft <= 0) && !hw->left) {
priv->mid_emu_state = MBE_LEFT_CLICK;
done = TRUE;
}
else if ((!hw->left) || (timeleft <= 0)) {
hw->left = TRUE;
priv->mid_emu_state = MBE_TIMEOUT;
done = TRUE;
}
else if (hw->right) {
priv->mid_emu_state = MBE_MID;
}
else {
hw->left = FALSE;
done = TRUE;
}
break;
case MBE_RIGHT:
timeleft =
TIME_DIFF(priv->button_delay_millis +
para->emulate_mid_button_time, now);
if (timeleft > 0)
*delay = MIN(*delay, timeleft);
/* timeout, but within the same ReadInput cycle! */
if ((timeleft <= 0) && !hw->right) {
priv->mid_emu_state = MBE_RIGHT_CLICK;
done = TRUE;
}
else if (!hw->right || (timeleft <= 0)) {
hw->right = TRUE;
priv->mid_emu_state = MBE_TIMEOUT;
done = TRUE;
}
else if (hw->left) {
priv->mid_emu_state = MBE_MID;
}
else {
hw->right = FALSE;
done = TRUE;
}
break;
case MBE_MID:
if (!hw->left && !hw->right) {
priv->mid_emu_state = MBE_OFF;
}
else {
mid = TRUE;
hw->left = hw->right = FALSE;
done = TRUE;
}
break;
case MBE_TIMEOUT:
if (!hw->left && !hw->right) {
priv->mid_emu_state = MBE_OFF;
}
else {
done = TRUE;
}
}
}
return mid;
}
static enum FingerState
SynapticsDetectFinger(SynapticsPrivate * priv, struct SynapticsHwState *hw)
{
SynapticsParameters *para = &priv->synpara;
enum FingerState finger;
/* finger detection thru pressure and threshold */
if (hw->z < para->finger_low)
return FS_UNTOUCHED;
if (priv->finger_state == FS_BLOCKED)
return FS_BLOCKED;
if (hw->z > para->finger_high && priv->finger_state == FS_UNTOUCHED)
finger = FS_TOUCHED;
else
finger = priv->finger_state;
if (!para->palm_detect)
return finger;
/* palm detection */
if ((hw->z > para->palm_min_z) && (hw->fingerWidth > para->palm_min_width))
return FS_BLOCKED;
if (priv->has_mt_palm_detect)
return finger;
if (hw->x == 0 || priv->finger_state == FS_UNTOUCHED)
priv->avg_width = 0;
else
priv->avg_width += (hw->fingerWidth - priv->avg_width + 1) / 2;
if (finger != FS_UNTOUCHED && priv->finger_state == FS_UNTOUCHED) {
int safe_width = MAX(hw->fingerWidth, priv->avg_width);
if (hw->numFingers > 1 || /* more than one finger -> not a palm */
((safe_width < 6) && (priv->prev_z < para->finger_high)) || /* thin finger, distinct touch -> not a palm */
((safe_width < 7) && (priv->prev_z < para->finger_high / 2))) { /* thin finger, distinct touch -> not a palm */
/* leave finger value as is */
}
else if (hw->z > priv->prev_z + 1) /* z not stable, may be a palm */
finger = FS_UNTOUCHED;
else if (hw->z < priv->prev_z - 5) /* z not stable, may be a palm */
finger = FS_UNTOUCHED;
else if (hw->fingerWidth > para->palm_min_width) /* finger width too large -> probably palm */
finger = FS_UNTOUCHED;
}
priv->prev_z = hw->z;
return finger;
}
static void
SelectTapButton(SynapticsPrivate * priv, enum EdgeType edge)
{
enum TapEvent tap;
if (priv->synpara.touchpad_off == TOUCHPAD_TAP_OFF) {
priv->tap_button = 0;
return;
}
switch (priv->tap_max_fingers) {
case 1:
switch (edge) {
case RIGHT_TOP_EDGE:
DBG(7, "right top edge\n");
tap = RT_TAP;
break;
case RIGHT_BOTTOM_EDGE:
DBG(7, "right bottom edge\n");
tap = RB_TAP;
break;
case LEFT_TOP_EDGE:
DBG(7, "left top edge\n");
tap = LT_TAP;
break;
case LEFT_BOTTOM_EDGE:
DBG(7, "left bottom edge\n");
tap = LB_TAP;
break;
default:
DBG(7, "no edge\n");
tap = F1_TAP;
break;
}
break;
case 2:
DBG(7, "two finger tap\n");
tap = F2_TAP;
break;
case 3:
DBG(7, "three finger tap\n");
tap = F3_TAP;
break;
default:
priv->tap_button = 0;
return;
}
priv->tap_button = priv->synpara.tap_action[tap];
priv->tap_button = clamp(priv->tap_button, 0, SYN_MAX_BUTTONS);
}
static void
SetTapState(SynapticsPrivate * priv, enum TapState tap_state, CARD32 millis)
{
DBG(3, "SetTapState - %d -> %d (millis:%u)\n", priv->tap_state, tap_state,
millis);
switch (tap_state) {
case TS_START:
priv->tap_button_state = TBS_BUTTON_UP;
priv->tap_max_fingers = 0;
break;
case TS_1:
priv->tap_button_state = TBS_BUTTON_UP;
break;
case TS_2A:
priv->tap_button_state = TBS_BUTTON_UP;
break;
case TS_2B:
priv->tap_button_state = TBS_BUTTON_UP;
break;
case TS_3:
priv->tap_button_state = TBS_BUTTON_DOWN;
break;
case TS_SINGLETAP:
priv->tap_button_state = TBS_BUTTON_DOWN;
priv->touch_on.millis = millis;
break;
default:
break;
}
priv->tap_state = tap_state;
}
static void
SetMovingState(SynapticsPrivate * priv, enum MovingState moving_state,
CARD32 millis)
{
DBG(7, "SetMovingState - %d -> %d center at %d/%d (millis:%u)\n",
priv->moving_state, moving_state, priv->hwState->x, priv->hwState->y,
millis);
priv->moving_state = moving_state;
}
static int
GetTimeOut(SynapticsPrivate * priv)
{
SynapticsParameters *para = &priv->synpara;
switch (priv->tap_state) {
case TS_1:
case TS_3:
case TS_5:
return para->tap_time;
case TS_SINGLETAP:
return para->click_time;
case TS_2A:
return para->single_tap_timeout;
case TS_2B:
return para->tap_time_2;
case TS_4:
return para->locked_drag_time;
default:
return -1; /* No timeout */
}
}
static int
HandleTapProcessing(SynapticsPrivate * priv, struct SynapticsHwState *hw,
CARD32 now, enum FingerState finger,
Bool inside_active_area)
{
SynapticsParameters *para = &priv->synpara;
Bool touch, release, is_timeout, move, press;
int timeleft, timeout;
enum EdgeType edge;
int delay = 1000000000;
if (para->touchpad_off == TOUCHPAD_OFF ||
priv->finger_state == FS_BLOCKED)
return delay;
touch = finger >= FS_TOUCHED && priv->finger_state == FS_UNTOUCHED;
release = finger == FS_UNTOUCHED && priv->finger_state >= FS_TOUCHED;
move = (finger >= FS_TOUCHED &&
(priv->tap_max_fingers <=
((priv->horiz_scroll_twofinger_on ||
priv->vert_scroll_twofinger_on) ? 2 : 1)) &&
(priv->prevFingers == hw->numFingers &&
((abs(hw->x - priv->touch_on.x) >= para->tap_move) ||
(abs(hw->y - priv->touch_on.y) >= para->tap_move))));
press = (hw->left || hw->right || hw->middle);
if (touch) {
priv->touch_on.x = hw->x;
priv->touch_on.y = hw->y;
priv->touch_on.millis = now;
}
else if (release) {
priv->touch_on.millis = now;
}
if (hw->z > para->finger_high)
if (priv->tap_max_fingers < hw->numFingers)
priv->tap_max_fingers = hw->numFingers;
timeout = GetTimeOut(priv);
timeleft = TIME_DIFF(priv->touch_on.millis + timeout, now);
is_timeout = timeleft <= 0;
restart:
switch (priv->tap_state) {
case TS_START:
if (touch)
SetTapState(priv, TS_1, now);
break;
case TS_1:
if (para->clickpad && press) {
SetTapState(priv, TS_CLICKPAD_MOVE, now);
goto restart;
}
if (move) {
SetMovingState(priv, MS_TOUCHPAD_RELATIVE, now);
SetTapState(priv, TS_MOVE, now);
goto restart;
}
else if (is_timeout) {
if (finger == FS_TOUCHED) {
SetMovingState(priv, MS_TOUCHPAD_RELATIVE, now);
}
SetTapState(priv, TS_MOVE, now);
goto restart;
}
else if (release) {
edge = edge_detection(priv, priv->touch_on.x, priv->touch_on.y);
SelectTapButton(priv, edge);
/* Disable taps outside of the active area */
if (!inside_active_area) {
priv->tap_button = 0;
}
SetTapState(priv, TS_2A, now);
}
break;
case TS_MOVE:
if (para->clickpad && press) {
SetTapState(priv, TS_CLICKPAD_MOVE, now);
goto restart;
}
if (release) {
SetMovingState(priv, MS_FALSE, now);
SetTapState(priv, TS_START, now);
}
break;
case TS_2A:
if (touch)
SetTapState(priv, TS_3, now);
else if (is_timeout)
SetTapState(priv, TS_SINGLETAP, now);
break;
case TS_2B:
if (touch)
SetTapState(priv, TS_3, now);
else if (is_timeout)
SetTapState(priv, TS_SINGLETAP, now);
break;
case TS_SINGLETAP:
if (touch)
SetTapState(priv, TS_1, now);
else if (is_timeout)
SetTapState(priv, TS_START, now);
break;
case TS_3:
if (move) {
if (para->tap_and_drag_gesture) {
SetMovingState(priv, MS_TOUCHPAD_RELATIVE, now);
SetTapState(priv, TS_DRAG, now);
}
else {
SetTapState(priv, TS_1, now);
}
goto restart;
}
else if (is_timeout) {
if (para->tap_and_drag_gesture) {
if (finger == FS_TOUCHED) {
SetMovingState(priv, MS_TOUCHPAD_RELATIVE, now);
}
SetTapState(priv, TS_DRAG, now);
}
else {
SetTapState(priv, TS_1, now);
}
goto restart;
}
else if (release) {
SetTapState(priv, TS_2B, now);
}
break;
case TS_DRAG:
if (para->clickpad && press) {
SetTapState(priv, TS_CLICKPAD_MOVE, now);
goto restart;
}
if (move)
SetMovingState(priv, MS_TOUCHPAD_RELATIVE, now);
if (release) {
SetMovingState(priv, MS_FALSE, now);
if (para->locked_drags) {
SetTapState(priv, TS_4, now);
}
else {
SetTapState(priv, TS_START, now);
}
}
break;
case TS_4:
if (is_timeout) {
SetTapState(priv, TS_START, now);
goto restart;
}
if (touch)
SetTapState(priv, TS_5, now);
break;
case TS_5:
if (is_timeout || move) {
SetTapState(priv, TS_DRAG, now);
goto restart;
}
else if (release) {
SetMovingState(priv, MS_FALSE, now);
SetTapState(priv, TS_START, now);
}
break;
case TS_CLICKPAD_MOVE:
/* Disable scrolling once a button is pressed on a clickpad */
priv->vert_scroll_edge_on = FALSE;
priv->horiz_scroll_edge_on = FALSE;
priv->vert_scroll_twofinger_on = FALSE;
priv->horiz_scroll_twofinger_on = FALSE;
/* Assume one touch is only for holding the clickpad button down */
if (hw->numFingers > 1)
hw->numFingers--;
SetMovingState(priv, MS_TOUCHPAD_RELATIVE, now);
if (!press) {
SetMovingState(priv, MS_FALSE, now);
SetTapState(priv, TS_MOVE, now);
priv->count_packet_finger = 0;
}
break;
}
timeout = GetTimeOut(priv);
if (timeout >= 0) {
timeleft = TIME_DIFF(priv->touch_on.millis + timeout, now);
delay = clamp(timeleft, 1, delay);
}
return delay;
}
#define HIST(a) (priv->move_hist[((priv->hist_index - (a) + SYNAPTICS_MOVE_HISTORY) % SYNAPTICS_MOVE_HISTORY)])
#define HIST_DELTA(a, b, e) ((HIST((a)).e) - (HIST((b)).e))
static void
store_history(SynapticsPrivate * priv, int x, int y, CARD32 millis)
{
int idx = (priv->hist_index + 1) % SYNAPTICS_MOVE_HISTORY;
priv->move_hist[idx].x = x;
priv->move_hist[idx].y = y;
priv->move_hist[idx].millis = millis;
priv->hist_index = idx;
if (priv->count_packet_finger < SYNAPTICS_MOVE_HISTORY)
priv->count_packet_finger++;
}
/*
* Estimate the slope for the data sequence [x3, x2, x1, x0] by using
* linear regression to fit a line to the data and use the slope of the
* line.
*/
static double
estimate_delta(double x0, double x1, double x2, double x3)
{
return x0 * 0.3 + x1 * 0.1 - x2 * 0.1 - x3 * 0.3;
}
/**
* Applies hysteresis. center is shifted such that it is in range with
* in by the margin again. The new center is returned.
* @param in the current value
* @param center the current center
* @param margin the margin to center in which no change is applied
* @return the new center (which might coincide with the previous)
*/
static int
hysteresis(int in, int center, int margin)
{
int diff = in - center;
if (abs(diff) <= margin) {
diff = 0;
}
else if (diff > margin) {
diff -= margin;
}
else if (diff < -margin) {
diff += margin;
}
return center + diff;
}
static void
get_delta(SynapticsPrivate *priv, const struct SynapticsHwState *hw,
enum EdgeType edge, double *dx, double *dy)
{
*dx = hw->x - HIST(0).x;
*dy = hw->y - HIST(0).y;
}
/* Vector length, but not sqrt'ed, we only need it for comparison */
static inline double
vlenpow2(double x, double y)
{
return x * x + y * y;
}
/**
* Compute relative motion ('deltas') including edge motion.
*/
static int
ComputeDeltas(SynapticsPrivate * priv, const struct SynapticsHwState *hw,
enum EdgeType edge, int *dxP, int *dyP, Bool inside_area)
{
enum MovingState moving_state;
double dx, dy;
double vlen;
int delay = 1000000000;
dx = dy = 0;
moving_state = priv->moving_state;
if (moving_state == MS_FALSE) {
switch (priv->tap_state) {
case TS_MOVE:
case TS_DRAG:
moving_state = MS_TOUCHPAD_RELATIVE;
break;
case TS_1:
case TS_3:
case TS_5:
moving_state = MS_TOUCHPAD_RELATIVE;
break;
default:
break;
}
}
if (!inside_area || !moving_state || priv->finger_state == FS_BLOCKED ||
priv->vert_scroll_edge_on || priv->horiz_scroll_edge_on ||
priv->vert_scroll_twofinger_on || priv->horiz_scroll_twofinger_on ||
priv->circ_scroll_on || priv->prevFingers != hw->numFingers ||
(moving_state == MS_TOUCHPAD_RELATIVE && hw->numFingers != 1)) {
/* reset packet counter. */
priv->count_packet_finger = 0;
goto out;
}
/* To create the illusion of fluid motion, call back at roughly the report
* rate, even in the absence of new hardware events; see comment above
* POLL_MS declaration. */
delay = MIN(delay, POLL_MS);
if (priv->count_packet_finger <= 1)
goto out; /* skip the lot */
if (moving_state == MS_TOUCHPAD_RELATIVE)
get_delta(priv, hw, edge, &dx, &dy);
out:
priv->prevFingers = hw->numFingers;
vlen = vlenpow2(dx/priv->synpara.resolution_horiz,
dy/priv->synpara.resolution_vert);
if (vlen > priv->synpara.maxDeltaMM * priv->synpara.maxDeltaMM) {
dx = 0;
dy = 0;
}
*dxP = dx;
*dyP = dy;
return delay;
}
static double
estimate_delta_circ(SynapticsPrivate * priv)
{
double a1 = angle(priv, HIST(3).x, HIST(3).y);
double a2 = angle(priv, HIST(2).x, HIST(2).y);
double a3 = angle(priv, HIST(1).x, HIST(1).y);
double a4 = angle(priv, HIST(0).x, HIST(0).y);
double d1 = diffa(a2, a1);
double d2 = d1 + diffa(a3, a2);
double d3 = d2 + diffa(a4, a3);
return estimate_delta(d3, d2, d1, 0);
}
/* vert and horiz are to know which direction to start coasting
* circ is true if the user had been circular scrolling.
*/
static void
start_coasting(SynapticsPrivate * priv, struct SynapticsHwState *hw,
Bool vert, Bool horiz, Bool circ)
{
SynapticsParameters *para = &priv->synpara;
priv->scroll.coast_delta_y = 0.0;
priv->scroll.coast_delta_x = 0.0;
if ((priv->scroll.packets_this_scroll > 3) && (para->coasting_speed > 0.0)) {
double pkt_time = HIST_DELTA(0, 3, millis) / 1000.0;
if (vert && !circ) {
double dy =
estimate_delta(HIST(0).y, HIST(1).y, HIST(2).y, HIST(3).y);
if (pkt_time > 0) {
double scrolls_per_sec = (dy / abs(para->scroll_dist_vert)) / pkt_time;
if (fabs(scrolls_per_sec) >= para->coasting_speed) {
priv->scroll.coast_speed_y = scrolls_per_sec;
priv->scroll.coast_delta_y = (hw->y - priv->scroll.last_y);
}
}
}
if (horiz && !circ) {
double dx =
estimate_delta(HIST(0).x, HIST(1).x, HIST(2).x, HIST(3).x);
if (pkt_time > 0) {
double scrolls_per_sec = (dx / abs(para->scroll_dist_vert)) / pkt_time;
if (fabs(scrolls_per_sec) >= para->coasting_speed) {
priv->scroll.coast_speed_x = scrolls_per_sec;
priv->scroll.coast_delta_x = (hw->x - priv->scroll.last_x);
}
}
}
if (circ) {
double da = estimate_delta_circ(priv);
if (pkt_time > 0) {
double scrolls_per_sec = (da / para->scroll_dist_circ) / pkt_time;
if (fabs(scrolls_per_sec) >= para->coasting_speed) {
if (vert) {
priv->scroll.coast_speed_y = scrolls_per_sec;
priv->scroll.coast_delta_y =
diffa(priv->scroll.last_a,
angle(priv, hw->x, hw->y));
}
else if (horiz) {
priv->scroll.coast_speed_x = scrolls_per_sec;
priv->scroll.coast_delta_x =
diffa(priv->scroll.last_a,
angle(priv, hw->x, hw->y));
}
}
}
}
}
priv->scroll.packets_this_scroll = 0;
}
static void
stop_coasting(SynapticsPrivate * priv)
{
priv->scroll.coast_speed_x = 0;
priv->scroll.coast_speed_y = 0;
priv->scroll.packets_this_scroll = 0;
}
static int
HandleScrolling(SynapticsPrivate * priv, struct SynapticsHwState *hw,
enum EdgeType edge, Bool finger)
{
SynapticsParameters *para = &priv->synpara;
int delay = 1000000000;
if (priv->synpara.touchpad_off == TOUCHPAD_TAP_OFF ||
priv->synpara.touchpad_off == TOUCHPAD_OFF ||
priv->finger_state == FS_BLOCKED) {
stop_coasting(priv);
priv->circ_scroll_on = FALSE;
priv->vert_scroll_edge_on = FALSE;
priv->horiz_scroll_edge_on = FALSE;
priv->vert_scroll_twofinger_on = FALSE;
priv->horiz_scroll_twofinger_on = FALSE;
return delay;
}
/* scroll detection */
if (finger && priv->finger_state == FS_UNTOUCHED) {
stop_coasting(priv);
priv->scroll.delta_y = 0;
priv->scroll.delta_x = 0;
if (para->circular_scrolling) {
if ((para->circular_trigger == 0 && edge) ||
(para->circular_trigger == 1 && edge & TOP_EDGE) ||
(para->circular_trigger == 2 && edge & TOP_EDGE &&
edge & RIGHT_EDGE) || (para->circular_trigger == 3 &&
edge & RIGHT_EDGE) ||
(para->circular_trigger == 4 && edge & RIGHT_EDGE &&
edge & BOTTOM_EDGE) || (para->circular_trigger == 5 &&
edge & BOTTOM_EDGE) ||
(para->circular_trigger == 6 && edge & BOTTOM_EDGE &&
edge & LEFT_EDGE) || (para->circular_trigger == 7 &&
edge & LEFT_EDGE) ||
(para->circular_trigger == 8 && edge & LEFT_EDGE &&
edge & TOP_EDGE)) {
priv->circ_scroll_on = TRUE;
priv->circ_scroll_vert = TRUE;
priv->scroll.last_a = angle(priv, hw->x, hw->y);
DBG(7, "circular scroll detected on edge\n");
}
}
}
if (!priv->circ_scroll_on) {
if (finger) {
if (hw->numFingers == 2) {
if (!priv->vert_scroll_twofinger_on &&
(para->scroll_twofinger_vert) &&
(para->scroll_dist_vert != 0)) {
stop_coasting(priv);
priv->vert_scroll_twofinger_on = TRUE;
priv->vert_scroll_edge_on = FALSE;
priv->scroll.last_y = hw->y;
DBG(7, "vert two-finger scroll detected\n");
}
if (!priv->horiz_scroll_twofinger_on &&
(para->scroll_twofinger_horiz) &&
(para->scroll_dist_horiz != 0)) {
stop_coasting(priv);
priv->horiz_scroll_twofinger_on = TRUE;
priv->horiz_scroll_edge_on = FALSE;
priv->scroll.last_x = hw->x;
DBG(7, "horiz two-finger scroll detected\n");
}
}
}
if (finger && priv->finger_state == FS_UNTOUCHED) {
if (!priv->vert_scroll_twofinger_on &&
!priv->horiz_scroll_twofinger_on) {
if ((para->scroll_edge_vert) && (para->scroll_dist_vert != 0) &&
(edge & RIGHT_EDGE)) {
priv->vert_scroll_edge_on = TRUE;
priv->scroll.last_y = hw->y;
DBG(7, "vert edge scroll detected on right edge\n");
}
if ((para->scroll_edge_horiz) && (para->scroll_dist_horiz != 0)
&& (edge & BOTTOM_EDGE)) {
priv->horiz_scroll_edge_on = TRUE;
priv->scroll.last_x = hw->x;
DBG(7, "horiz edge scroll detected on bottom edge\n");
}
}
}
}
{
Bool oldv = priv->vert_scroll_twofinger_on || priv->vert_scroll_edge_on
|| (priv->circ_scroll_on && priv->circ_scroll_vert);
Bool oldh = priv->horiz_scroll_twofinger_on ||
priv->horiz_scroll_edge_on || (priv->circ_scroll_on &&
!priv->circ_scroll_vert);
Bool oldc = priv->circ_scroll_on;
if (priv->circ_scroll_on && !finger) {
/* circular scroll locks in until finger is raised */
DBG(7, "cicular scroll off\n");
priv->circ_scroll_on = FALSE;
}
if (!finger || hw->numFingers != 2) {
if (priv->vert_scroll_twofinger_on) {
DBG(7, "vert two-finger scroll off\n");
priv->vert_scroll_twofinger_on = FALSE;
}
if (priv->horiz_scroll_twofinger_on) {
DBG(7, "horiz two-finger scroll off\n");
priv->horiz_scroll_twofinger_on = FALSE;
}
}
if (priv->vert_scroll_edge_on && (!(edge & RIGHT_EDGE) || !finger)) {
DBG(7, "vert edge scroll off\n");
priv->vert_scroll_edge_on = FALSE;
}
if (priv->horiz_scroll_edge_on && (!(edge & BOTTOM_EDGE) || !finger)) {
DBG(7, "horiz edge scroll off\n");
priv->horiz_scroll_edge_on = FALSE;
}
/* If we were corner edge scrolling (coasting),
* but no longer in corner or raised a finger, then stop coasting. */
if (para->scroll_edge_corner &&
(priv->scroll.coast_speed_x || priv->scroll.coast_speed_y)) {
Bool is_in_corner = ((edge & RIGHT_EDGE) &&
(edge & (TOP_EDGE | BOTTOM_EDGE))) ||
((edge & BOTTOM_EDGE) && (edge & (LEFT_EDGE | RIGHT_EDGE)));
if (!is_in_corner || !finger) {
DBG(7, "corner edge scroll off\n");
stop_coasting(priv);
}
}
/* if we were scrolling, but couldn't corner edge scroll,
* and are no longer scrolling, then start coasting */
oldv = oldv && !(priv->vert_scroll_twofinger_on ||
priv->vert_scroll_edge_on || (priv->circ_scroll_on &&
priv->circ_scroll_vert));
oldh = oldh && !(priv->horiz_scroll_twofinger_on ||
priv->horiz_scroll_edge_on || (priv->circ_scroll_on &&
!priv->
circ_scroll_vert));
oldc = oldc && !priv->circ_scroll_on;
if ((oldv || oldh) && !para->scroll_edge_corner) {
start_coasting(priv, hw, oldv, oldh, oldc);
}
}
/* if hitting a corner (top right or bottom right) while vertical
* scrolling is active, consider starting corner edge scrolling or
* switching over to circular scrolling smoothly */
if (priv->vert_scroll_edge_on && !priv->horiz_scroll_edge_on &&
(edge & RIGHT_EDGE) && (edge & (TOP_EDGE | BOTTOM_EDGE))) {
if (para->scroll_edge_corner) {
if (priv->scroll.coast_speed_y == 0) {
/* FYI: We can generate multiple start_coasting requests if
* we're in the corner, but we were moving so slowly when we
* got here that we didn't actually start coasting. */
DBG(7, "corner edge scroll on\n");
start_coasting(priv, hw, TRUE, FALSE, FALSE);
}
}
else if (para->circular_scrolling) {
priv->vert_scroll_edge_on = FALSE;
priv->circ_scroll_on = TRUE;
priv->circ_scroll_vert = TRUE;
priv->scroll.last_a = angle(priv, hw->x, hw->y);
DBG(7, "switching to circular scrolling\n");
}
}
/* Same treatment for horizontal scrolling */
if (priv->horiz_scroll_edge_on && !priv->vert_scroll_edge_on &&
(edge & BOTTOM_EDGE) && (edge & (LEFT_EDGE | RIGHT_EDGE))) {
if (para->scroll_edge_corner) {
if (priv->scroll.coast_speed_x == 0) {
/* FYI: We can generate multiple start_coasting requests if
* we're in the corner, but we were moving so slowly when we
* got here that we didn't actually start coasting. */
DBG(7, "corner edge scroll on\n");
start_coasting(priv, hw, FALSE, TRUE, FALSE);
}
}
else if (para->circular_scrolling) {
priv->horiz_scroll_edge_on = FALSE;
priv->circ_scroll_on = TRUE;
priv->circ_scroll_vert = FALSE;
priv->scroll.last_a = angle(priv, hw->x, hw->y);
DBG(7, "switching to circular scrolling\n");
}
}
if (priv->vert_scroll_edge_on || priv->horiz_scroll_edge_on ||
priv->vert_scroll_twofinger_on || priv->horiz_scroll_twofinger_on ||
priv->circ_scroll_on) {
priv->scroll.packets_this_scroll++;
}
if (priv->vert_scroll_edge_on || priv->vert_scroll_twofinger_on) {
/* + = down, - = up */
if (para->scroll_dist_vert != 0 && hw->y != priv->scroll.last_y) {
priv->scroll.delta_y += (hw->y - priv->scroll.last_y);
priv->scroll.last_y = hw->y;
}
}
if (priv->horiz_scroll_edge_on || priv->horiz_scroll_twofinger_on) {
/* + = right, - = left */
if (para->scroll_dist_horiz != 0 && hw->x != priv->scroll.last_x) {
priv->scroll.delta_x += (hw->x - priv->scroll.last_x);
priv->scroll.last_x = hw->x;
}
}
if (priv->circ_scroll_on) {
/* + = counter clockwise, - = clockwise */
double delta = para->scroll_dist_circ;
double diff = diffa(priv->scroll.last_a, angle(priv, hw->x, hw->y));
if (delta >= 0.005 && diff != 0.0) {
if (priv->circ_scroll_vert)
priv->scroll.delta_y -= diff / delta * para->scroll_dist_vert;
else
priv->scroll.delta_x -= diff / delta * para->scroll_dist_horiz;
priv->scroll.last_a = angle(priv, hw->x, hw->y);
}
}
if (priv->scroll.coast_speed_y) {
double dtime = (hw->millis - priv->scroll.last_millis) / 1000.0;
double ddy = para->coasting_friction * dtime;
priv->scroll.delta_y += priv->scroll.coast_speed_y * dtime * abs(para->scroll_dist_vert);
delay = MIN(delay, POLL_MS);
if (fabs(priv->scroll.coast_speed_y) < ddy) {
priv->scroll.coast_speed_y = 0;
priv->scroll.packets_this_scroll = 0;
}
else {
priv->scroll.coast_speed_y +=
(priv->scroll.coast_speed_y < 0 ? ddy : -ddy);
}
}
if (priv->scroll.coast_speed_x) {
double dtime = (hw->millis - priv->scroll.last_millis) / 1000.0;
double ddx = para->coasting_friction * dtime;
priv->scroll.delta_x += priv->scroll.coast_speed_x * dtime * abs(para->scroll_dist_horiz);
delay = MIN(delay, POLL_MS);
if (fabs(priv->scroll.coast_speed_x) < ddx) {
priv->scroll.coast_speed_x = 0;
priv->scroll.packets_this_scroll = 0;
}
else {
priv->scroll.coast_speed_x +=
(priv->scroll.coast_speed_x < 0 ? ddx : -ddx);
}
}
return delay;
}
/**
* Check if any 2+ fingers are close enough together to assume this is a
* ClickFinger action.
*/
static int
clickpad_guess_clickfingers(SynapticsPrivate * priv,
struct SynapticsHwState *hw)
{
int nfingers = 0;
uint32_t close_point = 0; /* 1 bit for each point close to another one */
int i, j;
BUG_RETURN_VAL(hw->num_mt_mask > sizeof(close_point) * 8, 0);
for (i = 0; i < hw->num_mt_mask - 1; i++) {
ValuatorMask *f1;
if (hw->slot_state[i] == SLOTSTATE_EMPTY ||
hw->slot_state[i] == SLOTSTATE_CLOSE)
continue;
f1 = hw->mt_mask[i];
for (j = i + 1; j < hw->num_mt_mask; j++) {
ValuatorMask *f2;
double x1, x2, y1, y2;
if (hw->slot_state[j] == SLOTSTATE_EMPTY ||
hw->slot_state[j] == SLOTSTATE_CLOSE)
continue;
f2 = hw->mt_mask[j];
x1 = valuator_mask_get_double(f1, 0);
y1 = valuator_mask_get_double(f1, 1);
x2 = valuator_mask_get_double(f2, 0);
y2 = valuator_mask_get_double(f2, 1);
/* FIXME: fingers closer together than 30% of touchpad width, but
* really, this should be dependent on the touchpad size. Also,
* you'll need to find a touchpad that doesn't lie about it's
* size. Good luck. */
if (fabs(x1 - x2) < (priv->maxx - priv->minx) * .3 &&
fabs(y1 - y2) < (priv->maxy - priv->miny) * .3) {
close_point |= (1 << j);
close_point |= (1 << i);
}
}
}
while (close_point > 0) {
nfingers += close_point & 0x1;
close_point >>= 1;
}
/* Some trackpads touchpad only track two touchpoints but announce
* BTN_TOOL_TRIPLETAP (which sets hw->numFingers to 3), when this happens
* the user likely intents to do a 3 finger click, so handle it as such.
*/
if (hw->numFingers >= 3 && hw->num_mt_mask < 3)
nfingers = 3;
return nfingers;
}
static void
handle_clickfinger(SynapticsPrivate * priv, struct SynapticsHwState *hw)
{
SynapticsParameters *para = &priv->synpara;
int action = 0;
int nfingers = hw->numFingers;
/* if this is a clickpad, clickfinger handling is:
* one finger down: no action, this is a normal click
* two fingers down: F2_CLICK
* three fingers down: F3_CLICK
*/
if (para->clickpad)
nfingers = clickpad_guess_clickfingers(priv, hw);
switch (nfingers) {
case 1:
action = para->click_action[F1_CLICK1];
break;
case 2:
action = para->click_action[F2_CLICK1];
break;
case 3:
action = para->click_action[F3_CLICK1];
break;
}
switch (action) {
case 1:
hw->left = 1 | BTN_EMULATED_FLAG;
break;
case 2:
hw->left = 0;
hw->middle = 1 | BTN_EMULATED_FLAG;
break;
case 3:
hw->left = 0;
hw->right = 1 | BTN_EMULATED_FLAG;
break;
}
}
/* Adjust the hardware state according to the extra buttons (if the touchpad
* has any and not many touchpads do these days). These buttons are up/down
* tilt buttons and/or left/right buttons that then map into a specific
* function (or scrolling into).
*/
static Bool
adjust_state_from_scrollbuttons(const InputInfoPtr pInfo,
struct SynapticsHwState *hw)
{
SynapticsPrivate *priv = (SynapticsPrivate *) (pInfo->private);
SynapticsParameters *para = &priv->synpara;
Bool double_click = FALSE;
if (!para->updown_button_scrolling) {
if (hw->down) { /* map down button to middle button */
hw->middle = TRUE;
}
if (hw->up) { /* up button generates double click */
if (!priv->prev_up)
double_click = TRUE;
}
priv->prev_up = hw->up;
/* reset up/down button events */
hw->up = hw->down = FALSE;
}
/* Left/right button scrolling, or middle clicks */
if (!para->leftright_button_scrolling) {
if (hw->multi[2] || hw->multi[3])
hw->middle = TRUE;
/* reset left/right button events */
hw->multi[2] = hw->multi[3] = FALSE;
}
return double_click;
}
static void
update_hw_button_state(const InputInfoPtr pInfo, struct SynapticsHwState *hw,
CARD32 now, int *delay)
{
SynapticsPrivate *priv = (SynapticsPrivate *) (pInfo->private);
SynapticsParameters *para = &priv->synpara;
/* Treat the first two multi buttons as up/down for now. */
hw->up |= hw->multi[0];
hw->down |= hw->multi[1];
/* 3rd button emulation */
hw->middle |= HandleMidButtonEmulation(priv, hw, now, delay);
/* If this is a clickpad and the user clicks in a soft button area, press
* the soft button instead. */
if (para->clickpad) {
/* hw->left is down, but no other buttons were already down */
if (!(priv->lastButtons & 7) && hw->left && !hw->right && !hw->middle) {
/* If the finger down event is delayed, the x and y
* coordinates are stale so we delay processing the click */
if (hw->z < para->finger_low) {
hw->left = 0;
goto out;
}
if (is_inside_rightbutton_area(para, hw->x, hw->y)) {
hw->left = 0;
hw->right = 1;
}
else if (is_inside_sec_rightbutton_area(para, hw->x, hw->y)) {
hw->left = 0;
hw->right = 1;
}
else if (is_inside_middlebutton_area(para, hw->x, hw->y)) {
hw->left = 0;
hw->middle = 1;
}
else if (is_inside_sec_middlebutton_area(para, hw->x, hw->y)) {
hw->left = 0;
hw->middle = 1;
}
priv->clickpad_click_millis = now;
}
else if (hw->left) {
hw->left = (priv->lastButtons & 1) ? 1 : 0;
hw->middle = (priv->lastButtons & 2) ? 1 : 0;
hw->right = (priv->lastButtons & 4) ? 1 : 0;
}
}
/* Fingers emulate other buttons. ClickFinger can only be
triggered on transition, when left is pressed
*/
if (hw->left && !(priv->lastButtons & 7) && hw->numFingers >= 1)
handle_clickfinger(priv, hw);
out:
/* Two finger emulation */
if (hw->numFingers == 1 && hw->z >= para->emulate_twofinger_z &&
hw->fingerWidth >= para->emulate_twofinger_w) {
hw->numFingers = 2;
}
}
static void
post_button_click(const InputInfoPtr pInfo, const int button)
{
xf86PostButtonEvent(pInfo->dev, FALSE, button, TRUE, 0, 0);
xf86PostButtonEvent(pInfo->dev, FALSE, button, FALSE, 0, 0);
}
static void
post_scroll_events(const InputInfoPtr pInfo)
{
SynapticsPrivate *priv = (SynapticsPrivate *) (pInfo->private);
valuator_mask_zero(priv->scroll_events_mask);
if (priv->scroll.delta_y != 0.0) {
valuator_mask_set_double(priv->scroll_events_mask,
priv->scroll_axis_vert, priv->scroll.delta_y);
priv->scroll.delta_y = 0;
}
if (priv->scroll.delta_x != 0.0) {
valuator_mask_set_double(priv->scroll_events_mask,
priv->scroll_axis_horiz, priv->scroll.delta_x);
priv->scroll.delta_x = 0;
}
if (valuator_mask_num_valuators(priv->scroll_events_mask))
xf86PostMotionEventM(pInfo->dev, FALSE, priv->scroll_events_mask);
}
static inline int
repeat_scrollbuttons(const InputInfoPtr pInfo,
const struct SynapticsHwState *hw,
int buttons, CARD32 now, int delay)
{
SynapticsPrivate *priv = (SynapticsPrivate *) (pInfo->private);
SynapticsParameters *para = &priv->synpara;
int repeat_delay, timeleft;
int rep_buttons = 0;
if (para->updown_button_repeat)
rep_buttons |= (1 << (4 - 1)) | (1 << (5 - 1));
if (para->leftright_button_repeat)
rep_buttons |= (1 << (6 - 1)) | (1 << (7 - 1));
/* Handle auto repeat buttons */
repeat_delay = clamp(para->scroll_button_repeat, SBR_MIN, SBR_MAX);
if (((hw->up || hw->down) && para->updown_button_repeat &&
para->updown_button_scrolling) ||
((hw->multi[2] || hw->multi[3]) && para->leftright_button_repeat &&
para->leftright_button_scrolling)) {
priv->repeatButtons = buttons & rep_buttons;
if (!priv->nextRepeat) {
priv->nextRepeat = now + repeat_delay * 2;
}
}
else {
priv->repeatButtons = 0;
priv->nextRepeat = 0;
}
if (priv->repeatButtons) {
timeleft = TIME_DIFF(priv->nextRepeat, now);
if (timeleft > 0)
delay = MIN(delay, timeleft);
if (timeleft <= 0) {
int change, id;
change = priv->repeatButtons;
while (change) {
id = ffs(change);
change &= ~(1 << (id - 1));
if (id == 4)
priv->scroll.delta_y -= para->scroll_dist_vert;
else if (id == 5)
priv->scroll.delta_y += para->scroll_dist_vert;
else if (id == 6)
priv->scroll.delta_x -= para->scroll_dist_horiz;
else if (id == 7)
priv->scroll.delta_x += para->scroll_dist_horiz;
}
priv->nextRepeat = now + repeat_delay;
delay = MIN(delay, repeat_delay);
}
}
return delay;
}
/* Update the open slots and number of active touches */
static void
UpdateTouchState(InputInfoPtr pInfo, struct SynapticsHwState *hw)
{
SynapticsPrivate *priv = (SynapticsPrivate *) pInfo->private;
int i;
for (i = 0; i < hw->num_mt_mask; i++) {
if (hw->slot_state[i] == SLOTSTATE_OPEN) {
priv->open_slots[priv->num_active_touches] = i;
priv->num_active_touches++;
BUG_WARN(priv->num_active_touches > priv->num_slots);
}
else if (hw->slot_state[i] == SLOTSTATE_CLOSE) {
Bool found = FALSE;
int j;
for (j = 0; j < priv->num_active_touches - 1; j++) {
if (priv->open_slots[j] == i)
found = TRUE;
if (found)
priv->open_slots[j] = priv->open_slots[j + 1];
}
BUG_WARN(priv->num_active_touches == 0);
if (priv->num_active_touches > 0)
priv->num_active_touches--;
}
}
SynapticsResetTouchHwState(hw, FALSE);
}
static void
filter_jitter(SynapticsPrivate * priv, int *x, int *y)
{
SynapticsParameters *para = &priv->synpara;
priv->hyst_center_x = hysteresis(*x, priv->hyst_center_x, para->hyst_x);
priv->hyst_center_y = hysteresis(*y, priv->hyst_center_y, para->hyst_y);
*x = priv->hyst_center_x;
*y = priv->hyst_center_y;
}
static void
reset_hw_state(struct SynapticsHwState *hw)
{
hw->x = 0;
hw->y = 0;
hw->z = 0;
hw->numFingers = 0;
hw->fingerWidth = 0;
}
/*
* React on changes in the hardware state. This function is called every time
* the hardware state changes. The return value is used to specify how many
* milliseconds to wait before calling the function again if no state change
* occurs.
*
* from_timer denotes if HandleState was triggered from a timer (e.g. to
* generate fake motion events, or for the tap-to-click state machine), rather
* than from having received a motion event.
*/
static int
HandleState(InputInfoPtr pInfo, struct SynapticsHwState *hw, CARD32 now,
Bool from_timer)
{
SynapticsPrivate *priv = (SynapticsPrivate *) (pInfo->private);
SynapticsParameters *para = &priv->synpara;
enum FingerState finger = FS_UNTOUCHED;
int dx = 0, dy = 0, buttons, id;
enum EdgeType edge = NO_EDGE;
int change;
int double_click = FALSE;
int delay = 1000000000;
int timeleft;
Bool inside_active_area;
Bool using_cumulative_coords = FALSE;
Bool ignore_motion;
/* We need both and x/y, the driver can't handle just one of the two
* yet. But since it's possible to hit a phys button on non-clickpads
* without ever getting motion data first, we must continue with 0/0 for
* that case. */
if (hw->x == INT_MIN || hw->y == INT_MAX) {
if (para->clickpad)
return delay;
else if (hw->left || hw->right || hw->middle) {
hw->x = (hw->x == INT_MIN) ? 0 : hw->x;
hw->y = (hw->y == INT_MIN) ? 0 : hw->y;
}
}
/* If a physical button is pressed on a clickpad or a two-finger scrolling
* is ongoing, use cumulative relative touch movements for motion */
if (para->clickpad &&
((priv->lastButtons & 7) ||
(priv->vert_scroll_twofinger_on || priv->horiz_scroll_twofinger_on)) &&
priv->last_button_area != TOP_BUTTON_AREA) {
hw->x = hw->cumulative_dx;
hw->y = hw->cumulative_dy;
using_cumulative_coords = TRUE;
}
/* apply hysteresis before doing anything serious. This cancels
* out a lot of noise which might surface in strange phenomena
* like flicker in scrolling or noise motion. */
filter_jitter(priv, &hw->x, &hw->y);
inside_active_area = is_inside_active_area(priv, hw->x, hw->y);
/* Ignore motion *starting* inside softbuttonareas */
if (priv->finger_state < FS_TOUCHED)
priv->last_button_area = current_button_area(para, hw->x, hw->y);
/* If we already have a finger down, clear last_button_area if it goes
outside of the softbuttonareas */
else if (priv->last_button_area != NO_BUTTON_AREA &&
current_button_area(para, hw->x, hw->y) == NO_BUTTON_AREA)
priv->last_button_area = NO_BUTTON_AREA;
ignore_motion = para->touchpad_off == TOUCHPAD_OFF ||
(!using_cumulative_coords && priv->last_button_area != NO_BUTTON_AREA);
/* these two just update hw->left, right, etc. */
update_hw_button_state(pInfo, hw, now, &delay);
if (priv->has_scrollbuttons)
double_click = adjust_state_from_scrollbuttons(pInfo, hw);
/* Ignore motion the first X ms after a clickpad click */
if (priv->clickpad_click_millis) {
if(TIME_DIFF(priv->clickpad_click_millis +
para->clickpad_ignore_motion_time, now) > 0)
ignore_motion = TRUE;
else
priv->clickpad_click_millis = 0;
}
/* now we know that these _coordinates_ aren't in the area.
invalid are: x, y, z, numFingers, fingerWidth
valid are: millis, left/right/middle/up/down/etc.
*/
if (!inside_active_area)
reset_hw_state(hw);
/* no edge or finger detection outside of area */
if (inside_active_area) {
edge = edge_detection(priv, hw->x, hw->y);
if (!from_timer)
finger = SynapticsDetectFinger(priv, hw);
else
finger = priv->finger_state;
}
/* tap and drag detection. Needs to be performed even if the finger is in
* the dead area to reset the state. */
timeleft = HandleTapProcessing(priv, hw, now, finger, inside_active_area);
if (timeleft > 0)
delay = MIN(delay, timeleft);
if (inside_active_area) {
/* Don't bother about scrolling in the dead area of the touchpad. */
timeleft = HandleScrolling(priv, hw, edge, (finger >= FS_TOUCHED));
if (timeleft > 0)
delay = MIN(delay, timeleft);
/*
* Compensate for unequal x/y resolution. This needs to be done after
* calculations that require unadjusted coordinates, for example edge
* detection.
*/
#ifndef NO_DRIVER_SCALING
ScaleCoordinates(priv, hw);
#endif
}
dx = dy = 0;
timeleft = ComputeDeltas(priv, hw, edge, &dx, &dy, inside_active_area);
delay = MIN(delay, timeleft);
buttons = ((hw->left ? 0x01 : 0) |
(hw->middle ? 0x02 : 0) |
(hw->right ? 0x04 : 0) |
(hw->up ? 0x08 : 0) |
(hw->down ? 0x10 : 0) |
(hw->multi[2] ? 0x20 : 0) | (hw->multi[3] ? 0x40 : 0));
if (priv->tap_button > 0 && priv->tap_button_state == TBS_BUTTON_DOWN)
buttons |= 1 << (priv->tap_button - 1);
/* Post events */
if (finger >= FS_TOUCHED && (dx || dy) && !ignore_motion)
xf86PostMotionEvent(pInfo->dev, 0, 0, 2, dx, dy);
if (priv->mid_emu_state == MBE_LEFT_CLICK) {
post_button_click(pInfo, 1);
priv->mid_emu_state = MBE_OFF;
}
else if (priv->mid_emu_state == MBE_RIGHT_CLICK) {
post_button_click(pInfo, 3);
priv->mid_emu_state = MBE_OFF;
}
change = buttons ^ priv->lastButtons;
while (change) {
id = ffs(change); /* number of first set bit 1..32 is returned */
change &= ~(1 << (id - 1));
xf86PostButtonEvent(pInfo->dev, FALSE, id, (buttons & (1 << (id - 1))),
0, 0);
}
if (priv->has_scrollbuttons)
delay = repeat_scrollbuttons(pInfo, hw, buttons, now, delay);
/* Process scroll events only if coordinates are
* in the Synaptics Area
*/
if (inside_active_area &&
(priv->scroll.delta_x != 0.0 || priv->scroll.delta_y != 0.0)) {
post_scroll_events(pInfo);
priv->scroll.last_millis = hw->millis;
}
if (double_click) {
post_button_click(pInfo, 1);
post_button_click(pInfo, 1);
}
UpdateTouchState(pInfo, hw);
/* Save old values of some state variables */
priv->finger_state = finger;
priv->lastButtons = buttons;
/* generate a history of the absolute positions */
if (inside_active_area)
store_history(priv, hw->x, hw->y, hw->millis);
return delay;
}
static int
ControlProc(InputInfoPtr pInfo, xDeviceCtl * control)
{
DBG(3, "Control Proc called\n");
return Success;
}
static int
SwitchMode(ClientPtr client, DeviceIntPtr dev, int mode)
{
DBG(3, "SwitchMode called\n");
return XI_BadMode;
}
static void
ReadDevDimensions(InputInfoPtr pInfo)
{
SynapticsPrivate *priv = (SynapticsPrivate *) pInfo->private;
if (priv->proto_ops->ReadDevDimensions)
priv->proto_ops->ReadDevDimensions(pInfo);
SanitizeDimensions(pInfo);
}
static Bool
QueryHardware(InputInfoPtr pInfo)
{
SynapticsPrivate *priv = (SynapticsPrivate *) pInfo->private;
priv->comm.protoBufTail = 0;
if (!priv->proto_ops->QueryHardware(pInfo)) {
xf86IDrvMsg(pInfo, X_PROBED, "no supported touchpad found\n");
if (priv->proto_ops->DeviceOffHook)
priv->proto_ops->DeviceOffHook(pInfo);
return FALSE;
}
return TRUE;
}
#ifndef NO_DRIVER_SCALING
static void
ScaleCoordinates(SynapticsPrivate * priv, struct SynapticsHwState *hw)
{
int xCenter = (priv->synpara.left_edge + priv->synpara.right_edge) / 2;
int yCenter = (priv->synpara.top_edge + priv->synpara.bottom_edge) / 2;
hw->x = (hw->x - xCenter) * priv->horiz_coeff + xCenter;
hw->y = (hw->y - yCenter) * priv->vert_coeff + yCenter;
}
void
CalculateScalingCoeffs(SynapticsPrivate * priv)
{
int vertRes = priv->synpara.resolution_vert;
int horizRes = priv->synpara.resolution_horiz;
if ((horizRes > vertRes) && (horizRes > 0)) {
priv->horiz_coeff = vertRes / (double) horizRes;
priv->vert_coeff = 1;
}
else if ((horizRes < vertRes) && (vertRes > 0)) {
priv->horiz_coeff = 1;
priv->vert_coeff = horizRes / (double) vertRes;
}
else {
priv->horiz_coeff = 1;
priv->vert_coeff = 1;
}
}
#endif
xf86-input-synaptics-1.9.2/src/Makefile.am 0000644 0143106 0000012 00000003764 14262661535 015246 0000000 0000000 # Copyright 2005 Adam Jackson.
#
# Permission is hereby granted, free of charge, to any person obtaining a
# copy of this software and associated documentation files (the "Software"),
# to deal in the Software without restriction, including without limitation
# on the rights to use, copy, modify, merge, publish, distribute, sub
# license, and/or sell copies of the Software, and to permit persons to whom
# the Software is furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice (including the next
# paragraph) shall be included in all copies or substantial portions of the
# Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
# ADAM JACKSON BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
# this is obnoxious:
# -module lets us name the module exactly how we want
# -avoid-version prevents gratuitous .0.0.0 version numbers on the end
# _ladir passes a dummy rpath to libtool so the thing will actually link
# TODO: -nostdlib/-Bstatic/-lgcc platform magic, not installing the .a, etc.
synaptics_drv_la_LTLIBRARIES = synaptics_drv.la
synaptics_drv_la_LDFLAGS = -module -avoid-version
synaptics_drv_ladir = @inputdir@
AM_CPPFLAGS = -I$(top_srcdir)/include
AM_CFLAGS = $(XORG_CFLAGS)
synaptics_drv_la_SOURCES = \
synaptics.c \
synapticsstr.h \
synproto.c \
synproto.h \
properties.c
if BUILD_PS2COMM
synaptics_drv_la_SOURCES += \
alpscomm.c \
ps2comm.c ps2comm.h
endif
if BUILD_EVENTCOMM
synaptics_drv_la_SOURCES += \
eventcomm.c eventcomm.h
synaptics_drv_la_LIBADD = \
$(LIBEVDEV_LIBS)
AM_CPPFLAGS += $(LIBEVDEV_CFLAGS)
endif
if BUILD_PSMCOMM
synaptics_drv_la_SOURCES += \
psmcomm.c
endif
xf86-input-synaptics-1.9.2/src/alpscomm.c 0000644 0143106 0000012 00000014536 14262661535 015170 0000000 0000000 /*
* Copyright © 2001 Stefan Gmeiner
* Copyright © 2003 Neil Brown
* Copyright © 2003-2005,2007 Peter Osterlund
*
* 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.
*
* Authors:
* Stefan Gmeiner (riddlebox@freesurf.ch)
* Neil Brown (neilb@cse.unsw.edu.au)
* Peter Osterlund (petero2@telia.com)
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include
#include "synproto.h"
#include "synapticsstr.h"
#include "ps2comm.h"
#include
/* Wait for the channel to go silent, which means we're in sync */
static void
ALPS_sync(int fd)
{
byte buffer[64];
while (xf86WaitForInput(fd, 250000) > 0) {
xf86ReadSerial(fd, &buffer, 64);
}
}
/*
* send the ALPS init sequence, ie 4 consecutive "disable"s before the "enable"
* This "magic knock" is performed both for the trackpad and for the pointing
* stick. Not all models have a pointing stick, but trying to initialize it
* anyway doesn't seem to hurt.
*/
static void
ALPS_initialize(int fd)
{
xf86FlushInput(fd);
ps2_putbyte(fd, PS2_CMD_SET_DEFAULT);
ps2_putbyte(fd, PS2_CMD_SET_SCALING_2_1);
ps2_putbyte(fd, PS2_CMD_SET_SCALING_2_1);
ps2_putbyte(fd, PS2_CMD_SET_SCALING_2_1);
ps2_putbyte(fd, PS2_CMD_DISABLE);
ps2_putbyte(fd, PS2_CMD_DISABLE);
ps2_putbyte(fd, PS2_CMD_DISABLE);
ps2_putbyte(fd, PS2_CMD_DISABLE);
ps2_putbyte(fd, PS2_CMD_DISABLE);
ps2_putbyte(fd, PS2_CMD_ENABLE);
ps2_putbyte(fd, PS2_CMD_SET_SCALING_1_1);
ps2_putbyte(fd, PS2_CMD_SET_SCALING_1_1);
ps2_putbyte(fd, PS2_CMD_SET_SCALING_1_1);
ps2_putbyte(fd, PS2_CMD_DISABLE);
ps2_putbyte(fd, PS2_CMD_DISABLE);
ps2_putbyte(fd, PS2_CMD_DISABLE);
ps2_putbyte(fd, PS2_CMD_DISABLE);
ps2_putbyte(fd, PS2_CMD_DISABLE);
ps2_putbyte(fd, PS2_CMD_ENABLE);
ALPS_sync(fd);
}
static Bool
ALPSQueryHardware(InputInfoPtr pInfo)
{
ALPS_initialize(pInfo->fd);
return TRUE;
}
static Bool
ALPS_packet_ok(struct CommData *comm)
{
/* ALPS absolute mode packets start with 0b11111mrl */
if ((comm->protoBuf[0] & 0xf8) == 0xf8)
return TRUE;
return FALSE;
}
static Bool
ALPS_get_packet(struct CommData *comm, InputInfoPtr pInfo)
{
int c;
while ((c = XisbRead(comm->buffer)) >= 0) {
unsigned char u = (unsigned char) c;
comm->protoBuf[comm->protoBufTail++] = u;
if (comm->protoBufTail == 3) { /* PS/2 packet received? */
if ((comm->protoBuf[0] & 0xc8) == 0x08) {
comm->protoBufTail = 0;
return TRUE;
}
}
if (comm->protoBufTail >= 6) { /* Full packet received */
comm->protoBufTail = 0;
if (ALPS_packet_ok(comm))
return TRUE;
while ((c = XisbRead(comm->buffer)) >= 0); /* If packet is invalid, re-sync */
}
}
return FALSE;
}
/*
* ALPS absolute Mode
* byte 0: 1 1 1 1 1 mid0 rig0 lef0
* byte 1: 0 x6 x5 x4 x3 x2 x1 x0
* byte 2: 0 x10 x9 x8 x7 up1 fin ges
* byte 3: 0 y9 y8 y7 1 mid1 rig1 lef1
* byte 4: 0 y6 y5 y4 y3 y2 y1 y0
* byte 5: 0 z6 z5 z4 z3 z2 z1 z0
*
* On a dualpoint, {mid,rig,lef}0 are the stick, 1 are the pad.
* We just 'or' them together for now.
*
* The touchpad on an 'Acer Aspire' has 4 buttons:
* left,right,up,down.
* This device always sets {mid,rig,lef}0 to 1 and
* reflects left,right,down,up in lef1,rig1,mid1,up1.
*/
static void
ALPS_process_packet(unsigned char *packet, struct SynapticsHwState *hw)
{
int x = 0, y = 0, z = 0;
int left = 0, right = 0, middle = 0;
int i;
hw->millis = GetTimeInMillis();
x = (packet[1] & 0x7f) | ((packet[2] & 0x78) << (7 - 3));
y = (packet[4] & 0x7f) | ((packet[3] & 0x70) << (7 - 4));
z = packet[5];
if (z == 127) { /* DualPoint stick is relative, not absolute */
hw->left = packet[3] & 1;
hw->right = (packet[3] >> 1) & 1;
return;
}
/* Handle normal packets */
hw->x = hw->y = hw->z = hw->numFingers = hw->fingerWidth = 0;
hw->left = hw->right = hw->up = hw->down = hw->middle = FALSE;
for (i = 0; i < 8; i++)
hw->multi[i] = FALSE;
if (z > 0) {
hw->x = x;
hw->y = y;
}
hw->z = z;
hw->numFingers = (z > 0) ? 1 : 0;
hw->fingerWidth = 5;
left |= (packet[2]) & 1;
left |= (packet[3]) & 1;
right |= (packet[3] >> 1) & 1;
if (packet[0] == 0xff) {
int back = (packet[3] >> 2) & 1;
int forward = (packet[2] >> 2) & 1;
if (back && forward) {
middle = 1;
back = 0;
forward = 0;
}
hw->down = back;
hw->up = forward;
}
else {
left |= (packet[0]) & 1;
right |= (packet[0] >> 1) & 1;
middle |= (packet[0] >> 2) & 1;
middle |= (packet[3] >> 2) & 1;
}
hw->left = left;
hw->right = right;
hw->middle = middle;
}
static Bool
ALPSReadHwState(InputInfoPtr pInfo,
struct CommData *comm, struct SynapticsHwState *hwRet)
{
unsigned char *buf = comm->protoBuf;
struct SynapticsHwState *hw = comm->hwState;
if (!ALPS_get_packet(comm, pInfo))
return FALSE;
ALPS_process_packet(buf, hw);
SynapticsCopyHwState(hwRet, hw);
return TRUE;
}
struct SynapticsProtocolOperations alps_proto_operations = {
NULL,
NULL,
ALPSQueryHardware,
ALPSReadHwState,
NULL,
NULL
};
xf86-input-synaptics-1.9.2/src/ps2comm.h 0000644 0143106 0000012 00000011252 14262661535 014732 0000000 0000000 /*
* 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.
*/
#ifndef _PS2COMM_H_
#define _PS2COMM_H_
#include
#include
#include
#include "xf86_OSproc.h"
/* acknowledge for commands and parameter */
#define PS2_ACK 0xFA
#define PS2_ERROR 0xFC
/* standard PS/2 commands */
#define PS2_CMD_RESET 0xFF
#define PS2_CMD_RESEND 0xFE
#define PS2_CMD_SET_DEFAULT 0xF6
#define PS2_CMD_DISABLE 0xF5
#define PS2_CMD_ENABLE 0xF4
#define PS2_CMD_SET_SAMPLE_RATE 0xF3
#define PS2_CMD_READ_DEVICE_TYPE 0xF2
#define PS2_CMD_SET_REMOTE_MODE 0xF0
#define PS2_CMD_SET_WRAP_MODE 0xEE
#define PS2_CMD_RESET_WRAP_MODE 0xEC
#define PS2_CMD_READ_DATA 0xEB
#define PS2_CMD_SET_STREAM_MODE 0xEA
#define PS2_CMD_STATUS_REQUEST 0xE9
#define PS2_CMD_SET_RESOLUTION 0xE8
#define PS2_CMD_SET_SCALING_2_1 0xE7
#define PS2_CMD_SET_SCALING_1_1 0xE6
/* synaptics modes */
#define SYN_BIT_ABSOLUTE_MODE (1 << 7)
#define SYN_BIT_HIGH_RATE (1 << 6)
#define SYN_BIT_SLEEP_MODE (1 << 3)
#define SYN_BIT_DISABLE_GESTURE (1 << 2)
#define SYN_BIT_W_MODE (1 << 0)
/* synaptics model ID bits */
#define SYN_MODEL_ROT180(synhw) ((synhw)->model_id & (1 << 23))
#define SYN_MODEL_PORTRAIT(synhw) ((synhw)->model_id & (1 << 22))
#define SYN_MODEL_SENSOR(synhw) (((synhw)->model_id >> 16) & 0x3f)
#define SYN_MODEL_HARDWARE(synhw) (((synhw)->model_id >> 9) & 0x7f)
#define SYN_MODEL_NEWABS(synhw) ((synhw)->model_id & (1 << 7))
#define SYN_MODEL_PEN(synhw) ((synhw)->model_id & (1 << 6))
#define SYN_MODEL_SIMPLIC(synhw) ((synhw)->model_id & (1 << 5))
#define SYN_MODEL_GEOMETRY(synhw) ((synhw)->model_id & 0x0f)
/* synaptics capability bits */
#define SYN_CAP_EXTENDED(synhw) ((synhw)->capabilities & (1 << 23))
#define SYN_CAP_MIDDLE_BUTTON(synhw) ((synhw)->capabilities & (1 << 18))
#define SYN_CAP_PASSTHROUGH(synhw) ((synhw)->capabilities & (1 << 7))
#define SYN_CAP_SLEEP(synhw) ((synhw)->capabilities & (1 << 4))
#define SYN_CAP_FOUR_BUTTON(synhw) ((synhw)->capabilities & (1 << 3))
#define SYN_CAP_MULTIFINGER(synhw) ((synhw)->capabilities & (1 << 1))
#define SYN_CAP_PALMDETECT(synhw) ((synhw)->capabilities & (1 << 0))
#define SYN_CAP_VALID(synhw) ((((synhw)->capabilities & 0x00ff00) >> 8) == 0x47)
#define SYN_EXT_CAP_REQUESTS(synhw) (((synhw)->capabilities & 0x700000) != 0)
#define SYN_CAP_MULTI_BUTTON_NO(synhw) (((synhw)->ext_cap & 0x00f000) >> 12)
/* synaptics modes query bits */
#define SYN_MODE_ABSOLUTE(m) ((m) & (1 << 7))
#define SYN_MODE_RATE(m) ((m) & (1 << 6))
#define SYN_MODE_BAUD_SLEEP(m) ((m) & (1 << 3))
#define SYN_MODE_DISABLE_GESTURE(m) ((m) & (1 << 2))
#define SYN_MODE_PACKSIZE(m) ((m) & (1 << 1))
#define SYN_MODE_WMODE(m) ((m) & (1 << 0))
#define SYN_MODE_VALID(m) (((m) & 0xffff00) == 0x3B47)
/* synaptics identify query bits */
#define SYN_ID_MODEL(synhw) (((synhw)->identity >> 4) & 0x0f)
#define SYN_ID_MAJOR(synhw) ((synhw)->identity & 0x0f)
#define SYN_ID_MINOR(synhw) (((synhw)->identity >> 16) & 0xff)
#define SYN_ID_IS_SYNAPTICS(synhw) ((((synhw)->identity >> 8) & 0xff) == 0x47)
typedef unsigned char byte;
struct PS2SynapticsHwInfo {
unsigned int model_id; /* Model-ID */
unsigned int capabilities; /* Capabilities */
unsigned int ext_cap; /* Extended Capabilities */
unsigned int identity; /* Identification */
};
Bool ps2_putbyte(int fd, byte b);
void ps2_print_ident(InputInfoPtr pInfo,
const struct PS2SynapticsHwInfo *synhw);
Bool PS2ReadHwStateProto(InputInfoPtr pInfo,
struct SynapticsProtocolOperations *proto_ops,
struct CommData *comm, struct SynapticsHwState *hwRet);
#endif /* _PS2COMM_H_ */
xf86-input-synaptics-1.9.2/src/properties.c 0000644 0143106 0000012 00000065111 14262661535 015544 0000000 0000000 /*
* Copyright © 2008-2012 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.
*
* Authors: Peter Hutterer
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include
#include "xf86Module.h"
#include
#include
#include
#include
#include "synapticsstr.h"
#include "synaptics-properties.h"
#ifndef XATOM_FLOAT
#define XATOM_FLOAT "FLOAT"
#endif
#ifndef XI_PROP_PRODUCT_ID
#define XI_PROP_PRODUCT_ID "Device Product ID"
#endif
#ifndef XI_PROP_DEVICE_NODE
#define XI_PROP_DEVICE_NODE "Device Node"
#endif
static Atom float_type;
Atom prop_edges = 0;
Atom prop_finger = 0;
Atom prop_tap_time = 0;
Atom prop_tap_move = 0;
Atom prop_tap_durations = 0;
Atom prop_clickpad = 0;
Atom prop_middle_timeout = 0;
Atom prop_twofinger_pressure = 0;
Atom prop_twofinger_width = 0;
Atom prop_scrolldist = 0;
Atom prop_scrolledge = 0;
Atom prop_scrolltwofinger = 0;
Atom prop_speed = 0;
Atom prop_edgemotion_pressure = 0;
Atom prop_edgemotion_speed = 0;
Atom prop_edgemotion_always = 0;
Atom prop_buttonscroll = 0;
Atom prop_buttonscroll_repeat = 0;
Atom prop_buttonscroll_time = 0;
Atom prop_off = 0;
Atom prop_lockdrags = 0;
Atom prop_lockdrags_time = 0;
Atom prop_tapaction = 0;
Atom prop_clickaction = 0;
Atom prop_circscroll = 0;
Atom prop_circscroll_dist = 0;
Atom prop_circscroll_trigger = 0;
Atom prop_circpad = 0;
Atom prop_palm = 0;
Atom prop_palm_dim = 0;
Atom prop_coastspeed = 0;
Atom prop_pressuremotion = 0;
Atom prop_pressuremotion_factor = 0;
Atom prop_grab = 0;
Atom prop_gestures = 0;
Atom prop_capabilities = 0;
Atom prop_resolution = 0;
Atom prop_area = 0;
Atom prop_softbutton_areas = 0;
Atom prop_secondary_softbutton_areas = 0;
Atom prop_noise_cancellation = 0;
Atom prop_product_id = 0;
Atom prop_device_node = 0;
static Atom
InitTypedAtom(DeviceIntPtr dev, char *name, Atom type, int format, int nvalues,
int *values)
{
int i;
Atom atom;
uint8_t val_8[9]; /* we never have more than 9 values in an atom */
uint16_t val_16[9];
uint32_t val_32[9];
pointer converted;
for (i = 0; i < nvalues; i++) {
switch (format) {
case 8:
val_8[i] = values[i];
break;
case 16:
val_16[i] = values[i];
break;
case 32:
val_32[i] = values[i];
break;
}
}
switch (format) {
case 8:
converted = val_8;
break;
case 16:
converted = val_16;
break;
case 32:
default:
converted = val_32;
break;
}
atom = MakeAtom(name, strlen(name), TRUE);
XIChangeDeviceProperty(dev, atom, type, format, PropModeReplace, nvalues,
converted, FALSE);
XISetDevicePropertyDeletable(dev, atom, FALSE);
return atom;
}
static Atom
InitAtom(DeviceIntPtr dev, char *name, int format, int nvalues, int *values)
{
return InitTypedAtom(dev, name, XA_INTEGER, format, nvalues, values);
}
static Atom
InitFloatAtom(DeviceIntPtr dev, char *name, int nvalues, float *values)
{
Atom atom;
atom = MakeAtom(name, strlen(name), TRUE);
XIChangeDeviceProperty(dev, atom, float_type, 32, PropModeReplace,
nvalues, values, FALSE);
XISetDevicePropertyDeletable(dev, atom, FALSE);
return atom;
}
static void
InitSoftButtonProperty(InputInfoPtr pInfo)
{
SynapticsPrivate *priv = (SynapticsPrivate *) pInfo->private;
SynapticsParameters *para = &priv->synpara;
int values[8];
values[0] = para->softbutton_areas[BOTTOM_RIGHT_BUTTON_AREA][LEFT];
values[1] = para->softbutton_areas[BOTTOM_RIGHT_BUTTON_AREA][RIGHT];
values[2] = para->softbutton_areas[BOTTOM_RIGHT_BUTTON_AREA][TOP];
values[3] = para->softbutton_areas[BOTTOM_RIGHT_BUTTON_AREA][BOTTOM];
values[4] = para->softbutton_areas[BOTTOM_MIDDLE_BUTTON_AREA][LEFT];
values[5] = para->softbutton_areas[BOTTOM_MIDDLE_BUTTON_AREA][RIGHT];
values[6] = para->softbutton_areas[BOTTOM_MIDDLE_BUTTON_AREA][TOP];
values[7] = para->softbutton_areas[BOTTOM_MIDDLE_BUTTON_AREA][BOTTOM];
prop_softbutton_areas =
InitAtom(pInfo->dev, SYNAPTICS_PROP_SOFTBUTTON_AREAS, 32, 8, values);
if (!para->has_secondary_buttons)
return;
values[0] = para->softbutton_areas[TOP_RIGHT_BUTTON_AREA][LEFT];
values[1] = para->softbutton_areas[TOP_RIGHT_BUTTON_AREA][RIGHT];
values[2] = para->softbutton_areas[TOP_RIGHT_BUTTON_AREA][TOP];
values[3] = para->softbutton_areas[TOP_RIGHT_BUTTON_AREA][BOTTOM];
values[4] = para->softbutton_areas[TOP_MIDDLE_BUTTON_AREA][LEFT];
values[5] = para->softbutton_areas[TOP_MIDDLE_BUTTON_AREA][RIGHT];
values[6] = para->softbutton_areas[TOP_MIDDLE_BUTTON_AREA][TOP];
values[7] = para->softbutton_areas[TOP_MIDDLE_BUTTON_AREA][BOTTOM];
if (values[0] || values[1] || values[2] || values[4] ||
values[5] || values[6] || values[7])
prop_secondary_softbutton_areas =
InitAtom(pInfo->dev, SYNAPTICS_PROP_SECONDARY_SOFTBUTTON_AREAS, 32, 8, values);
}
void
InitDeviceProperties(InputInfoPtr pInfo)
{
SynapticsPrivate *priv = (SynapticsPrivate *) pInfo->private;
SynapticsParameters *para = &priv->synpara;
int values[9]; /* we never have more than 9 values in an atom */
float fvalues[4]; /* never have more than 4 float values */
float_type = XIGetKnownProperty(XATOM_FLOAT);
if (!float_type) {
float_type = MakeAtom(XATOM_FLOAT, strlen(XATOM_FLOAT), TRUE);
if (!float_type) {
xf86IDrvMsg(pInfo, X_ERROR, "Failed to init float atom. "
"Disabling property support.\n");
return;
}
}
values[0] = para->left_edge;
values[1] = para->right_edge;
values[2] = para->top_edge;
values[3] = para->bottom_edge;
prop_edges = InitAtom(pInfo->dev, SYNAPTICS_PROP_EDGES, 32, 4, values);
values[0] = para->finger_low;
values[1] = para->finger_high;
values[2] = 0;
prop_finger = InitAtom(pInfo->dev, SYNAPTICS_PROP_FINGER, 32, 3, values);
prop_tap_time =
InitAtom(pInfo->dev, SYNAPTICS_PROP_TAP_TIME, 32, 1, ¶->tap_time);
prop_tap_move =
InitAtom(pInfo->dev, SYNAPTICS_PROP_TAP_MOVE, 32, 1, ¶->tap_move);
values[0] = para->single_tap_timeout;
values[1] = para->tap_time_2;
values[2] = para->click_time;
prop_tap_durations =
InitAtom(pInfo->dev, SYNAPTICS_PROP_TAP_DURATIONS, 32, 3, values);
prop_clickpad =
InitAtom(pInfo->dev, SYNAPTICS_PROP_CLICKPAD, 8, 1, ¶->clickpad);
prop_middle_timeout =
InitAtom(pInfo->dev, SYNAPTICS_PROP_MIDDLE_TIMEOUT, 32, 1,
¶->emulate_mid_button_time);
prop_twofinger_pressure =
InitAtom(pInfo->dev, SYNAPTICS_PROP_TWOFINGER_PRESSURE, 32, 1,
¶->emulate_twofinger_z);
prop_twofinger_width =
InitAtom(pInfo->dev, SYNAPTICS_PROP_TWOFINGER_WIDTH, 32, 1,
¶->emulate_twofinger_w);
values[0] = para->scroll_dist_vert;
values[1] = para->scroll_dist_horiz;
prop_scrolldist =
InitAtom(pInfo->dev, SYNAPTICS_PROP_SCROLL_DISTANCE, 32, 2, values);
values[0] = para->scroll_edge_vert;
values[1] = para->scroll_edge_horiz;
values[2] = para->scroll_edge_corner;
prop_scrolledge =
InitAtom(pInfo->dev, SYNAPTICS_PROP_SCROLL_EDGE, 8, 3, values);
values[0] = para->scroll_twofinger_vert;
values[1] = para->scroll_twofinger_horiz;
prop_scrolltwofinger =
InitAtom(pInfo->dev, SYNAPTICS_PROP_SCROLL_TWOFINGER, 8, 2, values);
fvalues[0] = para->min_speed;
fvalues[1] = para->max_speed;
fvalues[2] = para->accl;
fvalues[3] = 0;
prop_speed = InitFloatAtom(pInfo->dev, SYNAPTICS_PROP_SPEED, 4, fvalues);
if (priv->has_scrollbuttons) {
values[0] = para->updown_button_scrolling;
values[1] = para->leftright_button_scrolling;
prop_buttonscroll =
InitAtom(pInfo->dev, SYNAPTICS_PROP_BUTTONSCROLLING, 8, 2, values);
values[0] = para->updown_button_repeat;
values[1] = para->leftright_button_repeat;
prop_buttonscroll_repeat =
InitAtom(pInfo->dev, SYNAPTICS_PROP_BUTTONSCROLLING_REPEAT, 8, 2,
values);
prop_buttonscroll_time =
InitAtom(pInfo->dev, SYNAPTICS_PROP_BUTTONSCROLLING_TIME, 32, 1,
¶->scroll_button_repeat);
}
prop_off =
InitAtom(pInfo->dev, SYNAPTICS_PROP_OFF, 8, 1, ¶->touchpad_off);
prop_lockdrags =
InitAtom(pInfo->dev, SYNAPTICS_PROP_LOCKED_DRAGS, 8, 1,
¶->locked_drags);
prop_lockdrags_time =
InitAtom(pInfo->dev, SYNAPTICS_PROP_LOCKED_DRAGS_TIMEOUT, 32, 1,
¶->locked_drag_time);
memcpy(values, para->tap_action, MAX_TAP * sizeof(int));
prop_tapaction =
InitAtom(pInfo->dev, SYNAPTICS_PROP_TAP_ACTION, 8, MAX_TAP, values);
memcpy(values, para->click_action, MAX_CLICK * sizeof(int));
prop_clickaction =
InitAtom(pInfo->dev, SYNAPTICS_PROP_CLICK_ACTION, 8, MAX_CLICK, values);
prop_circscroll =
InitAtom(pInfo->dev, SYNAPTICS_PROP_CIRCULAR_SCROLLING, 8, 1,
¶->circular_scrolling);
fvalues[0] = para->scroll_dist_circ;
prop_circscroll_dist =
InitFloatAtom(pInfo->dev, SYNAPTICS_PROP_CIRCULAR_SCROLLING_DIST, 1,
fvalues);
prop_circscroll_trigger =
InitAtom(pInfo->dev, SYNAPTICS_PROP_CIRCULAR_SCROLLING_TRIGGER, 8, 1,
¶->circular_trigger);
prop_circpad =
InitAtom(pInfo->dev, SYNAPTICS_PROP_CIRCULAR_PAD, 8, 1,
¶->circular_pad);
prop_palm =
InitAtom(pInfo->dev, SYNAPTICS_PROP_PALM_DETECT, 8, 1,
¶->palm_detect);
values[0] = para->palm_min_width;
values[1] = para->palm_min_z;
prop_palm_dim =
InitAtom(pInfo->dev, SYNAPTICS_PROP_PALM_DIMENSIONS, 32, 2, values);
fvalues[0] = para->coasting_speed;
fvalues[1] = para->coasting_friction;
prop_coastspeed =
InitFloatAtom(pInfo->dev, SYNAPTICS_PROP_COASTING_SPEED, 2, fvalues);
values[0] = para->press_motion_min_z;
values[1] = para->press_motion_max_z;
prop_pressuremotion =
InitTypedAtom(pInfo->dev, SYNAPTICS_PROP_PRESSURE_MOTION, XA_CARDINAL,
32, 2, values);
fvalues[0] = para->press_motion_min_factor;
fvalues[1] = para->press_motion_max_factor;
prop_pressuremotion_factor =
InitFloatAtom(pInfo->dev, SYNAPTICS_PROP_PRESSURE_MOTION_FACTOR, 2,
fvalues);
prop_grab =
InitAtom(pInfo->dev, SYNAPTICS_PROP_GRAB, 8, 1,
¶->grab_event_device);
values[0] = para->tap_and_drag_gesture;
prop_gestures = InitAtom(pInfo->dev, SYNAPTICS_PROP_GESTURES, 8, 1, values);
values[0] = priv->has_left;
values[1] = priv->has_middle;
values[2] = priv->has_right;
values[3] = priv->has_double;
values[4] = priv->has_triple;
values[5] = priv->has_pressure;
values[6] = priv->has_width;
prop_capabilities =
InitAtom(pInfo->dev, SYNAPTICS_PROP_CAPABILITIES, 8, 7, values);
values[0] = para->resolution_vert;
values[1] = para->resolution_horiz;
prop_resolution =
InitAtom(pInfo->dev, SYNAPTICS_PROP_RESOLUTION, 32, 2, values);
values[0] = para->area_left_edge;
values[1] = para->area_right_edge;
values[2] = para->area_top_edge;
values[3] = para->area_bottom_edge;
prop_area = InitAtom(pInfo->dev, SYNAPTICS_PROP_AREA, 32, 4, values);
if (para->clickpad)
InitSoftButtonProperty(pInfo);
values[0] = para->hyst_x;
values[1] = para->hyst_y;
prop_noise_cancellation = InitAtom(pInfo->dev,
SYNAPTICS_PROP_NOISE_CANCELLATION, 32, 2,
values);
/* only init product_id property if we actually know them */
if (priv->id_vendor || priv->id_product) {
values[0] = priv->id_vendor;
values[1] = priv->id_product;
prop_product_id =
InitAtom(pInfo->dev, XI_PROP_PRODUCT_ID, 32, 2, values);
}
if (priv->device) {
prop_device_node =
MakeAtom(XI_PROP_DEVICE_NODE, strlen(XI_PROP_DEVICE_NODE), TRUE);
XIChangeDeviceProperty(pInfo->dev, prop_device_node, XA_STRING, 8,
PropModeReplace, strlen(priv->device),
(pointer) priv->device, FALSE);
XISetDevicePropertyDeletable(pInfo->dev, prop_device_node, FALSE);
}
}
int
SetProperty(DeviceIntPtr dev, Atom property, XIPropertyValuePtr prop,
BOOL checkonly)
{
InputInfoPtr pInfo = dev->public.devicePrivate;
SynapticsPrivate *priv = (SynapticsPrivate *) pInfo->private;
SynapticsParameters *para = &priv->synpara;
SynapticsParameters tmp;
/* If checkonly is set, no parameters may be changed. So just let the code
* change temporary variables and forget about it. */
if (checkonly) {
tmp = *para;
para = &tmp;
}
if (property == prop_edges) {
INT32 *edges;
if (prop->size != 4 || prop->format != 32 || prop->type != XA_INTEGER)
return BadMatch;
edges = (INT32 *) prop->data;
if (edges[0] > edges[1] || edges[2] > edges[3])
return BadValue;
para->left_edge = edges[0];
para->right_edge = edges[1];
para->top_edge = edges[2];
para->bottom_edge = edges[3];
}
else if (property == prop_finger) {
INT32 *finger;
if (prop->size != 3 || prop->format != 32 || prop->type != XA_INTEGER)
return BadMatch;
finger = (INT32 *) prop->data;
if (finger[0] > finger[1])
return BadValue;
para->finger_low = finger[0];
para->finger_high = finger[1];
}
else if (property == prop_tap_time) {
if (prop->size != 1 || prop->format != 32 || prop->type != XA_INTEGER)
return BadMatch;
para->tap_time = *(INT32 *) prop->data;
}
else if (property == prop_tap_move) {
if (prop->size != 1 || prop->format != 32 || prop->type != XA_INTEGER)
return BadMatch;
para->tap_move = *(INT32 *) prop->data;
}
else if (property == prop_tap_durations) {
INT32 *timeouts;
if (prop->size != 3 || prop->format != 32 || prop->type != XA_INTEGER)
return BadMatch;
timeouts = (INT32 *) prop->data;
para->single_tap_timeout = timeouts[0];
para->tap_time_2 = timeouts[1];
para->click_time = timeouts[2];
}
else if (property == prop_clickpad) {
BOOL value;
if (prop->size != 1 || prop->format != 8 || prop->type != XA_INTEGER)
return BadMatch;
value = *(BOOL *) prop->data;
if (!para->clickpad && value && !prop_softbutton_areas)
InitSoftButtonProperty(pInfo);
else if (para->clickpad && !value && prop_softbutton_areas) {
XIDeleteDeviceProperty(dev, prop_softbutton_areas, FALSE);
prop_softbutton_areas = 0;
}
para->clickpad = *(BOOL *) prop->data;
}
else if (property == prop_middle_timeout) {
if (prop->size != 1 || prop->format != 32 || prop->type != XA_INTEGER)
return BadMatch;
para->emulate_mid_button_time = *(INT32 *) prop->data;
}
else if (property == prop_twofinger_pressure) {
if (prop->size != 1 || prop->format != 32 || prop->type != XA_INTEGER)
return BadMatch;
para->emulate_twofinger_z = *(INT32 *) prop->data;
}
else if (property == prop_twofinger_width) {
if (prop->size != 1 || prop->format != 32 || prop->type != XA_INTEGER)
return BadMatch;
para->emulate_twofinger_w = *(INT32 *) prop->data;
}
else if (property == prop_scrolldist) {
INT32 *dist;
if (prop->size != 2 || prop->format != 32 || prop->type != XA_INTEGER)
return BadMatch;
dist = (INT32 *) prop->data;
if (dist[0] == 0 || dist[1] == 0)
return BadValue;
if (para->scroll_dist_vert != dist[0]) {
para->scroll_dist_vert = dist[0];
SetScrollValuator(dev, priv->scroll_axis_vert, SCROLL_TYPE_VERTICAL,
para->scroll_dist_vert, 0);
}
if (para->scroll_dist_horiz != dist[1]) {
para->scroll_dist_horiz = dist[1];
SetScrollValuator(dev, priv->scroll_axis_horiz,
SCROLL_TYPE_HORIZONTAL, para->scroll_dist_horiz,
0);
}
}
else if (property == prop_scrolledge) {
CARD8 *edge;
if (prop->size != 3 || prop->format != 8 || prop->type != XA_INTEGER)
return BadMatch;
edge = (BOOL *) prop->data;
para->scroll_edge_vert = edge[0];
para->scroll_edge_horiz = edge[1];
para->scroll_edge_corner = edge[2];
}
else if (property == prop_scrolltwofinger) {
CARD8 *twofinger;
if (prop->size != 2 || prop->format != 8 || prop->type != XA_INTEGER)
return BadMatch;
twofinger = (BOOL *) prop->data;
para->scroll_twofinger_vert = twofinger[0];
para->scroll_twofinger_horiz = twofinger[1];
}
else if (property == prop_speed) {
float *speed;
if (prop->size != 4 || prop->format != 32 || prop->type != float_type)
return BadMatch;
speed = (float *) prop->data;
para->min_speed = speed[0];
para->max_speed = speed[1];
para->accl = speed[2];
}
else if (property == prop_buttonscroll) {
BOOL *scroll;
if (!priv->has_scrollbuttons)
return BadMatch;
if (prop->size != 2 || prop->format != 8 || prop->type != XA_INTEGER)
return BadMatch;
scroll = (BOOL *) prop->data;
para->updown_button_scrolling = scroll[0];
para->leftright_button_scrolling = scroll[1];
}
else if (property == prop_buttonscroll_repeat) {
BOOL *repeat;
if (!priv->has_scrollbuttons)
return BadMatch;
if (prop->size != 2 || prop->format != 8 || prop->type != XA_INTEGER)
return BadMatch;
repeat = (BOOL *) prop->data;
para->updown_button_repeat = repeat[0];
para->leftright_button_repeat = repeat[1];
}
else if (property == prop_buttonscroll_time) {
if (!priv->has_scrollbuttons)
return BadMatch;
if (prop->size != 1 || prop->format != 32 || prop->type != XA_INTEGER)
return BadMatch;
para->scroll_button_repeat = *(INT32 *) prop->data;
}
else if (property == prop_off) {
CARD8 off;
if (prop->size != 1 || prop->format != 8 || prop->type != XA_INTEGER)
return BadMatch;
off = *(CARD8 *) prop->data;
if (off > 2)
return BadValue;
para->touchpad_off = off;
}
else if (property == prop_gestures) {
BOOL *gestures;
if (prop->size != 1 || prop->format != 8 || prop->type != XA_INTEGER)
return BadMatch;
gestures = (BOOL *) prop->data;
para->tap_and_drag_gesture = gestures[0];
}
else if (property == prop_lockdrags) {
if (prop->size != 1 || prop->format != 8 || prop->type != XA_INTEGER)
return BadMatch;
para->locked_drags = *(BOOL *) prop->data;
}
else if (property == prop_lockdrags_time) {
if (prop->size != 1 || prop->format != 32 || prop->type != XA_INTEGER)
return BadMatch;
para->locked_drag_time = *(INT32 *) prop->data;
}
else if (property == prop_tapaction) {
int i;
CARD8 *action;
if (prop->size > MAX_TAP || prop->format != 8 ||
prop->type != XA_INTEGER)
return BadMatch;
action = (CARD8 *) prop->data;
for (i = 0; i < MAX_TAP; i++)
para->tap_action[i] = action[i];
}
else if (property == prop_clickaction) {
int i;
CARD8 *action;
if (prop->size > MAX_CLICK || prop->format != 8 ||
prop->type != XA_INTEGER)
return BadMatch;
action = (CARD8 *) prop->data;
for (i = 0; i < MAX_CLICK; i++)
para->click_action[i] = action[i];
}
else if (property == prop_circscroll) {
if (prop->size != 1 || prop->format != 8 || prop->type != XA_INTEGER)
return BadMatch;
para->circular_scrolling = *(BOOL *) prop->data;
}
else if (property == prop_circscroll_dist) {
float circdist;
if (prop->size != 1 || prop->format != 32 || prop->type != float_type)
return BadMatch;
circdist = *(float *) prop->data;
if (circdist == 0)
return BadValue;
para->scroll_dist_circ = circdist;
}
else if (property == prop_circscroll_trigger) {
int trigger;
if (prop->size != 1 || prop->format != 8 || prop->type != XA_INTEGER)
return BadMatch;
trigger = *(CARD8 *) prop->data;
if (trigger > 8)
return BadValue;
para->circular_trigger = trigger;
}
else if (property == prop_circpad) {
if (prop->size != 1 || prop->format != 8 || prop->type != XA_INTEGER)
return BadMatch;
para->circular_pad = *(BOOL *) prop->data;
}
else if (property == prop_palm) {
if (prop->size != 1 || prop->format != 8 || prop->type != XA_INTEGER)
return BadMatch;
para->palm_detect = *(BOOL *) prop->data;
}
else if (property == prop_palm_dim) {
INT32 *dim;
if (prop->size != 2 || prop->format != 32 || prop->type != XA_INTEGER)
return BadMatch;
dim = (INT32 *) prop->data;
para->palm_min_width = dim[0];
para->palm_min_z = dim[1];
}
else if (property == prop_coastspeed) {
float *coast_speeds;
if (prop->size != 2 || prop->format != 32 || prop->type != float_type)
return BadMatch;
coast_speeds = (float *) prop->data;
para->coasting_speed = coast_speeds[0];
para->coasting_friction = coast_speeds[1];
}
else if (property == prop_pressuremotion) {
CARD32 *press;
if (prop->size != 2 || prop->format != 32 || prop->type != XA_CARDINAL)
return BadMatch;
press = (CARD32 *) prop->data;
if (press[0] > press[1])
return BadValue;
para->press_motion_min_z = press[0];
para->press_motion_max_z = press[1];
}
else if (property == prop_pressuremotion_factor) {
float *press;
if (prop->size != 2 || prop->format != 32 || prop->type != float_type)
return BadMatch;
press = (float *) prop->data;
if (press[0] > press[1])
return BadValue;
para->press_motion_min_factor = press[0];
para->press_motion_max_factor = press[1];
}
else if (property == prop_grab) {
if (prop->size != 1 || prop->format != 8 || prop->type != XA_INTEGER)
return BadMatch;
para->grab_event_device = *(BOOL *) prop->data;
}
else if (property == prop_capabilities) {
/* read-only */
return BadValue;
}
else if (property == prop_resolution) {
/* read-only */
return BadValue;
}
else if (property == prop_area) {
INT32 *area;
if (prop->size != 4 || prop->format != 32 || prop->type != XA_INTEGER)
return BadMatch;
area = (INT32 *) prop->data;
if ((((area[0] != 0) && (area[1] != 0)) && (area[0] > area[1])) ||
(((area[2] != 0) && (area[3] != 0)) && (area[2] > area[3])))
return BadValue;
para->area_left_edge = area[0];
para->area_right_edge = area[1];
para->area_top_edge = area[2];
para->area_bottom_edge = area[3];
}
else if (property == prop_softbutton_areas) {
int *areas;
if (prop->size != 8 || prop->format != 32 || prop->type != XA_INTEGER)
return BadMatch;
areas = (int *) prop->data;
if (!SynapticsIsSoftButtonAreasValid(areas))
return BadValue;
memcpy(para->softbutton_areas[BOTTOM_RIGHT_BUTTON_AREA], areas, 4 * sizeof(int));
memcpy(para->softbutton_areas[BOTTOM_MIDDLE_BUTTON_AREA], areas + 4, 4 * sizeof(int));
}
else if (property == prop_secondary_softbutton_areas) {
int *areas;
if (prop->size != 8 || prop->format != 32 || prop->type != XA_INTEGER)
return BadMatch;
areas = (int *) prop->data;
if (!SynapticsIsSoftButtonAreasValid(areas))
return BadValue;
memcpy(para->softbutton_areas[TOP_RIGHT_BUTTON_AREA], areas, 4 * sizeof(int));
memcpy(para->softbutton_areas[TOP_MIDDLE_BUTTON_AREA], areas + 4, 4 * sizeof(int));
}
else if (property == prop_noise_cancellation) {
INT32 *hyst;
if (prop->size != 2 || prop->format != 32 || prop->type != XA_INTEGER)
return BadMatch;
hyst = (INT32 *) prop->data;
if (hyst[0] < 0 || hyst[1] < 0)
return BadValue;
para->hyst_x = hyst[0];
para->hyst_y = hyst[1];
}
else if (property == prop_product_id || property == prop_device_node)
return BadValue; /* read-only */
else { /* unknown property */
if (strcmp(SYNAPTICS_PROP_SOFTBUTTON_AREAS, NameForAtom(property)) == 0)
{
prop_softbutton_areas = property;
if (SetProperty(dev, property, prop, checkonly) != Success)
prop_softbutton_areas = 0;
else if (!checkonly)
XISetDevicePropertyDeletable(dev, property, FALSE);
}
}
return Success;
}
xf86-input-synaptics-1.9.2/config.sub 0000755 0143106 0000012 00000104714 14262661543 014402 0000000 0000000 #! /bin/sh
# Configuration validation subroutine script.
# Copyright 1992-2021 Free Software Foundation, Inc.
# shellcheck disable=SC2006,SC2268 # see below for rationale
timestamp='2021-08-14'
# This file 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 3 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, see .
#
# As a special exception to the GNU General Public License, if you
# distribute this file as part of a program that contains a
# configuration script generated by Autoconf, you may include it under
# the same distribution terms that you use for the rest of that
# program. This Exception is an additional permission under section 7
# of the GNU General Public License, version 3 ("GPLv3").
# Please send patches to .
#
# Configuration subroutine to validate and canonicalize a configuration type.
# Supply the specified configuration type as an argument.
# If it is invalid, we print an error message on stderr and exit with code 1.
# Otherwise, we print the canonical config type on stdout and succeed.
# You can get the latest version of this script from:
# https://git.savannah.gnu.org/cgit/config.git/plain/config.sub
# This file is supposed to be the same for all GNU packages
# and recognize all the CPU types, system types and aliases
# that are meaningful with *any* GNU software.
# Each package is responsible for reporting which valid configurations
# it does not support. The user should be able to distinguish
# a failure to support a valid configuration from a meaningless
# configuration.
# The goal of this file is to map all the various variations of a given
# machine specification into a single specification in the form:
# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM
# or in some cases, the newer four-part form:
# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM
# It is wrong to echo any other type of specification.
# The "shellcheck disable" line above the timestamp inhibits complaints
# about features and limitations of the classic Bourne shell that were
# superseded or lifted in POSIX. However, this script identifies a wide
# variety of pre-POSIX systems that do not have POSIX shells at all, and
# even some reasonably current systems (Solaris 10 as case-in-point) still
# have a pre-POSIX /bin/sh.
me=`echo "$0" | sed -e 's,.*/,,'`
usage="\
Usage: $0 [OPTION] CPU-MFR-OPSYS or ALIAS
Canonicalize a configuration name.
Options:
-h, --help print this help, then exit
-t, --time-stamp print date of last modification, then exit
-v, --version print version number, then exit
Report bugs and patches to ."
version="\
GNU config.sub ($timestamp)
Copyright 1992-2021 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
help="
Try \`$me --help' for more information."
# Parse command line
while test $# -gt 0 ; do
case $1 in
--time-stamp | --time* | -t )
echo "$timestamp" ; exit ;;
--version | -v )
echo "$version" ; exit ;;
--help | --h* | -h )
echo "$usage"; exit ;;
-- ) # Stop option processing
shift; break ;;
- ) # Use stdin as input.
break ;;
-* )
echo "$me: invalid option $1$help" >&2
exit 1 ;;
*local*)
# First pass through any local machine types.
echo "$1"
exit ;;
* )
break ;;
esac
done
case $# in
0) echo "$me: missing argument$help" >&2
exit 1;;
1) ;;
*) echo "$me: too many arguments$help" >&2
exit 1;;
esac
# Split fields of configuration type
# shellcheck disable=SC2162
saved_IFS=$IFS
IFS="-" read field1 field2 field3 field4 <&2
exit 1
;;
*-*-*-*)
basic_machine=$field1-$field2
basic_os=$field3-$field4
;;
*-*-*)
# Ambiguous whether COMPANY is present, or skipped and KERNEL-OS is two
# parts
maybe_os=$field2-$field3
case $maybe_os in
nto-qnx* | linux-* | uclinux-uclibc* \
| uclinux-gnu* | kfreebsd*-gnu* | knetbsd*-gnu* | netbsd*-gnu* \
| netbsd*-eabi* | kopensolaris*-gnu* | cloudabi*-eabi* \
| storm-chaos* | os2-emx* | rtmk-nova*)
basic_machine=$field1
basic_os=$maybe_os
;;
android-linux)
basic_machine=$field1-unknown
basic_os=linux-android
;;
*)
basic_machine=$field1-$field2
basic_os=$field3
;;
esac
;;
*-*)
# A lone config we happen to match not fitting any pattern
case $field1-$field2 in
decstation-3100)
basic_machine=mips-dec
basic_os=
;;
*-*)
# Second component is usually, but not always the OS
case $field2 in
# Prevent following clause from handling this valid os
sun*os*)
basic_machine=$field1
basic_os=$field2
;;
zephyr*)
basic_machine=$field1-unknown
basic_os=$field2
;;
# Manufacturers
dec* | mips* | sequent* | encore* | pc533* | sgi* | sony* \
| att* | 7300* | 3300* | delta* | motorola* | sun[234]* \
| unicom* | ibm* | next | hp | isi* | apollo | altos* \
| convergent* | ncr* | news | 32* | 3600* | 3100* \
| hitachi* | c[123]* | convex* | sun | crds | omron* | dg \
| ultra | tti* | harris | dolphin | highlevel | gould \
| cbm | ns | masscomp | apple | axis | knuth | cray \
| microblaze* | sim | cisco \
| oki | wec | wrs | winbond)
basic_machine=$field1-$field2
basic_os=
;;
*)
basic_machine=$field1
basic_os=$field2
;;
esac
;;
esac
;;
*)
# Convert single-component short-hands not valid as part of
# multi-component configurations.
case $field1 in
386bsd)
basic_machine=i386-pc
basic_os=bsd
;;
a29khif)
basic_machine=a29k-amd
basic_os=udi
;;
adobe68k)
basic_machine=m68010-adobe
basic_os=scout
;;
alliant)
basic_machine=fx80-alliant
basic_os=
;;
altos | altos3068)
basic_machine=m68k-altos
basic_os=
;;
am29k)
basic_machine=a29k-none
basic_os=bsd
;;
amdahl)
basic_machine=580-amdahl
basic_os=sysv
;;
amiga)
basic_machine=m68k-unknown
basic_os=
;;
amigaos | amigados)
basic_machine=m68k-unknown
basic_os=amigaos
;;
amigaunix | amix)
basic_machine=m68k-unknown
basic_os=sysv4
;;
apollo68)
basic_machine=m68k-apollo
basic_os=sysv
;;
apollo68bsd)
basic_machine=m68k-apollo
basic_os=bsd
;;
aros)
basic_machine=i386-pc
basic_os=aros
;;
aux)
basic_machine=m68k-apple
basic_os=aux
;;
balance)
basic_machine=ns32k-sequent
basic_os=dynix
;;
blackfin)
basic_machine=bfin-unknown
basic_os=linux
;;
cegcc)
basic_machine=arm-unknown
basic_os=cegcc
;;
convex-c1)
basic_machine=c1-convex
basic_os=bsd
;;
convex-c2)
basic_machine=c2-convex
basic_os=bsd
;;
convex-c32)
basic_machine=c32-convex
basic_os=bsd
;;
convex-c34)
basic_machine=c34-convex
basic_os=bsd
;;
convex-c38)
basic_machine=c38-convex
basic_os=bsd
;;
cray)
basic_machine=j90-cray
basic_os=unicos
;;
crds | unos)
basic_machine=m68k-crds
basic_os=
;;
da30)
basic_machine=m68k-da30
basic_os=
;;
decstation | pmax | pmin | dec3100 | decstatn)
basic_machine=mips-dec
basic_os=
;;
delta88)
basic_machine=m88k-motorola
basic_os=sysv3
;;
dicos)
basic_machine=i686-pc
basic_os=dicos
;;
djgpp)
basic_machine=i586-pc
basic_os=msdosdjgpp
;;
ebmon29k)
basic_machine=a29k-amd
basic_os=ebmon
;;
es1800 | OSE68k | ose68k | ose | OSE)
basic_machine=m68k-ericsson
basic_os=ose
;;
gmicro)
basic_machine=tron-gmicro
basic_os=sysv
;;
go32)
basic_machine=i386-pc
basic_os=go32
;;
h8300hms)
basic_machine=h8300-hitachi
basic_os=hms
;;
h8300xray)
basic_machine=h8300-hitachi
basic_os=xray
;;
h8500hms)
basic_machine=h8500-hitachi
basic_os=hms
;;
harris)
basic_machine=m88k-harris
basic_os=sysv3
;;
hp300 | hp300hpux)
basic_machine=m68k-hp
basic_os=hpux
;;
hp300bsd)
basic_machine=m68k-hp
basic_os=bsd
;;
hppaosf)
basic_machine=hppa1.1-hp
basic_os=osf
;;
hppro)
basic_machine=hppa1.1-hp
basic_os=proelf
;;
i386mach)
basic_machine=i386-mach
basic_os=mach
;;
isi68 | isi)
basic_machine=m68k-isi
basic_os=sysv
;;
m68knommu)
basic_machine=m68k-unknown
basic_os=linux
;;
magnum | m3230)
basic_machine=mips-mips
basic_os=sysv
;;
merlin)
basic_machine=ns32k-utek
basic_os=sysv
;;
mingw64)
basic_machine=x86_64-pc
basic_os=mingw64
;;
mingw32)
basic_machine=i686-pc
basic_os=mingw32
;;
mingw32ce)
basic_machine=arm-unknown
basic_os=mingw32ce
;;
monitor)
basic_machine=m68k-rom68k
basic_os=coff
;;
morphos)
basic_machine=powerpc-unknown
basic_os=morphos
;;
moxiebox)
basic_machine=moxie-unknown
basic_os=moxiebox
;;
msdos)
basic_machine=i386-pc
basic_os=msdos
;;
msys)
basic_machine=i686-pc
basic_os=msys
;;
mvs)
basic_machine=i370-ibm
basic_os=mvs
;;
nacl)
basic_machine=le32-unknown
basic_os=nacl
;;
ncr3000)
basic_machine=i486-ncr
basic_os=sysv4
;;
netbsd386)
basic_machine=i386-pc
basic_os=netbsd
;;
netwinder)
basic_machine=armv4l-rebel
basic_os=linux
;;
news | news700 | news800 | news900)
basic_machine=m68k-sony
basic_os=newsos
;;
news1000)
basic_machine=m68030-sony
basic_os=newsos
;;
necv70)
basic_machine=v70-nec
basic_os=sysv
;;
nh3000)
basic_machine=m68k-harris
basic_os=cxux
;;
nh[45]000)
basic_machine=m88k-harris
basic_os=cxux
;;
nindy960)
basic_machine=i960-intel
basic_os=nindy
;;
mon960)
basic_machine=i960-intel
basic_os=mon960
;;
nonstopux)
basic_machine=mips-compaq
basic_os=nonstopux
;;
os400)
basic_machine=powerpc-ibm
basic_os=os400
;;
OSE68000 | ose68000)
basic_machine=m68000-ericsson
basic_os=ose
;;
os68k)
basic_machine=m68k-none
basic_os=os68k
;;
paragon)
basic_machine=i860-intel
basic_os=osf
;;
parisc)
basic_machine=hppa-unknown
basic_os=linux
;;
psp)
basic_machine=mipsallegrexel-sony
basic_os=psp
;;
pw32)
basic_machine=i586-unknown
basic_os=pw32
;;
rdos | rdos64)
basic_machine=x86_64-pc
basic_os=rdos
;;
rdos32)
basic_machine=i386-pc
basic_os=rdos
;;
rom68k)
basic_machine=m68k-rom68k
basic_os=coff
;;
sa29200)
basic_machine=a29k-amd
basic_os=udi
;;
sei)
basic_machine=mips-sei
basic_os=seiux
;;
sequent)
basic_machine=i386-sequent
basic_os=
;;
sps7)
basic_machine=m68k-bull
basic_os=sysv2
;;
st2000)
basic_machine=m68k-tandem
basic_os=
;;
stratus)
basic_machine=i860-stratus
basic_os=sysv4
;;
sun2)
basic_machine=m68000-sun
basic_os=
;;
sun2os3)
basic_machine=m68000-sun
basic_os=sunos3
;;
sun2os4)
basic_machine=m68000-sun
basic_os=sunos4
;;
sun3)
basic_machine=m68k-sun
basic_os=
;;
sun3os3)
basic_machine=m68k-sun
basic_os=sunos3
;;
sun3os4)
basic_machine=m68k-sun
basic_os=sunos4
;;
sun4)
basic_machine=sparc-sun
basic_os=
;;
sun4os3)
basic_machine=sparc-sun
basic_os=sunos3
;;
sun4os4)
basic_machine=sparc-sun
basic_os=sunos4
;;
sun4sol2)
basic_machine=sparc-sun
basic_os=solaris2
;;
sun386 | sun386i | roadrunner)
basic_machine=i386-sun
basic_os=
;;
sv1)
basic_machine=sv1-cray
basic_os=unicos
;;
symmetry)
basic_machine=i386-sequent
basic_os=dynix
;;
t3e)
basic_machine=alphaev5-cray
basic_os=unicos
;;
t90)
basic_machine=t90-cray
basic_os=unicos
;;
toad1)
basic_machine=pdp10-xkl
basic_os=tops20
;;
tpf)
basic_machine=s390x-ibm
basic_os=tpf
;;
udi29k)
basic_machine=a29k-amd
basic_os=udi
;;
ultra3)
basic_machine=a29k-nyu
basic_os=sym1
;;
v810 | necv810)
basic_machine=v810-nec
basic_os=none
;;
vaxv)
basic_machine=vax-dec
basic_os=sysv
;;
vms)
basic_machine=vax-dec
basic_os=vms
;;
vsta)
basic_machine=i386-pc
basic_os=vsta
;;
vxworks960)
basic_machine=i960-wrs
basic_os=vxworks
;;
vxworks68)
basic_machine=m68k-wrs
basic_os=vxworks
;;
vxworks29k)
basic_machine=a29k-wrs
basic_os=vxworks
;;
xbox)
basic_machine=i686-pc
basic_os=mingw32
;;
ymp)
basic_machine=ymp-cray
basic_os=unicos
;;
*)
basic_machine=$1
basic_os=
;;
esac
;;
esac
# Decode 1-component or ad-hoc basic machines
case $basic_machine in
# Here we handle the default manufacturer of certain CPU types. It is in
# some cases the only manufacturer, in others, it is the most popular.
w89k)
cpu=hppa1.1
vendor=winbond
;;
op50n)
cpu=hppa1.1
vendor=oki
;;
op60c)
cpu=hppa1.1
vendor=oki
;;
ibm*)
cpu=i370
vendor=ibm
;;
orion105)
cpu=clipper
vendor=highlevel
;;
mac | mpw | mac-mpw)
cpu=m68k
vendor=apple
;;
pmac | pmac-mpw)
cpu=powerpc
vendor=apple
;;
# Recognize the various machine names and aliases which stand
# for a CPU type and a company and sometimes even an OS.
3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc)
cpu=m68000
vendor=att
;;
3b*)
cpu=we32k
vendor=att
;;
bluegene*)
cpu=powerpc
vendor=ibm
basic_os=cnk
;;
decsystem10* | dec10*)
cpu=pdp10
vendor=dec
basic_os=tops10
;;
decsystem20* | dec20*)
cpu=pdp10
vendor=dec
basic_os=tops20
;;
delta | 3300 | motorola-3300 | motorola-delta \
| 3300-motorola | delta-motorola)
cpu=m68k
vendor=motorola
;;
dpx2*)
cpu=m68k
vendor=bull
basic_os=sysv3
;;
encore | umax | mmax)
cpu=ns32k
vendor=encore
;;
elxsi)
cpu=elxsi
vendor=elxsi
basic_os=${basic_os:-bsd}
;;
fx2800)
cpu=i860
vendor=alliant
;;
genix)
cpu=ns32k
vendor=ns
;;
h3050r* | hiux*)
cpu=hppa1.1
vendor=hitachi
basic_os=hiuxwe2
;;
hp3k9[0-9][0-9] | hp9[0-9][0-9])
cpu=hppa1.0
vendor=hp
;;
hp9k2[0-9][0-9] | hp9k31[0-9])
cpu=m68000
vendor=hp
;;
hp9k3[2-9][0-9])
cpu=m68k
vendor=hp
;;
hp9k6[0-9][0-9] | hp6[0-9][0-9])
cpu=hppa1.0
vendor=hp
;;
hp9k7[0-79][0-9] | hp7[0-79][0-9])
cpu=hppa1.1
vendor=hp
;;
hp9k78[0-9] | hp78[0-9])
# FIXME: really hppa2.0-hp
cpu=hppa1.1
vendor=hp
;;
hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893)
# FIXME: really hppa2.0-hp
cpu=hppa1.1
vendor=hp
;;
hp9k8[0-9][13679] | hp8[0-9][13679])
cpu=hppa1.1
vendor=hp
;;
hp9k8[0-9][0-9] | hp8[0-9][0-9])
cpu=hppa1.0
vendor=hp
;;
i*86v32)
cpu=`echo "$1" | sed -e 's/86.*/86/'`
vendor=pc
basic_os=sysv32
;;
i*86v4*)
cpu=`echo "$1" | sed -e 's/86.*/86/'`
vendor=pc
basic_os=sysv4
;;
i*86v)
cpu=`echo "$1" | sed -e 's/86.*/86/'`
vendor=pc
basic_os=sysv
;;
i*86sol2)
cpu=`echo "$1" | sed -e 's/86.*/86/'`
vendor=pc
basic_os=solaris2
;;
j90 | j90-cray)
cpu=j90
vendor=cray
basic_os=${basic_os:-unicos}
;;
iris | iris4d)
cpu=mips
vendor=sgi
case $basic_os in
irix*)
;;
*)
basic_os=irix4
;;
esac
;;
miniframe)
cpu=m68000
vendor=convergent
;;
*mint | mint[0-9]* | *MiNT | *MiNT[0-9]*)
cpu=m68k
vendor=atari
basic_os=mint
;;
news-3600 | risc-news)
cpu=mips
vendor=sony
basic_os=newsos
;;
next | m*-next)
cpu=m68k
vendor=next
case $basic_os in
openstep*)
;;
nextstep*)
;;
ns2*)
basic_os=nextstep2
;;
*)
basic_os=nextstep3
;;
esac
;;
np1)
cpu=np1
vendor=gould
;;
op50n-* | op60c-*)
cpu=hppa1.1
vendor=oki
basic_os=proelf
;;
pa-hitachi)
cpu=hppa1.1
vendor=hitachi
basic_os=hiuxwe2
;;
pbd)
cpu=sparc
vendor=tti
;;
pbb)
cpu=m68k
vendor=tti
;;
pc532)
cpu=ns32k
vendor=pc532
;;
pn)
cpu=pn
vendor=gould
;;
power)
cpu=power
vendor=ibm
;;
ps2)
cpu=i386
vendor=ibm
;;
rm[46]00)
cpu=mips
vendor=siemens
;;
rtpc | rtpc-*)
cpu=romp
vendor=ibm
;;
sde)
cpu=mipsisa32
vendor=sde
basic_os=${basic_os:-elf}
;;
simso-wrs)
cpu=sparclite
vendor=wrs
basic_os=vxworks
;;
tower | tower-32)
cpu=m68k
vendor=ncr
;;
vpp*|vx|vx-*)
cpu=f301
vendor=fujitsu
;;
w65)
cpu=w65
vendor=wdc
;;
w89k-*)
cpu=hppa1.1
vendor=winbond
basic_os=proelf
;;
none)
cpu=none
vendor=none
;;
leon|leon[3-9])
cpu=sparc
vendor=$basic_machine
;;
leon-*|leon[3-9]-*)
cpu=sparc
vendor=`echo "$basic_machine" | sed 's/-.*//'`
;;
*-*)
# shellcheck disable=SC2162
saved_IFS=$IFS
IFS="-" read cpu vendor <&2
exit 1
;;
esac
;;
esac
# Here we canonicalize certain aliases for manufacturers.
case $vendor in
digital*)
vendor=dec
;;
commodore*)
vendor=cbm
;;
*)
;;
esac
# Decode manufacturer-specific aliases for certain operating systems.
if test x$basic_os != x
then
# First recognize some ad-hoc caes, or perhaps split kernel-os, or else just
# set os.
case $basic_os in
gnu/linux*)
kernel=linux
os=`echo "$basic_os" | sed -e 's|gnu/linux|gnu|'`
;;
os2-emx)
kernel=os2
os=`echo "$basic_os" | sed -e 's|os2-emx|emx|'`
;;
nto-qnx*)
kernel=nto
os=`echo "$basic_os" | sed -e 's|nto-qnx|qnx|'`
;;
*-*)
# shellcheck disable=SC2162
saved_IFS=$IFS
IFS="-" read kernel os <&2
exit 1
;;
esac
# As a final step for OS-related things, validate the OS-kernel combination
# (given a valid OS), if there is a kernel.
case $kernel-$os in
linux-gnu* | linux-dietlibc* | linux-android* | linux-newlib* \
| linux-musl* | linux-relibc* | linux-uclibc* )
;;
uclinux-uclibc* )
;;
-dietlibc* | -newlib* | -musl* | -relibc* | -uclibc* )
# These are just libc implementations, not actual OSes, and thus
# require a kernel.
echo "Invalid configuration \`$1': libc \`$os' needs explicit kernel." 1>&2
exit 1
;;
kfreebsd*-gnu* | kopensolaris*-gnu*)
;;
vxworks-simlinux | vxworks-simwindows | vxworks-spe)
;;
nto-qnx*)
;;
os2-emx)
;;
*-eabi* | *-gnueabi*)
;;
-*)
# Blank kernel with real OS is always fine.
;;
*-*)
echo "Invalid configuration \`$1': Kernel \`$kernel' not known to work with OS \`$os'." 1>&2
exit 1
;;
esac
# Here we handle the case where we know the os, and the CPU type, but not the
# manufacturer. We pick the logical manufacturer.
case $vendor in
unknown)
case $cpu-$os in
*-riscix*)
vendor=acorn
;;
*-sunos*)
vendor=sun
;;
*-cnk* | *-aix*)
vendor=ibm
;;
*-beos*)
vendor=be
;;
*-hpux*)
vendor=hp
;;
*-mpeix*)
vendor=hp
;;
*-hiux*)
vendor=hitachi
;;
*-unos*)
vendor=crds
;;
*-dgux*)
vendor=dg
;;
*-luna*)
vendor=omron
;;
*-genix*)
vendor=ns
;;
*-clix*)
vendor=intergraph
;;
*-mvs* | *-opened*)
vendor=ibm
;;
*-os400*)
vendor=ibm
;;
s390-* | s390x-*)
vendor=ibm
;;
*-ptx*)
vendor=sequent
;;
*-tpf*)
vendor=ibm
;;
*-vxsim* | *-vxworks* | *-windiss*)
vendor=wrs
;;
*-aux*)
vendor=apple
;;
*-hms*)
vendor=hitachi
;;
*-mpw* | *-macos*)
vendor=apple
;;
*-*mint | *-mint[0-9]* | *-*MiNT | *-MiNT[0-9]*)
vendor=atari
;;
*-vos*)
vendor=stratus
;;
esac
;;
esac
echo "$cpu-$vendor-${kernel:+$kernel-}$os"
exit
# Local variables:
# eval: (add-hook 'before-save-hook 'time-stamp)
# time-stamp-start: "timestamp='"
# time-stamp-format: "%:y-%02m-%02d"
# time-stamp-end: "'"
# End:
xf86-input-synaptics-1.9.2/Makefile.in 0000644 0143106 0000012 00000074301 14262661543 014462 0000000 0000000 # Makefile.in generated by automake 1.16.5 from Makefile.am.
# @configure_input@
# Copyright (C) 1994-2021 Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE.
@SET_MAKE@
# Copyright 2005 Adam Jackson.
#
# Permission is hereby granted, free of charge, to any person obtaining a
# copy of this software and associated documentation files (the "Software"),
# to deal in the Software without restriction, including without limitation
# on the rights to use, copy, modify, merge, publish, distribute, sub
# license, and/or sell copies of the Software, and to permit persons to whom
# the Software is furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice (including the next
# paragraph) shall be included in all copies or substantial portions of the
# Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
# ADAM JACKSON BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
VPATH = @srcdir@
am__is_gnu_make = { \
if test -z '$(MAKELEVEL)'; then \
false; \
elif test -n '$(MAKE_HOST)'; then \
true; \
elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
true; \
else \
false; \
fi; \
}
am__make_running_with_option = \
case $${target_option-} in \
?) ;; \
*) echo "am__make_running_with_option: internal error: invalid" \
"target option '$${target_option-}' specified" >&2; \
exit 1;; \
esac; \
has_opt=no; \
sane_makeflags=$$MAKEFLAGS; \
if $(am__is_gnu_make); then \
sane_makeflags=$$MFLAGS; \
else \
case $$MAKEFLAGS in \
*\\[\ \ ]*) \
bs=\\; \
sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
| sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \
esac; \
fi; \
skip_next=no; \
strip_trailopt () \
{ \
flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
}; \
for flg in $$sane_makeflags; do \
test $$skip_next = yes && { skip_next=no; continue; }; \
case $$flg in \
*=*|--*) continue;; \
-*I) strip_trailopt 'I'; skip_next=yes;; \
-*I?*) strip_trailopt 'I';; \
-*O) strip_trailopt 'O'; skip_next=yes;; \
-*O?*) strip_trailopt 'O';; \
-*l) strip_trailopt 'l'; skip_next=yes;; \
-*l?*) strip_trailopt 'l';; \
-[dEDm]) skip_next=yes;; \
-[JT]) skip_next=yes;; \
esac; \
case $$flg in \
*$$target_option*) has_opt=yes; break;; \
esac; \
done; \
test $$has_opt = yes
am__make_dryrun = (target_option=n; $(am__make_running_with_option))
am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
pkgdatadir = $(datadir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
pkglibexecdir = $(libexecdir)/@PACKAGE@
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
install_sh_DATA = $(install_sh) -c -m 644
install_sh_PROGRAM = $(install_sh) -c
install_sh_SCRIPT = $(install_sh) -c
INSTALL_HEADER = $(INSTALL_DATA)
transform = $(program_transform_name)
NORMAL_INSTALL = :
PRE_INSTALL = :
POST_INSTALL = :
NORMAL_UNINSTALL = :
PRE_UNINSTALL = :
POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
subdir = .
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
DIST_COMMON = $(srcdir)/Makefile.am $(top_srcdir)/configure \
$(am__configure_deps) $(am__DIST_COMMON)
am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \
configure.lineno config.status.lineno
mkinstalldirs = $(install_sh) -d
CONFIG_HEADER = config.h
CONFIG_CLEAN_FILES = xorg-synaptics.pc
CONFIG_CLEAN_VPATH_FILES =
AM_V_P = $(am__v_P_@AM_V@)
am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
am__v_P_0 = false
am__v_P_1 = :
AM_V_GEN = $(am__v_GEN_@AM_V@)
am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
am__v_GEN_0 = @echo " GEN " $@;
am__v_GEN_1 =
AM_V_at = $(am__v_at_@AM_V@)
am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
am__v_at_0 = @
am__v_at_1 =
SOURCES =
DIST_SOURCES =
RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \
ctags-recursive dvi-recursive html-recursive info-recursive \
install-data-recursive install-dvi-recursive \
install-exec-recursive install-html-recursive \
install-info-recursive install-pdf-recursive \
install-ps-recursive install-recursive installcheck-recursive \
installdirs-recursive pdf-recursive ps-recursive \
tags-recursive uninstall-recursive
am__can_run_installinfo = \
case $$AM_UPDATE_INFO_DIR in \
n|no|NO) false;; \
*) (install-info --version) >/dev/null 2>&1;; \
esac
am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
am__vpath_adj = case $$p in \
$(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
*) f=$$p;; \
esac;
am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
am__install_max = 40
am__nobase_strip_setup = \
srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
am__nobase_strip = \
for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
am__nobase_list = $(am__nobase_strip_setup); \
for p in $$list; do echo "$$p $$p"; done | \
sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
$(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
if (++n[$$2] == $(am__install_max)) \
{ print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
END { for (dir in files) print dir, files[dir] }'
am__base_list = \
sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
am__uninstall_files_from_dir = { \
test -z "$$files" \
|| { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
|| { echo " ( cd '$$dir' && rm -f" $$files ")"; \
$(am__cd) "$$dir" && rm -f $$files; }; \
}
am__installdirs = "$(DESTDIR)$(pkgconfigdir)"
DATA = $(pkgconfig_DATA)
RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \
distclean-recursive maintainer-clean-recursive
am__recursive_targets = \
$(RECURSIVE_TARGETS) \
$(RECURSIVE_CLEAN_TARGETS) \
$(am__extra_recursive_targets)
AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \
cscope distdir distdir-am dist dist-all distcheck
am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) \
config.h.in
# Read a list of newline-separated strings from the standard input,
# and print each of them once, without duplicates. Input order is
# *not* preserved.
am__uniquify_input = $(AWK) '\
BEGIN { nonempty = 0; } \
{ items[$$0] = 1; nonempty = 1; } \
END { if (nonempty) { for (i in items) print i; }; } \
'
# Make sure the list of sources is unique. This is necessary because,
# e.g., the same source file might be shared among _SOURCES variables
# for different programs/libraries.
am__define_uniq_tagged_files = \
list='$(am__tagged_files)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | $(am__uniquify_input)`
DIST_SUBDIRS = $(SUBDIRS)
am__DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/config.h.in \
$(srcdir)/xorg-synaptics.pc.in COPYING ChangeLog INSTALL \
README.md compile config.guess config.sub install-sh ltmain.sh \
missing
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
distdir = $(PACKAGE)-$(VERSION)
top_distdir = $(distdir)
am__remove_distdir = \
if test -d "$(distdir)"; then \
find "$(distdir)" -type d ! -perm -200 -exec chmod u+w {} ';' \
&& rm -rf "$(distdir)" \
|| { sleep 5 && rm -rf "$(distdir)"; }; \
else :; fi
am__post_remove_distdir = $(am__remove_distdir)
am__relativize = \
dir0=`pwd`; \
sed_first='s,^\([^/]*\)/.*$$,\1,'; \
sed_rest='s,^[^/]*/*,,'; \
sed_last='s,^.*/\([^/]*\)$$,\1,'; \
sed_butlast='s,/*[^/]*$$,,'; \
while test -n "$$dir1"; do \
first=`echo "$$dir1" | sed -e "$$sed_first"`; \
if test "$$first" != "."; then \
if test "$$first" = ".."; then \
dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \
dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \
else \
first2=`echo "$$dir2" | sed -e "$$sed_first"`; \
if test "$$first2" = "$$first"; then \
dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \
else \
dir2="../$$dir2"; \
fi; \
dir0="$$dir0"/"$$first"; \
fi; \
fi; \
dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \
done; \
reldir="$$dir2"
DIST_ARCHIVES = $(distdir).tar.gz $(distdir).tar.xz
GZIP_ENV = --best
DIST_TARGETS = dist-xz dist-gzip
# Exists only to be overridden by the user if desired.
AM_DISTCHECK_DVI_TARGET = dvi
distuninstallcheck_listfiles = find . -type f -print
am__distuninstallcheck_listfiles = $(distuninstallcheck_listfiles) \
| sed 's|^\./|$(prefix)/|' | grep -v '$(infodir)/dir$$'
distcleancheck_listfiles = find . -type f -print
ACLOCAL = @ACLOCAL@
ADMIN_MAN_DIR = @ADMIN_MAN_DIR@
ADMIN_MAN_SUFFIX = @ADMIN_MAN_SUFFIX@
AMTAR = @AMTAR@
AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
APP_MAN_DIR = @APP_MAN_DIR@
APP_MAN_SUFFIX = @APP_MAN_SUFFIX@
AR = @AR@
AUTOCONF = @AUTOCONF@
AUTOHEADER = @AUTOHEADER@
AUTOMAKE = @AUTOMAKE@
AWK = @AWK@
BASE_CFLAGS = @BASE_CFLAGS@
CC = @CC@
CCDEPMODE = @CCDEPMODE@
CFLAGS = @CFLAGS@
CHANGELOG_CMD = @CHANGELOG_CMD@
CPPFLAGS = @CPPFLAGS@
CSCOPE = @CSCOPE@
CTAGS = @CTAGS@
CWARNFLAGS = @CWARNFLAGS@
CYGPATH_W = @CYGPATH_W@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
DLLTOOL = @DLLTOOL@
DRIVER_MAN_DIR = @DRIVER_MAN_DIR@
DRIVER_MAN_SUFFIX = @DRIVER_MAN_SUFFIX@
DSYMUTIL = @DSYMUTIL@
DUMPBIN = @DUMPBIN@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
EGREP = @EGREP@
ETAGS = @ETAGS@
EXEEXT = @EXEEXT@
FGREP = @FGREP@
FILECMD = @FILECMD@
FILE_MAN_DIR = @FILE_MAN_DIR@
FILE_MAN_SUFFIX = @FILE_MAN_SUFFIX@
GREP = @GREP@
INSTALL = @INSTALL@
INSTALL_CMD = @INSTALL_CMD@
INSTALL_DATA = @INSTALL_DATA@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
LD = @LD@
LDFLAGS = @LDFLAGS@
LIBEVDEV_CFLAGS = @LIBEVDEV_CFLAGS@
LIBEVDEV_LIBS = @LIBEVDEV_LIBS@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
LIBTOOL = @LIBTOOL@
LIB_MAN_DIR = @LIB_MAN_DIR@
LIB_MAN_SUFFIX = @LIB_MAN_SUFFIX@
LIPO = @LIPO@
LN_S = @LN_S@
LTLIBOBJS = @LTLIBOBJS@
LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
MAKEINFO = @MAKEINFO@
MANIFEST_TOOL = @MANIFEST_TOOL@
MAN_SUBSTS = @MAN_SUBSTS@
MISC_MAN_DIR = @MISC_MAN_DIR@
MISC_MAN_SUFFIX = @MISC_MAN_SUFFIX@
MKDIR_P = @MKDIR_P@
NM = @NM@
NMEDIT = @NMEDIT@
OBJDUMP = @OBJDUMP@
OBJEXT = @OBJEXT@
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@
RANLIB = @RANLIB@
SED = @SED@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
STRICT_CFLAGS = @STRICT_CFLAGS@
STRIP = @STRIP@
VERSION = @VERSION@
XI_CFLAGS = @XI_CFLAGS@
XI_LIBS = @XI_LIBS@
XORG_CFLAGS = @XORG_CFLAGS@
XORG_LIBS = @XORG_LIBS@
XORG_MALLOC_DEBUG_ENV = @XORG_MALLOC_DEBUG_ENV@
XORG_MAN_PAGE = @XORG_MAN_PAGE@
XTST_CFLAGS = @XTST_CFLAGS@
XTST_LIBS = @XTST_LIBS@
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@
configdir = @configdir@
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@
inputdir = @inputdir@
install_sh = @install_sh@
libdir = @libdir@
libexecdir = @libexecdir@
localedir = @localedir@
localstatedir = @localstatedir@
mandir = @mandir@
mkdir_p = @mkdir_p@
oldincludedir = @oldincludedir@
pdfdir = @pdfdir@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
runstatedir = @runstatedir@
sbindir = @sbindir@
sdkdir = @sdkdir@
sharedstatedir = @sharedstatedir@
srcdir = @srcdir@
sysconfdir = @sysconfdir@
target_alias = @target_alias@
top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
# During distcheck, system locations (as provided by pkg-config) may
# not be writable; provide instead relative locations.
DISTCHECK_CONFIGURE_FLAGS = \
--with-sdkdir='$${includedir}/xorg' \
--with-xorg-conf-dir='$${datadir}/X11/xorg.conf.d'
SUBDIRS = include src man tools conf
MAINTAINERCLEANFILES = ChangeLog INSTALL
pkgconfigdir = $(libdir)/pkgconfig
pkgconfig_DATA = xorg-synaptics.pc
EXTRA_DIST = README.md
all: config.h
$(MAKE) $(AM_MAKEFLAGS) all-recursive
.SUFFIXES:
am--refresh: Makefile
@:
$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
@for dep in $?; do \
case '$(am__configure_deps)' in \
*$$dep*) \
echo ' cd $(srcdir) && $(AUTOMAKE) --foreign'; \
$(am__cd) $(srcdir) && $(AUTOMAKE) --foreign \
&& exit 0; \
exit 1;; \
esac; \
done; \
echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign Makefile'; \
$(am__cd) $(top_srcdir) && \
$(AUTOMAKE) --foreign Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
@case '$?' in \
*config.status*) \
echo ' $(SHELL) ./config.status'; \
$(SHELL) ./config.status;; \
*) \
echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__maybe_remake_depfiles)'; \
cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__maybe_remake_depfiles);; \
esac;
$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
$(SHELL) ./config.status --recheck
$(top_srcdir)/configure: $(am__configure_deps)
$(am__cd) $(srcdir) && $(AUTOCONF)
$(ACLOCAL_M4): $(am__aclocal_m4_deps)
$(am__cd) $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS)
$(am__aclocal_m4_deps):
config.h: stamp-h1
@test -f $@ || rm -f stamp-h1
@test -f $@ || $(MAKE) $(AM_MAKEFLAGS) stamp-h1
stamp-h1: $(srcdir)/config.h.in $(top_builddir)/config.status
@rm -f stamp-h1
cd $(top_builddir) && $(SHELL) ./config.status config.h
$(srcdir)/config.h.in: $(am__configure_deps)
($(am__cd) $(top_srcdir) && $(AUTOHEADER))
rm -f stamp-h1
touch $@
distclean-hdr:
-rm -f config.h stamp-h1
xorg-synaptics.pc: $(top_builddir)/config.status $(srcdir)/xorg-synaptics.pc.in
cd $(top_builddir) && $(SHELL) ./config.status $@
mostlyclean-libtool:
-rm -f *.lo
clean-libtool:
-rm -rf .libs _libs
distclean-libtool:
-rm -f libtool config.lt
install-pkgconfigDATA: $(pkgconfig_DATA)
@$(NORMAL_INSTALL)
@list='$(pkgconfig_DATA)'; test -n "$(pkgconfigdir)" || list=; \
if test -n "$$list"; then \
echo " $(MKDIR_P) '$(DESTDIR)$(pkgconfigdir)'"; \
$(MKDIR_P) "$(DESTDIR)$(pkgconfigdir)" || exit 1; \
fi; \
for p in $$list; do \
if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
echo "$$d$$p"; \
done | $(am__base_list) | \
while read files; do \
echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(pkgconfigdir)'"; \
$(INSTALL_DATA) $$files "$(DESTDIR)$(pkgconfigdir)" || exit $$?; \
done
uninstall-pkgconfigDATA:
@$(NORMAL_UNINSTALL)
@list='$(pkgconfig_DATA)'; test -n "$(pkgconfigdir)" || list=; \
files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
dir='$(DESTDIR)$(pkgconfigdir)'; $(am__uninstall_files_from_dir)
# This directory's subdirectories are mostly independent; you can cd
# into them and run 'make' without going through this Makefile.
# To change the values of 'make' variables: instead of editing Makefiles,
# (1) if the variable is set in 'config.status', edit 'config.status'
# (which will cause the Makefiles to be regenerated when you run 'make');
# (2) otherwise, pass the desired values on the 'make' command line.
$(am__recursive_targets):
@fail=; \
if $(am__make_keepgoing); then \
failcom='fail=yes'; \
else \
failcom='exit 1'; \
fi; \
dot_seen=no; \
target=`echo $@ | sed s/-recursive//`; \
case "$@" in \
distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \
*) list='$(SUBDIRS)' ;; \
esac; \
for subdir in $$list; do \
echo "Making $$target in $$subdir"; \
if test "$$subdir" = "."; then \
dot_seen=yes; \
local_target="$$target-am"; \
else \
local_target="$$target"; \
fi; \
($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
|| eval $$failcom; \
done; \
if test "$$dot_seen" = "no"; then \
$(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \
fi; test -z "$$fail"
ID: $(am__tagged_files)
$(am__define_uniq_tagged_files); mkid -fID $$unique
tags: tags-recursive
TAGS: tags
tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
set x; \
here=`pwd`; \
if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \
include_option=--etags-include; \
empty_fix=.; \
else \
include_option=--include; \
empty_fix=; \
fi; \
list='$(SUBDIRS)'; for subdir in $$list; do \
if test "$$subdir" = .; then :; else \
test ! -f $$subdir/TAGS || \
set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \
fi; \
done; \
$(am__define_uniq_tagged_files); \
shift; \
if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
test -n "$$unique" || unique=$$empty_fix; \
if test $$# -gt 0; then \
$(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
"$$@" $$unique; \
else \
$(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
$$unique; \
fi; \
fi
ctags: ctags-recursive
CTAGS: ctags
ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
$(am__define_uniq_tagged_files); \
test -z "$(CTAGS_ARGS)$$unique" \
|| $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
$$unique
GTAGS:
here=`$(am__cd) $(top_builddir) && pwd` \
&& $(am__cd) $(top_srcdir) \
&& gtags -i $(GTAGS_ARGS) "$$here"
cscope: cscope.files
test ! -s cscope.files \
|| $(CSCOPE) -b -q $(AM_CSCOPEFLAGS) $(CSCOPEFLAGS) -i cscope.files $(CSCOPE_ARGS)
clean-cscope:
-rm -f cscope.files
cscope.files: clean-cscope cscopelist
cscopelist: cscopelist-recursive
cscopelist-am: $(am__tagged_files)
list='$(am__tagged_files)'; \
case "$(srcdir)" in \
[\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
*) sdir=$(subdir)/$(srcdir) ;; \
esac; \
for i in $$list; do \
if test -f "$$i"; then \
echo "$(subdir)/$$i"; \
else \
echo "$$sdir/$$i"; \
fi; \
done >> $(top_builddir)/cscope.files
distclean-tags:
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
-rm -f cscope.out cscope.in.out cscope.po.out cscope.files
distdir: $(BUILT_SOURCES)
$(MAKE) $(AM_MAKEFLAGS) distdir-am
distdir-am: $(DISTFILES)
$(am__remove_distdir)
test -d "$(distdir)" || mkdir "$(distdir)"
@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
list='$(DISTFILES)'; \
dist_files=`for file in $$list; do echo $$file; done | \
sed -e "s|^$$srcdirstrip/||;t" \
-e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
case $$dist_files in \
*/*) $(MKDIR_P) `echo "$$dist_files" | \
sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
sort -u` ;; \
esac; \
for file in $$dist_files; do \
if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
if test -d $$d/$$file; then \
dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
if test -d "$(distdir)/$$file"; then \
find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
fi; \
if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
fi; \
cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
else \
test -f "$(distdir)/$$file" \
|| cp -p $$d/$$file "$(distdir)/$$file" \
|| exit 1; \
fi; \
done
@list='$(DIST_SUBDIRS)'; for subdir in $$list; do \
if test "$$subdir" = .; then :; else \
$(am__make_dryrun) \
|| test -d "$(distdir)/$$subdir" \
|| $(MKDIR_P) "$(distdir)/$$subdir" \
|| exit 1; \
dir1=$$subdir; dir2="$(distdir)/$$subdir"; \
$(am__relativize); \
new_distdir=$$reldir; \
dir1=$$subdir; dir2="$(top_distdir)"; \
$(am__relativize); \
new_top_distdir=$$reldir; \
echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \
echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \
($(am__cd) $$subdir && \
$(MAKE) $(AM_MAKEFLAGS) \
top_distdir="$$new_top_distdir" \
distdir="$$new_distdir" \
am__remove_distdir=: \
am__skip_length_check=: \
am__skip_mode_fix=: \
distdir) \
|| exit 1; \
fi; \
done
$(MAKE) $(AM_MAKEFLAGS) \
top_distdir="$(top_distdir)" distdir="$(distdir)" \
dist-hook
-test -n "$(am__skip_mode_fix)" \
|| find "$(distdir)" -type d ! -perm -755 \
-exec chmod u+rwx,go+rx {} \; -o \
! -type d ! -perm -444 -links 1 -exec chmod a+r {} \; -o \
! -type d ! -perm -400 -exec chmod a+r {} \; -o \
! -type d ! -perm -444 -exec $(install_sh) -c -m a+r {} {} \; \
|| chmod -R a+r "$(distdir)"
dist-gzip: distdir
tardir=$(distdir) && $(am__tar) | eval GZIP= gzip $(GZIP_ENV) -c >$(distdir).tar.gz
$(am__post_remove_distdir)
dist-bzip2: distdir
tardir=$(distdir) && $(am__tar) | BZIP2=$${BZIP2--9} bzip2 -c >$(distdir).tar.bz2
$(am__post_remove_distdir)
dist-lzip: distdir
tardir=$(distdir) && $(am__tar) | lzip -c $${LZIP_OPT--9} >$(distdir).tar.lz
$(am__post_remove_distdir)
dist-xz: distdir
tardir=$(distdir) && $(am__tar) | XZ_OPT=$${XZ_OPT--e} xz -c >$(distdir).tar.xz
$(am__post_remove_distdir)
dist-zstd: distdir
tardir=$(distdir) && $(am__tar) | zstd -c $${ZSTD_CLEVEL-$${ZSTD_OPT--19}} >$(distdir).tar.zst
$(am__post_remove_distdir)
dist-tarZ: distdir
@echo WARNING: "Support for distribution archives compressed with" \
"legacy program 'compress' is deprecated." >&2
@echo WARNING: "It will be removed altogether in Automake 2.0" >&2
tardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z
$(am__post_remove_distdir)
dist-shar: distdir
@echo WARNING: "Support for shar distribution archives is" \
"deprecated." >&2
@echo WARNING: "It will be removed altogether in Automake 2.0" >&2
shar $(distdir) | eval GZIP= gzip $(GZIP_ENV) -c >$(distdir).shar.gz
$(am__post_remove_distdir)
dist-zip: distdir
-rm -f $(distdir).zip
zip -rq $(distdir).zip $(distdir)
$(am__post_remove_distdir)
dist dist-all:
$(MAKE) $(AM_MAKEFLAGS) $(DIST_TARGETS) am__post_remove_distdir='@:'
$(am__post_remove_distdir)
# This target untars the dist file and tries a VPATH configuration. Then
# it guarantees that the distribution is self-contained by making another
# tarfile.
distcheck: dist
case '$(DIST_ARCHIVES)' in \
*.tar.gz*) \
eval GZIP= gzip $(GZIP_ENV) -dc $(distdir).tar.gz | $(am__untar) ;;\
*.tar.bz2*) \
bzip2 -dc $(distdir).tar.bz2 | $(am__untar) ;;\
*.tar.lz*) \
lzip -dc $(distdir).tar.lz | $(am__untar) ;;\
*.tar.xz*) \
xz -dc $(distdir).tar.xz | $(am__untar) ;;\
*.tar.Z*) \
uncompress -c $(distdir).tar.Z | $(am__untar) ;;\
*.shar.gz*) \
eval GZIP= gzip $(GZIP_ENV) -dc $(distdir).shar.gz | unshar ;;\
*.zip*) \
unzip $(distdir).zip ;;\
*.tar.zst*) \
zstd -dc $(distdir).tar.zst | $(am__untar) ;;\
esac
chmod -R a-w $(distdir)
chmod u+w $(distdir)
mkdir $(distdir)/_build $(distdir)/_build/sub $(distdir)/_inst
chmod a-w $(distdir)
test -d $(distdir)/_build || exit 0; \
dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \
&& dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \
&& am__cwd=`pwd` \
&& $(am__cd) $(distdir)/_build/sub \
&& ../../configure \
$(AM_DISTCHECK_CONFIGURE_FLAGS) \
$(DISTCHECK_CONFIGURE_FLAGS) \
--srcdir=../.. --prefix="$$dc_install_base" \
&& $(MAKE) $(AM_MAKEFLAGS) \
&& $(MAKE) $(AM_MAKEFLAGS) $(AM_DISTCHECK_DVI_TARGET) \
&& $(MAKE) $(AM_MAKEFLAGS) check \
&& $(MAKE) $(AM_MAKEFLAGS) install \
&& $(MAKE) $(AM_MAKEFLAGS) installcheck \
&& $(MAKE) $(AM_MAKEFLAGS) uninstall \
&& $(MAKE) $(AM_MAKEFLAGS) distuninstallcheck_dir="$$dc_install_base" \
distuninstallcheck \
&& chmod -R a-w "$$dc_install_base" \
&& ({ \
(cd ../.. && umask 077 && mkdir "$$dc_destdir") \
&& $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" install \
&& $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" uninstall \
&& $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" \
distuninstallcheck_dir="$$dc_destdir" distuninstallcheck; \
} || { rm -rf "$$dc_destdir"; exit 1; }) \
&& rm -rf "$$dc_destdir" \
&& $(MAKE) $(AM_MAKEFLAGS) dist \
&& rm -rf $(DIST_ARCHIVES) \
&& $(MAKE) $(AM_MAKEFLAGS) distcleancheck \
&& cd "$$am__cwd" \
|| exit 1
$(am__post_remove_distdir)
@(echo "$(distdir) archives ready for distribution: "; \
list='$(DIST_ARCHIVES)'; for i in $$list; do echo $$i; done) | \
sed -e 1h -e 1s/./=/g -e 1p -e 1x -e '$$p' -e '$$x'
distuninstallcheck:
@test -n '$(distuninstallcheck_dir)' || { \
echo 'ERROR: trying to run $@ with an empty' \
'$$(distuninstallcheck_dir)' >&2; \
exit 1; \
}; \
$(am__cd) '$(distuninstallcheck_dir)' || { \
echo 'ERROR: cannot chdir into $(distuninstallcheck_dir)' >&2; \
exit 1; \
}; \
test `$(am__distuninstallcheck_listfiles) | wc -l` -eq 0 \
|| { echo "ERROR: files left after uninstall:" ; \
if test -n "$(DESTDIR)"; then \
echo " (check DESTDIR support)"; \
fi ; \
$(distuninstallcheck_listfiles) ; \
exit 1; } >&2
distcleancheck: distclean
@if test '$(srcdir)' = . ; then \
echo "ERROR: distcleancheck can only run from a VPATH build" ; \
exit 1 ; \
fi
@test `$(distcleancheck_listfiles) | wc -l` -eq 0 \
|| { echo "ERROR: files left in build directory after distclean:" ; \
$(distcleancheck_listfiles) ; \
exit 1; } >&2
check-am: all-am
check: check-recursive
all-am: Makefile $(DATA) config.h
installdirs: installdirs-recursive
installdirs-am:
for dir in "$(DESTDIR)$(pkgconfigdir)"; do \
test -z "$$dir" || $(MKDIR_P) "$$dir"; \
done
install: install-recursive
install-exec: install-exec-recursive
install-data: install-data-recursive
uninstall: uninstall-recursive
install-am: all-am
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
installcheck: installcheck-recursive
install-strip:
if test -z '$(STRIP)'; then \
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
install; \
else \
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
"INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
fi
mostlyclean-generic:
clean-generic:
distclean-generic:
-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
maintainer-clean-generic:
@echo "This command is intended for maintainers to use"
@echo "it deletes files that may require special tools to rebuild."
-test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES)
clean: clean-recursive
clean-am: clean-generic clean-libtool mostlyclean-am
distclean: distclean-recursive
-rm -f $(am__CONFIG_DISTCLEAN_FILES)
-rm -f Makefile
distclean-am: clean-am distclean-generic distclean-hdr \
distclean-libtool distclean-tags
dvi: dvi-recursive
dvi-am:
html: html-recursive
html-am:
info: info-recursive
info-am:
install-data-am: install-pkgconfigDATA
install-dvi: install-dvi-recursive
install-dvi-am:
install-exec-am:
install-html: install-html-recursive
install-html-am:
install-info: install-info-recursive
install-info-am:
install-man:
install-pdf: install-pdf-recursive
install-pdf-am:
install-ps: install-ps-recursive
install-ps-am:
installcheck-am:
maintainer-clean: maintainer-clean-recursive
-rm -f $(am__CONFIG_DISTCLEAN_FILES)
-rm -rf $(top_srcdir)/autom4te.cache
-rm -f Makefile
maintainer-clean-am: distclean-am maintainer-clean-generic
mostlyclean: mostlyclean-recursive
mostlyclean-am: mostlyclean-generic mostlyclean-libtool
pdf: pdf-recursive
pdf-am:
ps: ps-recursive
ps-am:
uninstall-am: uninstall-pkgconfigDATA
.MAKE: $(am__recursive_targets) all install-am install-strip
.PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am \
am--refresh check check-am clean clean-cscope clean-generic \
clean-libtool cscope cscopelist-am ctags ctags-am dist \
dist-all dist-bzip2 dist-gzip dist-hook dist-lzip dist-shar \
dist-tarZ dist-xz dist-zip dist-zstd distcheck distclean \
distclean-generic distclean-hdr distclean-libtool \
distclean-tags distcleancheck distdir distuninstallcheck dvi \
dvi-am html html-am info info-am install install-am \
install-data install-data-am install-dvi install-dvi-am \
install-exec install-exec-am install-html install-html-am \
install-info install-info-am install-man install-pdf \
install-pdf-am install-pkgconfigDATA install-ps install-ps-am \
install-strip installcheck installcheck-am installdirs \
installdirs-am maintainer-clean maintainer-clean-generic \
mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \
ps ps-am tags tags-am uninstall uninstall-am \
uninstall-pkgconfigDATA
.PRECIOUS: Makefile
.PHONY: ChangeLog INSTALL
INSTALL:
$(INSTALL_CMD)
ChangeLog:
$(CHANGELOG_CMD)
dist-hook: ChangeLog INSTALL
# 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:
xf86-input-synaptics-1.9.2/configure.ac 0000644 0143106 0000012 00000015536 14262661535 014711 0000000 0000000 # Copyright 2005 Adam Jackson.
#
# Permission is hereby granted, free of charge, to any person obtaining a
# copy of this software and associated documentation files (the "Software"),
# to deal in the Software without restriction, including without limitation
# on the rights to use, copy, modify, merge, publish, distribute, sub
# license, and/or sell copies of the Software, and to permit persons to whom
# the Software is furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice (including the next
# paragraph) shall be included in all copies or substantial portions of the
# Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
# ADAM JACKSON BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
# Process this file with autoconf to produce a configure script
# Initialize Autoconf
AC_PREREQ([2.60])
AC_INIT([xf86-input-synaptics],
[1.9.2],
[https://gitlab.freedesktop.org/xorg/driver/xf86-input-synaptics/issues],
[xf86-input-synaptics])
AC_CONFIG_SRCDIR([Makefile.am])
AC_CONFIG_HEADERS([config.h])
AC_CONFIG_AUX_DIR(.)
# Initialize Automake
AM_INIT_AUTOMAKE([foreign dist-xz])
# Initialize libtool
AC_DISABLE_STATIC
AC_PROG_LIBTOOL
# Initialize X.Org macros 1.13 or later for XORG_ENABLE_UNIT_TESTS
m4_ifndef([XORG_MACROS_VERSION],
[m4_fatal([must install xorg-macros 1.13 or later before running autoconf/autogen])])
XORG_MACROS_VERSION(1.13)
XORG_DEFAULT_OPTIONS
XORG_ENABLE_UNIT_TESTS
# Checks for libraries.
AC_CHECK_LIB([m], [rint])
# Store the list of server defined optional extensions in REQUIRED_MODULES
m4_ifndef([XORG_DRIVER_CHECK_EXT],
[m4_fatal([must install xorg-server development files before running autoconf/autogen])])
XORG_DRIVER_CHECK_EXT(RANDR, randrproto)
# Obtain compiler/linker options for the Synaptics driver dependencies
PKG_CHECK_MODULES(XORG, [inputproto >= 2.1.99.3] [xorg-server >= 1.12] xproto inputproto $REQUIRED_MODULES)
# X Server SDK location is required to install Synaptics header files
# This location is also relayed in the xorg-synaptics.pc file
sdkdir=`$PKG_CONFIG --variable=sdkdir xorg-server`
AC_SUBST([sdkdir])
# -----------------------------------------------------------------------------
# Configuration options
# -----------------------------------------------------------------------------
# Define a configure option for an alternate input module directory
AC_ARG_WITH(xorg-module-dir,
AC_HELP_STRING([--with-xorg-module-dir=DIR],
[Default xorg module directory [[default=$libdir/xorg/modules]]]),
[moduledir="$withval"],
[moduledir="$libdir/xorg/modules"])
inputdir=${moduledir}/input
AC_SUBST(inputdir)
# Define a configure option for an alternate X Server configuration directory
sysconfigdir=`$PKG_CONFIG --variable=sysconfigdir xorg-server`
AC_ARG_WITH(xorg-conf-dir,
AC_HELP_STRING([--with-xorg-conf-dir=DIR],
[Default xorg.conf.d directory [[default=from $PKG_CONFIG xorg-server]]]),
[configdir="$withval"],
[configdir="$sysconfigdir"])
AC_SUBST(configdir)
AM_CONDITIONAL(HAS_XORG_CONF_DIR, [test "x$sysconfigdir" != "x"])
# Define a configure option to enable code debugging
AC_ARG_ENABLE(debug, AS_HELP_STRING([--enable-debug],
[Enable debugging (default: disabled)]),
[DEBUGGING=$enableval], [DEBUGGING=no])
if test "x$DEBUGGING" = xyes; then
AC_DEFINE(DEBUG, 1, [Enable debugging code])
fi
AM_CONDITIONAL(DEBUG, [test "x$DEBUGGING" = xyes])
# -----------------------------------------------------------------------------
# Determine which backend, if any, to build
# -----------------------------------------------------------------------------
AC_MSG_CHECKING([which optional backends will be build])
case "${host}" in
*linux*)
AC_MSG_RESULT([ps2comm alpscomm eventcomm])
BUILD_PS2COMM="yes"
BUILD_EVENTCOMM="yes"
;;
*freebsd* | *netbsd* | *dragonfly*)
AC_MSG_RESULT([ps2comm alpscomm psmcomm])
BUILD_PS2COMM="yes"
BUILD_PSMCOMM="yes"
;;
*solaris* | *gnu*)
AC_MSG_RESULT([ps2comm alpscomm])
BUILD_PS2COMM="yes"
;;
*)
AC_MSG_ERROR([Cannot find suitable backends for this platform.])
;;
esac
if test "x$BUILD_EVENTCOMM" = xyes; then
AC_DEFINE(BUILD_EVENTCOMM, 1, [Optional backend eventcomm enabled])
PKG_CHECK_MODULES(LIBEVDEV, [libevdev >= 0.4])
SAVE_LIBS="$LIBS"
LIBS="$LIBEVDEV_LIBS"
AC_CHECK_LIB(evdev, libevdev_set_device_log_function,
[AC_DEFINE(HAVE_LIBEVDEV_DEVICE_LOG_FUNCS, 1,
[libevdev supports per-device log functions])],
[])
LIBS="$SAVE_LIBS"
fi
if test "x$BUILD_PSMCOMM" = xyes; then
AC_DEFINE(BUILD_PSMCOMM, 1, [Optional backend psmcomm enabled])
fi
if test "x$BUILD_PS2COMM" = xyes; then
AC_DEFINE(BUILD_PS2COMM, 1, [Optional backend ps2comm and alpscomm enabled])
fi
AM_CONDITIONAL([BUILD_EVENTCOMM], [test "x${BUILD_EVENTCOMM}" = "xyes"])
AM_CONDITIONAL([BUILD_PSMCOMM], [test "x${BUILD_PSMCOMM}" = "xyes"])
AM_CONDITIONAL([BUILD_PS2COMM], [test "x${BUILD_PS2COMM}" = "xyes"])
# -----------------------------------------------------------------------------
# Dependencies for synclient and syndaemon
# -----------------------------------------------------------------------------
# Obtain compiler/linker options for the Synaptics apps dependencies
PKG_CHECK_MODULES(XI, x11 inputproto [xi >= 1.2])
# The syndaemon program uses an optional XRecord extension implementation
# If libxtst >= 1.0.99 is installed, Cflags contains the path to record.h
# If recordproto < 1.13.99.1 is installed, Cflags contains the path to record.h
PKG_CHECK_MODULES(XTST, xtst recordproto, have_libxtst="yes", have_libxtst="no")
if test "x$have_libxtst" = "xyes" ; then
# Header record.h may come from the xtst or recordproto package, or may be missing
SAVE_CPPFLAGS="$CPPFLAGS"
CPPFLAGS="$CPPFLAGS $XTST_CFLAGS"
AC_CHECK_HEADERS([X11/extensions/record.h],,,[#include ])
CPPFLAGS="$SAVE_CPPFLAGS"
fi
# -----------------------------------------------------------------------------
# Workaround overriding sdkdir to be able to create a tarball when user has no
# write permission in sdkdir. See DISTCHECK_CONFIGURE_FLAGS in Makefile.am
AC_ARG_WITH([sdkdir], [], [sdkdir="$withval"])
AC_CONFIG_FILES([Makefile
src/Makefile
man/Makefile
tools/Makefile
conf/Makefile
include/Makefile
xorg-synaptics.pc])
AC_OUTPUT
xf86-input-synaptics-1.9.2/INSTALL 0000644 0143106 0000012 00000036600 14262661552 013446 0000000 0000000 Installation Instructions
*************************
Copyright (C) 1994-1996, 1999-2002, 2004-2011 Free Software Foundation,
Inc.
Copying and distribution of this file, with or without modification,
are permitted in any medium without royalty provided the copyright
notice and this notice are preserved. This file is offered as-is,
without warranty of any kind.
Basic Installation
==================
Briefly, the shell commands `./configure; make; make install' should
configure, build, and install this package. The following
more-detailed instructions are generic; see the `README' file for
instructions specific to this package. Some packages provide this
`INSTALL' file but do not implement all of the features documented
below. The lack of an optional feature in a given package is not
necessarily a bug. More recommendations for GNU packages can be found
in *note Makefile Conventions: (standards)Makefile Conventions.
The `configure' shell script attempts to guess correct values for
various system-dependent variables used during compilation. It uses
those values to create a `Makefile' in each directory of the package.
It may also create one or more `.h' files containing system-dependent
definitions. Finally, it creates a shell script `config.status' that
you can run in the future to recreate the current configuration, and a
file `config.log' containing compiler output (useful mainly for
debugging `configure').
It can also use an optional file (typically called `config.cache'
and enabled with `--cache-file=config.cache' or simply `-C') that saves
the results of its tests to speed up reconfiguring. Caching is
disabled by default to prevent problems with accidental use of stale
cache files.
If you need to do unusual things to compile the package, please try
to figure out how `configure' could check whether to do them, and mail
diffs or instructions to the address given in the `README' so they can
be considered for the next release. If you are using the cache, and at
some point `config.cache' contains results you don't want to keep, you
may remove or edit it.
The file `configure.ac' (or `configure.in') is used to create
`configure' by a program called `autoconf'. You need `configure.ac' if
you want to change it or regenerate `configure' using a newer version
of `autoconf'.
The simplest way to compile this package is:
1. `cd' to the directory containing the package's source code and type
`./configure' to configure the package for your system.
Running `configure' might take a while. While running, it prints
some messages telling which features it is checking for.
2. Type `make' to compile the package.
3. Optionally, type `make check' to run any self-tests that come with
the package, generally using the just-built uninstalled binaries.
4. Type `make install' to install the programs and any data files and
documentation. When installing into a prefix owned by root, it is
recommended that the package be configured and built as a regular
user, and only the `make install' phase executed with root
privileges.
5. Optionally, type `make installcheck' to repeat any self-tests, but
this time using the binaries in their final installed location.
This target does not install anything. Running this target as a
regular user, particularly if the prior `make install' required
root privileges, verifies that the installation completed
correctly.
6. You can remove the program binaries and object files from the
source code directory by typing `make clean'. To also remove the
files that `configure' created (so you can compile the package for
a different kind of computer), type `make distclean'. There is
also a `make maintainer-clean' target, but that is intended mainly
for the package's developers. If you use it, you may have to get
all sorts of other programs in order to regenerate files that came
with the distribution.
7. Often, you can also type `make uninstall' to remove the installed
files again. In practice, not all packages have tested that
uninstallation works correctly, even though it is required by the
GNU Coding Standards.
8. Some packages, particularly those that use Automake, provide `make
distcheck', which can by used by developers to test that all other
targets like `make install' and `make uninstall' work correctly.
This target is generally not run by end users.
Compilers and Options
=====================
Some systems require unusual options for compilation or linking that
the `configure' script does not know about. Run `./configure --help'
for details on some of the pertinent environment variables.
You can give `configure' initial values for configuration parameters
by setting variables in the command line or in the environment. Here
is an example:
./configure CC=c99 CFLAGS=-g LIBS=-lposix
*Note Defining Variables::, for more details.
Compiling For Multiple Architectures
====================================
You can compile the package for more than one kind of computer at the
same time, by placing the object files for each architecture in their
own directory. To do this, you can use GNU `make'. `cd' to the
directory where you want the object files and executables to go and run
the `configure' script. `configure' automatically checks for the
source code in the directory that `configure' is in and in `..'. This
is known as a "VPATH" build.
With a non-GNU `make', it is safer to compile the package for one
architecture at a time in the source code directory. After you have
installed the package for one architecture, use `make distclean' before
reconfiguring for another architecture.
On MacOS X 10.5 and later systems, you can create libraries and
executables that work on multiple system types--known as "fat" or
"universal" binaries--by specifying multiple `-arch' options to the
compiler but only a single `-arch' option to the preprocessor. Like
this:
./configure CC="gcc -arch i386 -arch x86_64 -arch ppc -arch ppc64" \
CXX="g++ -arch i386 -arch x86_64 -arch ppc -arch ppc64" \
CPP="gcc -E" CXXCPP="g++ -E"
This is not guaranteed to produce working output in all cases, you
may have to build one architecture at a time and combine the results
using the `lipo' tool if you have problems.
Installation Names
==================
By default, `make install' installs the package's commands under
`/usr/local/bin', include files under `/usr/local/include', etc. You
can specify an installation prefix other than `/usr/local' by giving
`configure' the option `--prefix=PREFIX', where PREFIX must be an
absolute file name.
You can specify separate installation prefixes for
architecture-specific files and architecture-independent files. If you
pass the option `--exec-prefix=PREFIX' to `configure', the package uses
PREFIX as the prefix for installing programs and libraries.
Documentation and other data files still use the regular prefix.
In addition, if you use an unusual directory layout you can give
options like `--bindir=DIR' to specify different values for particular
kinds of files. Run `configure --help' for a list of the directories
you can set and what kinds of files go in them. In general, the
default for these options is expressed in terms of `${prefix}', so that
specifying just `--prefix' will affect all of the other directory
specifications that were not explicitly provided.
The most portable way to affect installation locations is to pass the
correct locations to `configure'; however, many packages provide one or
both of the following shortcuts of passing variable assignments to the
`make install' command line to change installation locations without
having to reconfigure or recompile.
The first method involves providing an override variable for each
affected directory. For example, `make install
prefix=/alternate/directory' will choose an alternate location for all
directory configuration variables that were expressed in terms of
`${prefix}'. Any directories that were specified during `configure',
but not in terms of `${prefix}', must each be overridden at install
time for the entire installation to be relocated. The approach of
makefile variable overrides for each directory variable is required by
the GNU Coding Standards, and ideally causes no recompilation.
However, some platforms have known limitations with the semantics of
shared libraries that end up requiring recompilation when using this
method, particularly noticeable in packages that use GNU Libtool.
The second method involves providing the `DESTDIR' variable. For
example, `make install DESTDIR=/alternate/directory' will prepend
`/alternate/directory' before all installation names. The approach of
`DESTDIR' overrides is not required by the GNU Coding Standards, and
does not work on platforms that have drive letters. On the other hand,
it does better at avoiding recompilation issues, and works well even
when some directory options were not specified in terms of `${prefix}'
at `configure' time.
Optional Features
=================
If the package supports it, you can cause programs to be installed
with an extra prefix or suffix on their names by giving `configure' the
option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'.
Some packages pay attention to `--enable-FEATURE' options to
`configure', where FEATURE indicates an optional part of the package.
They may also pay attention to `--with-PACKAGE' options, where PACKAGE
is something like `gnu-as' or `x' (for the X Window System). The
`README' should mention any `--enable-' and `--with-' options that the
package recognizes.
For packages that use the X Window System, `configure' can usually
find the X include and library files automatically, but if it doesn't,
you can use the `configure' options `--x-includes=DIR' and
`--x-libraries=DIR' to specify their locations.
Some packages offer the ability to configure how verbose the
execution of `make' will be. For these packages, running `./configure
--enable-silent-rules' sets the default to minimal output, which can be
overridden with `make V=1'; while running `./configure
--disable-silent-rules' sets the default to verbose, which can be
overridden with `make V=0'.
Particular systems
==================
On HP-UX, the default C compiler is not ANSI C compatible. If GNU
CC is not installed, it is recommended to use the following options in
order to use an ANSI C compiler:
./configure CC="cc -Ae -D_XOPEN_SOURCE=500"
and if that doesn't work, install pre-built binaries of GCC for HP-UX.
HP-UX `make' updates targets which have the same time stamps as
their prerequisites, which makes it generally unusable when shipped
generated files such as `configure' are involved. Use GNU `make'
instead.
On OSF/1 a.k.a. Tru64, some versions of the default C compiler cannot
parse its `' header file. The option `-nodtk' can be used as
a workaround. If GNU CC is not installed, it is therefore recommended
to try
./configure CC="cc"
and if that doesn't work, try
./configure CC="cc -nodtk"
On Solaris, don't put `/usr/ucb' early in your `PATH'. This
directory contains several dysfunctional programs; working variants of
these programs are available in `/usr/bin'. So, if you need `/usr/ucb'
in your `PATH', put it _after_ `/usr/bin'.
On Haiku, software installed for all users goes in `/boot/common',
not `/usr/local'. It is recommended to use the following options:
./configure --prefix=/boot/common
Specifying the System Type
==========================
There may be some features `configure' cannot figure out
automatically, but needs to determine by the type of machine the package
will run on. Usually, assuming the package is built to be run on the
_same_ architectures, `configure' can figure that out, but if it prints
a message saying it cannot guess the machine type, give it the
`--build=TYPE' option. TYPE can either be a short name for the system
type, such as `sun4', or a canonical name which has the form:
CPU-COMPANY-SYSTEM
where SYSTEM can have one of these forms:
OS
KERNEL-OS
See the file `config.sub' for the possible values of each field. If
`config.sub' isn't included in this package, then this package doesn't
need to know the machine type.
If you are _building_ compiler tools for cross-compiling, you should
use the option `--target=TYPE' to select the type of system they will
produce code for.
If you want to _use_ a cross compiler, that generates code for a
platform different from the build platform, you should specify the
"host" platform (i.e., that on which the generated programs will
eventually be run) with `--host=TYPE'.
Sharing Defaults
================
If you want to set default values for `configure' scripts to share,
you can create a site shell script called `config.site' that gives
default values for variables like `CC', `cache_file', and `prefix'.
`configure' looks for `PREFIX/share/config.site' if it exists, then
`PREFIX/etc/config.site' if it exists. Or, you can set the
`CONFIG_SITE' environment variable to the location of the site script.
A warning: not all `configure' scripts look for a site script.
Defining Variables
==================
Variables not defined in a site shell script can be set in the
environment passed to `configure'. However, some packages may run
configure again during the build, and the customized values of these
variables may be lost. In order to avoid this problem, you should set
them in the `configure' command line, using `VAR=value'. For example:
./configure CC=/usr/local2/bin/gcc
causes the specified `gcc' to be used as the C compiler (unless it is
overridden in the site shell script).
Unfortunately, this technique does not work for `CONFIG_SHELL' due to
an Autoconf bug. Until the bug is fixed you can use this workaround:
CONFIG_SHELL=/bin/bash /bin/bash ./configure CONFIG_SHELL=/bin/bash
`configure' Invocation
======================
`configure' recognizes the following options to control how it
operates.
`--help'
`-h'
Print a summary of all of the options to `configure', and exit.
`--help=short'
`--help=recursive'
Print a summary of the options unique to this package's
`configure', and exit. The `short' variant lists options used
only in the top level, while the `recursive' variant lists options
also present in any nested packages.
`--version'
`-V'
Print the version of Autoconf used to generate the `configure'
script, and exit.
`--cache-file=FILE'
Enable the cache: use and save the results of the tests in FILE,
traditionally `config.cache'. FILE defaults to `/dev/null' to
disable caching.
`--config-cache'
`-C'
Alias for `--cache-file=config.cache'.
`--quiet'
`--silent'
`-q'
Do not print messages saying which checks are being made. To
suppress all normal output, redirect it to `/dev/null' (any error
messages will still be shown).
`--srcdir=DIR'
Look for the package's source code in directory DIR. Usually
`configure' can determine that directory automatically.
`--prefix=DIR'
Use DIR as the installation prefix. *note Installation Names::
for more details, including other options available for fine-tuning
the installation locations.
`--no-create'
`-n'
Run the configure checks, but stop before creating any output
files.
`configure' also accepts some other, not widely useful, options. Run
`configure --help' for more details.
xf86-input-synaptics-1.9.2/ChangeLog 0000644 0143106 0000012 00001777154 14262661552 014210 0000000 0000000 commit bf3c0cb38ad5dba43f0454e655e0448712cb412e
Author: Alan Coopersmith
Date: Sun Jul 10 16:32:38 2022 -0700
xf86-input-synaptics 1.9.2
Signed-off-by: Alan Coopersmith
commit ae160fc87bd2d52e0ab807b31dc2682beb3db772
Author: Alan Coopersmith
Date: Sun Jan 16 13:04:35 2022 -0800
Convert remaining source files from ISO-8859-1 to UTF-8
Most were already converted. Fixes error raised by FlawFinder in CI:
Error: encoding error in ./src/synaptics.c
'utf-8' codec can't decode byte 0xa9 in position 16: invalid start byte
Signed-off-by: Alan Coopersmith
commit 74282e856cb09c18460dd81ae2e5cac8cc531d51
Author: Alan Coopersmith
Date: Sun Jan 16 12:46:06 2022 -0800
gitlab CI: add a basic build test
Signed-off-by: Alan Coopersmith
commit 592215a584100db752cde86f6e9fb2115212a648
Author: Alan Coopersmith
Date: Sun Jan 16 12:42:17 2022 -0800
Fix spelling/wording issues
Found by using:
codespell --builtin clear,rare,usage,informal,code,names
Signed-off-by: Alan Coopersmith
commit 6d6c2e79221e6f362d1f47d3e52259e1d4e32315
Author: Alan Coopersmith
Date: Sun Jan 16 12:37:06 2022 -0800
Build xz tarballs instead of bzip2
Signed-off-by: Alan Coopersmith
commit 3e4bc35dfe96208fc55d1b5a279206a2013153ef
Author: Pip Cet
Date: Fri Apr 9 16:58:38 2021 +0000
synclient: allow negative/large values for AreaLeftEdge etc.
commit 7c32bc6f1f689b2c877be3a6b65a68844f9ce7e4
Author: Ariadne Conill
Date: Tue Jul 28 04:03:08 2020 -0600
eventcomm: fix compile with pre-time64 kernels
commit 073b1b40bde9935928758c3452176c0d8dc67370
Author: Ariadne Conill
Date: Wed Jul 22 02:29:08 2020 -0600
eventcomm: use 64-bit time safe accessors instead of timeval directly
when building on a 32-bit host with 64-bit time_t, using the
input_event and input_event_usec accessors are necessary to deal with
translation.
commit a4e5f74b589441077678d5d1546f7de0365a4627
Author: Matthieu Herrb
Date: Sun Feb 10 17:29:22 2019 +0100
Use fabs() instead of abs() on double values.
Silences clang warnings.
Signed-off-by: Matthieu Herrb
Reviewed-by: Walter Harms
Signed-off-by: Peter Hutterer
commit f8d896ddca8f24fcbe115366db9ab3ce2badefd1
Author: Alan Coopersmith
Date: Sun Nov 25 12:50:31 2018 -0800
Update configure.ac bug URL for gitlab migration
Signed-off-by: Alan Coopersmith
commit 8e61f0d57ecf967d523cd0ca63088120a12e942a
Author: Alan Coopersmith
Date: Sun Nov 18 12:01:00 2018 -0800
Update README for gitlab migration
Signed-off-by: Alan Coopersmith
commit a46338a9923a2434b130cdaaed014e54020edf2a
Author: Peter Hutterer
Date: Tue May 29 13:17:59 2018 +1000
synaptics 1.9.1
Signed-off-by: Peter Hutterer
commit 9f3a6ac97e9d3f13cdfb38e54fbce92452025830
Author: Peter Hutterer
Date: Mon May 14 09:49:00 2018 +1000
eventcomm: if we get a read error other than EAGAIN, remove the fd
Otherwise poll() keeps on triggering on our fd until udev gets around to
notifying the server that the device is in some state of deadness. Meanwhile,
the input thread is busy filling the log up with "Read error" messages. Great
way to test file systems and their capacity to handle out of space scenarios
but otherwise a bit pointless. Those FS developers should write their own
tests instead of relying on the synaptics driver!
Signed-off-by: Peter Hutterer
Reviewed-by: Adam Jackson
commit 59eb0c372b615fce5039e69b5067adc0efe5b64b
Author: Luca Castagnini
Date: Wed Oct 25 12:14:45 2017 +0200
Replace SA_ONESHOT with the more portable SA_RESETHAND.
Signed-off-by: Peter Hutterer
commit 6d3749105d964da5b4e534206fdb47f5ff8a697f
Author: Peter Hutterer
Date: Thu Aug 17 13:10:31 2017 +1000
Drop HandleTouches - it's a noop
With the removal of touch events in 0a4cf80a00663, this function is a noop. It
merely counted the number of touches but discarded the result. And
UpdateTouchState does the update anyway.
https://bugs.freedesktop.org/show_bug.cgi?id=102209
Signed-off-by: Peter Hutterer
commit afa8d7bb469e7ce01d9239f0dd790d3d620bfbd6
Author: Mihail Konev
Date: Thu Jan 26 14:00:21 2017 +1000
autogen: add default patch prefix
Signed-off-by: Mihail Konev
commit 703b44fa687148e400f3a92bfe3a7e120e6c355e
Author: Emil Velikov
Date: Mon Mar 9 12:00:52 2015 +0000
autogen.sh: use quoted string variables
Place quotes around the $srcdir, $ORIGDIR and $0 variables to prevent
fall-outs, when they contain space.
Signed-off-by: Emil Velikov
Reviewed-by: Peter Hutterer
Signed-off-by: Peter Hutterer
commit 3261e07c923c449f08a96a8439c97479b7ff899c
Author: Peter Hutterer
Date: Fri Nov 18 13:00:09 2016 +1000
synaptics 1.9.0
Signed-off-by: Peter Hutterer
commit a7d76f4275a88d98b18eed29a1ee94a70e7fa367
Author: Peter Hutterer
Date: Sun Oct 9 19:27:47 2016 +1000
synaptics 1.8.99.2
Signed-off-by: Peter Hutterer
commit 35b9472a189c88415fed137fb4c62a5081caaea5
Author: Peter Hutterer
Date: Thu Sep 15 13:47:09 2016 +1000
Remove unused fraction calculations
hw.x and the motion history are integers so our deltas are always integers.
It's a bit pointless to split them into the fractional and integral part.
obsolete since defc1d008e5674306a or so
Signed-off-by: Peter Hutterer
commit 486322116d70365c2e2a1d9f45830057fa03153e
Author: Peter Hutterer
Date: Wed Aug 17 11:32:12 2016 +1000
eventcomm: don't ever probe if a device is set
If opening the fd fails we still need to fail the device. This is particularly
the case when a device disappears before we can open it - the current code
wouldn't exit but instead switch to auto-probe touchpad devices on the system.
Signed-off-by: Peter Hutterer
Reviewed-by: Hans de Goede
commit cd9f9799235aefff1ec1a0af9ec6b45969119659
Author: Anton Lindqvist
Date: Fri Aug 5 10:21:59 2016 +0200
syndaemon: enable touchpad when pressing a modifier combo
When ignoring modifiers, ensure the touchpad is enabled once a modifier
key is pressed disregarding any previous key press that caused the
touchpad to be disabled.
Signed-off-by: Anton Lindqvist
Signed-off-by: Peter Hutterer
commit 248c5936a0151d0766a95457330c7d3ef9335b94
Author: Peter Hutterer
Date: Thu Jun 2 10:05:02 2016 +1000
Support XINPUT ABI version 23
Use input_lock/input_unlock calls instead of SIGIO functions
Signed-off-by: Peter Hutterer
commit 59e5db025307404fbfbc82f2fb3fe91d6a3005d7
Author: Stefan Dirsch
Date: Thu May 19 17:35:57 2016 +0200
conf: rename to 70-synaptics.conf
Bump up the synaptics driver to 70, so it get's preferred over libinput, which
was dropped down to 60. The synaptics driver is more of a leaf package
than libinput (which covers a multitude of device types) and can be removed by
default. When specifically installed by the user, the synaptics driver should
override the system default.
Similar to what was done for wacom configuration file.
https://bugzilla.suse.com/show_bug.cgi?id=979554
Signed-off-by: Stefan Dirsch
Signed-off-by: Peter Hutterer
commit 979fbec84197cd2c8ea3ffdd8e7726e8a617328b
Author: Peter Hutterer
Date: Fri Apr 29 10:51:17 2016 +1000
Revert MaxDoubleTapTime back to 180
Fallout from 90c6d7fc60f3db1bd9db1c7702062fcaef3b3352 where it got changed to
100ms. This is too short for triple-tap-and-drag gestures so revert it to the
previous value.
https://bugs.freedesktop.org/show_bug.cgi?id=95171
Signed-off-by: Peter Hutterer
commit 2a1a17244f067b2ae893ea01d737e135586b151c
Author: Peter Hutterer
Date: Fri Apr 29 08:48:19 2016 +1000
synaptics 1.8.99.1
Signed-off-by: Peter Hutterer
commit f1f58fffbf482de74bc7907e0af69feb9fe88a45
Author: Peter Hutterer
Date: Wed Apr 27 09:29:27 2016 +1000
eventcomm: fix typo checking for two-finger scrolling
Signed-off-by: Peter Hutterer
commit 0a4cf80a00663ff3ce8e76baf0940782576efe13
Author: Peter Hutterer
Date: Thu Mar 26 16:28:56 2015 +1000
Drop touch events from the driver
This was a bad idea. No-one seems to use this and it gives us little benefits.
To even get this feature a number of other features need to be turned off
(like two-finger scrolling and tapping). Many of these are enabled by default,
if they are disabled a client stack with full touchpad gesture support could
in theory support true touchpad gestures. This has never happened.
Drop the touch events from the synaptics driver. This allows us to switch the
touchpad fully over to look like a relative device, thus also removing the
bug that changes the touchpad speed whenever a monitor is added/removed in.
Signed-off-by: Peter Hutterer
Reviewed-by: Hans de Goede
commit 7aa327603fb2a8af58c8df6f4a4dd46e8294050e
Author: Peter Hutterer
Date: Wed Jun 17 15:31:08 2015 +1000
eventcomm: ignore key repeat events
Usually doesn't happen, but the evtest output in
https://bugs.freedesktop.org/show_bug.cgi?id=90392
actually has repeat events for the button. Ignore them if they happen.
Signed-off-by: Peter Hutterer
commit fc9f490a2c87e6f87b0f483cd6bf5f526dddbb8d
Author: Peter Hutterer
Date: Tue Mar 24 15:41:39 2015 +1000
eventcomm: ignore fake and broken MT devices
An MT device without X/Y is not a touchpad. And neither are fake MT devices.
Signed-off-by: Peter Hutterer
Reviewed-by: Hans de Goede
commit 30866b97be6939b895327b930154ef758eed7ff8
Author: Peter Hutterer
Date: Mon Mar 23 11:38:15 2015 +1000
eventcomm: prevent possibly division by zero
This came up as a kernel bug, but it's valid to create uinput devices with a
min == max range for x/y. Technically valid, but effectively useless, so catch
it, complain and hobble on along.
Signed-off-by: Peter Hutterer
Reviewed-by: Hans de Goede
commit 5378a020a003cbdfa565d43c9e01997b570059c9
Author: Peter Hutterer
Date: Tue Mar 17 16:06:41 2015 +1000
Revert "Support the new Lenovo X1 Carbon 3rd trackpoint buttons"
This reverts commit 064445364b4775b25ba49c2250b22b169f291147.
The Lenovo *50 series, including the X1 Carbon 3rd always require multiple
kernel patches to enable the touchpad buttons. This patch in synaptics only
addresses the re-routing of the top buttons.
The final iteration of the kernel patches also route the trackpoint buttons
through the trackpoint device, rendering this patch unnecessary. These patches
are queued for 4.0.
See kernel patch series up to commit cdd9dc195916ef5644cfac079094c3c1d1616e4c
Author: Benjamin Tissoires
Date: Sun Mar 8 22:35:41 2015 -0700
Input: synaptics - re-route tracksticks buttons on the Lenovo 2015 series
Currently in Dmitry's for-linus branch.
Distributions running older kernels or the kernel stable series which has
partial backports of the above patch series are encouraged to leave the
0644453 commit in and undo this revert.
Signed-off-by: Peter Hutterer
Reviewed-by: Hans de Goede
commit 00db769067fa0703f96284bd50ea384efd47e2de
Author: Peter Hutterer
Date: Fri Mar 6 11:06:41 2015 +1000
conf: add Lenovo T450s and W451 to rules
Signed-off-by: Peter Hutterer
commit 37d34f0356cc556dd8a49ec5d1ed64d49417a9b2
Author: Gabriele Mazzotta
Date: Thu Jan 15 22:04:17 2015 +0100
Add a delay between the second button down-up event of double taps
Some applications ignore the second tap of double taps because of the
lack of a delay between the button down and button up events.
Prevent this by replacing the transition from TS_2B to TS_START with a
transition from TS_2B to TS_SINGLETAP that emits only a button down
event. The button up event will be emitted when transitioning from
TS_SINGLETAP to TS_START.
In addition, decrease the default value of MaxDoubleTapTime from 180 ms
to 100 ms in order to make double taps faster.
Signed-off-by: Gabriele Mazzotta
Signed-off-by: Peter Hutterer
commit 064445364b4775b25ba49c2250b22b169f291147
Author: Peter Hutterer
Date: Thu Jan 29 11:25:26 2015 +1000
Support the new Lenovo X1 Carbon 3rd trackpoint buttons
This device has the trackpoint buttons wired up to the touchpad to send BTN_0,
BTN_1 and BTN_2 for left, right, middle. This conflicts with previous
touchpads that used those event codes for dedicated scroll buttons.
Add an option HasTrackpointButtons that can be set via a xorg.conf.d
snippets. This option is not intended as a user-set option, rather
we expect distributions to ship some conglomerate of udev/hal rules with
xorg.conf snippets that take effect.
If the option is set, we look at the three affected buttons at the beginning
of HandleState and send button events immediately for them. The HW state is
reset to neutral and other processing continues. This saves us from having to
synchronize these buttons with software buttons (also present on this device),
tapping, etc.
Since the buttons are physically different and (mentally) associated with the
trackpoint device we also don't need to worry about having finger motion event
correctly synced up with the button presses - it's acceptable to send the
presses before the motion events.
Signed-off-by: Peter Hutterer
Reviewed-by: Hans de Goede
Tested-by: Benjamin Tissoires
commit a357647d3fb918b94efbda98138fb0240a949ef2
Author: Gabriele Mazzotta
Date: Thu Jan 15 22:04:16 2015 +0100
Update machine state diagram
The diagram didn't entirely reflect the current state of the code.
Signed-off-by: Gabriele Mazzotta
Signed-off-by: Peter Hutterer
commit 383355fa5f536205759f10efa99eaec4e5089376
Author: Gabriele Mazzotta
Date: Fri Jan 9 17:01:42 2015 +0100
Remove FastTap leftovers
FastTap was removed with d14ea867ad5d ("Purge fast-taps option"),
remove all of what remained.
Signed-off-by: Gabriele Mazzotta
Signed-off-by: Peter Hutterer
commit a05894d169be42f03d21fb8287da902d8c24c566
Author: Gabriele Mazzotta
Date: Wed Jan 7 14:12:33 2015 +0100
Don't assume that touch devices report per finger width and pressure
The palm detection relies on both the width and the pressure.
a897147be04 ("Use ABS_MT events for the palm detection when supported")
assumed that all the touch devices can report both ABS_MT_TOUCH_MAJOR
and ABS_MT_PRESSURE, but this is not necessarily true. This assumption
could hence break the palm detection when at least one of the mentioned
events is not declared but both ABS_TOOL_WIDTH and ABS_PRESSURE are
reported.
Signed-off-by: Gabriele Mazzotta
Signed-off-by: Peter Hutterer
commit a897147be04d74ed452cda166fd4e01f9615ff72
Author: Gabriele Mazzotta
Date: Tue Sep 16 17:20:15 2014 +0200
Use ABS_MT events for the palm detection when supported
Use ABS_MT_TOUCH_MAJOR and ABS_MT_PRESSURE instead of ABS_TOOL_WIDTH
and ABS_PRESSURE when supported so that the pressure and the width of
all the fingers is taken into account for the palm detection.
This also fixes the palm detection for those touchpads for which the
kernel only sends ABS_MT_TOUCH_MAJOR and not ABS_TOOL_WIDTH.
Signed-off-by: Gabriele Mazzotta
Signed-off-by: Peter Hutterer
commit 41b2312c006fca1f24e1a366174d3203a63fa04a
Author: Peter Hutterer
Date: Tue Sep 16 08:52:56 2014 +1000
Limit the movement to 20 mm per event
Touchpads are limited by a fixed sampling rate (usually 80Hz). Some finger
changes may happen too fast for this sampling rate, resulting in two distinct
event sequences:
* finger 1 up and finger 2 down in the same EV_SYN frame. Synaptics sees one
finger down before and after and the changed coordinates
* finger 1 up and finger 2 down _between_ two EV_SYN frames. Synaptics sees one
touchpoint move from f1 position to f2 position.
That move causes a large cursor jump. The former could be solved (with
difficulty) by adding fake EV_SYN handling after releasing touchpoints but
that won't fix the latter case.
So as a solution for now limit the finger movement to 20mm per event.
Tests on a T440 and an x220 showed that this is just above what a reasonable
finger movement would trigger. If a movement is greater than that limit, reset
it to 0/0.
On devices without resolution, use 0.25 of the touchpad's diagonal instead.
Signed-off-by: Peter Hutterer
Reviewed-by: Hans de Goede
commit 049611bd7f04e285909c55807478306cce83385f
Author: Peter Hutterer
Date: Tue Sep 16 10:44:40 2014 +1000
Prohibit negative or zero x/y resolutions
Default resolution is 1, don't allow setting 0 to avoid divisions by 0 or
just general weirdness.
Signed-off-by: Peter Hutterer
commit afbbcfa10eb3a2295823720907f35bb59972dd82
Author: Peter Hutterer
Date: Fri Sep 5 15:14:47 2014 +1000
When resetting, reset the open slots to -1
open_slots holds the slot index, resetting it to 0 is a bad idea. And make
sure that we do reset after DEVICE_INIT. We already do so on DEVICE_CLOSE, but
after the first DEVICE_ON the data could still be random.
Signed-off-by: Peter Hutterer
Reviewed-by: Keith Packard
commit d239f831f17ccf5468f5dc6b2f199a9c1f6e35af
Author: Peter Hutterer
Date: Fri Sep 5 14:24:29 2014 +1000
eventcomm: add missing axis labels to avoid array overrun
And warn when we run out of labels.
Signed-off-by: Peter Hutterer
Reviewed-by: Keith Packard
commit 4d3d761799436e80fbcf0d99797eed35e68c90d2
Author: Peter Hutterer
Date: Fri Sep 5 14:15:46 2014 +1000
Shut up a coverity warning
xf86-input-synaptics-1.8.0/src/synaptics.c:498: var_compare_op: Comparing
"end_str" to null implies that "end_str" might be null.
end_str can't be null, so no need for this check and no need to get Coverity
all confused.
Signed-off-by: Peter Hutterer
Reviewed-by: Keith Packard
commit 536e17c83e565ddba9c7c5a4cd613edf8378e9aa
Author: Peter Hutterer
Date: Fri Sep 5 14:13:08 2014 +1000
Mark some switch case fallthroughs with comments
Just to make it explicit
Signed-off-by: Peter Hutterer
Reviewed-by: Keith Packard
commit ec0901e5f81d9cad6cc8bbdcb5ea075009c13de5
Author: Gabriele Mazzotta
Date: Thu Aug 14 20:03:42 2014 +0200
Use cumulative relative touch movements while scrolling
Signed-off-by: Gabriele Mazzotta
Reviewed-by: Peter Hutterer
Signed-off-by: Peter Hutterer
commit 90d19302306f49722e210227b2fb5161e6f51880
Author: Peter Hutterer
Date: Thu Aug 28 14:13:38 2014 +1000
eventcomm: ensure we're on the same clock as the server
Default on evdev devices is CLOCK_REALTIME. If that clock falls behind the
server's CLOCK_MONOTONIC, motion after a clickpad click may be delayed by the
difference in the clocks.
In detail:
When the timer func is triggered, GetTimeInMillis() which is CLOCK_MONOTONIC,
is stored as hwState->millis. The eventcomm backend uses struct
input_event time (CLOCK_REALTIME).
When we read events from the device, if the evdev time is less than the server
time, the fix for (#48777) sets the current event time to hwState->millis.
Until the evdev time overtakes that stored time, all events have the
hwState->millis time.
If during that time a clickpad triggers a physical click,
clickpad_click_millis is set to hwState->millis + the ignore-motion timeout.
Thus, all motion is ignored until the event time overtakes that stored
time.
The whole issue is further enhanced by us unconditionally setting the timer
func if we get any events, which is a separate issue anyway.
Signed-off-by: Peter Hutterer
Reviewed-by: Hans de Goede
commit 96e60a4ea242d2decf109835981ae186cc36f642
Author: Peter Hutterer
Date: Fri Aug 29 07:57:41 2014 +1000
Include xorg-server.h to fix build errors on newest glibc
In file included from /usr/include/string.h:634:0,
from /usr/include/xorg/os.h:53,
from /usr/include/xorg/misc.h:115,
from /usr/include/xorg/xf86str.h:37,
from /usr/include/xorg/xf86Xinput.h:54,
from synproto.h:36,
from synproto.c:24:
/usr/include/xorg/os.h:579:1: error: expected identifier or '(' before '__extension__'
strndup(const char *str, size_t n);
See http://lists.freedesktop.org/archives/xorg-devel/2014-July/043070.html
Signed-off-by: Peter Hutterer
commit 68d22ecf145bb9073121fd3a9fc1fdd0f880e48b
Author: Peter Hutterer
Date: Thu Aug 28 16:50:18 2014 +1000
Silence two compiler warnings
Potentially uninitialized, false positive in both cases.
Signed-off-by: Peter Hutterer
commit 7d0ff39519e4d3760722b914883bee276035061c
Author: Gabriele Mazzotta
Date: Sun Jul 27 12:58:18 2014 +0200
Prevent two-finger taps from being ignored
When two fingers are used, the coordinates of only one of them is taken into
account. This can lead to sudden variations of the absolute coordinates when
two-fingers taps are performed if the finger considered changes.
Take into account coordinates variations to prevent unwanted taps only if
the number of fingers doesn't change.
Reviewed-by: Peter Hutterer
Signed-off-by: Peter Hutterer
commit a36edf8307ab9b5bffca103dd875623a66012c0b
Author: Peter Hutterer
Date: Thu May 15 08:34:55 2014 +1000
Use libevdev's per-device logging functions instead of the global handler
Per-device logging functions don't interfere with other drivers if they also
use libevdev, so use those instead the global log handler if available. If not
available, drop libevdev logging, I don't want to maintain the ifdef mess and
the logging doesn't give us _that_ much benefit.
Signed-off-by: Peter Hutterer
commit c1457c0f71e30c194180164320759849fa09bf9b
Author: Peter Hutterer
Date: Thu May 29 14:44:43 2014 +1000
synaptics 1.8.99
Signed-off-by: Peter Hutterer
commit 730101223432f60397c61f74a5e6789b3ee34ecd
Author: Peter Hutterer
Date: Wed Aug 6 12:04:14 2014 +1000
conf: increase top software button area to 15%
We had reports that the top software button area is hard to hit for those
using the trackpoint and clicking the buttons with their thumb.
Analysis of event recordings (3 different people) for left, right and middle
clicks shows that there is a significant amount of events up to about 10mm
(with outliers up to 12mm) from the top of the touchpad. That maps to 15%.
Interestingly, the middle button does not seem to need this, presumably the
haptic feedback of the little dots sticking out from the surface make hitting
the button easier. Its size is increased to 15% anyway, for simplicity and
because a sample set of 3 is too small to be definitive about this.
Signed-off-by: Peter Hutterer
Reviewed-by: Hans de Goede
commit ddd8844a47bfa28974e40fc9aec9b17656415a6c
Author: Peter Hutterer
Date: Mon May 19 08:06:46 2014 +1000
eventcomm: Drop requirement for a grab during init
When we required a grab on the device, this was a shortcut so we didn't have
to query the device only to realise we can't read events off it anyway. Now
that we don't actually grab the device by default, this is unnecessary.
Something else may have a temporary grab on the device during init, in which
case we just continue as usual and read events if and when they become
available.
Signed-off-by: Peter Hutterer
Reviewed-by: Hans de Goede
commit 3a4cc96590ca0e0ff526a5e5406f29a402bddd1a
Author: Peter Hutterer
Date: Tue May 13 11:20:25 2014 +1000
synaptics 1.8.0
Signed-off-by: Peter Hutterer
commit d4d7229c41a20cf6757882a24f45e28d936a27c5
Author: Peter Hutterer
Date: Wed Apr 30 13:08:53 2014 +1000
conf: drop the PNPID matching from the fdi file
Rely on INPUT_PROP_TOP_BUTTONPAD and default button areas as well.
Signed-off-by: Peter Hutterer
commit a31ecb669f40d8db3ab1867eaedfe364bbd6fafe
Author: Peter Hutterer
Date: Wed Apr 30 07:45:34 2014 +1000
synaptics 1.7.99.2
Signed-off-by: Peter Hutterer
commit efa424b5c9c084c1c1136a68329709c7dc9ddfda
Author: Clinton Sprain
Date: Tue Apr 29 19:47:17 2014 -0500
Fix product ID cutoff for MODEL_APPLETOUCH/MODEL_UNIBODY_MACBOOK
Some Macbooks are being tagged as MODEL_UNIBODY_MACBOOKs when they should not
be. This causes the default sensitivity to be very low for them, making the
touchpad almost unusable. This change puts those devices into the correct
bucket again.
Signed-off-by: Clinton Sprain
Reviewed-by: Peter Hutterer
Signed-off-by: Peter Hutterer
commit 7bf27568417691e772e715f8fc6c30ea7ec892d6
Author: Hans de Goede
Date: Tue Apr 22 18:58:11 2014 +0200
Add support for INPUT_PROP_TOPBUTTONPAD
Add a HasSecondaryButtons boolean config option which defaults to true for
devices with the INPUT_PROP_TOPBUTTONPAD and false for all other devices.
Only parse the SecondarySoftButtonAreas when this option is true, effectively
disabling the top buttons when it is false. Likewise, only initialize the
SecondarySoftButtonAreas property if we enable support for it.
This means that it is now safe to always set a SecondarySoftButtonAreas
default in 50-synaptics.conf, and that he section which was intended for
use with future pnp-id matching can be dropped, as that is now all handled
in the kernel.
While at also remove the comment about disabling the bottom edge area, as that
is now done automatically.
Signed-off-by: Hans de Goede
Signed-off-by: Peter Hutterer
Reviewed-by: Hans de Goede
commit 41afac2abf12dd74a171f726b57014f7fb266957
Author: Peter Hutterer
Date: Tue Apr 29 12:13:10 2014 +1000
man: add some missing quotes
Signed-off-by: Peter Hutterer
commit a6f0f4c9a5bcb0e25343dd4c59d4cc47cc5e8006
Author: Hans de Goede
Date: Fri Apr 11 20:41:36 2014 +0200
Always count tripletap + click as 3 fingerclick on pads with < 3 touches
When trying to do a 3 fingerclick on a touchpad which only tracks 2 touches,
this may register as a 3 or 2 fingerclick depending on the order in which
the touchpad detects the fingers. If the 2 outer fingers of the 3 get seen
first, then the 2 touches will be too far apart for the heuristic to see
them as being close together, and the click gets counted as a 2 finger click.
A user will likely never do a 2 finger click with a 3th finger resting
somewhere else on the pad, where-as the above misdetection of the clicks is
a real issue, so simply always count a click with trippletap set as a
3 finger click on pads which track less then 3 touches.
https://bugzilla.redhat.com/show_bug.cgi?id=1086218
Signed-off-by: Hans de Goede
Reviewed-by: Peter Hutterer
Signed-off-by: Peter Hutterer
commit f183c1c38778b659b4c75a0e2c532dd5a9f8d437
Author: Peter Hutterer
Date: Wed Apr 9 10:41:29 2014 +1000
conf: add more PnPIDs and DMI matches for Lenovos
And expand DMI strings to more precise matches
Signed-off-by: Peter Hutterer
Reviewed-by: Hans de Goede
commit 62ef210d11714703345dc8d35915ff53c37aee01
Author: Peter Hutterer
Date: Mon Apr 7 16:16:13 2014 +1000
Comment the touch states
Everytime I look at this I get confused about OPEN_EMPTY vs EMPTY. Let's fix
that.
Signed-off-by: Peter Hutterer
Reviewed-by: Hans de Goede
commit bfceb1bc580656aceb14e4b0f880bfcb3e4bc368
Author: Peter Hutterer
Date: Fri Apr 4 15:51:22 2014 +1000
eventcomm: Hook up the libevdev log handler
This is a bit problematic: libevdev only has one global log handler.
So if we have another driver use libevdev, we'll either overwrite that handler
or get overwritten, whichever comes first. So we need to re-set the handler
every time we get an event to make sure we log through our handler.
Likewise, if we ever drop the device, we need to unset the log handler back to
NULL because we may unload the module and our handler may disappear.
Use the lowest logging priority, let the server filter based on the verbosity
level instead.
Signed-off-by: Peter Hutterer
Reviewed-by: Hans de Goede
commit 6ad856790630393bbd41b0bd7746ed9b0629a7c6
Author: Peter Hutterer
Date: Thu Apr 3 16:41:15 2014 +1000
eventcomm: read one more event after finishing a sync
Once the sync finishes, we get -EAGAIN. This only indicates the sync is done,
but some events may still be waiting in the pipe for us to read. We must read
those now, otherwise select may not trigger on further data.
Signed-off-by: Peter Hutterer
Reviewed-by: Hans de Goede
commit bec41416dbbee73eef9eee122d0acacc148e329d
Author: Peter Hutterer
Date: Thu Apr 3 15:42:45 2014 +1000
eventcomm: drop superflous helper function
last_mt_vals_slot is only used in one location and there we can just use
cur_slot
Signed-off-by: Peter Hutterer
Reviewed-by: Hans de Goede
commit f1948e08ee9894864254a18098e4f4fceb6e322f
Author: Peter Hutterer
Date: Wed Mar 19 15:08:15 2014 +1000
Disable GrabEventDevice by default
This was required when we started supporting hotplugging to avoid duplicate
events. These days the drawback of not being able to record events in the case
of a bug is significant.
Check the configuration source on init. If the device was hotplugged through a
a server config backend, disable the grab. If the device was statically
configured through an xorg.conf then leave the default grab enabled to avoid
a duplicate device.
Signed-off-by: Peter Hutterer
Reviewed-by: Hans de Goede
commit fd709900445e3cb9f31ce7e780bfa98ecb6dab9b
Author: Peter Hutterer
Date: Tue Mar 18 07:28:44 2014 +1000
synaptics 1.7.99.1
Signed-off-by: Peter Hutterer
commit dc5474964d4ec73b5c324961026e1037bb344946
Author: Peter Hutterer
Date: Mon Mar 17 14:55:37 2014 +1000
If the touchpad is in TOUCHPAD_OFF mode, allow physical clicks
Enabling clicks in off mode also allows for the new Lenovo *40 series to use
the top software buttons while the touchpad is disabled. This benefits those
that usually disable touchpads altogether but still need the buttons for the
trackstick.
This changes existing behaviour, but TouchpadOff was always intended to stop
erroneous events while typing. Physical button presses are hard to trigger
accidentally. On the touchpads that TouchpadOff concept was originally
designed for the buttons are nowhere near the keyboard and are physically
separated from the touchpad anyway. On Clickpads, triggering a physical
click requires more force than accidentally touching the surface.
https://bugs.freedesktop.org/show_bug.cgi?id=76156
Signed-off-by: Peter Hutterer