1
Index: xserver-xorg-input-synaptics/include/synaptics-properties.h
2
===================================================================
3
--- xserver-xorg-input-synaptics.orig/include/synaptics-properties.h 2012-03-02 11:50:00.000000000 -0800
4
+++ xserver-xorg-input-synaptics/include/synaptics-properties.h 2012-03-02 11:50:06.235780000 -0800
6
#define SYNAPTICS_PROP_TAP_DURATIONS "Synaptics Tap Durations"
9
+#define SYNAPTICS_PROP_CLICKPAD "Synaptics ClickPad"
12
#define SYNAPTICS_PROP_TAP_FAST "Synaptics Tap FastTap"
16
/* 32 bit, 4 values, left, right, top, bottom */
17
#define SYNAPTICS_PROP_AREA "Synaptics Area"
19
+/* 32 bit, 4 values, left, right, top, buttom */
20
+#define SYNAPTICS_PROP_SOFTBUTTON_AREAS "Synaptics Soft Button Areas"
22
/* 32 Bit Integer, 2 values, horizontal hysteresis, vertical hysteresis */
23
#define SYNAPTICS_PROP_NOISE_CANCELLATION "Synaptics Noise Cancellation"
25
Index: xserver-xorg-input-synaptics/man/synaptics.man
26
===================================================================
27
--- xserver-xorg-input-synaptics.orig/man/synaptics.man 2012-03-02 11:50:00.000000000 -0800
28
+++ xserver-xorg-input-synaptics/man/synaptics.man 2012-03-02 11:50:06.235780000 -0800
29
@@ -143,6 +143,12 @@ Maximum time (in milliseconds) for detec
30
The duration of the mouse click generated by tapping. Property: "Synaptics Tap
33
+.BI "Option \*qClickPad\*q \*q" boolean \*q
34
+Whether the device is a click pad. A click pad device has button(s) integrated
35
+into the touchpad surface. The user must press downward on the touchpad in order
36
+to generated a button press. This property may be set automatically if a click
37
+pad device is detected at initialization time. Property: "Synaptics ClickPad"
39
.BI "Option \*qFastTaps\*q \*q" boolean \*q
40
Makes the driver react faster to a single tap, but also makes double
41
clicks caused by double tapping slower. Property: "Synaptics Tap FastTap"
42
@@ -524,6 +530,20 @@ AreaBottomEdge option to any integer val
43
server (version 1.9 and later), the edge may be specified in percent of
44
the total height of the touchpad. Property: "Synaptics Area"
47
+.BI "Option \*qSoftButtonAreas\*q \*q" "RBL RBR RBT RBB MBL MBR MBT MBB" \*q
48
+Enable soft button click area support on ClickPad devices. The first four
49
+parameters define the area of the right button, and the second four parameters
50
+define the area of the middle button. The areas are defined by the left, right,
51
+top, and bottom edges as sequential values of the property. If any edge is set
52
+to 0, the button is assumed to extend to infinity in the given direction.
54
+When the user performs a click within the defined soft button areas, the right
55
+or middle click action is performed.
57
+The use of soft button areas is disabled by setting all the values for the area
58
+to 0. Property: "Synaptics Soft Button Areas"
61
.SH CONFIGURATION DETAILS
63
@@ -797,6 +817,10 @@ Properties supported:
64
duration of a single click.
67
+.BI "Synaptics ClickPad"
71
.BI "Synaptics Tap FastTap"
74
@@ -933,6 +957,14 @@ default.
75
32 bit, 4 values, left, right, top, bottom. 0 disables an element.
78
+.BI "Synaptics Soft Button Areas"
79
+The Right and middle soft button areas are used to support right and middle
80
+click actions on a ClickPad device. Providing 0 for all values of a given button
81
+disables the button area.
83
+32 bit, 8 values, RBL, RBR, RBT, RBB, MBL, MBR, MBT, MBB.
86
.BI "Synaptics Capabilities"
87
This read-only property expresses the physical capability of the touchpad,
88
most notably whether the touchpad hardware supports multi-finger tapping and
89
Index: xserver-xorg-input-synaptics/src/eventcomm.c
90
===================================================================
91
--- xserver-xorg-input-synaptics.orig/src/eventcomm.c 2012-03-02 11:50:00.207780002 -0800
92
+++ xserver-xorg-input-synaptics/src/eventcomm.c 2012-03-02 11:50:06.235780000 -0800
93
@@ -526,6 +526,18 @@ SynapticsReadEvent(InputInfoPtr pInfo, s
98
+EventTouchSlotPreviouslyOpen(SynapticsPrivate *priv, int slot)
102
+ for (i = 0; i < priv->num_active_touches; i++)
103
+ if (priv->open_slots[i] == slot)
110
EventProcessTouchEvent(InputInfoPtr pInfo, struct SynapticsHwState *hw,
111
struct input_event *ev)
112
@@ -566,8 +578,20 @@ EventProcessTouchEvent(InputInfoPtr pInf
113
int map = proto_data->axis_map[ev->code - ABS_MT_TOUCH_MAJOR];
114
valuator_mask_set(hw->mt_mask[slot_index], map, ev->value);
116
- valuator_mask_set(proto_data->last_mt_vals[slot_index], map,
119
+ ValuatorMask *mask = proto_data->last_mt_vals[slot_index];
120
+ int last_val = valuator_mask_get(mask, map);
122
+ if (EventTouchSlotPreviouslyOpen(priv, slot_index))
124
+ if (ev->code == ABS_MT_POSITION_X)
125
+ hw->cumulative_dx += ev->value - last_val;
126
+ else if (ev->code == ABS_MT_POSITION_Y)
127
+ hw->cumulative_dy += ev->value - last_val;
130
+ valuator_mask_set(mask, map, ev->value);
135
@@ -609,6 +633,13 @@ EventReadHwState(InputInfoPtr pInfo,
137
SynapticsResetTouchHwState(hw);
139
+ /* Reset cumulative values if buttons were not previously pressed */
140
+ if (!hw->left && !hw->right && !hw->middle)
142
+ hw->cumulative_dx = hw->x;
143
+ hw->cumulative_dy = hw->y;
146
while (SynapticsReadEvent(pInfo, &ev)) {
149
@@ -713,6 +744,7 @@ static void
150
event_query_touch(InputInfoPtr pInfo)
152
SynapticsPrivate *priv = (SynapticsPrivate *)pInfo->private;
153
+ SynapticsParameters *para = &priv->synpara;
154
struct eventcomm_proto_data *proto_data = priv->proto_data;
157
@@ -727,7 +759,13 @@ event_query_touch(InputInfoPtr pInfo)
159
xf86IDrvMsg(pInfo, X_INFO,
160
"ignoring touch events for semi-multitouch device\n");
162
+ priv->has_semi_mt = TRUE;
165
+ if (rc >= 0 && BitIsOn(&prop, INPUT_PROP_BUTTONPAD))
167
+ xf86IDrvMsg(pInfo, X_INFO, "found clickpad property\n");
168
+ para->clickpad = TRUE;
171
mtdev = mtdev_new_open(pInfo->fd);
172
Index: xserver-xorg-input-synaptics/src/properties.c
173
===================================================================
174
--- xserver-xorg-input-synaptics.orig/src/properties.c 2012-03-02 11:50:00.000000000 -0800
175
+++ xserver-xorg-input-synaptics/src/properties.c 2012-03-02 11:50:06.239780000 -0800
176
@@ -58,6 +58,7 @@ Atom prop_finger = 0;
177
Atom prop_tap_time = 0;
178
Atom prop_tap_move = 0;
179
Atom prop_tap_durations = 0;
180
+Atom prop_clickpad = 0;
181
Atom prop_tap_fast = 0;
182
Atom prop_middle_timeout = 0;
183
Atom prop_twofinger_pressure = 0;
184
@@ -92,6 +93,7 @@ Atom prop_gestures = 0;
185
Atom prop_capabilities = 0;
186
Atom prop_resolution = 0;
188
+Atom prop_softbutton_areas = 0;
189
Atom prop_noise_cancellation = 0;
190
Atom prop_product_id = 0;
191
Atom prop_device_node = 0;
192
@@ -190,6 +192,8 @@ InitDeviceProperties(InputInfoPtr pInfo)
193
values[2] = para->click_time;
195
prop_tap_durations = InitAtom(pInfo->dev, SYNAPTICS_PROP_TAP_DURATIONS, 32, 3, values);
196
+ prop_clickpad = InitAtom(pInfo->dev, SYNAPTICS_PROP_CLICKPAD, 8, 1,
198
prop_tap_fast = InitAtom(pInfo->dev, SYNAPTICS_PROP_TAP_FAST, 8, 1, ¶->fast_taps);
199
prop_middle_timeout = InitAtom(pInfo->dev, SYNAPTICS_PROP_MIDDLE_TIMEOUT,
200
32, 1, ¶->emulate_mid_button_time);
201
@@ -298,6 +302,16 @@ InitDeviceProperties(InputInfoPtr pInfo)
202
values[3] = para->area_bottom_edge;
203
prop_area = InitAtom(pInfo->dev, SYNAPTICS_PROP_AREA, 32, 4, values);
205
+ values[0] = para->softbutton_areas[0][0];
206
+ values[1] = para->softbutton_areas[0][1];
207
+ values[2] = para->softbutton_areas[0][2];
208
+ values[3] = para->softbutton_areas[0][3];
209
+ values[4] = para->softbutton_areas[1][0];
210
+ values[5] = para->softbutton_areas[1][1];
211
+ values[6] = para->softbutton_areas[1][2];
212
+ values[7] = para->softbutton_areas[1][3];
213
+ prop_softbutton_areas = InitAtom(pInfo->dev, SYNAPTICS_PROP_SOFTBUTTON_AREAS, 32, 8, values);
215
values[0] = para->hyst_x;
216
values[1] = para->hyst_y;
217
prop_noise_cancellation = InitAtom(pInfo->dev,
218
@@ -393,7 +407,25 @@ SetProperty(DeviceIntPtr dev, Atom prope
219
para->single_tap_timeout = timeouts[0];
220
para->tap_time_2 = timeouts[1];
221
para->click_time = timeouts[2];
222
+ } else if (property == prop_clickpad) {
223
+ if (prop->size != 1 || prop->format != 8 || prop->type != XA_INTEGER)
226
+ para->clickpad = *(BOOL*)prop->data;
228
+ /* ClickPad support conflicts with click action support. Reset click
229
+ * actions. The user can override afterwards if they really want. */
230
+ if (para->clickpad)
232
+ CARD8 values[3] = {};
234
+ para->click_action[F1_CLICK1] = 0;
235
+ para->click_action[F2_CLICK1] = 0;
236
+ para->click_action[F3_CLICK1] = 0;
238
+ XIChangeDeviceProperty(dev, prop_clickaction, XA_INTEGER, 8,
239
+ PropModeReplace, 3, values, TRUE);
241
} else if (property == prop_tap_fast)
243
if (prop->size != 1 || prop->format != 8 || prop->type != XA_INTEGER)
244
@@ -711,6 +743,19 @@ SetProperty(DeviceIntPtr dev, Atom prope
245
para->area_right_edge = area[1];
246
para->area_top_edge = area[2];
247
para->area_bottom_edge = area[3];
248
+ } else if (property == prop_softbutton_areas)
252
+ if (prop->size != 8 || prop->format != 32 || prop->type != XA_INTEGER)
255
+ areas = (int*)prop->data;
256
+ if (!SynapticsIsSoftButtonAreasValid(areas))
259
+ memcpy(para->softbutton_areas[0], areas, 4 * sizeof(int));
260
+ memcpy(para->softbutton_areas[1], areas + 4, 4 * sizeof(int));
261
} else if (property == prop_noise_cancellation) {
263
if (prop->size != 2 || prop->format != 32 || prop->type != XA_INTEGER)
264
Index: xserver-xorg-input-synaptics/src/synaptics.c
265
===================================================================
266
--- xserver-xorg-input-synaptics.orig/src/synaptics.c 2012-03-02 11:50:00.000000000 -0800
267
+++ xserver-xorg-input-synaptics/src/synaptics.c 2012-03-02 11:50:19.495780001 -0800
268
@@ -410,6 +410,120 @@ static int set_percent_option(pointer op
272
+Bool SynapticsIsSoftButtonAreasValid(int *values)
274
+ Bool right_disabled = FALSE;
275
+ Bool middle_disabled = FALSE;
277
+ /* Check right button area */
278
+ if ((((values[0] != 0) && (values[1] != 0)) && (values[0] > values[1])) ||
279
+ (((values[2] != 0) && (values[3] != 0)) && (values[2] > values[3])))
282
+ /* Check middle button area */
283
+ if ((((values[4] != 0) && (values[5] != 0)) && (values[4] > values[5])) ||
284
+ (((values[6] != 0) && (values[7] != 0)) && (values[6] > values[7])))
287
+ if (values[0] == 0 && values[1] == 0 && values[2] == 0 && values[3] == 0)
288
+ right_disabled = TRUE;
290
+ if (values[4] == 0 && values[5] == 0 && values[6] == 0 && values[7] == 0)
291
+ middle_disabled = TRUE;
293
+ /* Check for overlapping button areas */
294
+ if (!right_disabled && !middle_disabled)
296
+ int right_left = values[0] ? values[0] : INT_MIN;
297
+ int right_right = values[1] ? values[1] : INT_MAX;
298
+ int right_top = values[2] ? values[2] : INT_MIN;
299
+ int right_bottom = values[3] ? values[3] : INT_MAX;
300
+ int middle_left = values[4] ? values[4] : INT_MIN;
301
+ int middle_right = values[5] ? values[5] : INT_MAX;
302
+ int middle_top = values[6] ? values[6] : INT_MIN;
303
+ int middle_bottom = values[7] ? values[7] : INT_MAX;
305
+ /* If areas overlap in the Y axis */
306
+ if ((right_bottom <= middle_bottom && right_bottom >= middle_top) ||
307
+ (right_top <= middle_bottom && right_top >= middle_top))
309
+ /* Check for identical right and left edges */
310
+ if (right_left == middle_left || right_right == middle_right)
313
+ /* Check for overlapping left edges */
314
+ if ((right_left < middle_left && right_right >= middle_left) ||
315
+ (middle_left < right_left && middle_right >= right_left))
318
+ /* Check for overlapping right edges */
319
+ if ((right_right > middle_right && right_left <= middle_right) ||
320
+ (middle_right > right_right && middle_left <= right_right))
324
+ /* If areas overlap in the X axis */
325
+ if ((right_left >= middle_left && right_left <= middle_right) ||
326
+ (right_right >= middle_left && right_right <= middle_right))
328
+ /* Check for overlapping top edges */
329
+ if ((right_top < middle_top && right_bottom >= middle_top) ||
330
+ (middle_top < right_top && middle_bottom >= right_top))
333
+ /* Check for overlapping bottom edges */
334
+ if ((right_bottom > middle_bottom && right_top <= middle_bottom) ||
335
+ (middle_bottom > right_bottom && middle_top <= right_bottom))
343
+static void set_softbutton_areas_option(InputInfoPtr pInfo)
345
+ SynapticsPrivate *priv = pInfo->private;
346
+ SynapticsParameters *pars = &priv->synpara;
348
+ char *option_string;
353
+ option_string = xf86CheckStrOption(pInfo->options, "SoftButtonAreas", NULL);
354
+ if (!option_string)
357
+ next_num = option_string;
359
+ for (i = 0; i < 8 && *next_num != '\0'; i++)
361
+ long int value = strtol(next_num, &end_str, 0);
362
+ if (value > INT_MAX || value < -INT_MAX)
367
+ if (next_num != end_str)
368
+ next_num = end_str;
373
+ if (i < 8 || *next_num != '\0' || !SynapticsIsSoftButtonAreasValid(values))
376
+ memcpy(pars->softbutton_areas[0], values, 4 * sizeof(int));
377
+ memcpy(pars->softbutton_areas[1], values + 4, 4 * sizeof(int));
382
+ xf86IDrvMsg(pInfo, X_ERROR, "invalid SoftButtonAreas value '%s', keeping defaults\n",
386
static void set_default_parameters(InputInfoPtr pInfo)
388
SynapticsPrivate *priv = pInfo->private; /* read-only */
389
@@ -428,7 +542,7 @@ static void set_default_parameters(Input
390
int pressureMotionMinZ, pressureMotionMaxZ; /* pressure */
391
int palmMinWidth, palmMinZ; /* pressure */
392
int tapButton1, tapButton2, tapButton3;
393
- int clickFinger1, clickFinger2, clickFinger3;
394
+ int clickFinger1 = 0, clickFinger2 = 0, clickFinger3 = 0;
395
Bool vertEdgeScroll, horizEdgeScroll;
396
Bool vertTwoFingerScroll, horizTwoFingerScroll;
397
int horizResolution = 1;
398
@@ -488,6 +602,11 @@ static void set_default_parameters(Input
399
palmMinWidth = priv->minw + range * (10.0/16);
400
emulateTwoFingerMinW = priv->minw + range * (7.0/16);
402
+ /* Clickpad conflicts with click actions, disable by default unless there
403
+ * is a physical right button. */
404
+ if (pars->clickpad && !priv->has_right)
405
+ pars->clickpad = 0;
410
@@ -495,9 +614,12 @@ static void set_default_parameters(Input
412
/* Enable multifinger-click if only have one physical button,
413
otherwise clickFinger is always button 1. */
415
- clickFinger2 = (priv->has_right || priv->has_middle) ? 1 : 3;
416
- clickFinger3 = 0; /* Disabled by default so three-touch gestures work */
417
+ if (!pars->clickpad)
420
+ clickFinger2 = (priv->has_right || priv->has_middle) ? 1 : 3;
421
+ clickFinger3 = 0; /* Disabled by default so three-touch gestures work */
424
/* Enable vert edge scroll */
425
vertEdgeScroll = TRUE;
426
@@ -534,6 +656,7 @@ static void set_default_parameters(Input
427
pars->tap_move = xf86SetIntOption(opts, "MaxTapMove", tapMove);
428
pars->tap_time_2 = xf86SetIntOption(opts, "MaxDoubleTapTime", 180);
429
pars->click_time = xf86SetIntOption(opts, "ClickTime", 100);
430
+ pars->clickpad = xf86SetIntOption(opts, "ClickPad", pars->clickpad); /* Probed */
431
pars->fast_taps = xf86SetBoolOption(opts, "FastTaps", FALSE);
432
pars->emulate_mid_button_time = xf86SetIntOption(opts, "EmulateMidButtonTime", 75);
433
pars->emulate_twofinger_z = xf86SetIntOption(opts, "EmulateTwoFingerMinZ", emulateTwoFingerMinZ);
434
@@ -602,6 +725,8 @@ static void set_default_parameters(Input
435
pars->bottom_edge = tmp;
436
xf86IDrvMsg(pInfo, X_WARNING, "TopEdge is bigger than BottomEdge. Fixing.\n");
439
+ set_softbutton_areas_option(pInfo);
442
#if GET_ABI_MAJOR(ABI_XINPUT_VERSION) >= 14
443
@@ -1355,6 +1480,60 @@ is_inside_active_area(SynapticsPrivate *
448
+is_inside_rightbutton_area(SynapticsParameters *para, int x, int y)
450
+ Bool inside_area = TRUE;
452
+ if (para->softbutton_areas[0][0] == 0 &&
453
+ para->softbutton_areas[0][1] == 0 &&
454
+ para->softbutton_areas[0][2] == 0 &&
455
+ para->softbutton_areas[0][3] == 0)
458
+ if (para->softbutton_areas[0][0] &&
459
+ x < para->softbutton_areas[0][0])
460
+ inside_area = FALSE;
461
+ else if (para->softbutton_areas[0][1] &&
462
+ x > para->softbutton_areas[0][1])
463
+ inside_area = FALSE;
464
+ else if (para->softbutton_areas[0][2] &&
465
+ y < para->softbutton_areas[0][2])
466
+ inside_area = FALSE;
467
+ else if (para->softbutton_areas[0][3] &&
468
+ y > para->softbutton_areas[0][3])
469
+ inside_area = FALSE;
471
+ return inside_area;
475
+is_inside_middlebutton_area(SynapticsParameters *para, int x, int y)
477
+ Bool inside_area = TRUE;
479
+ if (para->softbutton_areas[1][0] == 0 &&
480
+ para->softbutton_areas[1][1] == 0 &&
481
+ para->softbutton_areas[1][2] == 0 &&
482
+ para->softbutton_areas[1][3] == 0)
485
+ if (para->softbutton_areas[1][0] &&
486
+ x < para->softbutton_areas[1][0])
487
+ inside_area = FALSE;
488
+ else if (para->softbutton_areas[1][1] &&
489
+ x > para->softbutton_areas[1][1])
490
+ inside_area = FALSE;
491
+ else if (para->softbutton_areas[1][2] &&
492
+ y < para->softbutton_areas[1][2])
493
+ inside_area = FALSE;
494
+ else if (para->softbutton_areas[1][3] &&
495
+ y > para->softbutton_areas[1][3])
496
+ inside_area = FALSE;
498
+ return inside_area;
502
timerFunc(OsTimerPtr timer, CARD32 now, pointer arg)
504
@@ -1411,6 +1590,14 @@ ReadInput(InputInfoPtr pInfo)
505
SynapticsResetTouchHwState(hw);
507
while (SynapticsGetHwState(pInfo, priv, hw)) {
508
+ /* Semi-mt device touch slots do not track touches. When there is a
509
+ * change in the number of touches, we must disregard the temporary
510
+ * motion changes. */
511
+ if (priv->has_semi_mt && hw->numFingers != priv->hwState->numFingers) {
512
+ hw->cumulative_dx = priv->hwState->cumulative_dx;
513
+ hw->cumulative_dy = priv->hwState->cumulative_dy;
516
SynapticsCopyHwState(priv->hwState, hw);
517
delay = HandleState(pInfo, hw, hw->millis, FALSE);
519
@@ -1692,7 +1879,7 @@ HandleTapProcessing(SynapticsPrivate *pr
520
Bool inside_active_area)
522
SynapticsParameters *para = &priv->synpara;
523
- Bool touch, release, is_timeout, move;
524
+ Bool touch, release, is_timeout, move, press;
525
int timeleft, timeout;
527
int delay = 1000000000;
528
@@ -1706,6 +1893,7 @@ HandleTapProcessing(SynapticsPrivate *pr
529
(priv->tap_max_fingers <= ((priv->horiz_scroll_twofinger_on || priv->vert_scroll_twofinger_on)? 2 : 1)) &&
530
((abs(hw->x - priv->touch_on.x) >= para->tap_move) ||
531
(abs(hw->y - priv->touch_on.y) >= para->tap_move)));
532
+ press = (hw->left || hw->right || hw->middle);
535
priv->touch_on.x = hw->x;
536
@@ -1728,6 +1916,10 @@ HandleTapProcessing(SynapticsPrivate *pr
537
SetTapState(priv, TS_1, now);
540
+ if (para->clickpad && press) {
541
+ SetTapState(priv, TS_CLICKPAD_MOVE, now);
545
SetMovingState(priv, MS_TOUCHPAD_RELATIVE, now);
546
SetTapState(priv, TS_MOVE, now);
547
@@ -1751,6 +1943,10 @@ HandleTapProcessing(SynapticsPrivate *pr
551
+ if (para->clickpad && press) {
552
+ SetTapState(priv, TS_CLICKPAD_MOVE, now);
555
if (move && priv->moving_state == MS_TRACKSTICK) {
556
SetMovingState(priv, MS_TOUCHPAD_RELATIVE, now);
558
@@ -1805,6 +2001,10 @@ HandleTapProcessing(SynapticsPrivate *pr
562
+ if (para->clickpad && press) {
563
+ SetTapState(priv, TS_CLICKPAD_MOVE, now);
567
SetMovingState(priv, MS_TOUCHPAD_RELATIVE, now);
569
@@ -1833,6 +2033,23 @@ HandleTapProcessing(SynapticsPrivate *pr
570
SetTapState(priv, TS_START, now);
573
+ case TS_CLICKPAD_MOVE:
574
+ /* Disable scrolling once a button is pressed on a clickpad */
575
+ priv->vert_scroll_edge_on = FALSE;
576
+ priv->horiz_scroll_edge_on = FALSE;
577
+ priv->vert_scroll_twofinger_on = FALSE;
578
+ priv->horiz_scroll_twofinger_on = FALSE;
580
+ /* Assume one touch is only for holding the clickpad button down */
581
+ if (hw->numFingers > 1)
583
+ SetMovingState(priv, MS_TOUCHPAD_RELATIVE, now);
585
+ SetMovingState(priv, MS_FALSE, now);
586
+ SetTapState(priv, TS_MOVE, now);
587
+ priv->count_packet_finger = 0;
592
timeout = GetTimeOut(priv);
593
@@ -1955,9 +2172,8 @@ get_delta(SynapticsPrivate *priv, const
594
int x_edge_speed = 0;
595
int y_edge_speed = 0;
597
- /* HIST is full enough: priv->count_packet_finger > 3 */
598
- *dx = estimate_delta(hw->x, HIST(0).x, HIST(1).x, HIST(2).x);
599
- *dy = estimate_delta(hw->y, HIST(0).y, HIST(1).y, HIST(2).y);
600
+ *dx = hw->x - HIST(0).x;
601
+ *dy = hw->y - HIST(0).y;
603
if ((priv->tap_state == TS_DRAG) || para->edge_motion_use_always)
604
get_edge_speed(priv, hw, edge, &x_edge_speed, &y_edge_speed);
605
@@ -2026,7 +2242,7 @@ ComputeDeltas(SynapticsPrivate *priv, co
606
* POLL_MS declaration. */
607
delay = MIN(delay, POLL_MS);
609
- if (priv->count_packet_finger <= 3) /* min. 3 packets, see get_delta() */
610
+ if (priv->count_packet_finger <= 1)
611
goto out; /* skip the lot */
613
if (priv->moving_state == MS_TRACKSTICK)
614
@@ -2468,6 +2684,22 @@ update_hw_button_state(const InputInfoPt
615
/* 3rd button emulation */
616
hw->middle |= HandleMidButtonEmulation(priv, hw, now, delay);
618
+ /* If this is a clickpad and the user clicks in a soft button area, press
619
+ * the soft button instead. */
620
+ if (para->clickpad && hw->left && !hw->right && !hw->middle)
622
+ if (is_inside_rightbutton_area(para, hw->x, hw->y))
627
+ else if (is_inside_middlebutton_area(para, hw->x, hw->y))
634
/* Fingers emulate other buttons */
635
if(hw->left && hw->numFingers >= 1){
636
handle_clickfinger(para, hw);
637
@@ -2659,6 +2891,9 @@ HandleTouches(InputInfoPtr pInfo, struct
638
new_active_touches--;
641
+ if (priv->has_semi_mt)
644
if (priv->num_active_touches < min_touches &&
645
new_active_touches < min_touches)
647
@@ -2752,6 +2987,14 @@ HandleState(InputInfoPtr pInfo, struct S
651
+ /* If a physical button is pressed on a clickpad, use cumulative relative
652
+ * touch movements for motion */
653
+ if (para->clickpad && (hw->left || hw->right || hw->middle))
655
+ hw->x = hw->cumulative_dx;
656
+ hw->y = hw->cumulative_dy;
659
/* apply hysteresis before doing anything serious. This cancels
660
* out a lot of noise which might surface in strange phenomena
661
* like flicker in scrolling or noise motion. */
662
Index: xserver-xorg-input-synaptics/src/synapticsstr.h
663
===================================================================
664
--- xserver-xorg-input-synaptics.orig/src/synapticsstr.h 2012-03-02 11:50:00.000000000 -0800
665
+++ xserver-xorg-input-synaptics/src/synapticsstr.h 2012-03-02 11:50:06.239780000 -0800
666
@@ -99,7 +99,8 @@ enum TapState {
667
TS_3, /* After second touch */
668
TS_DRAG, /* Pointer drag enabled */
669
TS_4, /* After release when "locked drags" enabled */
670
- TS_5 /* After touch when "locked drags" enabled */
671
+ TS_5, /* After touch when "locked drags" enabled */
672
+ TS_CLICKPAD_MOVE, /* After left button press on a clickpad */
675
enum TapButtonState {
676
@@ -125,6 +126,7 @@ typedef struct _SynapticsParameters
677
int single_tap_timeout; /* timeout to recognize a single tap */
678
int tap_time_2; /* max. tapping time for double taps */
679
int click_time; /* The duration of a single click */
680
+ Bool clickpad; /* Device is a has integrated buttons */
681
Bool fast_taps; /* Faster reaction to single taps */
682
int emulate_mid_button_time; /* Max time between left and right button presses to
683
emulate a middle button press. */
684
@@ -179,6 +181,7 @@ typedef struct _SynapticsParameters
685
unsigned int resolution_horiz; /* horizontal resolution of touchpad in units/mm */
686
unsigned int resolution_vert; /* vertical resolution of touchpad in units/mm */
687
int area_left_edge, area_right_edge, area_top_edge, area_bottom_edge; /* area coordinates absolute */
688
+ int softbutton_areas[2][4]; /* soft button area coordinates, 0 => right, 1 => middle button */
689
int hyst_x, hyst_y; /* x and y width of hysteresis box */
690
} SynapticsParameters;
692
@@ -266,6 +269,7 @@ typedef struct _SynapticsPrivateRec
693
Bool has_pressure; /* device reports pressure */
694
Bool has_width; /* device reports finger width */
695
Bool has_scrollbuttons; /* device has physical scrollbuttons */
696
+ Bool has_semi_mt; /* device is only semi-multitouch capable */
698
enum TouchpadModel model; /* The detected model */
699
unsigned short id_vendor; /* vendor id */
700
Index: xserver-xorg-input-synaptics/src/synproto.c
701
===================================================================
702
--- xserver-xorg-input-synaptics.orig/src/synproto.c 2012-03-02 11:50:00.000000000 -0800
703
+++ xserver-xorg-input-synaptics/src/synproto.c 2012-03-02 11:50:06.239780000 -0800
704
@@ -120,6 +120,8 @@ SynapticsCopyHwState(struct SynapticsHwS
708
+ dst->cumulative_dx = src->cumulative_dx;
709
+ dst->cumulative_dy = src->cumulative_dy;
710
dst->numFingers = src->numFingers;
711
dst->fingerWidth = src->fingerWidth;
712
dst->left = src->left;
713
Index: xserver-xorg-input-synaptics/src/synproto.h
714
===================================================================
715
--- xserver-xorg-input-synaptics.orig/src/synproto.h 2012-03-02 11:50:00.000000000 -0800
716
+++ xserver-xorg-input-synaptics/src/synproto.h 2012-03-02 11:50:06.239780000 -0800
717
@@ -53,6 +53,8 @@ struct SynapticsHwState {
718
int x; /* X position of finger */
719
int y; /* Y position of finger */
720
int z; /* Finger pressure */
721
+ int cumulative_dx; /* Cumulative delta X for clickpad dragging */
722
+ int cumulative_dy; /* Cumulative delta Y for clickpad dragging */
726
@@ -115,4 +117,6 @@ extern void SynapticsCopyHwState(struct
727
const struct SynapticsHwState *src);
728
extern void SynapticsResetTouchHwState(struct SynapticsHwState *hw);
730
+extern Bool SynapticsIsSoftButtonAreasValid(int *values);
732
#endif /* _SYNPROTO_H_ */
733
Index: xserver-xorg-input-synaptics/test/fake-symbols.c
734
===================================================================
735
--- xserver-xorg-input-synaptics.orig/test/fake-symbols.c 2012-03-02 11:50:00.000000000 -0800
736
+++ xserver-xorg-input-synaptics/test/fake-symbols.c 2012-03-02 11:50:06.239780000 -0800
737
@@ -461,6 +461,11 @@ _X_EXPORT void valuator_mask_free(Valuat
741
+_X_EXPORT int valuator_mask_get(const ValuatorMask *mask, int valuator)
746
_X_EXPORT void valuator_mask_set(ValuatorMask *mask, int valuator, int data)
749
Index: xserver-xorg-input-synaptics/tools/synclient.c
750
===================================================================
751
--- xserver-xorg-input-synaptics.orig/tools/synclient.c 2012-03-02 11:50:00.000000000 -0800
752
+++ xserver-xorg-input-synaptics/tools/synclient.c 2012-03-02 11:50:06.243780000 -0800
759
#include <X11/Xdefs.h>
760
#include <X11/Xatom.h>
761
@@ -144,6 +145,15 @@ static struct Parameter params[] = {
762
{"AreaRightEdge", PT_INT, 0, 10000, SYNAPTICS_PROP_AREA, 32, 1},
763
{"AreaTopEdge", PT_INT, 0, 10000, SYNAPTICS_PROP_AREA, 32, 2},
764
{"AreaBottomEdge", PT_INT, 0, 10000, SYNAPTICS_PROP_AREA, 32, 3},
765
+ {"ClickPad", PT_BOOL, 0, 1, SYNAPTICS_PROP_CLICKPAD, 8, 0},
766
+ {"RightButtonAreaLeft", PT_INT, INT_MIN, INT_MAX, SYNAPTICS_PROP_SOFTBUTTON_AREAS, 32, 0},
767
+ {"RightButtonAreaRight", PT_INT, INT_MIN, INT_MAX, SYNAPTICS_PROP_SOFTBUTTON_AREAS, 32, 1},
768
+ {"RightButtonAreaTop", PT_INT, INT_MIN, INT_MAX, SYNAPTICS_PROP_SOFTBUTTON_AREAS, 32, 2},
769
+ {"RightButtonAreaBottom", PT_INT, INT_MIN, INT_MAX, SYNAPTICS_PROP_SOFTBUTTON_AREAS, 32, 3},
770
+ {"MiddleButtonAreaLeft", PT_INT, INT_MIN, INT_MAX, SYNAPTICS_PROP_SOFTBUTTON_AREAS, 32, 4},
771
+ {"MiddleButtonAreaRight", PT_INT, INT_MIN, INT_MAX, SYNAPTICS_PROP_SOFTBUTTON_AREAS, 32, 5},
772
+ {"MiddleButtonAreaTop", PT_INT, INT_MIN, INT_MAX, SYNAPTICS_PROP_SOFTBUTTON_AREAS, 32, 6},
773
+ {"MiddleButtonAreaBottom", PT_INT, INT_MIN, INT_MAX, SYNAPTICS_PROP_SOFTBUTTON_AREAS, 32, 7},