Linux event device protocol support for GPM
ChangeLog
Ok, I am a proud owner of a laptop with Synaptics touchpad and recently support for
Synaptics in absolute mode has been added to Linux kernel (2.5/2.6). The problem is that it is exported via
event input interface only and GPM's support for Linux event devices is pretty much nonexistent
(only relative devices reporting via /dev/input/eventX are supported, no SYNC event support).
As I have never worked on GPM before I needed to understand how it works; while doing so I did some
refactoring of the existing code, splitting it in more manageable chunks. Although changes are pretty substantial I tried not touch the protocol handling code so changes must be relatively safe.
Here are the patches (incremental, starting against vanilla gpm-1.20.1):
-
gpm-1.20.1-001-separate-console-code.patch.gz
Separates all console and selection/paste code into separate file,
cleanups.
-
gpm-1.20.1-002-repeater.patch.gz
Separates repeater handling into separate data structures and functions.
-
gpm-1.20.1-003-separate-client-code.patch.gz
Separates client handling code into separate source file, cleanups.
-
gpm-1.20.1-004-optparser.patch.gz
Splits option parsing (-o text) into separate file suitable for use outside of
mice.c
-
gpm-1.20.1-005-more-than-2-mouses.patch.gz
Gets rid of 2 mouse limitation by removing mouse_features array,
mice are allocated on the heap, protocol drivers can allocate and attach private data to the mouse structure for later use (required for evdev support later).
-
gpm-1.20.1-006-absolute-is-device-property.patch.gz
Allows same protocol control devices in absolute and relative mode. Before, if a protocold driver supported devices in both relative and absolute mode it would, like Wacom, change absolute attribute right in the Gpm_Type structure. It obviously does not work if you have 2 devices using 2 different methods at the same time.
-
gpm-1.20.1-007-remove-global-state-structure.patch.gz
Code cleanups to improve readability.
-
gpm-1.20.1-008-evdev.patch.gz
The main thing ;). Extended support for event devices. The driver is controlled via '-o' command line option (no spaces in option string!):
-o type=xxxx, nosync, y_iversed, left=1900, right=5400, bottom=1800, top=3900, touch_high=30, touch_low=25, tap_time=180, tap_move=220
- type - relative, absolute, touchpad, synaptics, auto.
- relative - suits for devices reporting relative motion packets, like regular PS/2 mouses. GPM expects REL_X, REL_Y, REL_WHEEL, REL_HWHEEL and various BTN_* events from the kernel.
- absolute - suits for touch screens and tablets reporting absolute coordinates. GPM expects ABS_X, ABS_Y and various BTN_* events from the kernel.
- touchpad - device reporting absolute coodrinates but cursor should not move if there is no touch. Also if you take your finger off and then touch the pad in some other place cursor should not jump across the screen as in the case with touch screen or tablet. Supports tapping, distinguishes corner and normal taps. Normal taps generate left button events, right-top corner tap generates middle button event, right-bottom corner tap generates right button event. GPM expects ABS_X, ABS_Y, various BTN_* and ABS_PRESSURE events from the kernel.
- synaptics - same as touchpad but recognizes multi-finger tapping. Two finger tap generates middle button event, three finger tap generates right button event. GPM expects ABS_X, ABS_Y, various BTN_*, ABS_PRESSURE and MSC_GESTURE events from the kernel.
- auto - interrogates device via ioctls and selects one of above based on devices reported capabilities.
Default is "auto"
- nosync - GONE.
- y_inverted - allow to adjust to devices that reported inversed Y axis events. Turned on by default for synaptics, off for everything else.
- left, right, bottom, top - allow to specify size of an absolute device or define edges for touchpads and synaptics (to distinguish corner taps). Not valid for relative devices, automatically retrieved for absolute devices. Default values 1900, 5400, 1800 and 3900.
- touch_high, touch_low - minimum pressure to start (touch_high) and continue (touch_low) tracking finger motion on the touch pad. Not valid for relative or absolute devices. Default valies are 30 and 25.
- tap_time, tap_move - maximal time and movement between finger starting touching the pad and leaving it for touch to be considered a tap. Not valid for relative or absolute devices. Default valies are 180 and 220.
For example, I am using:
gpm -m /dev/input/event1 -t evdev -o type=synaptics -M -m /dev/input/event2 -t evdev -o type=relative
or:
gpm -m /dev/input/event1 -t evdev -o type=synaptics -M -m /dev/input/mice -t imps2
-
gpm-1.20.1-009-better-button-multiplexing.patch.gz
Allows using one mouse to click and another to select.
I have a Synaptics with Track Stick which does not report any button presses, only main touchpad does (it was a design solution when
inplementing pass-through port support in kernel). So the old code would forget that I pressed left button on the touchpad as soon as I
start using Track Stick to move cursor. With the patch it's no longer the case, GPM remembers that left button is kept pressed on
some mouse although the one we read packet from did not report any buttons.
- gpm-1.20.1-010-evdev-syn-touch-detect.patch.gz
Make palm detection work for synaptics (the check was inversed so it was
activated for regular touchpads).
- gpm-1.20.1-011-evdev-fix-absolute-mode.patch.gz
Absolute devices are supposed to return normalized coordinates (0,0) - (console.max_x, console.max_y). Do it.
- gpm-1.20.1-012-evdev-fix-tap-mode.patch.gz
Tap time parameter wasn't working as I measured all timeouts in seconds instead of milliseconds. So, unless you waited 3 minutes, almost every touch was considered a tap.
- gpm-1.20.1-013-evdev-use-ioctls.patch.gz
Use ioctls to retrieve device capabilities and select best mode.
- gpm-1.20.1-014-sticky-selection-fix.patch.gz
If, while selecting, mouse touches top or bottom edge of the screen from that moment on selection would stick to the right side of the screen.
- gpm-1.20.1-015-older-gcc-compile.patch.gz
Older GCCs give compile errors if variable declarations are mixed with other statements.
- gpm-1.20.1-016-margins.patch.gz
Fixed problem with applying limits to cordinates. Can easily be seen in Midnight Commander clicking on menu.
- gpm-1.20.1-017-three-button-mode.patch.gz
Mouse would not switch in strict 3-button mode after pressing middle button.
- gpm-1.20.1-018-synaptics-compile-warning.patch.gz
Harmless warning about unused debug code in synaptics driver.
- gpm-1.20.1-019-tap-and-drag.patch.gz
Tap-and-select support in evdev driver (for "touchpad" and "synaptics" types).
- gpm-1.20.1-020-optparser-crash.patch.gz
GPM would crash if string option used without argument in "-o". Also make argiments mandatory for string and integer options.
- gpm-1.20.1-021-2.6-t6-update.patch.gz
Updates to evdev protocol to support kernels >= 2.6.0-test; do not use Oops in evdev in case of mad input parameters, Synaptics detection uses get ID IOCTL now.
- gpm-1.20.1-022-console-selection-split.patch.gz
Separate console handling and selection handling code.
- gpm-1.20.1-023-libgpm-memory-leak.patch.gz
Small memory leak in libgpm (liblow.c).
You can also download
binary or source
RPMs (built on RedHat 8). These have some additional patches taken from gpm-1.20.1-38.src.rpm off RawHide.
You can see all the patches here.
Your comments and suggestions are appreciated! Please mail me if you find any issues.
Disclaimer: It works for me, but I can not guarantee that it won't blow up in your face. I am more of an X guy anyway.
Disclaimer 2: Still, I am interested in supporting my work and fixing any reported issues.
August 24, 2003
- Palm detection wasn't working on synaptics touchpads, thanks to Peter Ă–sterlund for pointing this out (patch #10).
- When using evdev's absolute mode coordinates weren't scaled (patch #11).
- Tap timeout wasn't working. Well, it worked but in seconds instead of milliseconds (patch #12).
- New RPMS (dt4). I installed emacs so t-mouse.elc is now packaged.
August 26, 2003
- As suggested by Vojtech Pavlik GPM now uses ioctls to interrogate device. Nosync option is gone; new type "auto" introduced. "Auto" selects the best of other 4 modes based on device reported capabilities (patch #13).
- New RPMS (dt5).
- Don't forget to do autoheader && autoconf when building.
August 27, 2003
- The following
kernel patch is required for GPM to automatically recognize
Synaptics touchpad as current 2.6 kernels do not report EV_MSC capabilities.
Update: the patch has been included in 2.6.0-test4-bk4
September 04, 2003
- Selection code was broken by me as it would stich to the left side of the
screen after cursor touched top or bottom edge (patch #14).
- Older GCCs choke on mouse-test.c (patch #15).
- New RPMS (dt6).
September 17, 2003
- Bunch of fixes for mostly my own bugs (patches #16, 17, 18 and 20).
- Support for tap-and-drag (well, tap and select actually) in evdev (patch #19).
- New RPMS (dt7).
October 01, 2003
- Updates to evdev protocol so it will work with kernels >= 2.6.0-test6 (patches #21).
- "y_inversed" option changed to "y_inverted"
- Split console code into console and selection (patch #22).
- Small memory leak in libgpm (patch #23).
- New RPMS (dt8).
Links
You are also might be interested in
Synaptics TouchPad driver for XFree86 by Peter Ă–sterlund