Compare commits

..

12 Commits

Author SHA1 Message Date
Peter Hutterer
5152d616ca evdev 2.0.3 2008-08-01 17:29:24 +09:30
Michel Dänzer
2e9a71df5f xf86-input-evdev: Fix EVIOCGBIT ioctl usage on big endian platforms.
With this fix, on my PowerBook HAL hotplugging correctly detects my USB mouse,
and no longer thinks keyboards have random numbers of mouse buttons. :)

The LONG_BITS and NBITS macro definitions are stolen from xf86-input-synaptics.

Signed-off-by: Michel Dänzer <michel@tungstengraphics.com>
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
[cherry-picked from master and fixed the trivial conflict -- jcristau]
2008-07-30 10:45:31 +02:00
Julien Cristau
49de32e70f Fill up the version info
Report correct versions instead of
"compiled for 0.0.0, module version = 1.0.0"
(cherry picked from commit 2b7edaa4ab)
2008-07-20 11:45:30 +02:00
Peter Hutterer
f135e07462 evdev 2.0.2 2008-07-14 13:34:36 +09:30
Peter Hutterer
e926356eb0 Don't enable the device if the grab failed with ENODEV.
After suspend/resume, sometimes the device doesn't come back up on the same
node. Since we do not call PreInit for the device (which would detect this
situation), we continue to try to read a nonexisting file, spamming the log
file with "Read Error".
(cherry picked from commit bf0d81011e)
2008-07-14 13:17:39 +09:30
Peter Hutterer
bd56ab3d72 Add .gitignore file.
(cherry picked from commit ef4bb69c1a)
2008-07-10 19:34:05 +09:30
Peter Hutterer
2b30413598 Remove static ChangeLog, autogenerate as part of make dist.
Hook taken from xserver's Makefile.am
(cherry picked from commit ec23c6b2f5)
2008-07-10 19:29:57 +09:30
Ander Conselvan de Oliveira
52fc8ee846 Mice with a lot of buttons (e.g. Logitech MX1000) generate button events greater than BTN_TASK.
Signed-off-by: Peter Hutterer <peter@cs.unisa.edu.au>
(cherry picked from commit 0830676a0c)
2008-07-10 19:29:45 +09:30
Peter Hutterer
b125b834f4 evdev 2.0.1 2008-06-22 17:52:58 +09:30
Peter Hutterer
05b20db8db No need to finalize MB emulation after EvdevProbe anymore.
Follow-up to 76800bfa75.
(cherry picked from commit 5a0ea39b79)
2008-06-22 16:26:10 +09:30
Simon Munton
43768d59da Close file descriptor if EvdevProbe fails.
Signed-off-by: Peter Hutterer <peter@cs.unisa.edu.au>
(cherry picked from commit 373e13ae35)
2008-06-22 16:25:48 +09:30
Keith Packard
9c524f6963 Enable middle button emulation at DEVICE_ON instead of DEVICE_INIT.
This ensures that the middle button emulation is re-enabled after VT switch,
otherwise the block handler that deals with the timeouts would not get
re-registered.

Signed-off-by: Keith Packard <keithp@keithp.com>
(cherry picked from commit 76800bfa75)
2008-06-22 16:24:57 +09:30
23 changed files with 1024 additions and 5352 deletions

19
.cvsignore Normal file
View File

@@ -0,0 +1,19 @@
Makefile
Makefile.in
*.la
*.lo
aclocal.m4
autom4te.cache
config.guess
config.h
config.h.in
config.log
config.status
config.sub
configure
depcomp
install-sh
libtool
ltmain.sh
missing
stamp-h1

78
.gitignore vendored
View File

@@ -1,78 +1,26 @@
#
# X.Org module default exclusion patterns
# The next section if for module specific patterns
#
# Do not edit the following section
# GNU Build System (Autotools)
aclocal.m4
autom4te.cache/
autoscan.log
*.patch
ChangeLog
compile
Makefile
Makefile.in
aclocal.m4
autom4te.cache
config.guess
config.h
config.h.in
config.log
config-ml.in
config.py
config.status
config.status.lineno
config.sub
configure
configure.scan
depcomp
.deps/
INSTALL
install-sh
.libs/
libtool
libtool.m4
ltmain.sh
lt~obsolete.m4
ltoptions.m4
ltsugar.m4
ltversion.m4
Makefile
Makefile.in
mdate-sh
man/evdev.4
missing
mkinstalldirs
*.pc
py-compile
stamp-h?
symlink-tree
texinfo.tex
ylwrap
# Do not edit the following section
# Edit Compile Debug Document Distribute
*~
*.[0-9]
*.[0-9]x
*.bak
*.bin
core
*.dll
*.exe
*-ISO*.bdf
*-JIS*.bdf
*-KOI8*.bdf
*.kld
*.ko
*.ko.cmd
*.lai
*.l[oa]
*.[oa]
*.obj
*.patch
*.so
*.pcf.gz
*.pdb
*.tar.bz2
*.tar.gz
#
# Add & Override patterns for xf86-input-evdev
#
# Edit the following section as needed
# For example, !report.pc overrides *.pc. See 'man gitignore'
#
.deps
.libs
*.lo
*.la
stamp-h1
*.bz2
*.gz

73
COPYING
View File

@@ -1,69 +1,12 @@
Copyright 1990,91 by Thomas Roell, Dinkelscherben, Germany.
Copyright 1993 by David Dawes <dawes@xfree86.org>
Copyright 2002 by SuSE Linux AG, Author: Egbert Eich
Copyright 1994-2002 by The XFree86 Project, Inc.
Copyright 2002 by Paul Elliott
Copyright © 2008 University of South Australia
Copyright 2008 by Chris Salch
Copyright © 2008 Red Hat, Inc.
This is a stub file. This package has not yet had its complete licensing
information compiled. Please see the individual source files for details on
your rights to use and modify this software.
Permission to use, copy, modify, distribute, and sell this software
and its documentation for any purpose is hereby granted without
fee, provided that the above copyright notice appear in all copies
and that both that copyright notice and this permission notice
appear in supporting documentation, and that the name of the authors
not be used in advertising or publicity pertaining to distribution of the
software without specific, written prior permission. The authors make no
representations about the suitability of this software for any
purpose. It is provided "as is" without express or implied
warranty.
Please submit updated COPYING files to the Xorg bugzilla:
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.
https://bugs.freedesktop.org/enter_bug.cgi?product=xorg
Copyright 2005 Sun Microsystems, Inc. All rights reserved.
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.
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.
All licensing questions regarding this software should be directed at the
Xorg mailing list:
http://lists.freedesktop.org/mailman/listinfo/xorg

View File

@@ -18,23 +18,17 @@
# 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.
AUTOMAKE_OPTIONS = foreign
SUBDIRS = src man
# Provide an sdk location that is writable by the evdev module
DISTCHECK_CONFIGURE_FLAGS = --with-sdkdir='$${includedir}/xorg'
EXTRA_DIST = ChangeLog autogen.sh
SUBDIRS = src man include
MAINTAINERCLEANFILES = ChangeLog INSTALL
MAINTAINERCLEANFILES=ChangeLog
pkgconfigdir = $(libdir)/pkgconfig
pkgconfig_DATA = xorg-evdev.pc
.PHONY: ChangeLog INSTALL
INSTALL:
$(INSTALL_CMD)
.PHONY: ChangeLog
ChangeLog:
$(CHANGELOG_CMD)
(GIT_DIR=$(top_srcdir)/.git git-log > .changelog.tmp && mv .changelog.tmp ChangeLog; rm -f .changelog.tmp) || \
(touch ChangeLog; echo 'git directory not found: installing possibly empty changelog.' >&2)
dist-hook: ChangeLog INSTALL
dist-hook: ChangeLog

20
README
View File

@@ -1,20 +0,0 @@
xf86-input-evdev - Generic Linux input driver for the Xorg X server
Please submit bugs & patches to the Xorg bugzilla:
https://bugs.freedesktop.org/enter_bug.cgi?product=xorg
All questions regarding this software should be directed at the
Xorg mailing list:
http://lists.freedesktop.org/mailman/listinfo/xorg
The master development code repository can be found at:
git://anongit.freedesktop.org/git/xorg/driver/xf86-input-evdev
http://cgit.freedesktop.org/xorg/driver/xf86-input-evdev
For more information on the git code manager, see:
http://wiki.x.org/wiki/GitPage

View File

@@ -9,6 +9,4 @@ cd $srcdir
autoreconf -v --install || exit 1
cd $ORIGDIR || exit $?
if test -z "$NOCONFIGURE"; then
$srcdir/configure "$@"
fi
$srcdir/configure --enable-maintainer-mode "$@"

View File

