* updated kmousetool (21.12.1 -> 21.12.2), untested
[t2-trunk.git] / package / x11 / synaptics / git.patch
blob4d9dfcbb76760a2f8a2171d0361809ac9e014cac
1 # --- T2-COPYRIGHT-NOTE-BEGIN ---
2 # This copyright note is auto-generated by ./scripts/Create-CopyPatch.
3 #
4 # T2 SDE: package/.../synaptics/git.patch
5 # Copyright (C) 2008 The T2 SDE Project
6 #
7 # More information can be found in the files COPYING and README.
8 #
9 # This patch file is dual-licensed. It is available under the license the
10 # patched project is licensed under, as long as it is an OpenSource license
11 # as defined at http://www.opensource.org/ (e.g. BSD, X11) or under the terms
12 # of the GNU General Public License as published by the Free Software
13 # Foundation; either version 2 of the License, or (at your option) any later
14 # version.
15 # --- T2-COPYRIGHT-NOTE-END ---
17 diff -urN synaptics-0.14.6/FILES synaptics-git/FILES
18 --- synaptics-0.14.6/FILES 2006-04-16 21:31:42.000000000 +0200
19 +++ synaptics-git/FILES 2008-05-28 14:56:57.000000000 +0200
20 @@ -9,5 +9,5 @@
21 an external USB-mouse is attached
22 syndaemon.c A user space program that disables the touchpad
23 when the keyboard is used.
24 -alps.patch Patch for 2.6 kernels that makes it possible to
25 +alps.patch Patch for older 2.6 kernels that makes it possible to
26 use the driver with an ALPS GlidePoint device.
27 diff -urN synaptics-0.14.6/INSTALL synaptics-git/INSTALL
28 --- synaptics-0.14.6/INSTALL 2006-06-05 18:58:22.000000000 +0200
29 +++ synaptics-git/INSTALL 2008-05-28 14:56:57.000000000 +0200
30 @@ -49,24 +49,28 @@
31 following lines:
33 Section "InputDevice"
34 - Identifier "Synaptics Mouse"
35 - Driver "synaptics"
36 - Option "Device" "/dev/psaux"
37 - Option "Protocol" "auto-dev"
38 - Option "LeftEdge" "1700"
39 - Option "RightEdge" "5300"
40 - Option "TopEdge" "1700"
41 - Option "BottomEdge" "4200"
42 - Option "FingerLow" "25"
43 - Option "FingerHigh" "30"
44 - Option "MaxTapTime" "180"
45 - Option "MaxTapMove" "220"
46 - Option "VertScrollDelta" "100"
47 - Option "MinSpeed" "0.09"
48 - Option "MaxSpeed" "0.18"
49 - Option "AccelFactor" "0.0015"
50 - Option "SHMConfig" "on"
51 -# Option "Repeater" "/dev/ps2mouse"
52 + Identifier "Synaptics Mouse"
53 + Driver "synaptics"
54 + Option "Device" "/dev/psaux"
55 + Option "Protocol" "auto-dev"
56 +# enable SHMConfig if you want to enable synclient
57 +# NB: enabling SHMConfig is insecure, since any user can invoke it
58 +# Option "SHMConfig" "on"
59 + Option "LeftEdge" "1700"
60 + Option "RightEdge" "5300"
61 + Option "TopEdge" "1700"
62 + Option "BottomEdge" "4200"
63 + Option "FingerLow" "25"
64 + Option "FingerHigh" "30"
65 + Option "MaxTapTime" "180"
66 + Option "MaxTapMove" "220"
67 + Option "VertScrollDelta" "100"
68 + Option "CornerCoasting" "1"
69 + Option "CoastingSpeed" "3"
70 + Option "MinSpeed" "0.09"
71 + Option "MaxSpeed" "0.18"
72 + Option "AccelFactor" "0.0015"
73 +# Option "Repeater" "/dev/ps2mouse"
74 EndSection
76 Change the Identifier to the same name as in the ServerLayout section.
77 diff -urN synaptics-0.14.6/README synaptics-git/README
78 --- synaptics-0.14.6/README 2006-07-15 17:54:29.000000000 +0200
79 +++ synaptics-git/README 2008-05-28 14:56:57.000000000 +0200
80 @@ -28,6 +28,7 @@
81 for right button events. (Needs hardware support. Not all models
82 implement this feature.)
83 - Pressure dependent motion speed.
84 +- Trackstick emulation.
85 - Run-time configuration using shared memory. This means you can
86 change parameter settings without restarting the X server.
88 diff -urN synaptics-0.14.6/alpscomm.c synaptics-git/alpscomm.c
89 --- synaptics-0.14.6/alpscomm.c 2006-04-16 21:31:43.000000000 +0200
90 +++ synaptics-git/alpscomm.c 2008-05-28 14:56:57.000000000 +0200
91 @@ -1,7 +1,7 @@
92 /* Copyright (C) 2001 Stefan Gmeiner <riddlebox@freesurf.ch>
94 * Copyright (c) 2003 Neil Brown <neilb@cse.unsw.edu.au>
95 - * Copyright (c) 2003-2004 Peter Osterlund <petero2@telia.com>
96 + * Copyright (c) 2003-2005,2007 Peter Osterlund <petero2@telia.com>
98 * This program is free software; you can redistribute it and/or
99 * modify it under the terms of the GNU General Public License
100 @@ -72,7 +72,7 @@
103 static void
104 -ALPSDeviceOnHook(LocalDevicePtr local)
105 +ALPSDeviceOnHook(LocalDevicePtr local, SynapticsSHM *para)
109 diff -urN synaptics-0.14.6/eventcomm.c synaptics-git/eventcomm.c
110 --- synaptics-0.14.6/eventcomm.c 2006-07-15 17:54:29.000000000 +0200
111 +++ synaptics-git/eventcomm.c 2008-05-28 14:56:57.000000000 +0200
112 @@ -1,5 +1,5 @@
114 - * Copyright 2004 Peter Osterlund <petero2@telia.com>
115 + * Copyright 2004-2007 Peter Osterlund <petero2@telia.com>
117 * This program is free software; you can redistribute it and/or
118 * modify it under the terms of the GNU General Public License
119 @@ -24,6 +24,7 @@
120 #include <fcntl.h>
121 #include <stdio.h>
122 #include "synproto.h"
123 +#define SYNAPTICS_PRIVATE
124 #include "synaptics.h"
125 #include <xf86.h>
127 @@ -41,14 +42,16 @@
128 ****************************************************************************/
130 static void
131 -EventDeviceOnHook(LocalDevicePtr local)
132 +EventDeviceOnHook(LocalDevicePtr local, SynapticsSHM *para)
134 - /* Try to grab the event device so that data don't leak to /dev/input/mice */
135 - int ret;
136 - SYSCALL(ret = ioctl(local->fd, EVIOCGRAB, (pointer)1));
137 - if (ret < 0) {
138 - xf86Msg(X_WARNING, "%s can't grab event device, errno=%d\n",
139 - local->name, errno);
140 + if (para->grab_event_device) {
141 + /* Try to grab the event device so that data don't leak to /dev/input/mice */
142 + int ret;
143 + SYSCALL(ret = ioctl(local->fd, EVIOCGRAB, (pointer)1));
144 + if (ret < 0) {
145 + xf86Msg(X_WARNING, "%s can't grab event device, errno=%d\n",
146 + local->name, errno);
151 @@ -57,6 +60,27 @@
155 +static void
156 +event_query_abs_params(LocalDevicePtr local, int fd)
158 + int ret;
159 + SynapticsPrivate *priv = (SynapticsPrivate *) (local->private);
160 + struct input_absinfo absinfo;
161 + SYSCALL(ret = ioctl(fd, EVIOCGABS(ABS_X), &absinfo));
162 + if (ret < 0)
163 + return;
165 + priv->minx = absinfo.minimum;
166 + priv->maxx = absinfo.maximum;
168 + SYSCALL(ret = ioctl(fd, EVIOCGABS(ABS_Y), &absinfo));
169 + if (ret < 0)
170 + return;
172 + priv->miny = absinfo.minimum;
173 + priv->maxy = absinfo.maximum;
176 static Bool
177 event_query_is_touchpad(int fd)
179 @@ -86,6 +110,8 @@
180 return FALSE;
181 if (!TEST_BIT(BTN_TOOL_FINGER, evbits))
182 return FALSE;
183 + if (TEST_BIT(BTN_TOOL_PEN, evbits))
184 + return FALSE; /* Don't match wacom tablets */
186 return TRUE;
188 @@ -263,13 +289,15 @@
189 noent_cnt = 0;
190 have_evdev = TRUE;
191 is_touchpad = event_query_is_touchpad(fd);
192 - SYSCALL(close(fd));
193 if (is_touchpad) {
194 xf86Msg(X_PROBED, "%s auto-dev sets device to %s\n",
195 local->name, fname);
196 xf86ReplaceStrOption(local->options, "Device", fname);
197 + event_query_abs_params(local, fd);
198 + SYSCALL(close(fd));
199 return TRUE;
201 + SYSCALL(close(fd));
203 ErrorF("%s no synaptics event device found (checked %d nodes)\n",
204 local->name, i + 1);
205 diff -urN synaptics-0.14.6/linux_input.h synaptics-git/linux_input.h
206 --- synaptics-0.14.6/linux_input.h 2006-07-15 17:54:29.000000000 +0200
207 +++ synaptics-git/linux_input.h 2008-05-28 14:56:57.000000000 +0200
208 @@ -24,10 +24,18 @@
209 unsigned short version;
212 +struct input_absinfo {
213 + int value;
214 + int minimum;
215 + int maximum;
216 + int fuzz;
217 + int flat;
220 #define EVIOCGID _IOR('E', 0x02, struct input_id) /* get device ID */
221 #define EVIOCGRAB _IOW('E', 0x90, int) /* Grab/Release device */
222 #define EVIOCGBIT(ev,len) _IOC(_IOC_READ, 'E', 0x20 + ev, len) /* get event bits */
224 +#define EVIOCGABS(abs) _IOR('E', 0x40 + abs, struct input_absinfo) /* get abs value/limits */
226 #define EV_SYN 0x00
227 #define EV_KEY 0x01
228 @@ -53,6 +61,7 @@
229 #define BTN_7 0x107
230 #define BTN_A 0x130
231 #define BTN_B 0x131
232 +#define BTN_TOOL_PEN 0x140
233 #define BTN_TOOL_FINGER 0x145
234 #define BTN_TOOL_DOUBLETAP 0x14d
235 #define BTN_TOOL_TRIPLETAP 0x14e
236 diff -urN synaptics-0.14.6/manpages/synaptics.5 synaptics-git/manpages/synaptics.5
237 --- synaptics-0.14.6/manpages/synaptics.5 2006-07-15 17:59:04.000000000 +0200
238 +++ synaptics-git/manpages/synaptics.5 2008-05-28 14:56:57.000000000 +0200
239 @@ -61,7 +61,9 @@
240 These parameters are options in the InputDevice section in the
241 XOrg/XFree86 config file.
243 -See the INSTALL file for a working example.
244 +See the INSTALL file for a working example for a synaptics touchpad.
246 +See the README.alps file for a working example for an ALPS touchpad.
248 If you have the SHMConfig parameter enabled, these parameters can also
249 be changed at runtime with the synclient(1) program.
250 @@ -103,6 +105,13 @@
251 When finger pressure goes above this value, the driver counts it as a
252 touch.
254 +\fBFingerPress\fR (Integer)
255 +When finger pressure goes above this value, the driver counts it as a
256 +press.
258 +Currently a press is equivalent to putting the touchpad in trackstick
259 +emulation mode.
260 +.TP
261 \fBMaxTapTime\fR (Integer)
262 Maximum time (in milliseconds) for detecting a tap.
264 @@ -125,6 +134,9 @@
265 \fBHorizEdgeScroll\fR (Bool)
266 Enable horizontal scrolling when dragging along the bottom edge.
268 +\fBCornerCoasting\fR (Bool)
269 +Enable edge scrolling to continue while the finger stays in an edge corner.
270 +.TP
271 \fBVertTwoFingerScroll\fR (Bool)
272 Enable vertical scrolling when dragging with two fingers anywhere on
273 the touchpad.
274 @@ -166,7 +178,10 @@
275 Maximum speed factor.
277 \fBAccelFactor\fR (Float)
278 -Acceleration factor.
279 +Acceleration factor for normal pointer movements.
280 +.TP
281 +\fBTrackstickSpeed\fR (Float)
282 +Speed scale when in trackstick emulation mode.
284 \fBPressureMotionMinZ\fR (Integer)
285 Finger pressure at which minimum pressure motion factor is applied.
286 @@ -191,12 +206,12 @@
288 If off, the left/right buttons both generate button 2 events.
290 -\fBUpDownRepeat\fR (Bool)
291 +\fBUpDownScrollRepeat\fR (Bool)
292 If on, and the up/down buttons are used for scrolling
293 (\fBUpDownScrolling\fR), these buttons will send auto-repeating 4/5 events,
294 with the delay between repeats determined by \fBScrollButtonRepeat\fR.
296 -\fBLeftRightRepeat\fR (Bool)
297 +\fBLeftRightScrollRepeat\fR (Bool)
298 If on, and the left/right buttons are used for scrolling
299 (\fBLeftRightScrolling\fR), these buttons will send auto-repeating 6/7 events,
300 with the delay between repeats determined by \fBScrollButtonRepeat\fR.
301 @@ -208,6 +223,10 @@
302 \fBEmulateMidButtonTime\fR (Integer)
303 Maximum time (in milliseconds) for middle button emulation.
305 +\fBEmulateTwoFingerMinZ\fR (Integer)
306 +For touchpads not capable of detecting multiple fingers (Alps), this sets the
307 +Z pressure threshold to emulate a two finger press.
308 +.TP
309 \fBTouchpadOff\fR (Integer)
310 Switch off the touchpad.
312 @@ -225,7 +244,13 @@
313 \fBLockedDrags\fR (Bool)
314 If off, a tap and drag gesture ends when you release the finger.
316 -If on, the gesture is active until you tap a second time.
317 +If on, the gesture is active until you tap a second time, or until
318 +LockedDragTimeout expires.
319 +.TP
320 +\fBLockedDragTimeout\fR (Integer)
321 +This parameter specifies how long it takes (in milliseconds) for the
322 +LockedDrags mode to be automatically turned off after the finger is
323 +released from the touchpad.
325 \fBRTCornerButton\fR (Integer)
327 @@ -310,6 +335,26 @@
329 \fBSingleTapTimeout\fR (Integer)
330 Timeout after a tap to recognize it as a single tap.
331 +.TP
332 +\fBGrabEventDevice\fR (Bool)
333 +If GrabEventDevice is true, the driver will grab the event device for
334 +exclusive use when using the linux 2.6 event protocol.
336 +When using other protocols, this option has no effect.
338 +Grabbing the event device means that no other user space or kernel
339 +space program sees the touchpad events.
341 +This is desirable if the X config file includes /dev/input/mice as an
342 +input device, but is undesirable if you want to monitor the device
343 +from user space.
345 +When changing this parameter with the synclient program, the change
346 +will not take effect until the synaptics driver is disabled and
347 +reenabled.
349 +This can be achieved by switching to a text console and then switching
350 +back to X.
354 @@ -459,15 +504,15 @@
355 generates a middle mouse button event.
358 -Circular scrolling acts like a scrolling wheel on the trackpad.
359 +Circular scrolling acts like a scrolling wheel on the touchpad.
361 Scrolling is engaged when a drag starts in the given CircScrollTrigger
362 region, which can be all edges, a particular side, or a particular
363 corner.
365 Once scrolling is engaged, moving your finger in clockwise circles
366 -around the trackpad will generate scroll down events and counter
367 -clockwise scroll up events.
368 +around the center of the touchpad will generate scroll down events and
369 +counter clockwise motion will generate scroll up events.
371 Lifting your finger will disengage circular scrolling.
373 @@ -482,9 +527,15 @@
374 Coasting is enabled by setting the CoastingSpeed parameter to a
375 non-zero value.
377 -When coasting is enabled, horizontal/vertical scrolling can continue
378 -after the finger is released from the lower/right edge of the
379 -touchpad.
380 +Coasting comes in two flavors: conventional (finger off) coasting, and
381 +corner (finger on) coasting.
382 +.LP
383 +Conventional coasting is enabled when coasting is enabled,
384 +and CornerCoasting is set to false.
386 +When conventional coasting is enabled, horizontal/vertical scrolling
387 +can continue after the finger is released from the lower/right edge of
388 +the touchpad.
390 The driver computes the scrolling speed corresponding to the finger
391 speed immediately before the finger leaves the touchpad.
392 @@ -493,6 +544,41 @@
393 (measured in scroll events per second), the scrolling will continue
394 with the same speed in the same direction until the finger touches the
395 touchpad again.
397 +.LP
398 +Corner coasting is enabled when coasting is enabled, and
399 +CornerCoasting is set to true.
401 +When corner coasting is enabled, edge scrolling can continue as long
402 +as the finger stays in a corner.
404 +Coasting begins when the finger enters the corner, and continues until
405 +the finger leaves the corner.
407 +CornerCoasting takes precedence over the seamless switch from edge
408 +scrolling to circular scrolling. That is, if CornerCoasting is
409 +active, scrolling will stop, and circular scrolling will not start,
410 +when the finger leaves the corner.
412 +.LP
413 +Trackstick emulation mode is entered when pressing the finger hard on
414 +the touchpad.
416 +The FingerPress parameter controls the minimum required finger
417 +pressure.
419 +If the finger hasn't moved more than MaxTapMove after MaxTapTime has
420 +elapsed, trackstick mode is entered.
422 +In this mode, moving the finger slightly in any direction gives a
423 +speed vector that moves the pointer.
425 +The TrackstickSpeed parameter controls the ratio between pointer speed
426 +and finger movement distance.
428 +Trackstick mode is exited when the finger pressure drops below
429 +FingerLow or when the finger is moved further than MaxTapMove away
430 +from the initial position.
431 .SH "AUTHORS"
433 Peter Osterlund <petero2@telia.com> and many others.
434 diff -urN synaptics-0.14.6/ps2comm.c synaptics-git/ps2comm.c
435 --- synaptics-0.14.6/ps2comm.c 2006-04-17 00:20:10.000000000 +0200
436 +++ synaptics-git/ps2comm.c 2008-05-28 14:56:57.000000000 +0200
437 @@ -60,6 +60,10 @@
438 #define PS2DBG(x)
439 #endif
441 +#if GET_ABI_MAJOR(ABI_XINPUT_VERSION) >= 1
442 +#define DBG(a,b)
443 +#endif
445 /*****************************************************************************
446 * PS/2 Utility functions.
447 * Many parts adapted from tpconfig.c by C. Scott Ananian
448 @@ -429,7 +433,7 @@
451 static void
452 -PS2DeviceOnHook(LocalDevicePtr local)
453 +PS2DeviceOnHook(LocalDevicePtr local, SynapticsSHM* para)
457 diff -urN synaptics-0.14.6/psmcomm.c synaptics-git/psmcomm.c
458 --- synaptics-0.14.6/psmcomm.c 2006-07-09 18:53:02.000000000 +0200
459 +++ synaptics-git/psmcomm.c 2008-05-28 14:56:57.000000000 +0200
460 @@ -89,7 +89,7 @@
463 static void
464 -PSMDeviceOnHook(LocalDevicePtr local)
465 +PSMDeviceOnHook(LocalDevicePtr local, SynapticsSHM *para)
469 diff -urN synaptics-0.14.6/synaptics.c synaptics-git/synaptics.c
470 --- synaptics-0.14.6/synaptics.c 2006-07-15 17:54:29.000000000 +0200
471 +++ synaptics-git/synaptics.c 2008-05-28 14:56:57.000000000 +0200
472 @@ -1,4 +1,10 @@
474 + * Copyright 2007 Joseph P. Skudlarek <Jskud@Jskud.com>
475 + * patch for corner coasting (originally called corner edge scrolling)
477 + * Copyright 2006 Christian Thaeter <chth@gmx.net>
478 + * patch for Trackstick mode
480 * Copyright 2006 Stefan Bethge <stefan.bethge@web.de>
481 * patch for two-fingered scrolling
483 @@ -103,6 +109,8 @@
484 #define TIME_DIFF(a, b) ((int)((a)-(b)))
485 #define SYSCALL(call) while (((call) == -1) && (errno == EINTR))
487 +#define SQR(x) ((x) * (x))
489 #ifndef M_PI
490 #define M_PI 3.14159265358979323846
491 #endif
492 @@ -111,6 +119,10 @@
493 #define M_SQRT1_2 0.70710678118654752440 /* 1/sqrt(2) */
494 #endif
496 +#if GET_ABI_MAJOR(ABI_XINPUT_VERSION) >= 1
497 +#define DBG(a,b)
498 +#endif
500 /*****************************************************************************
501 * Forward declaration
502 ****************************************************************************/
503 @@ -321,8 +333,10 @@
504 local->private_flags = 0;
505 local->flags = XI86_POINTER_CAPABLE | XI86_SEND_DRAG_EVENTS;
506 local->conf_idev = dev;
507 +#if GET_ABI_MAJOR(ABI_XINPUT_VERSION) == 0
508 local->motion_history_proc = xf86GetMotionEvents;
509 local->history_size = 0;
510 +#endif
511 local->always_core_feedback = 0;
513 xf86Msg(X_INFO, "Synaptics touchpad driver version %s (%d)\n", VERSION, VERSION_ID);
514 @@ -359,12 +373,54 @@
515 /* read the parameters */
516 pars = &priv->synpara_default;
517 pars->version = VERSION_ID;
518 - pars->left_edge = xf86SetIntOption(opts, "LeftEdge", 1900);
519 - pars->right_edge = xf86SetIntOption(opts, "RightEdge", 5400);
520 - pars->top_edge = xf86SetIntOption(opts, "TopEdge", 1900);
521 - pars->bottom_edge = xf86SetIntOption(opts, "BottomEdge", 4000);
523 + if (priv->maxx && priv->maxy) {
524 + int xsize = priv->maxx - priv->minx;
525 + int ysize = priv->maxy - priv->miny;
526 + int xedgesize = xsize * 0.1;
527 + int yedgesize = ysize * 0.1;
529 + pars->left_edge = xf86SetIntOption(opts, "LeftEdge", priv->minx +
530 + xedgesize);
531 + pars->right_edge = xf86SetIntOption(opts, "RightEdge", priv->maxx -
532 + xedgesize);
533 + pars->top_edge = xf86SetIntOption(opts, "TopEdge", priv->miny +
534 + yedgesize);
535 + pars->bottom_edge = xf86SetIntOption(opts, "BottomEdge",
536 + priv->maxy - yedgesize);
537 + pars->scroll_dist_vert = xf86SetIntOption(opts, "VertScrollDelta",
538 + 0.02*ysize);
539 + pars->scroll_dist_horiz = xf86SetIntOption(opts,
540 + "HorizScrollDelta",
541 + 0.02*xsize);
542 + pars->edge_motion_min_speed = xf86SetIntOption(opts,
543 + "EdgeMotionMinSpeed", 1);
544 + pars->edge_motion_max_speed = xf86SetIntOption(opts,
545 + "EdgeMotionMaxSpeed", ysize * 0.1);
546 + pars->min_speed = synSetFloatOption(opts, "MinSpeed", 250.0 / ysize);
547 + pars->max_speed = synSetFloatOption(opts, "MaxSpeed", 600.0 / ysize);
548 + pars->accl = synSetFloatOption(opts, "AccelFactor", 5.0 / ysize);
549 + } else {
550 + pars->left_edge = xf86SetIntOption(opts, "LeftEdge", 1900);
551 + pars->right_edge = xf86SetIntOption(opts, "RightEdge", 5400);
552 + pars->top_edge = xf86SetIntOption(opts, "TopEdge", 1900);
553 + pars->bottom_edge = xf86SetIntOption(opts, "BottomEdge", 4000);
554 + pars->scroll_dist_vert = xf86SetIntOption(opts, "VertScrollDelta",
555 + 100);
556 + pars->scroll_dist_horiz = xf86SetIntOption(opts,
557 + "HorizScrollDelta",
558 + 100);
559 + pars->edge_motion_min_speed = xf86SetIntOption(opts,
560 + "EdgeMotionMinSpeed", 1);
561 + pars->edge_motion_max_speed = xf86SetIntOption(opts,
562 + "EdgeMotionMaxSpeed", 400);
563 + pars->min_speed = synSetFloatOption(opts, "MinSpeed", 0.09);
564 + pars->max_speed = synSetFloatOption(opts, "MaxSpeed", 0.18);
565 + pars->accl = synSetFloatOption(opts, "AccelFactor", 0.0015);
567 pars->finger_low = xf86SetIntOption(opts, "FingerLow", 25);
568 pars->finger_high = xf86SetIntOption(opts, "FingerHigh", 30);
569 + pars->finger_press = xf86SetIntOption(opts, "FingerPress", 256);
570 pars->tap_time = xf86SetIntOption(opts, "MaxTapTime", 180);
571 pars->tap_move = xf86SetIntOption(opts, "MaxTapMove", 220);
572 pars->tap_time_2 = xf86SetIntOption(opts, "MaxDoubleTapTime", 180);
573 @@ -372,16 +428,14 @@
574 pars->fast_taps = xf86SetIntOption(opts, "FastTaps", FALSE);
575 pars->emulate_mid_button_time = xf86SetIntOption(opts,
576 "EmulateMidButtonTime", 75);
577 - pars->scroll_dist_vert = xf86SetIntOption(opts, "VertScrollDelta", 100);
578 - pars->scroll_dist_horiz = xf86SetIntOption(opts, "HorizScrollDelta", 100);
579 + pars->emulate_twofinger_z = xf86SetIntOption(opts, "EmulateTwoFingerMinZ", 257);
580 pars->scroll_edge_vert = xf86SetBoolOption(opts, "VertEdgeScroll", TRUE);
581 pars->scroll_edge_horiz = xf86SetBoolOption(opts, "HorizEdgeScroll", TRUE);
582 + pars->scroll_edge_corner = xf86SetBoolOption(opts, "CornerCoasting", FALSE);
583 pars->scroll_twofinger_vert = xf86SetBoolOption(opts, "VertTwoFingerScroll", FALSE);
584 pars->scroll_twofinger_horiz = xf86SetBoolOption(opts, "HorizTwoFingerScroll", FALSE);
585 pars->edge_motion_min_z = xf86SetIntOption(opts, "EdgeMotionMinZ", 30);
586 pars->edge_motion_max_z = xf86SetIntOption(opts, "EdgeMotionMaxZ", 160);
587 - pars->edge_motion_min_speed = xf86SetIntOption(opts, "EdgeMotionMinSpeed", 1);
588 - pars->edge_motion_max_speed = xf86SetIntOption(opts, "EdgeMotionMaxSpeed", 400);
589 pars->edge_motion_use_always = xf86SetBoolOption(opts, "EdgeMotionUseAlways", FALSE);
590 repeater = xf86SetStrOption(opts, "Repeater", NULL);
591 pars->updown_button_scrolling = xf86SetBoolOption(opts, "UpDownScrolling", TRUE);
592 @@ -392,6 +446,7 @@
593 pars->touchpad_off = xf86SetIntOption(opts, "TouchpadOff", 0);
594 pars->guestmouse_off = xf86SetBoolOption(opts, "GuestMouseOff", FALSE);
595 pars->locked_drags = xf86SetBoolOption(opts, "LockedDrags", FALSE);
596 + pars->locked_drag_time = xf86SetIntOption(opts, "LockedDragTimeout", 5000);
597 pars->tap_action[RT_TAP] = xf86SetIntOption(opts, "RTCornerButton", 2);
598 pars->tap_action[RB_TAP] = xf86SetIntOption(opts, "RBCornerButton", 3);
599 pars->tap_action[LT_TAP] = xf86SetIntOption(opts, "LTCornerButton", 0);
600 @@ -409,13 +464,12 @@
601 pars->press_motion_min_z = xf86SetIntOption(opts, "PressureMotionMinZ", pars->edge_motion_min_z);
602 pars->press_motion_max_z = xf86SetIntOption(opts, "PressureMotionMaxZ", pars->edge_motion_max_z);
604 - pars->min_speed = synSetFloatOption(opts, "MinSpeed", 0.09);
605 - pars->max_speed = synSetFloatOption(opts, "MaxSpeed", 0.18);
606 - pars->accl = synSetFloatOption(opts, "AccelFactor", 0.0015);
607 + pars->trackstick_speed = synSetFloatOption(opts, "TrackstickSpeed", 40);
608 pars->scroll_dist_circ = synSetFloatOption(opts, "CircScrollDelta", 0.1);
609 pars->coasting_speed = synSetFloatOption(opts, "CoastingSpeed", 0.0);
610 pars->press_motion_min_factor = synSetFloatOption(opts, "PressureMotionMinFactor", 1.0);
611 pars->press_motion_max_factor = synSetFloatOption(opts, "PressureMotionMaxFactor", 1.0);
612 + pars->grab_event_device = xf86SetBoolOption(opts, "GrabEventDevice", TRUE);
614 /* Warn about (and fix) incorrectly configured TopEdge/BottomEdge parameters */
615 if (pars->top_edge > pars->bottom_edge) {
616 @@ -455,8 +509,6 @@
617 goto SetupProc_fail;
620 - local->history_size = xf86SetIntOption(opts, "HistorySize", 0);
622 xf86ProcessCommonOptions(local, opts);
623 local->flags |= XI86_CONFIGURED;
625 @@ -543,7 +595,7 @@
626 return !Success;
629 - priv->proto_ops->DeviceOnHook(local);
630 + priv->proto_ops->DeviceOnHook(local, priv->synpara);
632 priv->comm.buffer = XisbNew(local->fd, 64);
633 if (!priv->comm.buffer) {
634 @@ -613,17 +665,25 @@
636 InitPointerDeviceStruct((DevicePtr)dev, map,
637 SYN_MAX_BUTTONS,
638 - miPointerGetMotionEvents, SynapticsCtrl,
639 - miPointerGetMotionBufferSize());
641 +#if GET_ABI_MAJOR(ABI_XINPUT_VERSION) == 0
642 + miPointerGetMotionEvents,
643 + SynapticsCtrl,
644 + miPointerGetMotionBufferSize()
645 +#else
646 + GetMotionHistory,
647 + SynapticsCtrl,
648 + GetMotionHistorySize(), 2
649 +#endif
650 + );
651 /* X valuator */
652 xf86InitValuatorAxisStruct(dev, 0, 0, -1, 1, 0, 1);
653 xf86InitValuatorDefaults(dev, 0);
654 /* Y valuator */
655 xf86InitValuatorAxisStruct(dev, 1, 0, -1, 1, 0, 1);
656 xf86InitValuatorDefaults(dev, 1);
658 +#if GET_ABI_MAJOR(ABI_XINPUT_VERSION) == 0
659 xf86MotionHistoryAllocate(local);
660 +#endif
662 if (!alloc_param_data(local))
663 return !Success;
664 @@ -634,7 +694,7 @@
665 static int
666 move_distance(int dx, int dy)
668 - return xf86sqrt((dx * dx) + (dy * dy));
669 + return xf86sqrt(SQR(dx) + SQR(dy));
673 @@ -691,7 +751,7 @@
674 double relX, relY, relR;
676 relative_coords(priv, x, y, &relX, &relY);
677 - relR = relX * relX + relY * relY;
678 + relR = SQR(relX) + SQR(relY);
680 if (relR > 1) {
681 /* we are outside the ellipse enclosed by the edge parameters */
682 @@ -895,8 +955,10 @@
683 int finger;
685 /* finger detection thru pressure and threshold */
686 - finger = (((hw->z > para->finger_high) && !priv->finger_flag) ||
687 - ((hw->z > para->finger_low) && priv->finger_flag));
688 + finger = ((hw->z > para->finger_press) && priv->finger_state < FS_PRESSED) ? FS_PRESSED
689 + : ((hw->z > para->finger_high) && priv->finger_state < FS_TOUCHED) ? FS_TOUCHED
690 + : ((hw->z < para->finger_low) && priv->finger_state > FS_UNTOUCHED) ? FS_UNTOUCHED
691 + : priv->finger_state;
693 if (!para->palm_detect)
694 return finger;
695 @@ -912,7 +974,7 @@
696 priv->avg_width = 0;
697 else
698 priv->avg_width += (hw->fingerWidth - priv->avg_width + 1) / 2;
699 - if (finger && !priv->finger_flag) {
700 + if (finger && !priv->finger_state) {
701 int safe_width = MAX(hw->fingerWidth, priv->avg_width);
702 if (hw->numFingers > 1)
703 finger = TRUE; /* more than one finger -> not a palm */
704 @@ -1025,6 +1087,19 @@
705 priv->tap_state = tap_state;
708 +static void
709 +SetMovingState(SynapticsPrivate *priv, enum MovingState moving_state, int millis)
711 + DBG(7, ErrorF("SetMovingState - %d -> %d center at %d/%d (millis:%d)\n", priv->moving_state,
712 + moving_state,priv->hwState.x, priv->hwState.y, millis));
714 + if (moving_state == MS_TRACKSTICK) {
715 + priv->trackstick_neutral_x = priv->hwState.x;
716 + priv->trackstick_neutral_y = priv->hwState.y;
718 + priv->moving_state = moving_state;
721 static int
722 GetTimeOut(SynapticsPrivate *priv)
724 @@ -1041,6 +1116,8 @@
725 return para->single_tap_timeout;
726 case TS_2B:
727 return para->tap_time_2;
728 + case TS_4:
729 + return para->locked_drag_time;
730 default:
731 return -1; /* No timeout */
733 @@ -1048,7 +1125,7 @@
735 static int
736 HandleTapProcessing(SynapticsPrivate *priv, struct SynapticsHwState *hw,
737 - edge_type edge, Bool finger)
738 + edge_type edge, enum FingerState finger)
740 SynapticsSHM *para = priv->synpara;
741 Bool touch, release, is_timeout, move;
742 @@ -1058,18 +1135,18 @@
743 if (priv->palm)
744 return delay;
746 - touch = finger && !priv->finger_flag;
747 - release = !finger && priv->finger_flag;
748 - move = FALSE;
749 + touch = finger && !priv->finger_state;
750 + release = !finger && priv->finger_state;
751 + move = ((priv->tap_max_fingers <= 1) &&
752 + ((abs(hw->x - priv->touch_on.x) >= para->tap_move) ||
753 + (abs(hw->y - priv->touch_on.y) >= para->tap_move)));
755 if (touch) {
756 priv->touch_on.x = hw->x;
757 priv->touch_on.y = hw->y;
758 priv->touch_on.millis = hw->millis;
759 } else if (release) {
760 priv->touch_on.millis = hw->millis;
761 - move = ((priv->tap_max_fingers <= 1) &&
762 - ((abs(hw->x - priv->touch_on.x) >= para->tap_move) ||
763 - (abs(hw->y - priv->touch_on.y) >= para->tap_move)));
765 if (hw->z > para->finger_high)
766 if (priv->tap_max_fingers < hw->numFingers)
767 @@ -1085,7 +1162,16 @@
768 SetTapState(priv, TS_1, hw->millis);
769 break;
770 case TS_1:
771 - if (is_timeout || move) {
772 + if (move) {
773 + SetMovingState(priv, MS_TOUCHPAD_RELATIVE, hw->millis);
774 + SetTapState(priv, TS_MOVE, hw->millis);
775 + goto restart;
776 + } else if (is_timeout) {
777 + if (finger == FS_TOUCHED) {
778 + SetMovingState(priv, MS_TOUCHPAD_RELATIVE, hw->millis);
779 + } else if (finger == FS_PRESSED) {
780 + SetMovingState(priv, MS_TRACKSTICK, hw->millis);
782 SetTapState(priv, TS_MOVE, hw->millis);
783 goto restart;
784 } else if (release) {
785 @@ -1094,8 +1180,13 @@
787 break;
788 case TS_MOVE:
789 - if (release)
790 + if (move && priv->moving_state == MS_TRACKSTICK) {
791 + SetMovingState(priv, MS_TOUCHPAD_RELATIVE, hw->millis);
793 + if (release) {
794 + SetMovingState(priv, MS_FALSE, hw->millis);
795 SetTapState(priv, TS_START, hw->millis);
797 break;
798 case TS_2A:
799 if (touch)
800 @@ -1118,21 +1209,39 @@
801 SetTapState(priv, TS_START, hw->millis);
802 break;
803 case TS_3:
804 - if (is_timeout || move) {
805 + if (move) {
806 + SetMovingState(priv, MS_TOUCHPAD_RELATIVE, hw->millis);
807 + SetTapState(priv, TS_DRAG, hw->millis);
808 + goto restart;
809 + } else if (is_timeout) {
810 + if (finger == FS_TOUCHED) {
811 + SetMovingState(priv, MS_TOUCHPAD_RELATIVE, hw->millis);
812 + } else if (finger == FS_PRESSED) {
813 + SetMovingState(priv, MS_TRACKSTICK, hw->millis);
815 SetTapState(priv, TS_DRAG, hw->millis);
816 goto restart;
817 - } else if (release)
818 + } else if (release) {
819 SetTapState(priv, TS_2B, hw->millis);
821 break;
822 case TS_DRAG:
823 + if (move)
824 + SetMovingState(priv, MS_TOUCHPAD_RELATIVE, hw->millis);
825 if (release) {
826 - if (para->locked_drags)
827 + SetMovingState(priv, MS_FALSE, hw->millis);
828 + if (para->locked_drags) {
829 SetTapState(priv, TS_4, hw->millis);
830 - else
831 + } else {
832 SetTapState(priv, TS_START, hw->millis);
835 break;
836 case TS_4:
837 + if (is_timeout) {
838 + SetTapState(priv, TS_START, hw->millis);
839 + goto restart;
841 if (touch)
842 SetTapState(priv, TS_5, hw->millis);
843 break;
844 @@ -1140,8 +1249,10 @@
845 if (is_timeout || move) {
846 SetTapState(priv, TS_DRAG, hw->millis);
847 goto restart;
848 - } else if (release)
849 + } else if (release) {
850 + SetMovingState(priv, MS_FALSE, hw->millis);
851 SetTapState(priv, TS_START, hw->millis);
853 break;
856 @@ -1181,7 +1292,7 @@
857 edge_type edge, int *dxP, int *dyP)
859 SynapticsSHM *para = priv->synpara;
860 - Bool moving_state;
861 + enum MovingState moving_state;
862 int dist;
863 double dx, dy;
864 double speed, integral;
865 @@ -1189,20 +1300,22 @@
867 dx = dy = 0;
869 - moving_state = FALSE;
870 - switch (priv->tap_state) {
871 - case TS_MOVE:
872 - case TS_DRAG:
873 - moving_state = TRUE;
874 - break;
875 - case TS_1:
876 - case TS_3:
877 - case TS_5:
878 - if (hw->numFingers == 1)
879 - moving_state = TRUE;
880 - break;
881 - default:
882 - break;
883 + moving_state = priv->moving_state;
884 + if (moving_state == MS_FALSE) {
885 + switch (priv->tap_state) {
886 + case TS_MOVE:
887 + case TS_DRAG:
888 + moving_state = MS_TOUCHPAD_RELATIVE;
889 + break;
890 + case TS_1:
891 + case TS_3:
892 + case TS_5:
893 + if (hw->numFingers == 1)
894 + moving_state = MS_TOUCHPAD_RELATIVE;
895 + break;
896 + default:
897 + break;
900 if (moving_state && !priv->palm &&
901 !priv->vert_scroll_edge_on && !priv->horiz_scroll_edge_on &&
902 @@ -1214,42 +1327,51 @@
903 int x_edge_speed = 0;
904 int y_edge_speed = 0;
905 double dtime = (hw->millis - HIST(0).millis) / 1000.0;
906 - dx = estimate_delta(hw->x, HIST(0).x, HIST(1).x, HIST(2).x);
907 - dy = estimate_delta(hw->y, HIST(0).y, HIST(1).y, HIST(2).y);
909 - if ((priv->tap_state == TS_DRAG) || para->edge_motion_use_always) {
910 - int minZ = para->edge_motion_min_z;
911 - int maxZ = para->edge_motion_max_z;
912 - int minSpd = para->edge_motion_min_speed;
913 - int maxSpd = para->edge_motion_max_speed;
914 - int edge_speed;
916 - if (hw->z <= minZ) {
917 - edge_speed = minSpd;
918 - } else if (hw->z >= maxZ) {
919 - edge_speed = maxSpd;
920 - } else {
921 - edge_speed = minSpd + (hw->z - minZ) * (maxSpd - minSpd) / (maxZ - minZ);
923 - if (!priv->synpara->circular_pad) {
924 - /* on rectangular pad */
925 - if (edge & RIGHT_EDGE) {
926 - x_edge_speed = edge_speed;
927 - } else if (edge & LEFT_EDGE) {
928 - x_edge_speed = -edge_speed;
929 + if (priv->moving_state == MS_TRACKSTICK) {
930 + dx = (hw->x - priv->trackstick_neutral_x);
931 + dy = (hw->y - priv->trackstick_neutral_y);
933 + dx = dx * dtime * para->trackstick_speed;
934 + dy = dy * dtime * para->trackstick_speed;
935 + } else if (moving_state == MS_TOUCHPAD_RELATIVE) {
936 + dx = estimate_delta(hw->x, HIST(0).x, HIST(1).x, HIST(2).x);
937 + dy = estimate_delta(hw->y, HIST(0).y, HIST(1).y, HIST(2).y);
939 + if ((priv->tap_state == TS_DRAG) || para->edge_motion_use_always) {
940 + int minZ = para->edge_motion_min_z;
941 + int maxZ = para->edge_motion_max_z;
942 + int minSpd = para->edge_motion_min_speed;
943 + int maxSpd = para->edge_motion_max_speed;
944 + int edge_speed;
946 + if (hw->z <= minZ) {
947 + edge_speed = minSpd;
948 + } else if (hw->z >= maxZ) {
949 + edge_speed = maxSpd;
950 + } else {
951 + edge_speed = minSpd + (hw->z - minZ) * (maxSpd - minSpd) / (maxZ - minZ);
953 - if (edge & TOP_EDGE) {
954 - y_edge_speed = -edge_speed;
955 - } else if (edge & BOTTOM_EDGE) {
956 - y_edge_speed = edge_speed;
957 + if (!priv->synpara->circular_pad) {
958 + /* on rectangular pad */
959 + if (edge & RIGHT_EDGE) {
960 + x_edge_speed = edge_speed;
961 + } else if (edge & LEFT_EDGE) {
962 + x_edge_speed = -edge_speed;
964 + if (edge & TOP_EDGE) {
965 + y_edge_speed = -edge_speed;
966 + } else if (edge & BOTTOM_EDGE) {
967 + y_edge_speed = edge_speed;
969 + } else if (edge) {
970 + /* at edge of circular pad */
971 + double relX, relY;
973 + relative_coords(priv, hw->x, hw->y, &relX, &relY);
974 + x_edge_speed = (int)(edge_speed * relX);
975 + y_edge_speed = (int)(edge_speed * relY);
977 - } else if (edge) {
978 - /* at edge of circular pad */
979 - double relX, relY;
981 - relative_coords(priv, hw->x, hw->y, &relX, &relY);
982 - x_edge_speed = (int)(edge_speed * relX);
983 - y_edge_speed = (int)(edge_speed * relY);
987 @@ -1263,7 +1385,7 @@
990 /* modify speed according to pressure */
992 + if (priv->moving_state == MS_TOUCHPAD_RELATIVE) {
993 int minZ = para->press_motion_min_z;
994 int maxZ = para->press_motion_max_z;
995 double minFctr = para->press_motion_min_factor;
996 @@ -1347,6 +1469,14 @@
997 priv->scroll_packet_count = 0;
1000 +static void
1001 +stop_coasting(SynapticsPrivate *priv)
1003 + priv->autoscroll_xspd = 0;
1004 + priv->autoscroll_yspd = 0;
1005 + priv->scroll_packet_count = 0;
1008 static int
1009 HandleScrolling(SynapticsPrivate *priv, struct SynapticsHwState *hw,
1010 edge_type edge, Bool finger, struct ScrollData *sd)
1011 @@ -1357,8 +1487,7 @@
1012 sd->left = sd->right = sd->up = sd->down = 0;
1014 if (priv->synpara->touchpad_off == 2) {
1015 - priv->autoscroll_xspd = 0;
1016 - priv->autoscroll_yspd = 0;
1017 + stop_coasting(priv);
1018 priv->circ_scroll_on = FALSE;
1019 priv->vert_scroll_edge_on = FALSE;
1020 priv->horiz_scroll_edge_on = FALSE;
1021 @@ -1368,10 +1497,8 @@
1024 /* scroll detection */
1025 - if (finger && !priv->finger_flag) {
1026 - priv->autoscroll_xspd = 0;
1027 - priv->autoscroll_yspd = 0;
1028 - priv->scroll_packet_count = 0;
1029 + if (finger && !priv->finger_state) {
1030 + stop_coasting(priv);
1031 if (para->circular_scrolling) {
1032 if ((para->circular_trigger == 0 && edge) ||
1033 (para->circular_trigger == 1 && edge & TOP_EDGE) ||
1034 @@ -1388,19 +1515,27 @@
1035 DBG(7, ErrorF("circular scroll detected on edge\n"));
1038 - if (!priv->circ_scroll_on) {
1040 + if (!priv->circ_scroll_on) {
1041 + if (finger) {
1042 if (hw->numFingers == 2) {
1043 - if ((para->scroll_twofinger_vert) && (para->scroll_dist_vert != 0)) {
1044 + if (!priv->vert_scroll_twofinger_on &&
1045 + (para->scroll_twofinger_vert) && (para->scroll_dist_vert != 0)) {
1046 priv->vert_scroll_twofinger_on = TRUE;
1047 + priv->vert_scroll_edge_on = FALSE;
1048 priv->scroll_y = hw->y;
1049 DBG(7, ErrorF("vert two-finger scroll detected\n"));
1051 - if ((para->scroll_twofinger_horiz) && (para->scroll_dist_horiz != 0)) {
1052 + if (!priv->horiz_scroll_twofinger_on &&
1053 + (para->scroll_twofinger_horiz) && (para->scroll_dist_horiz != 0)) {
1054 priv->horiz_scroll_twofinger_on = TRUE;
1055 + priv->horiz_scroll_edge_on = FALSE;
1056 priv->scroll_x = hw->x;
1057 DBG(7, ErrorF("horiz two-finger scroll detected\n"));
1061 + if (finger && !priv->finger_state) {
1062 if (!priv->vert_scroll_twofinger_on && !priv->horiz_scroll_twofinger_on) {
1063 if ((para->scroll_edge_vert) && (para->scroll_dist_vert != 0) &&
1064 (edge & RIGHT_EDGE)) {
1065 @@ -1445,18 +1580,40 @@
1066 DBG(7, ErrorF("horiz edge scroll off\n"));
1067 priv->horiz_scroll_edge_on = FALSE;
1069 - if ((oldv || oldh) &&
1070 + /* If we were corner edge scrolling (coasting),
1071 + * but no longer in corner or raised a finger, then stop coasting. */
1072 + if (para->scroll_edge_corner && (priv->autoscroll_xspd || priv->autoscroll_yspd)) {
1073 + Bool is_in_corner =
1074 + ((edge & RIGHT_EDGE) && (edge & (TOP_EDGE | BOTTOM_EDGE))) ||
1075 + ((edge & BOTTOM_EDGE) && (edge & (LEFT_EDGE | RIGHT_EDGE))) ;
1076 + if (!is_in_corner || !finger) {
1077 + DBG(7, ErrorF("corner edge scroll off\n"));
1078 + stop_coasting(priv);
1081 + /* if we were scrolling, but couldn't corner edge scroll,
1082 + * and are no longer scrolling, then start coasting */
1083 + if ((oldv || oldh) && !para->scroll_edge_corner &&
1084 !(priv->circ_scroll_on || priv->vert_scroll_edge_on ||
1085 priv->horiz_scroll_edge_on)) {
1086 start_coasting(priv, hw, edge, oldv);
1090 - /* if hitting a corner (top right or bottom right) while vertical scrolling
1091 - is active, switch over to circular scrolling smoothly */
1092 + /* if hitting a corner (top right or bottom right) while vertical
1093 + * scrolling is active, consider starting corner edge scrolling or
1094 + * switching over to circular scrolling smoothly */
1095 if (priv->vert_scroll_edge_on && !priv->horiz_scroll_edge_on &&
1096 - para->circular_scrolling) {
1097 - if ((edge & RIGHT_EDGE) && (edge & (TOP_EDGE | BOTTOM_EDGE))) {
1098 + (edge & RIGHT_EDGE) && (edge & (TOP_EDGE | BOTTOM_EDGE))) {
1099 + if (para->scroll_edge_corner) {
1100 + if (priv->autoscroll_yspd == 0) {
1101 + /* FYI: We can generate multiple start_coasting requests if
1102 + * we're in the corner, but we were moving so slowly when we
1103 + * got here that we didn't actually start coasting. */
1104 + DBG(7, ErrorF("corner edge scroll on\n"));
1105 + start_coasting(priv, hw, edge, TRUE);
1107 + } else if (para->circular_scrolling) {
1108 priv->vert_scroll_edge_on = FALSE;
1109 priv->circ_scroll_on = TRUE;
1110 priv->circ_scroll_vert = TRUE;
1111 @@ -1466,8 +1623,16 @@
1113 /* Same treatment for horizontal scrolling */
1114 if (priv->horiz_scroll_edge_on && !priv->vert_scroll_edge_on &&
1115 - para->circular_scrolling) {
1116 - if ((edge & BOTTOM_EDGE) && (edge & (LEFT_EDGE | RIGHT_EDGE))) {
1117 + (edge & BOTTOM_EDGE) && (edge & (LEFT_EDGE | RIGHT_EDGE))) {
1118 + if (para->scroll_edge_corner) {
1119 + if (priv->autoscroll_xspd == 0) {
1120 + /* FYI: We can generate multiple start_coasting requests if
1121 + * we're in the corner, but we were moving so slowly when we
1122 + * got here that we didn't actually start coasting. */
1123 + DBG(7, ErrorF("corner edge scroll on\n"));
1124 + start_coasting(priv, hw, edge, FALSE);
1126 + } else if (para->circular_scrolling) {
1127 priv->horiz_scroll_edge_on = FALSE;
1128 priv->circ_scroll_on = TRUE;
1129 priv->circ_scroll_vert = FALSE;
1130 @@ -1576,7 +1741,7 @@
1132 SynapticsPrivate *priv = (SynapticsPrivate *) (local->private);
1133 SynapticsSHM *para = priv->synpara;
1134 - Bool finger;
1135 + int finger;
1136 int dx, dy, buttons, rep_buttons, id;
1137 edge_type edge;
1138 int change;
1139 @@ -1622,6 +1787,11 @@
1140 /* 3rd button emulation */
1141 hw->middle |= HandleMidButtonEmulation(priv, hw, &delay);
1143 + /* Two finger emulation */
1144 + if (hw->z >= para->emulate_twofinger_z && hw->numFingers == 1) {
1145 + hw->numFingers = 2;
1148 /* Up/Down button scrolling or middle/double click */
1149 double_click = FALSE;
1150 if (!para->updown_button_scrolling) {
1151 @@ -1770,7 +1940,7 @@
1154 /* Save old values of some state variables */
1155 - priv->finger_flag = finger;
1156 + priv->finger_state = finger;
1157 priv->lastButtons = buttons;
1159 return delay;
1160 diff -urN synaptics-0.14.6/synaptics.h synaptics-git/synaptics.h
1161 --- synaptics-0.14.6/synaptics.h 2006-07-15 17:54:29.000000000 +0200
1162 +++ synaptics-git/synaptics.h 2008-05-28 14:56:57.000000000 +0200
1163 @@ -50,7 +50,7 @@
1165 /* Parameter data */
1166 int left_edge, right_edge, top_edge, bottom_edge; /* edge coordinates absolute */
1167 - int finger_low, finger_high; /* finger detection values in Z-values */
1168 + int finger_low, finger_high, finger_press; /* finger detection values in Z-values */
1169 int tap_time;
1170 int tap_move; /* max. tapping time and movement in packets and coord. */
1171 int single_tap_timeout; /* timeout to recognize a single tap */
1172 @@ -59,13 +59,16 @@
1173 Bool fast_taps; /* Faster reaction to single taps */
1174 int emulate_mid_button_time; /* Max time between left and right button presses to
1175 emulate a middle button press. */
1176 + int emulate_twofinger_z; /* pressure threshold to emulate two finger touch (for Alps) */
1177 int scroll_dist_vert; /* Scrolling distance in absolute coordinates */
1178 int scroll_dist_horiz; /* Scrolling distance in absolute coordinates */
1179 Bool scroll_edge_vert; /* Enable/disable vertical scrolling on right edge */
1180 Bool scroll_edge_horiz; /* Enable/disable horizontal scrolling on left edge */
1181 + Bool scroll_edge_corner; /* Enable/disable continuous edge scrolling when in the corner */
1182 Bool scroll_twofinger_vert; /* Enable/disable vertical two-finger scrolling */
1183 Bool scroll_twofinger_horiz; /* Enable/disable horizontal two-finger scrolling */
1184 double min_speed, max_speed, accl; /* movement parameters */
1185 + double trackstick_speed; /* trackstick mode speed */
1186 int edge_motion_min_z; /* finger pressure at which minimum edge motion speed is set */
1187 int edge_motion_max_z; /* finger pressure at which maximum edge motion speed is set */
1188 int edge_motion_min_speed; /* slowest setting for edge motion speed */
1189 @@ -85,6 +88,7 @@
1191 Bool guestmouse_off; /* Switches the guest mouse off */
1192 Bool locked_drags; /* Enable locked drags */
1193 + int locked_drag_time; /* timeout for locked drags */
1194 int tap_action[MAX_TAP]; /* Button to report on tap events */
1195 Bool circular_scrolling; /* Enable circular scrolling */
1196 double scroll_dist_circ; /* Scrolling angle radians */
1197 @@ -98,6 +102,7 @@
1198 int press_motion_max_z; /* finger pressure at which maximum pressure motion factor is applied */
1199 double press_motion_min_factor; /* factor applied on speed when finger pressure is at minimum */
1200 double press_motion_max_factor; /* factor applied on speed when finger pressure is at minimum */
1201 + Bool grab_event_device; /* grab event device for exclusive use? */
1202 } SynapticsSHM;
1205 @@ -135,6 +140,18 @@
1206 int millis;
1207 } SynapticsMoveHistRec;
1209 +enum FingerState { /* Note! The order matters. Compared with < operator. */
1210 + FS_UNTOUCHED,
1211 + FS_TOUCHED,
1212 + FS_PRESSED
1215 +enum MovingState {
1216 + MS_FALSE,
1217 + MS_TOUCHPAD_RELATIVE,
1218 + MS_TRACKSTICK /* trackstick is always relative */
1221 enum MidButtonEmulation {
1222 MBE_OFF, /* No button pressed */
1223 MBE_LEFT, /* Left button pressed, waiting for right button or timeout */
1224 @@ -191,7 +208,7 @@
1225 int count_packet_finger; /* packet counter with finger on the touchpad */
1226 int button_delay_millis; /* button delay for 3rd button emulation */
1227 Bool prev_up; /* Previous up button value, for double click emulation */
1228 - Bool finger_flag; /* previous finger */
1229 + enum FingerState finger_state; /* previous finger state */
1231 enum TapState tap_state; /* State of tap processing */
1232 int tap_max_fingers; /* Max number of fingers seen since entering start state */
1233 @@ -199,6 +216,7 @@
1234 enum TapButtonState tap_button_state; /* Current tap action */
1235 SynapticsMoveHistRec touch_on; /* data when the touchpad is touched/released */
1237 + enum MovingState moving_state; /* previous moving state */
1238 Bool vert_scroll_edge_on; /* Keeps track of currently active scroll modes */
1239 Bool horiz_scroll_edge_on; /* Keeps track of currently active scroll modes */
1240 Bool vert_scroll_twofinger_on; /* Keeps track of currently active scroll modes */
1241 @@ -206,6 +224,8 @@
1242 Bool circ_scroll_on; /* Keeps track of currently active scroll modes */
1243 Bool circ_scroll_vert; /* True: Generate vertical scroll events
1244 False: Generate horizontal events */
1245 + int trackstick_neutral_x; /* neutral x position for trackstick mode */
1246 + int trackstick_neutral_y; /* neutral y position for trackstick mode */
1247 double autoscroll_xspd; /* Horizontal coasting speed */
1248 double autoscroll_yspd; /* Vertical coasting speed */
1249 double autoscroll_x; /* Accumulated horizontal coasting scroll */
1250 @@ -220,7 +240,10 @@
1251 palm/finger contact disappears */
1252 int prev_z; /* previous z value, for palm detection */
1253 int avg_width; /* weighted average of previous fingerWidth values */
1255 + int minx;
1256 + int maxx;
1257 + int miny;
1258 + int maxy;
1259 } SynapticsPrivate;
1262 diff -urN synaptics-0.14.6/synclient.c synaptics-git/synclient.c
1263 --- synaptics-0.14.6/synclient.c 2006-07-15 17:54:29.000000000 +0200
1264 +++ synaptics-git/synclient.c 2008-05-28 14:56:57.000000000 +0200
1265 @@ -1,5 +1,5 @@
1267 - * Copyright 2002-2004 Peter Osterlund <petero2@telia.com>
1268 + * Copyright 2002-2005,2007 Peter Osterlund <petero2@telia.com>
1270 * This program is free software; you can redistribute it and/or
1271 * modify it under the terms of the GNU General Public License
1272 @@ -55,6 +55,7 @@
1273 DEFINE_PAR("BottomEdge", bottom_edge, PT_INT, 0, 10000),
1274 DEFINE_PAR("FingerLow", finger_low, PT_INT, 0, 255),
1275 DEFINE_PAR("FingerHigh", finger_high, PT_INT, 0, 255),
1276 + DEFINE_PAR("FingerPress", finger_press, PT_INT, 0, 256),
1277 DEFINE_PAR("MaxTapTime", tap_time, PT_INT, 0, 1000),
1278 DEFINE_PAR("MaxTapMove", tap_move, PT_INT, 0, 2000),
1279 DEFINE_PAR("MaxDoubleTapTime", tap_time_2, PT_INT, 0, 1000),
1280 @@ -62,15 +63,18 @@
1281 DEFINE_PAR("ClickTime", click_time, PT_INT, 0, 1000),
1282 DEFINE_PAR("FastTaps", fast_taps, PT_BOOL, 0, 1),
1283 DEFINE_PAR("EmulateMidButtonTime", emulate_mid_button_time, PT_INT, 0, 1000),
1284 + DEFINE_PAR("EmulateTwoFingerMinZ", emulate_twofinger_z, PT_INT, 0, 1000),
1285 DEFINE_PAR("VertScrollDelta", scroll_dist_vert, PT_INT, 0, 1000),
1286 DEFINE_PAR("HorizScrollDelta", scroll_dist_horiz, PT_INT, 0, 1000),
1287 DEFINE_PAR("VertEdgeScroll", scroll_edge_vert, PT_BOOL, 0, 1),
1288 DEFINE_PAR("HorizEdgeScroll", scroll_edge_horiz, PT_BOOL, 0, 1),
1289 + DEFINE_PAR("CornerCoasting", scroll_edge_corner, PT_BOOL, 0, 1),
1290 DEFINE_PAR("VertTwoFingerScroll", scroll_twofinger_vert, PT_BOOL, 0, 1),
1291 DEFINE_PAR("HorizTwoFingerScroll", scroll_twofinger_horiz, PT_BOOL, 0, 1),
1292 DEFINE_PAR("MinSpeed", min_speed, PT_DOUBLE, 0, 1.0),
1293 DEFINE_PAR("MaxSpeed", max_speed, PT_DOUBLE, 0, 1.0),
1294 DEFINE_PAR("AccelFactor", accl, PT_DOUBLE, 0, 0.2),
1295 + DEFINE_PAR("TrackstickSpeed", trackstick_speed, PT_DOUBLE, 0, 200.0),
1296 DEFINE_PAR("EdgeMotionMinZ", edge_motion_min_z, PT_INT, 1, 255),
1297 DEFINE_PAR("EdgeMotionMaxZ", edge_motion_max_z, PT_INT, 1, 255),
1298 DEFINE_PAR("EdgeMotionMinSpeed", edge_motion_min_speed, PT_INT, 0, 1000),
1299 @@ -78,12 +82,13 @@
1300 DEFINE_PAR("EdgeMotionUseAlways", edge_motion_use_always, PT_BOOL, 0, 1),
1301 DEFINE_PAR("UpDownScrolling", updown_button_scrolling, PT_BOOL, 0, 1),
1302 DEFINE_PAR("LeftRightScrolling", leftright_button_scrolling, PT_BOOL, 0, 1),
1303 - DEFINE_PAR("UpDownRepeat", updown_button_repeat, PT_BOOL, 0, 1),
1304 - DEFINE_PAR("LeftRightRepeat", leftright_button_repeat, PT_BOOL, 0, 1),
1305 + DEFINE_PAR("UpDownScrollRepeat", updown_button_repeat, PT_BOOL, 0, 1),
1306 + DEFINE_PAR("LeftRightScrollRepeat",leftright_button_repeat, PT_BOOL, 0, 1),
1307 DEFINE_PAR("ScrollButtonRepeat", scroll_button_repeat, PT_INT, SBR_MIN , SBR_MAX),
1308 DEFINE_PAR("TouchpadOff", touchpad_off, PT_INT, 0, 2),
1309 DEFINE_PAR("GuestMouseOff", guestmouse_off, PT_BOOL, 0, 1),
1310 DEFINE_PAR("LockedDrags", locked_drags, PT_BOOL, 0, 1),
1311 + DEFINE_PAR("LockedDragTimeout", locked_drag_time, PT_INT, 0, 30000),
1312 DEFINE_PAR("RTCornerButton", tap_action[RT_TAP], PT_INT, 0, SYN_MAX_BUTTONS),
1313 DEFINE_PAR("RBCornerButton", tap_action[RB_TAP], PT_INT, 0, SYN_MAX_BUTTONS),
1314 DEFINE_PAR("LTCornerButton", tap_action[LT_TAP], PT_INT, 0, SYN_MAX_BUTTONS),
1315 @@ -102,7 +107,8 @@
1316 DEFINE_PAR("PressureMotionMinZ", press_motion_min_z, PT_INT, 1, 255),
1317 DEFINE_PAR("PressureMotionMaxZ", press_motion_max_z, PT_INT, 1, 255),
1318 DEFINE_PAR("PressureMotionMinFactor", press_motion_min_factor, PT_DOUBLE, 0, 10.0),
1319 - DEFINE_PAR("PressureMotionMaxFactor", press_motion_max_factor, PT_DOUBLE, 0, 10.0),
1320 + DEFINE_PAR("PressureMotionMaxFactor", press_motion_max_factor, PT_DOUBLE, 0, 10.0),
1321 + DEFINE_PAR("GrabEventDevice", grab_event_device, PT_BOOL, 0, 1),
1322 { 0, 0, 0, 0, 0 }
1325 @@ -132,13 +138,13 @@
1326 struct Parameter* par = &params[i];
1327 switch (par->type) {
1328 case PT_INT:
1329 - printf(" %-20s = %d\n", par->name, *(int*)((char*)synshm + par->offset));
1330 + printf(" %-23s = %d\n", par->name, *(int*)((char*)synshm + par->offset));
1331 break;
1332 case PT_BOOL:
1333 - printf(" %-20s = %d\n", par->name, *(Bool*)((char*)synshm + par->offset));
1334 + printf(" %-23s = %d\n", par->name, *(Bool*)((char*)synshm + par->offset));
1335 break;
1336 case PT_DOUBLE:
1337 - printf(" %-20s = %g\n", par->name, *(double*)((char*)synshm + par->offset));
1338 + printf(" %-23s = %g\n", par->name, *(double*)((char*)synshm + par->offset));
1339 break;
1342 diff -urN synaptics-0.14.6/synproto.h synaptics-git/synproto.h
1343 --- synaptics-0.14.6/synproto.h 2006-07-09 18:53:02.000000000 +0200
1344 +++ synaptics-git/synproto.h 2008-05-28 14:56:57.000000000 +0200
1345 @@ -72,11 +72,12 @@
1346 SYN_PROTO_ALPS /* ALPS touchpad protocol */
1349 +struct _SynapticsSHM;
1350 struct SynapticsHwInfo;
1351 struct CommData;
1353 struct SynapticsProtocolOperations {
1354 - void (*DeviceOnHook)(LocalDevicePtr local);
1355 + void (*DeviceOnHook)(LocalDevicePtr local, struct _SynapticsSHM *para);
1356 void (*DeviceOffHook)(LocalDevicePtr local);
1357 Bool (*QueryHardware)(LocalDevicePtr local, struct SynapticsHwInfo *synhw);
1358 Bool (*ReadHwState)(LocalDevicePtr local, struct SynapticsHwInfo *synhw,