@@ -20,45 +20,48 @@
#
# Process this file with autoconf to produce a configure script
# Initialize Autoconf
AC_PREREQ([2.60])
AC_PREREQ(2.57)
AC_INIT([xf86-input-evdev],
[2.8.99.1],
2.0.3,
[https://bugs.freedesktop.org/enter_bug.cgi?product=xorg],
[xf86-input-evdev])
xf86-input-evdev)
AC_CONFIG_SRCDIR([Makefile.am])
AC_CONFIG_HEADERS([config.h])
AC_CONFIG_AUX_DIR(.)
AM_INIT_AUTOMAKE([dist-bzip2])
# Initialize Automake
AM_INIT_AUTOMAKE([foreign dist-bzip2])
AM_MAINTAINER_MODE
# Initialize libtool
DRIVER_NAME=evdev
AC_SUBST([DRIVER_NAME])
AM_CONFIG_HEADER([config.h])
# Checks for programs.
AC_DISABLE_STATIC
AC_PROG_LIBTOOL
AC_PROG_CC
# Initialize X.Org macros 1.8 or later for MAN_SUBSTS set by XORG_MANPAGE_SECTIONS
m4_ifndef([XORG_MACROS_VERSION],
[m4_fatal([must install xorg-macros 1.8 or later before running autoconf/autogen])])
XORG_MACROS_VERSION(1.8)
XORG_DEFAULT_OPTIONS
AH_TOP([#include "xorg-server.h"])
# Obtain compiler/linker options from server and required extensions
PKG_CHECK_MODULES(XORG, [xorg-server >= 1.10] xproto inputproto)
PKG_CHECK_MODULES(UDEV, libudev)
#AC_DEFINE(XFree86LOADER,1,[Stub define for loadable drivers])
#
#AC_ARG_ENABLE(XINPUT, AS_HELP_STRING([--enable-xinput],
# [Build XInput support (default: yes)]),
# [XINPUT=$enableval],[XINPUT=yes])
#AM_CONDITIONAL(XINPUT, test "x$XINPUT" = "xyes")
#if test "x$XINPUT" = "xyes" ; then
# AC_DEFINE(XINPUT,1,[Enable XInput support])
#fi
#
#AC_ARG_ENABLE(XKB, AS_HELP_STRING([--enable-xkb],
# [Build XKB support (default: yes)]),
# [XKB=$enableval],[XKB=yes])
#AM_CONDITIONAL(XKB, test "x$XKB" = "xyes")
#if test "x$XKB" = "xyes" ; then
# AC_DEFINE(XKB,1,[Enable XKB support])
#fi
PKG_CHECK_MODULES(XI22, [inputproto >= 2.1.99.3] [xorg-server >= 1.11.99.901], HAVE_XI22="yes", HAVE_XI22="no")
PKG_CHECK_MODULES(LIBEVDEV, [libevdev >= 0.4])
if test "x$HAVE_XI22" = xyes; then
# Obtain compiler/linker options for mtdev
PKG_CHECK_MODULES(MTDEV, mtdev, HAVE_MTDEV="yes", HAVE_MTDEV="no")
fi
if test "x$HAVE_XI22" = xyes && test "x$HAVE_MTDEV" = xyes; then
AC_DEFINE(MULTITOUCH, 1, [XI2.2 available])
fi
# 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]]]),
@@ -67,21 +70,23 @@ AC_ARG_WITH(xorg-module-dir,
inputdir=${moduledir}/input
AC_SUBST(inputdir)
# X Server SDK location is required to install evdev header files
# This location is also relayed in the xorg-evdev.pc file
sdkdir=`$PKG_CONFIG --variable=sdkdir xorg-server`
# Checks for extensions
XORG_DRIVER_CHECK_EXT(RANDR, randrproto)
XORG_DRIVER_CHECK_EXT(XINPUT, inputproto)
# 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_SUBST([sdkdir])
# Checks for pkg-config packages
PKG_CHECK_MODULES(XORG, xorg-server xproto $REQUIRED_MODULES)
sdkdir=$(pkg-config --variable=sdkdir xorg-server)
DRIVER_NAME=evdev
AC_SUBST([DRIVER_NAME])
CFLAGS="$CFLAGS $XORG_CFLAGS "' -I$(top_srcdir)/src'
AC_SUBST([CFLAGS])
AC_CONFIG_FILES([Makefile
src/Makefile
man/Makefile
include/Makefile
xorg-evdev.pc])
AC_OUTPUT
# Checks for libraries.
# Checks for header files.
AC_HEADER_STDC
XORG_MANPAGE_SECTIONS
XORG_RELEASE_VERSION
AC_OUTPUT([Makefile src/Makefile man/Makefile])

View File

@@ -1 +0,0 @@
sdk_HEADERS = evdev-properties.h

View File

@@ -1,94 +0,0 @@
/*
* Copyright © 2008 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 (peter.hutterer@redhat.com)
*/
#ifndef _EVDEV_PROPERTIES_H_
#define _EVDEV_PROPERTIES_H_
/* Middle mouse button emulation */
/* BOOL */
#define EVDEV_PROP_MIDBUTTON "Evdev Middle Button Emulation"
/* CARD32 */
#define EVDEV_PROP_MIDBUTTON_TIMEOUT "Evdev Middle Button Timeout"
/* Wheel emulation */
/* BOOL */
#define EVDEV_PROP_WHEEL "Evdev Wheel Emulation"
/* CARD8, 4 values [x up, x down, y up, y down], 0 to disable a value*/
#define EVDEV_PROP_WHEEL_AXES "Evdev Wheel Emulation Axes"
/* CARD16 */
#define EVDEV_PROP_WHEEL_INERTIA "Evdev Wheel Emulation Inertia"
/* CARD16 */
#define EVDEV_PROP_WHEEL_TIMEOUT "Evdev Wheel Emulation Timeout"
/* CARD8, value range 0-32, 0 to always scroll */
#define EVDEV_PROP_WHEEL_BUTTON "Evdev Wheel Emulation Button"
/* Drag lock */
/* CARD8, either 1 value or pairs, value range 0-32, 0 to disable a value*/
#define EVDEV_PROP_DRAGLOCK "Evdev Drag Lock Buttons"
/* Axis inversion */
/* BOOL, 2 values [x, y], 1 inverts axis */
#define EVDEV_PROP_INVERT_AXES "Evdev Axis Inversion"
/* Reopen attempts. */
/* CARD8 */
#define EVDEV_PROP_REOPEN "Evdev Reopen Attempts" /* OBSOLETE */
/* Run-time calibration */
/* CARD32, 4 values [minx, maxx, miny, maxy], or no values for unset */
#define EVDEV_PROP_CALIBRATION "Evdev Axis Calibration"
/* Swap x and y axis. */
/* BOOL */
#define EVDEV_PROP_SWAP_AXES "Evdev Axes Swap"
/* BOOL */
#define EVDEV_PROP_THIRDBUTTON "Evdev Third Button Emulation"
/* CARD32 */
#define EVDEV_PROP_THIRDBUTTON_TIMEOUT "Evdev Third Button Emulation Timeout"
/* CARD8 */
#define EVDEV_PROP_THIRDBUTTON_BUTTON "Evdev Third Button Emulation Button"
/* CARD32 */
#define EVDEV_PROP_THIRDBUTTON_THRESHOLD "Evdev Third Button Emulation Threshold"
/* CARD8, 1 value,
This property is initialized on devices that have multimedia keys on the
function keys. The value of the property selects the default behaviour
for the function keys. The behaviour of the fn key (if any exists) is
hardware specific. On some hardware, fn may toggle the other set of
functions available on the keys.
0 send functions keys by default, fn may toggle to multimedia keys
1 send multimedia keys by default, fn may toggle to function keys
*/
#define EVDEV_PROP_FUNCTION_KEYS "Evdev Function Keys"
/* Smooth scroll */
/* INT32, 3 values (vertical, horizontal, dial) */
#define EVDEV_PROP_SCROLL_DISTANCE "Evdev Scrolling Distance"
#endif

2
man/.cvsignore Normal file
View File

@@ -0,0 +1,2 @@
Makefile
Makefile.in

View File

@@ -1,37 +1,59 @@
# $Id$
#
# Copyright 2005 Sun Microsystems, Inc. All rights reserved.
#
# 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.
#
# 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.
#
# The above copyright notice and this permission notice 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 OPEN GROUP 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.
#
# Except as contained in this notice, the name of the copyright holders shall
# not be used in advertising or otherwise to promote the sale, use or
# other dealings in this Software without prior written authorization
# from the copyright holders.
#
drivermandir = $(DRIVER_MAN_DIR)
driverman_PRE = $(DRIVER_NAME).man
driverman_PRE = @DRIVER_NAME@.man
driverman_DATA = $(driverman_PRE:man=$(DRIVER_MAN_SUFFIX))
driverman_DATA = $(driverman_PRE:man=@DRIVER_MAN_SUFFIX@)
EXTRA_DIST = $(DRIVER_NAME).man
EXTRA_DIST = @DRIVER_NAME@.man
CLEANFILES = $(driverman_DATA)
SED = sed
# Strings to replace in man pages
XORGRELSTRING = @PACKAGE_STRING@
XORGMANNAME = X Version 11
MAN_SUBSTS = \
-e 's|__vendorversion__|"$(XORGRELSTRING)" "$(XORGMANNAME)"|' \
-e 's|__xorgversion__|"$(XORGRELSTRING)" "$(XORGMANNAME)"|' \
-e 's|__xservername__|Xorg|g' \
-e 's|__xconfigfile__|xorg.conf|g' \
-e 's|__projectroot__|$(prefix)|g' \
-e 's|__appmansuffix__|$(APP_MAN_SUFFIX)|g' \
-e 's|__drivermansuffix__|$(DRIVER_MAN_SUFFIX)|g' \
-e 's|__adminmansuffix__|$(ADMIN_MAN_SUFFIX)|g' \
-e 's|__miscmansuffix__|$(MISC_MAN_SUFFIX)|g' \
-e 's|__filemansuffix__|$(FILE_MAN_SUFFIX)|g'
SUFFIXES = .$(DRIVER_MAN_SUFFIX) .man
# String replacements in MAN_SUBSTS now come from xorg-macros.m4 via configure
.man.$(DRIVER_MAN_SUFFIX):
$(AM_V_GEN)$(SED) $(MAN_SUBSTS) < $< > $@
sed $(MAN_SUBSTS) < $< > $@

View File

@@ -9,9 +9,9 @@ evdev \- Generic Linux input driver
.BI " Identifier \*q" devname \*q
.B " Driver \*qevdev\*q"
.BI " Option \*qDevice\*q \*q" devpath \*q
.BI " Option \*qPath\*q \*q" path \*q
.BI " Option \*qEmulate3Buttons\*q \*q" True \*q
.BI " Option \*qEmulate3Timeout\*q \*q" 50 \*q
.BI " Option \*qGrabDevice\*q \*q" False \*q
\ \ ...
.B EndSection
.fi
@@ -19,24 +19,15 @@ evdev \- Generic Linux input driver
.B evdev
is an __xservername__ input driver for Linux\'s generic event devices. It
therefore supports all input devices that the kernel knows about, including
most mice, keyboards, tablets and touchscreens.
.B evdev
is the default driver on the major Linux distributions.
most mice and keyboards.
.PP
The
.B evdev
driver can serve as both a pointer and a keyboard input device. Multiple
input devices are supported by multiple instances of this driver, with one
InputDevice section of your __xconfigfile__ for each input device that will
use this driver.
.PP
It is recommended that
.B evdev
devices are configured through the
.B InputClass
directive (refer to __xconfigfile__(__filemansuffix__)) instead of manual
per-device configuration. Devices configured in the
__xconfigfile__(__filemansuffix__) are not hot-plug capable.
driver can serve as both a pointer and a keyboard input device, and may be
used as both the core keyboard and the core pointer. Multiple input devices
are supported by multiple instances of this driver, with one Load
directive for evdev in the Module section of your __xconfigfile__ for each
input device that will use this driver.
.PP
.SH SUPPORTED HARDWARE
In general, any input device that the kernel has a driver for can be accessed
@@ -53,236 +44,31 @@ The following driver
.B Options
are supported:
.TP 7
.BI "Option \*qButtonMapping\*q \*q" string \*q
Sets the button mapping for this device. The mapping is a space-separated list
of button mappings that correspond in order to the physical buttons on the
device (i.e. the first number is the mapping for button 1, etc.). The default
mapping is "1 2 3 ... 32". A mapping of 0 deactivates the button. Multiple
buttons can have the same mapping.
For example, a left-handed mouse with deactivated scroll-wheel would use a
mapping of "3 2 1 0 0". Invalid mappings are ignored and the default mapping
is used. Buttons not specified in the user's mapping use the default mapping.
.TP 7
.BI "Option \*qDevice\*q \*q" string \*q
Specifies the device through which the device can be accessed. This will
generally be of the form \*q/dev/input/eventX\*q, where X is some integer.
The mapping from device node to hardware is system-dependent. Property:
"Device Node" (read-only).
.TP 7
.BI "Option \*qDragLockButtons\*q \*q" "L1 B2 L3 B4" \*q
Sets \*qdrag lock buttons\*q that simulate holding a button down, so
that low dexterity people do not have to hold a button down at the
same time they move a mouse cursor. Button numbers occur in pairs,
with the lock button number occurring first, followed by the button
number that is the target of the lock button. Property: "Evdev
Drag Lock Buttons".
.TP 7
.BI "Option \*qDragLockButtons\*q \*q" "M1" \*q
Sets a \*qmaster drag lock button\*q that acts as a \*qMeta Key\*q
indicating that the next button pressed is to be
\*qdrag locked\*q. Property: "Evdev Drag Lock Buttons".
The mapping from device node to hardware is system-dependent. This option is
mandatory unless \*qPath\*q is given, and there is no default setting.
.TP 7
.BI "Option \*qPath\*q \*q" string \*q
Specifies the device through which the device can be accessed. This will
generally be of the form \*q/dev/input/by-path/xyz\*q, where xyz includes the
name of the device. The mapping from device node to hardware is
system-dependent. This option has precedence over the \*qDevice\*q option but
one of \*qPath\*q or \*qDevice\*q must be given.
.TP 7
.BI "Option \*qEmulate3Buttons\*q \*q" boolean \*q
Enable/disable the emulation of the third (middle) mouse button for mice
which only have two physical buttons. The third button is emulated by
pressing both buttons simultaneously. Default: off. Property: "Evdev Middle
Button Emulation".
pressing both buttons simultaneously. Default: on, until a middle mouse
button event is registered.
.TP 7
.BI "Option \*qEmulate3Timeout\*q \*q" integer \*q
Sets the timeout (in milliseconds) that the driver waits before deciding
if two buttons where pressed "simultaneously" when 3 button emulation is
enabled. Default: 50. Property: "Evdev Middle Button Timeout".
.TP 7
.BI "Option \*qEmulateWheel\*q \*q" boolean \*q
Enable/disable "wheel" emulation. Wheel emulation means emulating button
press/release events when the mouse is moved while a specific real button
is pressed. Wheel button events (typically buttons 4 and 5) are
usually used for scrolling. Wheel emulation is useful for getting wheel-like
behaviour with trackballs. It can also be useful for mice with 4 or
more buttons but no wheel. See the description of the
.BR EmulateWheelButton ,
.BR EmulateWheelInertia ,
.BR EmulateWheelTimeout ,
.BR XAxisMapping ,
and
.B YAxisMapping
options. Default: off. Property "Evdev Wheel Emulation".
.TP 7
.BI "Option \*qEmulateWheelButton\*q \*q" integer \*q
Specifies which button must be held down to enable wheel emulation mode.
While this button is down, X and/or Y pointer movement will generate button
press/release events as specified for the
.B XAxisMapping
and
.B YAxisMapping
settings. If the button is 0 and
.BR EmulateWheel
is on, any motion of the device is converted into wheel events. Default: 4.
Property: "Evdev Wheel Emulation Button".
.TP 7
.BI "Option \*qEmulateWheelInertia\*q \*q" integer \*q
Specifies how far (in pixels) the pointer must move to generate button
press/release events in wheel emulation mode. Default: 10. Property: "Evdev
Wheel Emulation Inertia".
.TP 7
.BI "Option \*qEmulateWheelTimeout\*q \*q" integer \*q
Specifies the time in milliseconds the
.BR EmulateWheelButton
must be pressed before wheel emulation is started. If the
.BR EmulateWheelButton
is released before this timeout, the original button press/release event
is sent. Default: 200. Property: "Evdev Wheel Emulation Timeout".
.TP 7
.BI "Option \*qEmulateThirdButton\*q \*q" boolean \*q
Enable third button emulation. Third button emulation emits a right button
event (by default) by pressing and holding the first button. The first
button must be held down for the configured timeout and must not move more
than the configured threshold for the emulation to activate. Otherwise, the
first button event is posted as normal. Default: off. Property: "Evdev
Third Button Emulation".
.TP 7
.BI "Option \*qEmulateThirdButtonTimeout\*q \*q" integer \*q
Specifies the timeout in milliseconds between the initial button press and
the generation of the emulated button event.
Default: 1000. Property: "Evdev Third Button Emulation Timeout".
.TP 7
.BI "Option \*qEmulateThirdButtonButton\*q \*q" integer \*q
Specifies the physical button number to be emitted if third button emulation
is triggered.
Default: 3. Property: "Evdev Third Button Button".
.TP 7
.BI "Option \*qEmulateThirdButtonMoveThreshold\*q \*q" integer \*q
Specifies the maximum move fuzz in device coordinates for third button
emulation. If the device moves by more than this threshold before the third
button emulation is triggered, the emulation is cancelled and a first button
event is generated as normal.
Default: 20. Property: "Evdev Third Button Emulation Threshold".
.TP 7
.BI "Option \*qGrabDevice\*q \*q" boolean \*q
Force a grab on the event device. Doing so will ensure that no other driver
can initialise the same device and it will also stop the device from sending
events to /dev/kbd or /dev/input/mice. Events from this device will not be
sent to virtual devices (e.g. rfkill or the Macintosh mouse button emulation).
Default: disabled.
.TP 7
.BI "Option \*qInvertX\*q \*q" Bool \*q
.TP 7
.BI "Option \*qInvertY\*q \*q" Bool \*q
Invert the given axis. Default: off. Property: "Evdev Axis Inversion".
.TP 7
.BI "Option \*qIgnoreRelativeAxes\*q \*q" Bool \*q
.TP 7
.BI "Option \*qIgnoreAbsoluteAxes\*q \*q" Bool \*q
Ignore the specified type of axis. Default: unset. The X server cannot deal
with devices that have both relative and absolute axes. Evdev tries to guess
wich axes to ignore given the device type and disables absolute axes for
mice and relative axes for tablets, touchscreens and touchpad. These options
allow to forcibly disable an axis type. Mouse wheel axes are exempt and will
work even if relative axes are ignored. No property, this configuration must
be set in the configuration.
.br
If either option is set to False, the driver will not ignore the specified
axes regardless of the presence of other axes. This may trigger buggy
behavior and events from this axis are always forwarded. Users are
discouraged from setting this option.
.TP 7
.BI "Option \*qCalibration\*q \*q" "min-x max-x min-y max-y" \*q
Calibrates the X and Y axes for devices that need to scale to a different
coordinate system than reported to the X server. This feature is required
for devices that need to scale to a different coordinate system than
originally reported by the kernel (e.g. touchscreens). The scaling to the
custom coordinate system is done in-driver and the X server is unaware of
the transformation. Property: "Evdev Axis Calibration".
.TP 7
.B Option \*qMode\*q \*qRelative\*q\fP|\fP\*qAbsolute\*q
Sets the mode of the device if device has absolute axes.
The default value for touchpads is relative, for other absolute.
This option has no effect on devices without absolute axes.
.TP 7
.BI "Option \*qSwapAxes\*q \*q" Bool \*q
Swap x/y axes. Default: off. Property: "Evdev Axes Swap".
.TP 7
.BI "Option \*qXAxisMapping\*q \*q" "N1 N2" \*q
Specifies which buttons are mapped to motion in the X direction in wheel
emulation mode. Button number
.I N1
is mapped to the negative X axis motion and button number
.I N2
is mapped to the positive X axis motion. Default: no mapping. Property:
"Evdev Wheel Emulation Axes".
.TP 7
.BI "Option \*qYAxisMapping\*q \*q" "N1 N2" \*q
Specifies which buttons are mapped to motion in the Y direction in wheel
emulation mode. Button number
.I N1
is mapped to the negative Y axis motion and button number
.I N2
is mapped to the positive Y axis motion. Default: "4 5". Property:
"Evdev Wheel Emulation Axes".
.TP 7
.BI "Option \*qTypeName\*q \*q"type"\*q
Specify the X Input 1.x type (see XListInputDevices(__libmansuffix__)).
There is rarely a need to use this option, evdev will guess the device type
based on the device's capabilities. This option is provided for devices that
need quirks.
.TP 7
.BI "Option \*qVertScrollDelta\*q \*q" integer \*q
The amount of motion considered one unit of scrolling vertically.
Default: "1". Property: "Evdev Scrolling Distance".
.TP 7
.BI "Option \*qHorizScrollDelta\*q \*q" integer \*q
The amount of motion considered one unit of scrolling horizontally.
Default: "1". Property: "Evdev Scrolling Distance".
.TP 7
.BI "Option \*qDialDelta\*q \*q" integer \*q
The amount of motion considered one unit of turning the dial. Default: "1".
Property: "Evdev Scrolling Distance".
.SH SUPPORTED PROPERTIES
The following properties are provided by the
.B evdev
driver.
.TP 7
.BI "Evdev Axis Calibration"
4 32-bit values, order min-x, max-x, min-y, max-y or 0 values to disable
in-driver axis calibration.
.TP 7
.BI "Evdev Axis Inversion"
2 boolean values (8 bit, 0 or 1), order X, Y. 1 inverts the axis.
.TP 7
.BI "Evdev Axes Swap"
1 boolean value (8 bit, 0 or 1). 1 swaps x/y axes.
.TP 7
.BI "Evdev Drag Lock Buttons"
8-bit. Either 1 value or pairs of values. Value range 0-32, 0 disables a
value.
.TP 7
.BI "Evdev Middle Button Emulation"
1 boolean value (8 bit, 0 or 1).
.TP 7
.BI "Evdev Middle Button Timeout"
1 16-bit positive value.
.TP 7
.BI "Evdev Wheel Emulation"
1 boolean value (8 bit, 0 or 1).
.TP 7
.BI "Evdev Wheel Emulation Axes"
4 8-bit values, order X up, X down, Y up, Y down. 0 disables a value.
.TP 7
.BI "Evdev Wheel Emulation Button"
1 8-bit value, allowed range 0-32, 0 disables the button.
.TP 7
.BI "Evdev Wheel Emulation Inertia"
1 16-bit positive value.
.TP 7
.BI "Evdev Wheel Emulation Timeout"
1 16-bit positive value.
.TP 7
.BI "Evdev Scrolling Distance"
3 32-bit values: vertical, horizontal and dial.
enabled. Default: 50.
.SH AUTHORS
Kristian Høgsberg, Peter Hutterer
Kristian Høgsberg.
.SH "SEE ALSO"
__xservername__(__appmansuffix__), __xconfigfile__(__filemansuffix__), Xserver(__appmansuffix__), X(__miscmansuffix__)
__xservername__(__appmansuffix__), __xconfigfile__(__filemansuffix__), xorgconfig(__appmansuffix__), Xserver(__appmansuffix__), X(__miscmansuffix__),
README.mouse.

6
src/.cvsignore Normal file
View File

@@ -0,0 +1,6 @@
.deps
.libs
Makefile
Makefile.in
*.la
*.lo

View File

@@ -24,21 +24,10 @@
# -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.
AM_CFLAGS = $(XORG_CFLAGS) $(CWARNFLAGS)
AM_CPPFLAGS =-I$(top_srcdir)/include $(LIBEVDEV_CFLAGS)
@DRIVER_NAME@_drv_la_LTLIBRARIES = @DRIVER_NAME@_drv.la
@DRIVER_NAME@_drv_la_LDFLAGS = -module -avoid-version
@DRIVER_NAME@_drv_la_LIBADD = $(MTDEV_LIBS) $(UDEV_LIBS) $(LIBEVDEV_LIBS)
@DRIVER_NAME@_drv_ladir = @inputdir@
@DRIVER_NAME@_drv_la_SOURCES = @DRIVER_NAME@.c \
@DRIVER_NAME@.h \
emuMB.c \
emuThird.c \
emuWheel.c \
draglock.c \
apple.c \
axis_labels.h
emuMB.c

View File

@@ -1,313 +0,0 @@
/*
* Copyright © 2011 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 (peter.hutterer@redhat.com)
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <evdev.h>
#include <evdev-properties.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <exevents.h>
#include <xf86.h>
#include <xf86Xinput.h>
#include <X11/Xatom.h>
/* Apple-specific controls.
*
* On Apple keyboards, the multimedia function keys are overlaid with the F
* keys. F1 is also BrightnessDown, F10 is Mute, etc. The kernel provides a
* tweak to enable/disable this.
*
* /sys/module/hid_apple/parameters/fnmode
* 0 .. keyboard sends Fx keys, fn is disabled
* 1 .. keyboard sends multimedia keys, fn sends Fx keys
* 2 .. keyboard sends Fx keys, fn sends multimedia keys
*
* We only handle 1 and 2, don't care about 0. If fnmode is found to be on
* 0, we force it to 2 instead.
*/
/* In this file: fkeymode refers to the evdev-specific enums and parameters,
* fnmode refers to the fnmode parameter exposed by the kernel. fnmode is
* apple-specific */
#define FNMODE_PATH "/sys/module/hid_apple/parameters/fnmode"
/* Taken from the kernel */
#define USB_VENDOR_ID_APPLE 0x05ac
#define USB_DEVICE_ID_APPLE_ALU_MINI_ANSI 0x021d
#define USB_DEVICE_ID_APPLE_ALU_MINI_ISO 0x021e
#define USB_DEVICE_ID_APPLE_ALU_MINI_JIS 0x021f
#define USB_DEVICE_ID_APPLE_ALU_ANSI 0x0220
#define USB_DEVICE_ID_APPLE_ALU_ISO 0x0221
#define USB_DEVICE_ID_APPLE_ALU_JIS 0x0222
#define USB_DEVICE_ID_APPLE_ALU_WIRELESS_ANSI 0x022c
#define USB_DEVICE_ID_APPLE_ALU_WIRELESS_ISO 0x022d
#define USB_DEVICE_ID_APPLE_ALU_WIRELESS_JIS 0x022e
#define USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ANSI 0x0239
#define USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ISO 0x023a
#define USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_JIS 0x023b
static int EvdevAppleGetProperty (DeviceIntPtr dev, Atom property);
static int EvdevAppleSetProperty(DeviceIntPtr dev, Atom atom,
XIPropertyValuePtr val, BOOL checkonly);
static Atom prop_fkeymode;
static Bool fnmode_readonly; /* set if we can only read fnmode */
struct product_table
{
unsigned int vendor;
unsigned int product;
} apple_keyboard_table[] = {
{ USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_MINI_ANSI},
{ USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_MINI_ISO},
{ USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_MINI_JIS},
{ USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_ANSI},
{ USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_ISO},
{ USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_JIS},
{ USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_ANSI},
{ USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_ISO},
{ USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_JIS},
{ USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ANSI},
{ USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ISO},
{ USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_JIS},
{ 0, 0}
};
/**
* @return TRUE if the device matches a product in the given product table,
* FALSE otherwise
*/
static Bool product_check(const struct product_table *t, int vendor, int product)
{
while (t->vendor)
{
if (vendor == t->vendor && product == t->product)
return TRUE;
t++;
}
return FALSE;
}
/**
* @return 0 on success, -1 otherwise (check errno)
*/
static int
set_fnmode(enum fkeymode fkeymode)
{
int fd;
char mode;
int bytes_written;
if (fkeymode == FKEYMODE_UNKNOWN)
{
errno = EINVAL; /* silly you */
return -1;
}
fd = open(FNMODE_PATH, O_WRONLY);
if (fd < 0)
return -1;
mode = (fkeymode == FKEYMODE_FKEYS) ? '2' : '1';
bytes_written = write(fd, &mode, 1);
close(fd);
return (bytes_written == 1) ? 0 : -1;
}
/**
* Get the current value of fnmode. If fnmode is found to be on 0, we set it
* to 2 in the process. Yes, quite daring, I know. I live on the edge.
*
* @return The current setting of fnmode or FKEYMODE_UNKNOWN on error (check
* errno)
*/
static enum fkeymode
get_fnmode(void)
{
int fd;
char retvalue;
fd = open(FNMODE_PATH, O_RDWR);
if (fd < 0 && errno == EACCES)
{
fnmode_readonly = TRUE;
fd = open(FNMODE_PATH, O_RDONLY);
}
if (fd < 0)
goto err;
if (read(fd, &retvalue, 1) != 1)
goto err;
if (retvalue != '0' && retvalue != '1' && retvalue != '2')
{
xf86Msg(X_ERROR, "Invalid fnmode value: %c\n", retvalue);
errno = EINVAL;
goto err;
}
close(fd);
/* we don't want 0, switch to 2 */
if (retvalue == '0')
{
if (fnmode_readonly)
xf86Msg(X_WARNING, "fnmode is disabled and read-only. Fn key will"
"not toggle to multimedia keys.\n");
else
set_fnmode(FKEYMODE_FKEYS);
}
return retvalue == '1' ? FKEYMODE_MMKEYS : FKEYMODE_FKEYS;
err:
if (fd >= 0)
close(fd);
return FKEYMODE_UNKNOWN;
}
/**
* Set the property value to fkeymode. If the property doesn't exist,
* initialize it.
*/
static void set_fkeymode_property(InputInfoPtr pInfo, enum fkeymode fkeymode)
{
DeviceIntPtr dev = pInfo->dev;
BOOL init = FALSE;
char data;
switch(fkeymode)
{
case FKEYMODE_FKEYS: data = 0; break;
case FKEYMODE_MMKEYS: data = 1; break;
case FKEYMODE_UNKNOWN:
xf86IDrvMsg(pInfo, X_ERROR, "Failed to get fnmode (%s)\n", strerror(errno));
return;
}
if (!prop_fkeymode) {
init = TRUE;
prop_fkeymode = MakeAtom(EVDEV_PROP_FUNCTION_KEYS, strlen(EVDEV_PROP_FUNCTION_KEYS), TRUE);
}
/* Don't send an event if we're initializing the property */
XIChangeDeviceProperty(dev, prop_fkeymode, XA_INTEGER, 8,
PropModeReplace, 1, &data, !init);
if (init)
{
XISetDevicePropertyDeletable(dev, prop_fkeymode, FALSE);
XIRegisterPropertyHandler(dev, EvdevAppleSetProperty, EvdevAppleGetProperty, NULL);
}
}
/**
* Called when a client reads the property state.
* Update with current kernel state, it may have changed behind our back.
*/
static int
EvdevAppleGetProperty (DeviceIntPtr dev, Atom property)
{
if (property == prop_fkeymode)
{
InputInfoPtr pInfo = dev->public.devicePrivate;
EvdevPtr pEvdev = pInfo->private;
enum fkeymode fkeymode;
fkeymode = get_fnmode();
if (fkeymode != pEvdev->fkeymode) {
/* set internal copy first, so we don't write to the file in
* SetProperty handler */
pEvdev->fkeymode = fkeymode;
set_fkeymode_property(pInfo, fkeymode);
}
}
return Success;
}
static int
EvdevAppleSetProperty(DeviceIntPtr dev, Atom atom,
XIPropertyValuePtr val, BOOL checkonly)
{
InputInfoPtr pInfo = dev->public.devicePrivate;
EvdevPtr pEvdev = pInfo->private;
if (atom == prop_fkeymode)
{
CARD8 v = *(CARD8*)val->data;
if (val->format != 8 || val->type != XA_INTEGER)
return BadMatch;
if (fnmode_readonly)
return BadAccess;
if (v > 1)
return BadValue;
if (!checkonly)
{
if ((!v && pEvdev->fkeymode != FKEYMODE_FKEYS) ||
(v && pEvdev->fkeymode != FKEYMODE_MMKEYS))
{
pEvdev->fkeymode = v ? FKEYMODE_MMKEYS : FKEYMODE_FKEYS;
set_fnmode(pEvdev->fkeymode);
}
}
}
return Success;
}
void
EvdevAppleInitProperty(DeviceIntPtr dev)
{
InputInfoPtr pInfo = dev->public.devicePrivate;
EvdevPtr pEvdev = pInfo->private;
enum fkeymode fkeymode;
if (!product_check(apple_keyboard_table,
libevdev_get_id_vendor(pEvdev->dev),
libevdev_get_id_product(pEvdev->dev)))
return;
fkeymode = get_fnmode();
pEvdev->fkeymode = fkeymode;
set_fkeymode_property(pInfo, fkeymode);
}

View File

@@ -1,198 +0,0 @@
/*
* Copyright © 2004-2008 Red Hat, Inc.
*
* Permission to use, copy, modify, distribute, and sell this software
* and its documentation for any purpose is hereby granted without
* fee, provided that the above copyright notice appear in all copies
* and that both that copyright notice and this permission notice
* appear in supporting documentation, and that the name of Red Hat
* not be used in advertising or publicity pertaining to distribution
* of the software without specific, written prior permission. Red
* Hat makes no representations about the suitability of this software
* for any purpose. It is provided "as is" without express or implied
* warranty.
*
* THE AUTHORS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN
* NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
* OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
* NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <xserver-properties.h>
#ifndef AXIS_LABELS
#define AXIS_LABELS
/* Aligned with linux/input.h.
Note that there are holes in the ABS_ range, these are simply replaced with
MISC here */
static const char* abs_labels[] = {
AXIS_LABEL_PROP_ABS_X, /* 0x00 */
AXIS_LABEL_PROP_ABS_Y, /* 0x01 */
AXIS_LABEL_PROP_ABS_Z, /* 0x02 */
AXIS_LABEL_PROP_ABS_RX, /* 0x03 */
AXIS_LABEL_PROP_ABS_RY, /* 0x04 */
AXIS_LABEL_PROP_ABS_RZ, /* 0x05 */
AXIS_LABEL_PROP_ABS_THROTTLE, /* 0x06 */
AXIS_LABEL_PROP_ABS_RUDDER, /* 0x07 */
AXIS_LABEL_PROP_ABS_WHEEL, /* 0x08 */
AXIS_LABEL_PROP_ABS_GAS, /* 0x09 */
AXIS_LABEL_PROP_ABS_BRAKE, /* 0x0a */
AXIS_LABEL_PROP_ABS_MISC, /* undefined */
AXIS_LABEL_PROP_ABS_MISC, /* undefined */
AXIS_LABEL_PROP_ABS_MISC, /* undefined */
AXIS_LABEL_PROP_ABS_MISC, /* undefined */
AXIS_LABEL_PROP_ABS_MISC, /* undefined */
AXIS_LABEL_PROP_ABS_HAT0X, /* 0x10 */
AXIS_LABEL_PROP_ABS_HAT0Y, /* 0x11 */
AXIS_LABEL_PROP_ABS_HAT1X, /* 0x12 */
AXIS_LABEL_PROP_ABS_HAT1Y, /* 0x13 */
AXIS_LABEL_PROP_ABS_HAT2X, /* 0x14 */
AXIS_LABEL_PROP_ABS_HAT2Y, /* 0x15 */
AXIS_LABEL_PROP_ABS_HAT3X, /* 0x16 */
AXIS_LABEL_PROP_ABS_HAT3Y, /* 0x17 */
AXIS_LABEL_PROP_ABS_PRESSURE, /* 0x18 */
AXIS_LABEL_PROP_ABS_DISTANCE, /* 0x19 */
AXIS_LABEL_PROP_ABS_TILT_X, /* 0x1a */
AXIS_LABEL_PROP_ABS_TILT_Y, /* 0x1b */
AXIS_LABEL_PROP_ABS_TOOL_WIDTH, /* 0x1c */
AXIS_LABEL_PROP_ABS_MISC, /* undefined */
AXIS_LABEL_PROP_ABS_MISC, /* undefined */
AXIS_LABEL_PROP_ABS_MISC, /* undefined */
AXIS_LABEL_PROP_ABS_VOLUME /* 0x20 */
AXIS_LABEL_PROP_ABS_MISC, /* undefined */
AXIS_LABEL_PROP_ABS_MISC, /* undefined */
AXIS_LABEL_PROP_ABS_MISC, /* undefined */
AXIS_LABEL_PROP_ABS_MISC, /* undefined */
AXIS_LABEL_PROP_ABS_MISC, /* undefined */
AXIS_LABEL_PROP_ABS_MISC, /* undefined */
AXIS_LABEL_PROP_ABS_MISC, /* undefined */
AXIS_LABEL_PROP_ABS_MISC, /* undefined */
AXIS_LABEL_PROP_ABS_MISC, /* undefined */
AXIS_LABEL_PROP_ABS_MISC, /* undefined */
AXIS_LABEL_PROP_ABS_MISC, /* undefined */
AXIS_LABEL_PROP_ABS_MISC, /* undefined */
AXIS_LABEL_PROP_ABS_MISC, /* undefined */
AXIS_LABEL_PROP_ABS_MISC, /* undefined */
AXIS_LABEL_PROP_ABS_MISC, /* undefined */
AXIS_LABEL_PROP_ABS_MISC, /* undefined */
AXIS_LABEL_PROP_ABS_MT_TOUCH_MAJOR, /* 0x30 */
AXIS_LABEL_PROP_ABS_MT_TOUCH_MINOR, /* 0x31 */
AXIS_LABEL_PROP_ABS_MT_WIDTH_MAJOR, /* 0x32 */
AXIS_LABEL_PROP_ABS_MT_WIDTH_MINOR, /* 0x33 */
AXIS_LABEL_PROP_ABS_MT_ORIENTATION, /* 0x34 */
AXIS_LABEL_PROP_ABS_MT_POSITION_X, /* 0x35 */
AXIS_LABEL_PROP_ABS_MT_POSITION_Y, /* 0x36 */
AXIS_LABEL_PROP_ABS_MT_TOOL_TYPE, /* 0x37 */
AXIS_LABEL_PROP_ABS_MT_BLOB_ID, /* 0x38 */
AXIS_LABEL_PROP_ABS_MT_TRACKING_ID, /* 0x39 */
AXIS_LABEL_PROP_ABS_MT_PRESSURE, /* 0x3a */
#ifdef AXIS_LABEL_PROP_ABS_MT_DISTANCE
AXIS_LABEL_PROP_ABS_MT_DISTANCE, /* 0x3b */
AXIS_LABEL_PROP_ABS_MT_TOOL_X, /* 0x3c */
AXIS_LABEL_PROP_ABS_MT_TOOL_Y, /* 0x3d */
#endif /* AXIS_LABEL_PROP_ABS_MT_DISTANCE */
};
static const char* rel_labels[] = {
AXIS_LABEL_PROP_REL_X,
AXIS_LABEL_PROP_REL_Y,
AXIS_LABEL_PROP_REL_Z,
AXIS_LABEL_PROP_REL_RX,
AXIS_LABEL_PROP_REL_RY,
AXIS_LABEL_PROP_REL_RZ,
AXIS_LABEL_PROP_REL_HWHEEL,
AXIS_LABEL_PROP_REL_DIAL,
AXIS_LABEL_PROP_REL_WHEEL,
AXIS_LABEL_PROP_REL_MISC
};
static const char* btn_labels[][16] = {
{ /* BTN_MISC group offset 0x100*/
BTN_LABEL_PROP_BTN_0, /* 0x00 */
BTN_LABEL_PROP_BTN_1, /* 0x01 */
BTN_LABEL_PROP_BTN_2, /* 0x02 */
BTN_LABEL_PROP_BTN_3, /* 0x03 */
BTN_LABEL_PROP_BTN_4, /* 0x04 */
BTN_LABEL_PROP_BTN_5, /* 0x05 */
BTN_LABEL_PROP_BTN_6, /* 0x06 */
BTN_LABEL_PROP_BTN_7, /* 0x07 */
BTN_LABEL_PROP_BTN_8, /* 0x08 */
BTN_LABEL_PROP_BTN_9 /* 0x09 */
},
{ /* BTN_MOUSE group offset 0x110 */
BTN_LABEL_PROP_BTN_LEFT, /* 0x00 */
BTN_LABEL_PROP_BTN_RIGHT, /* 0x01 */
BTN_LABEL_PROP_BTN_MIDDLE, /* 0x02 */
BTN_LABEL_PROP_BTN_SIDE, /* 0x03 */
BTN_LABEL_PROP_BTN_EXTRA, /* 0x04 */
BTN_LABEL_PROP_BTN_FORWARD, /* 0x05 */
BTN_LABEL_PROP_BTN_BACK, /* 0x06 */
BTN_LABEL_PROP_BTN_TASK /* 0x07 */
},
{ /* BTN_JOYSTICK group offset 0x120 */
BTN_LABEL_PROP_BTN_TRIGGER, /* 0x00 */
BTN_LABEL_PROP_BTN_THUMB, /* 0x01 */
BTN_LABEL_PROP_BTN_THUMB2, /* 0x02 */
BTN_LABEL_PROP_BTN_TOP, /* 0x03 */
BTN_LABEL_PROP_BTN_TOP2, /* 0x04 */
BTN_LABEL_PROP_BTN_PINKIE, /* 0x05 */
BTN_LABEL_PROP_BTN_BASE, /* 0x06 */
BTN_LABEL_PROP_BTN_BASE2, /* 0x07 */
BTN_LABEL_PROP_BTN_BASE3, /* 0x08 */
BTN_LABEL_PROP_BTN_BASE4, /* 0x09 */
BTN_LABEL_PROP_BTN_BASE5, /* 0x0a */
BTN_LABEL_PROP_BTN_BASE6, /* 0x0b */
NULL,
NULL,
NULL,
BTN_LABEL_PROP_BTN_DEAD /* 0x0f */
},
{ /* BTN_GAMEPAD group offset 0x130 */
BTN_LABEL_PROP_BTN_A, /* 0x00 */
BTN_LABEL_PROP_BTN_B, /* 0x01 */
BTN_LABEL_PROP_BTN_C, /* 0x02 */
BTN_LABEL_PROP_BTN_X, /* 0x03 */
BTN_LABEL_PROP_BTN_Y, /* 0x04 */
BTN_LABEL_PROP_BTN_Z, /* 0x05 */
BTN_LABEL_PROP_BTN_TL, /* 0x06 */
BTN_LABEL_PROP_BTN_TR, /* 0x07 */
BTN_LABEL_PROP_BTN_TL2, /* 0x08 */
BTN_LABEL_PROP_BTN_TR2, /* 0x09 */
BTN_LABEL_PROP_BTN_SELECT, /* 0x0a */
BTN_LABEL_PROP_BTN_START, /* 0x0b */
BTN_LABEL_PROP_BTN_MODE, /* 0x0c */
BTN_LABEL_PROP_BTN_THUMBL, /* 0x0d */
BTN_LABEL_PROP_BTN_THUMBR /* 0x0e */
},
{ /* BTN_DIGI group offset 0x140 */
BTN_LABEL_PROP_BTN_TOOL_PEN, /* 0x00 */
BTN_LABEL_PROP_BTN_TOOL_RUBBER, /* 0x01 */
BTN_LABEL_PROP_BTN_TOOL_BRUSH, /* 0x02 */
BTN_LABEL_PROP_BTN_TOOL_PENCIL, /* 0x03 */
BTN_LABEL_PROP_BTN_TOOL_AIRBRUSH, /* 0x04 */
BTN_LABEL_PROP_BTN_TOOL_FINGER, /* 0x05 */
BTN_LABEL_PROP_BTN_TOOL_MOUSE, /* 0x06 */
BTN_LABEL_PROP_BTN_TOOL_LENS, /* 0x07 */
NULL,
NULL,
BTN_LABEL_PROP_BTN_TOUCH, /* 0x0a */
BTN_LABEL_PROP_BTN_STYLUS, /* 0x0b */
BTN_LABEL_PROP_BTN_STYLUS2, /* 0x0c */
BTN_LABEL_PROP_BTN_TOOL_DOUBLETAP, /* 0x0d */
BTN_LABEL_PROP_BTN_TOOL_TRIPLETAP /* 0x0e */
},
{ /* BTN_WHEEL group offset 0x150 */
BTN_LABEL_PROP_BTN_GEAR_DOWN, /* 0x00 */
BTN_LABEL_PROP_BTN_GEAR_UP /* 0x01 */
}
};
#endif

View File

@@ -1,318 +0,0 @@
/*
* Copyright 1990,91 by Thomas Roell, Dinkelscherben, Germany.
* Copyright 1993 by David Dawes <dawes@xfree86.org>
* Copyright 2002 by SuSE Linux AG, Author: Egbert Eich
* Copyright 1994-2002 by The XFree86 Project, Inc.
* Copyright 2002 by Paul Elliott
* (Ported from xf86-input-mouse, above copyrights taken from there)
* Copyright © 2008 University of South Australia
* Copyright 2008 by Chris Salch
* Copyright 2008 Red Hat, Inc.
*
* Permission to use, copy, modify, distribute, and sell this software
* and its documentation for any purpose is hereby granted without
* fee, provided that the above copyright notice appear in all copies
* and that both that copyright notice and this permission notice
* appear in supporting documentation, and that the name of the authors
* not be used in advertising or publicity pertaining to distribution of the
* software without specific, written prior permission. The authors make 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.
*
*/
/* Draglock code */
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "evdev.h"
#include <xf86.h>
#include <xf86Xinput.h>
#include <X11/Xatom.h>
#include <exevents.h>
#include <evdev-properties.h>
static Atom prop_dlock = 0; /* Drag lock buttons. */
void EvdevDragLockLockButton(InputInfoPtr pInfo, unsigned int button);
/* Setup and configuration code */
void
EvdevDragLockPreInit(InputInfoPtr pInfo)
{
EvdevPtr pEvdev = (EvdevPtr)pInfo->private;
char *option_string = NULL;
int meta_button = 0;
int lock_button = 0;
char *next_num = NULL;
char *end_str = NULL;
BOOL pairs = FALSE;
option_string = xf86CheckStrOption(pInfo->options, "DragLockButtons",NULL);
if (!option_string)
return;
next_num = option_string;
/* Loop until we hit the end of our option string */
while (next_num != NULL) {
lock_button = 0;
meta_button = strtol(next_num, &end_str, 10);
/* check to see if we found anything */
if (next_num != end_str) {
/* setup for the next number */
next_num = end_str;
} else {
/* we have nothing more to parse, drop out of the loop */
next_num = NULL;
}
/* Check for a button to lock if we have a meta button */
if (meta_button != 0 && next_num != NULL ) {
lock_button = strtol(next_num, &end_str, 10);
/* check to see if we found anything */
if (next_num != end_str) {
/* setup for the next number */
next_num = end_str;
} else {
/* we have nothing more to parse, drop out of the loop */
next_num = NULL;
}
}
/* Ok, let the user know what we found on this look */
if (meta_button != 0) {
if (lock_button == 0) {
if (!pairs) {
/* We only have a meta button */
pEvdev->dragLock.meta = meta_button;
xf86IDrvMsg(pInfo, X_CONFIG, "DragLockButtons : "
"%i as meta\n", meta_button);
} else {
xf86IDrvMsg(pInfo, X_ERROR, "DragLockButtons : "
"Incomplete pair specifying button pairs %s\n",
option_string);
}
} else {
/* Do bounds checking to make sure we don't crash */
if ((meta_button <= EVDEV_MAXBUTTONS) && (meta_button >= 0 ) &&
(lock_button <= EVDEV_MAXBUTTONS) && (lock_button >= 0)) {
xf86IDrvMsg(pInfo, X_CONFIG,
"DragLockButtons : %i -> %i\n",
meta_button, lock_button);
pEvdev->dragLock.lock_pair[meta_button - 1] = lock_button;
pairs=TRUE;
} else {
/* Let the user know something was wrong
with this pair of buttons */
xf86IDrvMsg(pInfo, X_CONFIG,"DragLockButtons : "
"Invalid button pair %i -> %i\n",
meta_button, lock_button);
}
}
} else {
xf86IDrvMsg(pInfo, X_ERROR, "Found DragLockButtons "
"with invalid lock button string : '%s'\n",
option_string);
/* This should be the case anyhow, just make sure */
next_num = NULL;
}
/* Check for end of string, to avoid annoying error */
if (next_num != NULL && *next_num == '\0')
next_num = NULL;
}
free(option_string);
}
/* Updates DragLock button state and fires button event messges */
void
EvdevDragLockLockButton(InputInfoPtr pInfo, unsigned int button)
{
EvdevPtr pEvdev = (EvdevPtr)pInfo->private;
BOOL state = 0;
/* update button state */
state = pEvdev->dragLock.lock_state[button - 1] ? FALSE : TRUE;
pEvdev->dragLock.lock_state[button - 1] = state;
EvdevQueueButtonEvent(pInfo, button, state);
}
/* Filter button presses looking for either a meta button or the
* control of a button pair.
*
* @param button button number (1 for left, 3 for right)
* @param value TRUE if button press, FALSE if release
*
* @return TRUE if the event was swallowed here, FALSE otherwise.
*/
BOOL
EvdevDragLockFilterEvent(InputInfoPtr pInfo, unsigned int button, int value)
{
EvdevPtr pEvdev = (EvdevPtr)pInfo->private;
if (button == 0)
return FALSE;
/* Do we have a single meta key or
several button pairings? */
if (pEvdev->dragLock.meta != 0) {
if (pEvdev->dragLock.meta == button) {
/* setup up for button lock */
if (value)
pEvdev->dragLock.meta_state = TRUE;
return TRUE;
} else if (pEvdev->dragLock.meta_state) { /* waiting to lock */
pEvdev->dragLock.meta_state = FALSE;
EvdevDragLockLockButton(pInfo, button);
return TRUE;
}
} else if (pEvdev->dragLock.lock_pair[button - 1] && value) {
/* A meta button in a meta/lock pair was pressed */
EvdevDragLockLockButton(pInfo, pEvdev->dragLock.lock_pair[button - 1]);
return TRUE;
}
/* Eat events for buttons that are locked */
if (pEvdev->dragLock.lock_state[button - 1])
return TRUE;
return FALSE;
}
/**
* Set the drag lock property.
* If only one value is supplied, then this is used as the meta button.
* If more than one value is supplied, then each value is the drag lock button
* for the pair. 0 disables a pair.
* i.e. to set bt 3 to draglock button 1, supply 0,0,1
*/
static int
EvdevDragLockSetProperty(DeviceIntPtr dev, Atom atom, XIPropertyValuePtr val,
BOOL checkonly)
{
InputInfoPtr pInfo = dev->public.devicePrivate;
EvdevPtr pEvdev = pInfo->private;
if (atom == prop_dlock)
{
int i;
if (val->format != 8 || val->type != XA_INTEGER)
return BadMatch;
/* Don't allow changes while a lock is active */
if (pEvdev->dragLock.meta)
{
if (pEvdev->dragLock.meta_state)
return BadAccess;
} else
{
for (i = 0; i < EVDEV_MAXBUTTONS; i++)
if (pEvdev->dragLock.lock_state[i])
return BadValue;
}
if (val->size == 0)
return BadMatch;
else if (val->size == 1)
{
int meta = *((CARD8*)val->data);
if (meta > EVDEV_MAXBUTTONS)
return BadValue;
if (!checkonly)
{
pEvdev->dragLock.meta = meta;
memset(pEvdev->dragLock.lock_pair, 0, sizeof(pEvdev->dragLock.lock_pair));
}
} else if ((val->size % 2) == 0)
{
CARD8* vals = (CARD8*)val->data;
for (i = 0; i < val->size && i < EVDEV_MAXBUTTONS; i++)
if (vals[i] > EVDEV_MAXBUTTONS)
return BadValue;
if (!checkonly)
{
pEvdev->dragLock.meta = 0;
memset(pEvdev->dragLock.lock_pair, 0, sizeof(pEvdev->dragLock.lock_pair));
for (i = 0; i < val->size && i < EVDEV_MAXBUTTONS; i += 2)
pEvdev->dragLock.lock_pair[vals[i] - 1] = vals[i + 1];
}
} else
return BadMatch;
}
return Success;
}
/**
* Initialise property for drag lock buttons setting.
*/
void
EvdevDragLockInitProperty(DeviceIntPtr dev)
{
InputInfoPtr pInfo = dev->public.devicePrivate;
EvdevPtr pEvdev = pInfo->private;
if (!dev->button) /* don't init prop for keyboards */
return;
prop_dlock = MakeAtom(EVDEV_PROP_DRAGLOCK, strlen(EVDEV_PROP_DRAGLOCK), TRUE);
if (pEvdev->dragLock.meta)
{
XIChangeDeviceProperty(dev, prop_dlock, XA_INTEGER, 8,
PropModeReplace, 1, &pEvdev->dragLock.meta,
FALSE);
} else {
int highest = 0;
int i;
CARD8 pair[EVDEV_MAXBUTTONS] = {0};
for (i = 0; i < EVDEV_MAXBUTTONS; i++)
{
if (pEvdev->dragLock.lock_pair[i])
highest = i;
pair[i] = pEvdev->dragLock.lock_pair[i];
}
XIChangeDeviceProperty(dev, prop_dlock, XA_INTEGER, 8, PropModeReplace,
highest + 1, pair, FALSE);
}
XISetDevicePropertyDeletable(dev, prop_dlock, FALSE);
XIRegisterPropertyHandler(dev, EvdevDragLockSetProperty, NULL, NULL);
}

View File

@@ -11,11 +11,11 @@
* and its documentation for any purpose is hereby granted without
* fee, provided that the above copyright notice appear in all copies
* and that both that copyright notice and this permission notice
* appear in supporting documentation, and that the name of the authors
* not be used in advertising or publicity pertaining to distribution of the
* software without specific, written prior permission. The authors make no
* representations about the suitability of this software for any
* purpose. It is provided "as is" without express or implied
* 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,
@@ -34,17 +34,16 @@
#include "config.h"
#endif
#include <xf86.h>
#include "evdev.h"
#include <X11/Xatom.h>
#include <xf86.h>
#include <xf86Xinput.h>
#include <exevents.h>
enum {
MBEMU_DISABLED = 0,
MBEMU_ENABLED,
MBEMU_AUTO
};
#include <evdev-properties.h>
static Atom prop_mbemu = 0; /* Middle button emulation on/off property */
static Atom prop_mbtimeout = 0; /* Middle button timeout property */
/*
* Lets create a simple finite-state machine for 3 button emulation:
*
@@ -191,13 +190,12 @@ EvdevMBEmuTimer(InputInfoPtr pInfo)
pEvdev->emulateMB.pending = FALSE;
if ((id = stateTab[pEvdev->emulateMB.state][4][0]) != 0) {
EvdevPostButtonEvent(pInfo, abs(id),
(id >= 0) ? BUTTON_PRESS : BUTTON_RELEASE);
xf86PostButtonEvent(pInfo->dev, 0, abs(id), (id >= 0), 0, 0);
pEvdev->emulateMB.state =
stateTab[pEvdev->emulateMB.state][4][2];
} else {
xf86IDrvMsg(pInfo, X_ERROR, "Got unexpected buttonTimer in state %d\n",
pEvdev->emulateMB.state);
ErrorF("Got unexpected buttonTimer in state %d\n",
pEvdev->emulateMB.state);
}
xf86UnblockSIGIO (sigstate);
@@ -208,14 +206,14 @@ EvdevMBEmuTimer(InputInfoPtr pInfo)
/**
* Emulate a middle button on button press.
*
* @param code button number (1 for left, 3 for right)
* @param code Evdev event code (BTN_LEFT or BTN_RIGHT)
* @param press TRUE if press, FALSE if release.
*
* @return TRUE if event was swallowed by middle mouse button emulation, FALSE
* otherwise.
*/
BOOL
EvdevMBEmuFilterEvent(InputInfoPtr pInfo, int button, BOOL press)
EvdevMBEmuFilterEvent(InputInfoPtr pInfo, int code, BOOL press)
{
EvdevPtr pEvdev = pInfo->private;
int id;
@@ -226,23 +224,23 @@ EvdevMBEmuFilterEvent(InputInfoPtr pInfo, int button, BOOL press)
return ret;
/* don't care about other buttons */
if (button != 1 && button != 3)
if (code != BTN_LEFT && code != BTN_RIGHT)
return ret;
btstate = &pEvdev->emulateMB.buttonstate;
if (press)
*btstate |= (button == 1) ? 0x1 : 0x2;
*btstate |= (code == BTN_LEFT) ? 0x1 : 0x2;
else
*btstate &= (button == 1) ? ~0x1 : ~0x2;
*btstate &= (code == BTN_LEFT) ? ~0x1 : ~0x2;
if ((id = stateTab[pEvdev->emulateMB.state][*btstate][0]) != 0)
{
EvdevQueueButtonEvent(pInfo, abs(id), (id >= 0));
xf86PostButtonEvent(pInfo->dev, 0, abs(id), (id >= 0), 0, 0);
ret = TRUE;
}
if ((id = stateTab[pEvdev->emulateMB.state][*btstate][1]) != 0)
{
EvdevQueueButtonEvent(pInfo, abs(id), (id >= 0));
xf86PostButtonEvent(pInfo->dev, 0, abs(id), (id >= 0), 0, 0);
ret = TRUE;
}
@@ -298,94 +296,39 @@ void
EvdevMBEmuPreInit(InputInfoPtr pInfo)
{
EvdevPtr pEvdev = (EvdevPtr)pInfo->private;
pEvdev->emulateMB.enabled = MBEMU_AUTO;
if (xf86FindOption(pInfo->options, "Emulate3Buttons"))
{
pEvdev->emulateMB.enabled = xf86SetBoolOption(pInfo->options,
"Emulate3Buttons",
MBEMU_ENABLED);
xf86Msg(X_INFO, "%s: Forcing middle mouse button emulation.\n",
pInfo->name);
}
pEvdev->emulateMB.enabled = xf86SetBoolOption(pInfo->options,
"Emulate3Buttons",
FALSE);
pEvdev->emulateMB.timeout = xf86SetIntOption(pInfo->options,
"Emulate3Timeout", 50);
}
void
EvdevMBEmuOn(InputInfoPtr pInfo)
{
if (!pInfo->dev->button) /* don't init for keyboards */
return;
RegisterBlockAndWakeupHandlers (EvdevMBEmuBlockHandler,
EvdevMBEmuWakeupHandler,
(pointer)pInfo);
}
void
EvdevMBEmuFinalize(InputInfoPtr pInfo)
{
if (!pInfo->dev->button) /* don't cleanup for keyboards */
return;
RemoveBlockAndWakeupHandlers (EvdevMBEmuBlockHandler,
EvdevMBEmuWakeupHandler,
(pointer)pInfo);
}
static int
EvdevMBEmuSetProperty(DeviceIntPtr dev, Atom atom, XIPropertyValuePtr val,
BOOL checkonly)
{
InputInfoPtr pInfo = dev->public.devicePrivate;
EvdevPtr pEvdev = pInfo->private;
if (atom == prop_mbemu)
{
if (val->format != 8 || val->size != 1 || val->type != XA_INTEGER)
return BadMatch;
if (!checkonly)
pEvdev->emulateMB.enabled = *((BOOL*)val->data);
} else if (atom == prop_mbtimeout)
{
if (val->format != 32 || val->size != 1 || val->type != XA_INTEGER)
return BadMatch;
if (!checkonly)
pEvdev->emulateMB.timeout = *((CARD32*)val->data);
}
return Success;
}
/**
* Initialise property for MB emulation on/off.
*/
/* Enable/disable middle mouse button emulation. */
void
EvdevMBEmuInitProperty(DeviceIntPtr dev)
EvdevMBEmuEnable(InputInfoPtr pInfo, BOOL enable)
{
InputInfoPtr pInfo = dev->public.devicePrivate;
EvdevPtr pEvdev = pInfo->private;
int rc;
if (!dev->button) /* don't init prop for keyboards */
return;
prop_mbemu = MakeAtom(EVDEV_PROP_MIDBUTTON, strlen(EVDEV_PROP_MIDBUTTON), TRUE);
rc = XIChangeDeviceProperty(dev, prop_mbemu, XA_INTEGER, 8,
PropModeReplace, 1,
&pEvdev->emulateMB.enabled,
FALSE);
if (rc != Success)
return;
XISetDevicePropertyDeletable(dev, prop_mbemu, FALSE);
prop_mbtimeout = MakeAtom(EVDEV_PROP_MIDBUTTON_TIMEOUT,
strlen(EVDEV_PROP_MIDBUTTON_TIMEOUT),
TRUE);
rc = XIChangeDeviceProperty(dev, prop_mbtimeout, XA_INTEGER, 32, PropModeReplace, 1,
&pEvdev->emulateMB.timeout, FALSE);
if (rc != Success)
return;
XISetDevicePropertyDeletable(dev, prop_mbtimeout, FALSE);
XIRegisterPropertyHandler(dev, EvdevMBEmuSetProperty, NULL, NULL);
EvdevPtr pEvdev = (EvdevPtr)pInfo->private;
if (pEvdev->emulateMB.enabled == MBEMU_AUTO)
pEvdev->emulateMB.enabled = enable;
}

View File

@@ -1,416 +0,0 @@
/*
* Copyright © 2011 Red Hat, Inc.
*
* Permission to use, copy, modify, distribute, and sell this software
* and its documentation for any purpose is hereby granted without
* fee, provided that the above copyright notice appear in all copies
* and that both that copyright notice and this permission notice
* appear in supporting documentation, and that the name of the authors
* not be used in advertising or publicity pertaining to distribution of the
* software without specific, written prior permission. The authors make 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.
*
*/
/* Right mouse button emulation code.
* Emulates a right button event if the first button is held down for a
* timeout. If the device moves more than a certain amount before the
* timeout is over, the emulation is cancelled and a normal button event is
* generated.
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "evdev.h"
#include <X11/Xatom.h>
#include <xf86.h>
#include <xf86Xinput.h>
#include <exevents.h>
#include <evdev-properties.h>
/* Threshold (in device coordinates) for devices to cancel emulation */
#define DEFAULT_MOVE_THRESHOLD 20
static Atom prop_3bemu; /* Right button emulation on/off property */
static Atom prop_3btimeout; /* Right button timeout property */
static Atom prop_3bbutton; /* Right button target physical button */
static Atom prop_3bthreshold; /* Right button move cancellation threshold */
/* State machine for 3rd button emulation */
enum EmulationState {
EM3B_OFF, /* no event */
EM3B_PENDING, /* timer pending */
EM3B_EMULATING /* in emulation */
};
static void
Evdev3BEmuPostButtonEvent(InputInfoPtr pInfo, int button, enum ButtonAction act)
{
EvdevPtr pEvdev = pInfo->private;
struct emulate3B *emu3B = &pEvdev->emulate3B;
int absolute = Relative;
/* if we cancel, emit the button down event at our start position,
* not at the current position. Only for absolute devices though. For
* relative events, this may be a bit iffy since pointer accel may shoot
* us back more than we moved and confuse the user.
*/
if (emu3B->flags & EVDEV_ABSOLUTE_EVENTS)
absolute = Absolute;
xf86PostButtonEventP(pInfo->dev, absolute, button,
(act == BUTTON_PRESS) ? 1 : 0, 0,
(absolute ? 2 : 0), emu3B->startpos);
}
/**
* Timer function. Post a button down event to the server.
*
* @param arg The InputInfoPtr for this device.
*/
CARD32
Evdev3BEmuTimer(OsTimerPtr timer, CARD32 time, pointer arg)
{
InputInfoPtr pInfo = (InputInfoPtr)arg;
EvdevPtr pEvdev = pInfo->private;
struct emulate3B *emu3B = &pEvdev->emulate3B;
int sigstate = 0;
sigstate = xf86BlockSIGIO ();
emu3B->state = EM3B_EMULATING;
Evdev3BEmuPostButtonEvent(pInfo, emu3B->button, BUTTON_PRESS);
xf86UnblockSIGIO (sigstate);
return 0;
}
/**
* Cancel all emulation, reset the timer and reset deltas.
*/
static void
Evdev3BCancel(InputInfoPtr pInfo)
{
EvdevPtr pEvdev = pInfo->private;
struct emulate3B *emu3B = &pEvdev->emulate3B;
if (emu3B->state != EM3B_OFF)
{
TimerCancel(emu3B->timer);
emu3B->state = EM3B_OFF;
memset(emu3B->delta, 0, sizeof(emu3B->delta));
}
emu3B->flags = 0;
}
/**
* Emulate a third button on button press. Note that emulation only triggers
* on button 1.
*
* Return TRUE if event was swallowed by middle mouse button emulation,
* FALSE otherwise.
*/
BOOL
Evdev3BEmuFilterEvent(InputInfoPtr pInfo, int button, BOOL press)
{
EvdevPtr pEvdev = pInfo->private;
struct emulate3B *emu3B = &pEvdev->emulate3B;
int ret = FALSE;
if (!emu3B->enabled)
goto out;
if (press)
emu3B->buttonstate |= button;
else
emu3B->buttonstate &= ~button;
/* Any other button pressed? Cancel timer */
if (button != 1)
{
switch (emu3B->state)
{
case EM3B_PENDING:
Evdev3BEmuPostButtonEvent(pInfo, 1, BUTTON_PRESS);
Evdev3BCancel(pInfo);
break;
case EM3B_EMULATING:
/* We're emulating and now the user pressed a different
* button. Just release the emulating one, tell the user to
* not do that and get on with life */
Evdev3BEmuPostButtonEvent(pInfo, emu3B->button, BUTTON_RELEASE);
Evdev3BCancel(pInfo);
break;
default:
break;
}
goto out;
}
/* Don't emulate if any other button is down */
if ((emu3B->buttonstate & ~0x1) != 0)
goto out;
/* Release event → cancel, send press and release now. */
if (!press)
{
switch(emu3B->state)
{
case EM3B_PENDING:
Evdev3BEmuPostButtonEvent(pInfo, 1, BUTTON_PRESS);
Evdev3BCancel(pInfo);
break;
case EM3B_EMULATING:
Evdev3BEmuPostButtonEvent(pInfo, emu3B->button, BUTTON_RELEASE);
Evdev3BCancel(pInfo);
ret = TRUE;
break;
default:
break;
}
goto out;
}
if (press && emu3B->state == EM3B_OFF)
{
emu3B->state = EM3B_PENDING;
emu3B->timer = TimerSet(emu3B->timer, 0, emu3B->timeout,
Evdev3BEmuTimer, pInfo);
ret = TRUE;
goto out;
}
out:
return ret;
}
/**
* Handle absolute x/y motion. If the motion is above the threshold, cancel
* emulation.
*/
void
Evdev3BEmuProcessAbsMotion(InputInfoPtr pInfo, ValuatorMask *vals)
{
EvdevPtr pEvdev = pInfo->private;
struct emulate3B *emu3B = &pEvdev->emulate3B;
int cancel = FALSE;
int axis = 0;
if (emu3B->state != EM3B_PENDING)
{
if (valuator_mask_isset(vals, 0))
emu3B->startpos[0] = valuator_mask_get(vals, 0);
if (valuator_mask_isset(vals, 1))
emu3B->startpos[1] = valuator_mask_get(vals, 1);
return;
}
if ((emu3B->flags & EVDEV_ABSOLUTE_EVENTS) == 0)
emu3B->flags |= EVDEV_ABSOLUTE_EVENTS;
while (axis <= 1 && !cancel)
{
if (valuator_mask_isset(vals, axis))
{
int delta = valuator_mask_get(vals, axis) - emu3B->startpos[axis];
if (abs(delta) > emu3B->threshold)
cancel = TRUE;
}
axis++;
}
if (cancel)
{
Evdev3BEmuPostButtonEvent(pInfo, 1, BUTTON_PRESS);
Evdev3BCancel(pInfo);
}
}
/**
* Handle relative x/y motion. If the motion is above the threshold, cancel
* emulation.
*/
void
Evdev3BEmuProcessRelMotion(InputInfoPtr pInfo, int dx, int dy)
{
EvdevPtr pEvdev = pInfo->private;
struct emulate3B *emu3B = &pEvdev->emulate3B;
if (emu3B->state != EM3B_PENDING)
return;
emu3B->delta[0] += dx;
emu3B->delta[1] += dy;
emu3B->flags |= EVDEV_RELATIVE_EVENTS;
if (abs(emu3B->delta[0]) > emu3B->threshold ||
abs(emu3B->delta[1]) > emu3B->threshold)
{
Evdev3BEmuPostButtonEvent(pInfo, 1, BUTTON_PRESS);
Evdev3BCancel(pInfo);
}
}
void
Evdev3BEmuPreInit(InputInfoPtr pInfo)
{
EvdevPtr pEvdev = pInfo->private;
struct emulate3B *emu3B = &pEvdev->emulate3B;
emu3B->enabled = xf86SetBoolOption(pInfo->options,
"EmulateThirdButton",
FALSE);
emu3B->timeout = xf86SetIntOption(pInfo->options,
"EmulateThirdButtonTimeout",
1000);
emu3B->button = xf86SetIntOption(pInfo->options,
"EmulateThirdButtonButton",
3);
/* FIXME: this should be auto-configured based on axis ranges */
emu3B->threshold = xf86SetIntOption(pInfo->options,
"EmulateThirdButtonMoveThreshold",
DEFAULT_MOVE_THRESHOLD);
/* allocate now so we don't allocate in the signal handler */
emu3B->timer = TimerSet(NULL, 0, 0, NULL, NULL);
}
void
Evdev3BEmuOn(InputInfoPtr pInfo)
{
/* This function just exists for symmetry in evdev.c */
}
void
Evdev3BEmuFinalize(InputInfoPtr pInfo)
{
EvdevPtr pEvdev = pInfo->private;
struct emulate3B *emu3B = &pEvdev->emulate3B;
TimerFree(emu3B->timer);
emu3B->timer = NULL;
}
static int
Evdev3BEmuSetProperty(DeviceIntPtr dev, Atom atom, XIPropertyValuePtr val,
BOOL checkonly)
{
InputInfoPtr pInfo = dev->public.devicePrivate;
EvdevPtr pEvdev = pInfo->private;
struct emulate3B *emu3B = &pEvdev->emulate3B;
if (atom == prop_3bemu)
{
if (val->format != 8 || val->size != 1 || val->type != XA_INTEGER)
return BadMatch;
if (!checkonly)
emu3B->enabled = *((BOOL*)val->data);
} else if (atom == prop_3btimeout)
{
if (val->format != 32 || val->size != 1 || val->type != XA_INTEGER)
return BadMatch;
if (!checkonly)
emu3B->timeout = *((CARD32*)val->data);
} else if (atom == prop_3bbutton)
{
if (val->format != 8 || val->size != 1 || val->type != XA_INTEGER)
return BadMatch;
if (!checkonly)
emu3B->button = *((CARD8*)val->data);
} else if (atom == prop_3bthreshold)
{
if (val->format != 32 || val->size != 1 || val->type != XA_INTEGER)
return BadMatch;
if (!checkonly)
emu3B->threshold = *((CARD32*)val->data);
}
return Success;
}
/**
* Initialise properties for third button emulation
*/
void
Evdev3BEmuInitProperty(DeviceIntPtr dev)
{
InputInfoPtr pInfo = dev->public.devicePrivate;
EvdevPtr pEvdev = pInfo->private;
struct emulate3B *emu3B = &pEvdev->emulate3B;
int rc;
if (!dev->button) /* don't init prop for keyboards */
return;
/* third button emulation on/off */
prop_3bemu = MakeAtom(EVDEV_PROP_THIRDBUTTON, strlen(EVDEV_PROP_THIRDBUTTON), TRUE);
rc = XIChangeDeviceProperty(dev, prop_3bemu, XA_INTEGER, 8,
PropModeReplace, 1,
&emu3B->enabled,
FALSE);
if (rc != Success)
return;
XISetDevicePropertyDeletable(dev, prop_3bemu, FALSE);
/* third button emulation timeout */
prop_3btimeout = MakeAtom(EVDEV_PROP_THIRDBUTTON_TIMEOUT,
strlen(EVDEV_PROP_THIRDBUTTON_TIMEOUT),
TRUE);
rc = XIChangeDeviceProperty(dev, prop_3btimeout, XA_INTEGER, 32, PropModeReplace, 1,
&emu3B->timeout, FALSE);
if (rc != Success)
return;
XISetDevicePropertyDeletable(dev, prop_3btimeout, FALSE);
/* third button emulation button to be triggered */
prop_3bbutton = MakeAtom(EVDEV_PROP_THIRDBUTTON_BUTTON,
strlen(EVDEV_PROP_THIRDBUTTON_BUTTON),
TRUE);
rc = XIChangeDeviceProperty(dev, prop_3bbutton, XA_INTEGER, 8, PropModeReplace, 1,
&emu3B->button, FALSE);
if (rc != Success)
return;
XISetDevicePropertyDeletable(dev, prop_3bbutton, FALSE);
/* third button emulation movement threshold */
prop_3bthreshold = MakeAtom(EVDEV_PROP_THIRDBUTTON_THRESHOLD,
strlen(EVDEV_PROP_THIRDBUTTON_THRESHOLD),
TRUE);
rc = XIChangeDeviceProperty(dev, prop_3bthreshold, XA_INTEGER, 32, PropModeReplace, 1,
&emu3B->threshold, FALSE);
if (rc != Success)
return;
XISetDevicePropertyDeletable(dev, prop_3bthreshold, FALSE);
XIRegisterPropertyHandler(dev, Evdev3BEmuSetProperty, NULL, NULL);
}

View File

@@ -1,482 +0,0 @@
/*
* Copyright 1990,91 by Thomas Roell, Dinkelscherben, Germany.
* Copyright 1993 by David Dawes <dawes@xfree86.org>
* Copyright 2002 by SuSE Linux AG, Author: Egbert Eich
* Copyright 1994-2002 by The XFree86 Project, Inc.
* Copyright 2002 by Paul Elliott
* (Ported from xf86-input-mouse, above copyrights taken from there)
* Copyright 2008 by Chris Salch
* Copyright © 2008 Red Hat, Inc.
*
* Permission to use, copy, modify, distribute, and sell this software
* and its documentation for any purpose is hereby granted without
* fee, provided that the above copyright notice appear in all copies
* and that both that copyright notice and this permission notice
* appear in supporting documentation, and that the name of the authors
* not be used in advertising or publicity pertaining to distribution of the
* software without specific, written prior permission. The authors make 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.
*
*/
/* Mouse wheel emulation code. */
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "evdev.h"
#include <X11/Xatom.h>
#include <xf86.h>
#include <xf86Xinput.h>
#include <exevents.h>
#include <evdev-properties.h>
#define WHEEL_NOT_CONFIGURED 0
static Atom prop_wheel_emu = 0;
static Atom prop_wheel_axismap = 0;
static Atom prop_wheel_inertia = 0;
static Atom prop_wheel_timeout = 0;
static Atom prop_wheel_button = 0;
/* Local Funciton Prototypes */
static int EvdevWheelEmuInertia(InputInfoPtr pInfo, WheelAxisPtr axis, int value);
/* Filter mouse button events */
BOOL
EvdevWheelEmuFilterButton(InputInfoPtr pInfo, unsigned int button, int value)
{
EvdevPtr pEvdev = (EvdevPtr)pInfo->private;
int ms;
/* Has wheel emulation been configured to be enabled? */
if (!pEvdev->emulateWheel.enabled)
return FALSE;
/* Check for EmulateWheelButton */
if (pEvdev->emulateWheel.button == button) {
pEvdev->emulateWheel.button_state = value;
if (value)
/* Start the timer when the button is pressed */
pEvdev->emulateWheel.expires = pEvdev->emulateWheel.timeout +
GetTimeInMillis();
else {
ms = pEvdev->emulateWheel.expires - GetTimeInMillis();
if (ms > 0) {
/*
* If the button is released early enough emit the button
* press/release events
*/
EvdevQueueButtonClicks(pInfo, button, 1);
}
}
return TRUE;
}
/* Don't care about this event */
return FALSE;
}
/* Filter mouse wheel events */
BOOL
EvdevWheelEmuFilterMotion(InputInfoPtr pInfo, struct input_event *pEv)
{
EvdevPtr pEvdev = (EvdevPtr)pInfo->private;
WheelAxisPtr pAxis = NULL, pOtherAxis = NULL;
int value = pEv->value;
/* Has wheel emulation been configured to be enabled? */
if (!pEvdev->emulateWheel.enabled)
return FALSE;
/* Handle our motion events if the emuWheel button is pressed
* wheel button of 0 means always emulate wheel.
*/
if (pEvdev->emulateWheel.button_state || !pEvdev->emulateWheel.button) {
/* Just return if the timeout hasn't expired yet */
if (pEvdev->emulateWheel.button)
{
int ms = pEvdev->emulateWheel.expires - GetTimeInMillis();
if (ms > 0)
return TRUE;
}
if(pEv->type == EV_ABS) {
int axis = pEvdev->abs_axis_map[pEv->code];
int oldValue;
if (axis > -1 && valuator_mask_fetch(pEvdev->old_vals, axis, &oldValue)) {
valuator_mask_set(pEvdev->vals, axis, value);
value -= oldValue; /* make value into a differential measurement */
} else
value = 0; /* avoid a jump on the first touch */
}
switch(pEv->code) {
/* ABS_X has the same value as REL_X, so this case catches both */
case REL_X:
pAxis = &(pEvdev->emulateWheel.X);
pOtherAxis = &(pEvdev->emulateWheel.Y);
break;
/* ABS_Y has the same value as REL_Y, so this case catches both */
case REL_Y:
pAxis = &(pEvdev->emulateWheel.Y);
pOtherAxis = &(pEvdev->emulateWheel.X);
break;
default:
break;
}
/* If we found REL_X, REL_Y, ABS_X or ABS_Y then emulate a mouse
wheel. Reset the inertia of the other axis when a scroll event
was sent to avoid the buildup of erroneous scroll events if the
user doesn't move in a perfectly straight line.
*/
if (pAxis)
{
if (EvdevWheelEmuInertia(pInfo, pAxis, value))
pOtherAxis->traveled_distance = 0;
}
/* Eat motion events while emulateWheel button pressed. */
return TRUE;
}
return FALSE;
}
/* Simulate inertia for our emulated mouse wheel.
Returns the number of wheel events generated.
*/
static int
EvdevWheelEmuInertia(InputInfoPtr pInfo, WheelAxisPtr axis, int value)
{
EvdevPtr pEvdev = (EvdevPtr)pInfo->private;
int button;
int inertia;
int rc = 0;
/* if this axis has not been configured, just eat the motion */
if (!axis->up_button)
return rc;
axis->traveled_distance += value;
if (axis->traveled_distance < 0) {
button = axis->up_button;
inertia = -pEvdev->emulateWheel.inertia;
} else {
button = axis->down_button;
inertia = pEvdev->emulateWheel.inertia;
}
/* Produce button press events for wheel motion */
while(abs(axis->traveled_distance) > pEvdev->emulateWheel.inertia) {
axis->traveled_distance -= inertia;
EvdevQueueButtonClicks(pInfo, button, 1);
rc++;
}
return rc;
}
/* Handle button mapping here to avoid code duplication,
returns true if a button mapping was found. */
static BOOL
EvdevWheelEmuHandleButtonMap(InputInfoPtr pInfo, WheelAxisPtr pAxis,
const char *axis_name)
{
EvdevPtr pEvdev = (EvdevPtr)pInfo->private;
char *option_string;
pAxis->up_button = WHEEL_NOT_CONFIGURED;
/* Check to see if there is configuration for this axis */
option_string = xf86SetStrOption(pInfo->options, axis_name, NULL);
if (option_string) {
int up_button = 0;
int down_button = 0;
char *msg = NULL;
if ((sscanf(option_string, "%d %d", &up_button, &down_button) == 2) &&
((up_button > 0) && (up_button <= EVDEV_MAXBUTTONS)) &&
((down_button > 0) && (down_button <= EVDEV_MAXBUTTONS))) {
/* Use xstrdup to allocate a string for us */
msg = xstrdup("buttons XX and YY");
if (msg)
sprintf(msg, "buttons %d and %d", up_button, down_button);
pAxis->up_button = up_button;
pAxis->down_button = down_button;
/* Update the number of buttons if needed */
if (up_button > pEvdev->num_buttons) pEvdev->num_buttons = up_button;
if (down_button > pEvdev->num_buttons) pEvdev->num_buttons = down_button;
} else {
xf86IDrvMsg(pInfo, X_WARNING, "Invalid %s value:\"%s\"\n",
axis_name, option_string);
}
free(option_string);
/* Clean up and log what happened */
if (msg) {
xf86IDrvMsg(pInfo, X_CONFIG, "%s: %s\n", axis_name, msg);
free(msg);
return TRUE;
}
}
return FALSE;
}
/* Setup the basic configuration options used by mouse wheel emulation */
void
EvdevWheelEmuPreInit(InputInfoPtr pInfo)
{
EvdevPtr pEvdev = (EvdevPtr)pInfo->private;
int wheelButton;
int inertia;
int timeout;
if (xf86SetBoolOption(pInfo->options, "EmulateWheel", FALSE)) {
pEvdev->emulateWheel.enabled = TRUE;
} else
pEvdev->emulateWheel.enabled = FALSE;
wheelButton = xf86SetIntOption(pInfo->options, "EmulateWheelButton", 4);
if ((wheelButton < 0) || (wheelButton > EVDEV_MAXBUTTONS)) {
xf86IDrvMsg(pInfo, X_WARNING, "Invalid EmulateWheelButton value: %d\n",
wheelButton);
xf86IDrvMsg(pInfo, X_WARNING, "Wheel emulation disabled.\n");
pEvdev->emulateWheel.enabled = FALSE;
}
pEvdev->emulateWheel.button = wheelButton;
inertia = xf86SetIntOption(pInfo->options, "EmulateWheelInertia", 10);
if (inertia <= 0) {
xf86IDrvMsg(pInfo, X_WARNING, "Invalid EmulateWheelInertia value: %d\n",
inertia);
xf86IDrvMsg(pInfo, X_WARNING, "Using built-in inertia value.\n");
inertia = 10;
}
pEvdev->emulateWheel.inertia = inertia;
timeout = xf86SetIntOption(pInfo->options, "EmulateWheelTimeout", 200);
if (timeout < 0) {
xf86IDrvMsg(pInfo, X_WARNING, "Invalid EmulateWheelTimeout value: %d\n",
timeout);
xf86IDrvMsg(pInfo, X_WARNING, "Using built-in timeout value.\n");
timeout = 200;
}
pEvdev->emulateWheel.timeout = timeout;
/* Configure the Y axis or default it */
if (!EvdevWheelEmuHandleButtonMap(pInfo, &(pEvdev->emulateWheel.Y),
"YAxisMapping")) {
/* Default the Y axis to sane values */
pEvdev->emulateWheel.Y.up_button = 4;
pEvdev->emulateWheel.Y.down_button = 5;
/* Simpler to check just the largest value in this case */
/* XXX: we should post this to the server */
if (5 > pEvdev->num_buttons)
pEvdev->num_buttons = 5;
/* Display default Configuration */
xf86IDrvMsg(pInfo, X_CONFIG, "YAxisMapping: buttons %d and %d\n",
pEvdev->emulateWheel.Y.up_button,
pEvdev->emulateWheel.Y.down_button);
}
/* This axis should default to an unconfigured state as most people
are not going to expect a Horizontal wheel. */
EvdevWheelEmuHandleButtonMap(pInfo, &(pEvdev->emulateWheel.X),
"XAxisMapping");
/* Used by the inertia code */
pEvdev->emulateWheel.X.traveled_distance = 0;
pEvdev->emulateWheel.Y.traveled_distance = 0;
xf86IDrvMsg(pInfo, X_CONFIG,
"EmulateWheelButton: %d, "
"EmulateWheelInertia: %d, "
"EmulateWheelTimeout: %d\n",
pEvdev->emulateWheel.button, inertia, timeout);
}
static int
EvdevWheelEmuSetProperty(DeviceIntPtr dev, Atom atom, XIPropertyValuePtr val,
BOOL checkonly)
{
InputInfoPtr pInfo = dev->public.devicePrivate;
EvdevPtr pEvdev = pInfo->private;
if (atom == prop_wheel_emu)
{
if (val->format != 8 || val->size != 1 || val->type != XA_INTEGER)
return BadMatch;
if (!checkonly)
{
pEvdev->emulateWheel.enabled = *((BOOL*)val->data);
/* Don't enable with zero inertia, otherwise we may get stuck in an
* infinite loop */
if (pEvdev->emulateWheel.inertia <= 0)
{
pEvdev->emulateWheel.inertia = 10;
/* We may get here before the property is actually enabled */
if (prop_wheel_inertia)
XIChangeDeviceProperty(dev, prop_wheel_inertia, XA_INTEGER,
16, PropModeReplace, 1,
&pEvdev->emulateWheel.inertia, TRUE);
}
}
}
else if (atom == prop_wheel_button)
{
int bt;
if (val->format != 8 || val->size != 1 || val->type != XA_INTEGER)
return BadMatch;
bt = *((CARD8*)val->data);
if (bt < 0 || bt >= EVDEV_MAXBUTTONS)
return BadValue;
if (!checkonly)
pEvdev->emulateWheel.button = bt;
} else if (atom == prop_wheel_axismap)
{
if (val->format != 8 || val->size != 4 || val->type != XA_INTEGER)
return BadMatch;
if (!checkonly)
{
pEvdev->emulateWheel.X.up_button = *((CARD8*)val->data);
pEvdev->emulateWheel.X.down_button = *(((CARD8*)val->data) + 1);
pEvdev->emulateWheel.Y.up_button = *(((CARD8*)val->data) + 2);
pEvdev->emulateWheel.Y.down_button = *(((CARD8*)val->data) + 3);
}
} else if (atom == prop_wheel_inertia)
{
int inertia;
if (val->format != 16 || val->size != 1 || val->type != XA_INTEGER)
return BadMatch;
inertia = *((CARD16*)val->data);
if (inertia <= 0)
return BadValue;
if (!checkonly)
pEvdev->emulateWheel.inertia = inertia;
} else if (atom == prop_wheel_timeout)
{
int timeout;
if (val->format != 16 || val->size != 1 || val->type != XA_INTEGER)
return BadMatch;
timeout = *((CARD16*)val->data);
if (timeout < 0)
return BadValue;
if (!checkonly)
pEvdev->emulateWheel.timeout = timeout;
}
return Success;
}
void
EvdevWheelEmuInitProperty(DeviceIntPtr dev)
{
InputInfoPtr pInfo = dev->public.devicePrivate;
EvdevPtr pEvdev = pInfo->private;
int rc = TRUE;
char vals[4];
if (!dev->button) /* don't init prop for keyboards */
return;
prop_wheel_emu = MakeAtom(EVDEV_PROP_WHEEL, strlen(EVDEV_PROP_WHEEL), TRUE);
rc = XIChangeDeviceProperty(dev, prop_wheel_emu, XA_INTEGER, 8,
PropModeReplace, 1,
&pEvdev->emulateWheel.enabled, FALSE);
if (rc != Success)
return;
XISetDevicePropertyDeletable(dev, prop_wheel_emu, FALSE);
vals[0] = pEvdev->emulateWheel.X.up_button;
vals[1] = pEvdev->emulateWheel.X.down_button;
vals[2] = pEvdev->emulateWheel.Y.up_button;
vals[3] = pEvdev->emulateWheel.Y.down_button;
prop_wheel_axismap = MakeAtom(EVDEV_PROP_WHEEL_AXES, strlen(EVDEV_PROP_WHEEL_AXES), TRUE);
rc = XIChangeDeviceProperty(dev, prop_wheel_axismap, XA_INTEGER, 8,
PropModeReplace, 4, vals, FALSE);
if (rc != Success)
return;
XISetDevicePropertyDeletable(dev, prop_wheel_axismap, FALSE);
prop_wheel_inertia = MakeAtom(EVDEV_PROP_WHEEL_INERTIA, strlen(EVDEV_PROP_WHEEL_INERTIA), TRUE);
rc = XIChangeDeviceProperty(dev, prop_wheel_inertia, XA_INTEGER, 16,
PropModeReplace, 1,
&pEvdev->emulateWheel.inertia, FALSE);
if (rc != Success)
return;
XISetDevicePropertyDeletable(dev, prop_wheel_inertia, FALSE);
prop_wheel_timeout = MakeAtom(EVDEV_PROP_WHEEL_TIMEOUT, strlen(EVDEV_PROP_WHEEL_TIMEOUT), TRUE);
rc = XIChangeDeviceProperty(dev, prop_wheel_timeout, XA_INTEGER, 16,
PropModeReplace, 1,
&pEvdev->emulateWheel.timeout, FALSE);
if (rc != Success)
return;
XISetDevicePropertyDeletable(dev, prop_wheel_timeout, FALSE);
prop_wheel_button = MakeAtom(EVDEV_PROP_WHEEL_BUTTON, strlen(EVDEV_PROP_WHEEL_BUTTON), TRUE);
rc = XIChangeDeviceProperty(dev, prop_wheel_button, XA_INTEGER, 8,
PropModeReplace, 1,
&pEvdev->emulateWheel.button, FALSE);
if (rc != Success)
return;
XISetDevicePropertyDeletable(dev, prop_wheel_button, FALSE);
XIRegisterPropertyHandler(dev, EvdevWheelEmuSetProperty, NULL, NULL);
}

File diff suppressed because it is too large Load Diff

View File

@@ -25,164 +25,39 @@
* Kristian Høgsberg (krh@redhat.com)
* Adam Jackson (ajax@redhat.com)
* Peter Hutterer (peter@cs.unisa.edu.au)
* Oliver McFadden (oliver.mcfadden@nokia.com)
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#ifndef EVDEV_H
#define EVDEV_H
#include <linux/input.h>
#include <linux/types.h>
#include <xorg-server.h>
#include <xf86Xinput.h>
#include <xf86_OSproc.h>
#include <xkbstr.h>
#ifdef MULTITOUCH
#include <mtdev.h>
#if defined(XKB)
/* XXX VERY WRONG. this is a client side header. */
#include <X11/extensions/XKBstr.h>
#endif
#include <libevdev/libevdev.h>
#ifndef EV_CNT /* linux 2.6.23 kernels and earlier lack _CNT defines */
#define EV_CNT (EV_MAX+1)
#endif
#ifndef KEY_CNT
#define KEY_CNT (KEY_MAX+1)
#endif
#ifndef REL_CNT
#define REL_CNT (REL_MAX+1)
#endif
#ifndef ABS_CNT
#define ABS_CNT (ABS_MAX+1)
#endif
#ifndef LED_CNT
#define LED_CNT (LED_MAX+1)
#endif
#if GET_ABI_MAJOR(ABI_XINPUT_VERSION) >= 14
#define HAVE_SMOOTH_SCROLLING 1
#endif
#if GET_ABI_MAJOR(ABI_XINPUT_VERSION) < 18
#define LogMessageVerbSigSafe xf86MsgVerb
#endif
#define EVDEV_MAXBUTTONS 32
#define EVDEV_MAXQUEUE 32
/* evdev flags */
#define EVDEV_KEYBOARD_EVENTS (1 << 0)
#define EVDEV_BUTTON_EVENTS (1 << 1)
#define EVDEV_RELATIVE_EVENTS (1 << 2)
#define EVDEV_ABSOLUTE_EVENTS (1 << 3)
#define EVDEV_TOUCHPAD (1 << 4)
#define EVDEV_INITIALIZED (1 << 5) /* WheelInit etc. called already? */
#define EVDEV_TOUCHSCREEN (1 << 6)
#define EVDEV_CALIBRATED (1 << 7) /* run-time calibrated? */
#define EVDEV_TABLET (1 << 8) /* device looks like a tablet? */
#define EVDEV_UNIGNORE_ABSOLUTE (1 << 9) /* explicitly unignore abs axes */
#define EVDEV_UNIGNORE_RELATIVE (1 << 10) /* explicitly unignore rel axes */
#define EVDEV_RELATIVE_MODE (1 << 11) /* Force relative events for devices with absolute axes */
#ifndef MAX_VALUATORS
#define MAX_VALUATORS 36
#endif
#ifndef XI_PROP_DEVICE_NODE
#define XI_PROP_DEVICE_NODE "Device Node"
#endif
#define LONG_BITS (sizeof(long) * 8)
/* Number of longs needed to hold the given number of bits */
#define NLONGS(x) (((x) + LONG_BITS - 1) / LONG_BITS)
/* Function key mode */
enum fkeymode {
FKEYMODE_UNKNOWN = 0,
FKEYMODE_FKEYS, /* function keys send function keys */
FKEYMODE_MMKEYS, /* function keys send multimedia keys */
};
enum SlotState {
SLOTSTATE_OPEN = 8,
SLOTSTATE_CLOSE,
SLOTSTATE_UPDATE,
SLOTSTATE_EMPTY,
};
enum ButtonAction {
BUTTON_RELEASE = 0,
BUTTON_PRESS = 1
};
/* axis specific data for wheel emulation */
typedef struct {
int up_button;
int down_button;
int traveled_distance;
} WheelAxis, *WheelAxisPtr;
/* Event queue used to defer keyboard/button events until EV_SYN time. */
typedef struct {
enum {
EV_QUEUE_KEY, /* xf86PostKeyboardEvent() */
EV_QUEUE_BTN, /* xf86PostButtonEvent() */
EV_QUEUE_PROXIMITY, /* xf86PostProximityEvent() */
#ifdef MULTITOUCH
EV_QUEUE_TOUCH, /*xf86PostTouchEvent() */
#endif
} type;
union {
int key; /* May be either a key code or button number. */
#ifdef MULTITOUCH
unsigned int touch; /* Touch ID */
#endif
} detail;
int val; /* State of the key/button/touch; pressed or released. */
#ifdef MULTITOUCH
ValuatorMask *touchMask;
#endif
} EventQueueRec, *EventQueuePtr;
typedef struct {
struct libevdev *dev;
char *device;
int grabDevice; /* grab the event device? */
int num_vals; /* number of valuators */
int num_mt_vals; /* number of multitouch valuators */
int abs_axis_map[ABS_CNT]; /* Map evdev ABS_* to index */
int rel_axis_map[REL_CNT]; /* Map evdev REL_* to index */
ValuatorMask *vals; /* new values coming in */
ValuatorMask *old_vals; /* old values for calculating relative motion */
ValuatorMask *prox; /* last values set while not in proximity */
ValuatorMask *mt_mask;
ValuatorMask **last_mt_vals;
int cur_slot;
enum SlotState slot_state;
#ifdef MULTITOUCH
struct mtdev *mtdev;
#endif
int kernel24;
int screen;
int min_x, min_y, max_x, max_y;
int abs_x, abs_y, old_x, old_y;
int flags;
int in_proximity; /* device in proximity */
int use_proximity; /* using the proximity bit? */
int num_buttons; /* number of buttons */
BOOL swap_axes;
BOOL invert_x;
BOOL invert_y;
int delta[REL_CNT];
unsigned int abs_queued, rel_queued, prox_queued;
int tool;
/* XKB stuff has to be per-device rather than per-driver */
int noXkb;
#ifdef XKB
char *xkb_rules;
char *xkb_model;
char *xkb_layout;
char *xkb_variant;
char *xkb_options;
XkbComponentNamesRec xkbnames;
#endif
/* Middle mouse button emulation */
struct {
BOOL enabled;
@@ -192,112 +67,15 @@ typedef struct {
Time expires; /* time of expiry */
Time timeout;
} emulateMB;
/* Third mouse button emulation */
struct emulate3B {
BOOL enabled;
BOOL state; /* current state */
Time timeout; /* timeout until third button press */
int buttonstate; /* phys. button state */
int button; /* phys button to emit */
int threshold; /* move threshold in dev coords */
OsTimerPtr timer;
int delta[2]; /* delta x/y, accumulating */
int startpos[2]; /* starting pos for abs devices */
int flags; /* remember if we had rel or abs movement */
} emulate3B;
struct {
int meta; /* meta key to lock any button */
BOOL meta_state; /* meta_button state */
unsigned int lock_pair[EVDEV_MAXBUTTONS]; /* specify a meta/lock pair */
BOOL lock_state[EVDEV_MAXBUTTONS]; /* state of any locked buttons */
} dragLock;
struct {
BOOL enabled;
int button;
int button_state;
int inertia;
WheelAxis X;
WheelAxis Y;
Time expires; /* time of expiry */
Time timeout;
} emulateWheel;
struct {
int vert_delta;
int horiz_delta;
int dial_delta;
} smoothScroll;
/* run-time calibration */
struct {
int min_x;
int max_x;
int min_y;
int max_y;
} calibration;
unsigned char btnmap[32]; /* config-file specified button mapping */
int reopen_attempts; /* max attempts to re-open after read failure */
int reopen_left; /* number of attempts left to re-open the device */
OsTimerPtr reopen_timer;
/* minor/major number */
dev_t min_maj;
/* Event queue used to defer keyboard/button events until EV_SYN time. */
int num_queue;
EventQueueRec queue[EVDEV_MAXQUEUE];
enum fkeymode fkeymode;
char *type_name;
} EvdevRec, *EvdevPtr;
/* Event posting functions */
void EvdevQueueKbdEvent(InputInfoPtr pInfo, struct input_event *ev, int value);
void EvdevQueueButtonEvent(InputInfoPtr pInfo, int button, int value);
void EvdevQueueProximityEvent(InputInfoPtr pInfo, int value);
#ifdef MULTITOUCH
void EvdevQueueTouchEvent(InputInfoPtr pInfo, unsigned int touch,
ValuatorMask *mask, uint16_t type);
#endif
void EvdevPostButtonEvent(InputInfoPtr pInfo, int button, enum ButtonAction act);
void EvdevQueueButtonClicks(InputInfoPtr pInfo, int button, int count);
void EvdevPostRelativeMotionEvents(InputInfoPtr pInfo, int num_v, int first_v,
int v[MAX_VALUATORS]);
void EvdevPostAbsoluteMotionEvents(InputInfoPtr pInfo, int num_v, int first_v,
int v[MAX_VALUATORS]);
unsigned int EvdevUtilButtonEventToButtonNumber(EvdevPtr pEvdev, int code);
/* Middle Button emulation */
int EvdevMBEmuTimer(InputInfoPtr);
BOOL EvdevMBEmuFilterEvent(InputInfoPtr, int, BOOL);
void EvdevMBEmuWakeupHandler(pointer, int, pointer);
void EvdevMBEmuBlockHandler(pointer, struct timeval**, pointer);
void EvdevMBEmuPreInit(InputInfoPtr);
void EvdevMBEmuOn(InputInfoPtr);
void EvdevMBEmuFinalize(InputInfoPtr);
void EvdevMBEmuEnable(InputInfoPtr, BOOL);
/* Third button emulation */
CARD32 Evdev3BEmuTimer(OsTimerPtr timer, CARD32 time, pointer arg);
BOOL Evdev3BEmuFilterEvent(InputInfoPtr, int, BOOL);
void Evdev3BEmuPreInit(InputInfoPtr pInfo);
void Evdev3BEmuOn(InputInfoPtr);
void Evdev3BEmuFinalize(InputInfoPtr);
void Evdev3BEmuProcessRelMotion(InputInfoPtr pInfo, int dx, int dy);
void Evdev3BEmuProcessAbsMotion(InputInfoPtr pInfo, ValuatorMask *vals);
/* Mouse Wheel emulation */
void EvdevWheelEmuPreInit(InputInfoPtr pInfo);
BOOL EvdevWheelEmuFilterButton(InputInfoPtr pInfo, unsigned int button, int value);
BOOL EvdevWheelEmuFilterMotion(InputInfoPtr pInfo, struct input_event *pEv);
/* Draglock code */
void EvdevDragLockPreInit(InputInfoPtr pInfo);
BOOL EvdevDragLockFilterEvent(InputInfoPtr pInfo, unsigned int button, int value);
void EvdevMBEmuInitProperty(DeviceIntPtr);
void Evdev3BEmuInitProperty(DeviceIntPtr);
void EvdevWheelEmuInitProperty(DeviceIntPtr);
void EvdevDragLockInitProperty(DeviceIntPtr);
void EvdevAppleInitProperty(DeviceIntPtr);
#endif

View File

@@ -1,6 +0,0 @@
sdkdir=@sdkdir@
Name: xorg-evdev
Description: X.Org evdev input driver.
Version: @PACKAGE_VERSION@
Cflags: -I${sdkdir}