~ubuntu-branches/ubuntu/raring/xserver-xorg-input-synaptics/raring-proposed

« back to all changes in this revision

Viewing changes to debian/patches/129_clickpad.patch

  • Committer: Package Import Robot
  • Author(s): Chase Douglas
  • Date: 2012-03-15 17:58:09 UTC
  • mfrom: (0.4.5)
  • Revision ID: package-import@ubuntu.com-20120315175809-pj71lv79zn8nlp3k
Tags: 1.5.99.901-0ubuntu1
* New upstream release
  - Includes ClickPad support
  - Fixes ClickPad click action interference
  - Re-enables ClickPad support by default (LP: #955404)
  - Everything else is bug fixes
* Remove 129_clickpad.patch, it has been merged upstream
* Bump lintian standards to 3.9.3

Show diffs side-by-side

added added

removed removed

Lines of Context:
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
5
 
@@ -49,6 +49,9 @@
6
 
 #define SYNAPTICS_PROP_TAP_DURATIONS "Synaptics Tap Durations"
7
 
 
8
 
 /* 8 bit (BOOL) */
9
 
+#define SYNAPTICS_PROP_CLICKPAD "Synaptics ClickPad"
10
 
+
11
 
+/* 8 bit (BOOL) */
12
 
 #define SYNAPTICS_PROP_TAP_FAST "Synaptics Tap FastTap"
13
 
 
14
 
 /* 32 bit */
15
 
@@ -158,6 +161,9 @@
16
 
 /* 32 bit, 4 values, left, right, top, bottom */
17
 
 #define SYNAPTICS_PROP_AREA "Synaptics Area"
18
 
 
19
 
+/* 32 bit, 4 values, left, right, top, buttom */
20
 
+#define SYNAPTICS_PROP_SOFTBUTTON_AREAS "Synaptics Soft Button Areas"
21
 
+
22
 
 /* 32 Bit Integer, 2 values, horizontal hysteresis, vertical hysteresis */
23
 
 #define SYNAPTICS_PROP_NOISE_CANCELLATION "Synaptics Noise Cancellation"
24
 
 
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
31
 
 Durations"
32
 
 .TP 7
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"
38
 
+.TP 7
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"
45
 
 .
46
 
+.TP
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.
53
 
+.
54
 
+When the user performs a click within the defined soft button areas, the right
55
 
+or middle click action is performed.
56
 
+.
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"
59
 
+.
60
 
 
61
 
 .SH CONFIGURATION DETAILS
62
 
 .SS Area handling
63
 
@@ -797,6 +817,10 @@ Properties supported:
64
 
 duration of a single click.
65
 
 
66
 
 .TP 7
67
 
+.BI "Synaptics ClickPad"
68
 
+8 bit (Bool).
69
 
+
70
 
+.TP 7
71
 
 .BI "Synaptics Tap FastTap"
72
 
 8 bit (BOOL).
73
 
 
74
 
@@ -933,6 +957,14 @@ default.
75
 
 32 bit, 4 values, left, right, top, bottom. 0 disables an element.
76
 
 
77
 
 .TP 7
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.
82
 
+
83
 
+32 bit, 8 values, RBL, RBR, RBT, RBB, MBL, MBR, MBT, MBB.
84
 
+
85
 
+.TP 7
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
94
 
     return rc;
95
 
 }
96
 
 
97
 
+static Bool
98
 
+EventTouchSlotPreviouslyOpen(SynapticsPrivate *priv, int slot)
99
 
+{
100
 
+    int i;
101
 
+
102
 
+    for (i = 0; i < priv->num_active_touches; i++)
103
 
+        if (priv->open_slots[i] == slot)
104
 
+            return TRUE;
105
 
+
106
 
+    return FALSE;
107
 
+}
108
 
+
109
 
 static void
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);
115
 
             if (slot_index >= 0)
116
 
-                valuator_mask_set(proto_data->last_mt_vals[slot_index], map,
117
 
-                                  ev->value);
118
 
+            {
119
 
+                ValuatorMask *mask = proto_data->last_mt_vals[slot_index];
120
 
+                int last_val = valuator_mask_get(mask, map);
121
 
+
122
 
+                if (EventTouchSlotPreviouslyOpen(priv, slot_index))
123
 
+                {
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;
128
 
+                }
129
 
+
130
 
+                valuator_mask_set(mask, map, ev->value);
131
 
+            }
132
 
         }
133
 
     }
134
 
 #endif
135
 
@@ -609,6 +633,13 @@ EventReadHwState(InputInfoPtr pInfo,
136
 
 
137
 
     SynapticsResetTouchHwState(hw);
138
 
 
139
 
+    /* Reset cumulative values if buttons were not previously pressed */
140
 
+    if (!hw->left && !hw->right && !hw->middle)
141
 
+    {
142
 
+        hw->cumulative_dx = hw->x;
143
 
+        hw->cumulative_dy = hw->y;
144
 
+    }
145
 
+
146
 
     while (SynapticsReadEvent(pInfo, &ev)) {
147
 
        switch (ev.type) {
148
 
        case EV_SYN:
149
 
@@ -713,6 +744,7 @@ static void
150
 
 event_query_touch(InputInfoPtr pInfo)
151
 
 {
152
 
     SynapticsPrivate *priv = (SynapticsPrivate *)pInfo->private;
153
 
+    SynapticsParameters *para = &priv->synpara;
154
 
     struct eventcomm_proto_data *proto_data = priv->proto_data;
155
 
     struct mtdev *mtdev;
156
 
     int i;
157
 
@@ -727,7 +759,13 @@ event_query_touch(InputInfoPtr pInfo)
158
 
     {
159
 
         xf86IDrvMsg(pInfo, X_INFO,
160
 
                     "ignoring touch events for semi-multitouch device\n");
161
 
-        return;
162
 
+        priv->has_semi_mt = TRUE;
163
 
+    }
164
 
+
165
 
+    if (rc >= 0 && BitIsOn(&prop, INPUT_PROP_BUTTONPAD))
166
 
+    {
167
 
+        xf86IDrvMsg(pInfo, X_INFO, "found clickpad property\n");
168
 
+        para->clickpad = TRUE;
169
 
     }
170
 
 
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;
187
 
 Atom prop_area                  = 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;
194
 
 
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,
197
 
+                             &para->clickpad);
198
 
     prop_tap_fast = InitAtom(pInfo->dev, SYNAPTICS_PROP_TAP_FAST, 8, 1, &para->fast_taps);
199
 
     prop_middle_timeout = InitAtom(pInfo->dev, SYNAPTICS_PROP_MIDDLE_TIMEOUT,
200
 
                                    32, 1, &para->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);
204
 
 
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);
214
 
+
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)
224
 
+            return BadMatch;
225
 
+
226
 
+        para->clickpad = *(BOOL*)prop->data;
227
 
+
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)
231
 
+        {
232
 
+            CARD8 values[3] = {};
233
 
+
234
 
+            para->click_action[F1_CLICK1] = 0;
235
 
+            para->click_action[F2_CLICK1] = 0;
236
 
+            para->click_action[F3_CLICK1] = 0;
237
 
 
238
 
+            XIChangeDeviceProperty(dev, prop_clickaction, XA_INTEGER, 8,
239
 
+                                   PropModeReplace, 3, values, TRUE);
240
 
+        }
241
 
     } else if (property == prop_tap_fast)
242
 
     {
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)
249
 
+    {
250
 
+        int *areas;
251
 
+
252
 
+        if (prop->size != 8 || prop->format != 32 || prop->type != XA_INTEGER)
253
 
+            return BadMatch;
254
 
+
255
 
+        areas = (int*)prop->data;
256
 
+        if (!SynapticsIsSoftButtonAreasValid(areas))
257
 
+            return BadValue;
258
 
+
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) {
262
 
         INT32 *hyst;
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
269
 
     return result;
270
 
 }
271
 
 
272
 
+Bool SynapticsIsSoftButtonAreasValid(int *values)
273
 
+{
274
 
+    Bool right_disabled = FALSE;
275
 
+    Bool middle_disabled = FALSE;
276
 
+
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])))
280
 
+        return FALSE;
281
 
+
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])))
285
 
+        return FALSE;
286
 
+
287
 
+    if (values[0] == 0 && values[1] == 0 && values[2] == 0 && values[3] == 0)
288
 
+        right_disabled = TRUE;
289
 
+
290
 
+    if (values[4] == 0 && values[5] == 0 && values[6] == 0 && values[7] == 0)
291
 
+        middle_disabled = TRUE;
292
 
+
293
 
+    /* Check for overlapping button areas */
294
 
+    if (!right_disabled && !middle_disabled)
295
 
+    {
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;
304
 
+
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))
308
 
+        {
309
 
+            /* Check for identical right and left edges */
310
 
+            if (right_left == middle_left || right_right == middle_right)
311
 
+                return FALSE;
312
 
+
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))
316
 
+                return FALSE;
317
 
+
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))
321
 
+                return FALSE;
322
 
+        }
323
 
+
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))
327
 
+        {
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))
331
 
+                return FALSE;
332
 
+
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))
336
 
+                return FALSE;
337
 
+        }
338
 
+    }
339
 
+
340
 
+    return TRUE;
341
 
+}
342
 
+
343
 
+static void set_softbutton_areas_option(InputInfoPtr pInfo)
344
 
+{
345
 
+    SynapticsPrivate *priv = pInfo->private;
346
 
+    SynapticsParameters *pars = &priv->synpara;
347
 
+    int values[8];
348
 
+    char *option_string;
349
 
+    char *next_num;
350
 
+    char *end_str;
351
 
+    int i;
352
 
+
353
 
+    option_string = xf86CheckStrOption(pInfo->options, "SoftButtonAreas", NULL);
354
 
+    if (!option_string)
355
 
+        return;
356
 
+
357
 
+    next_num = option_string;
358
 
+
359
 
+    for (i = 0; i < 8 && *next_num != '\0'; i++)
360
 
+    {
361
 
+        long int value = strtol(next_num, &end_str, 0);
362
 
+        if (value > INT_MAX || value < -INT_MAX)
363
 
+            goto fail;
364
 
+
365
 
+        values[i] = value;
366
 
+
367
 
+        if (next_num != end_str)
368
 
+            next_num = end_str;
369
 
+        else
370
 
+            goto fail;
371
 
+    }
372
 
+
373
 
+    if (i < 8 || *next_num != '\0' || !SynapticsIsSoftButtonAreasValid(values))
374
 
+        goto fail;
375
 
+
376
 
+    memcpy(pars->softbutton_areas[0], values, 4 * sizeof(int));
377
 
+    memcpy(pars->softbutton_areas[1], values + 4, 4 * sizeof(int));
378
 
+
379
 
+    return;
380
 
+
381
 
+fail:
382
 
+    xf86IDrvMsg(pInfo, X_ERROR, "invalid SoftButtonAreas value '%s', keeping defaults\n",
383
 
+                option_string);
384
 
+}
385
 
+
386
 
 static void set_default_parameters(InputInfoPtr pInfo)
387
 
 {
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);
401
 
 
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;
406
 
+
407
 
     /* Enable tap */
408
 
     tapButton1 = 1;
409
 
     tapButton2 = 2;
410
 
@@ -495,9 +614,12 @@ static void set_default_parameters(Input
411
 
 
412
 
     /* Enable multifinger-click if only have one physical button,
413
 
        otherwise clickFinger is always button 1. */
414
 
-    clickFinger1 = 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)
418
 
+    {
419
 
+        clickFinger1 = 1;
420
 
+        clickFinger2 = (priv->has_right || priv->has_middle) ? 1 : 3;
421
 
+        clickFinger3 = 0; /* Disabled by default so three-touch gestures work */
422
 
+    }
423
 
 
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");
437
 
     }
438
 
+
439
 
+    set_softbutton_areas_option(pInfo);
440
 
 }
441
 
 
442
 
 #if GET_ABI_MAJOR(ABI_XINPUT_VERSION) >= 14
443
 
@@ -1355,6 +1480,60 @@ is_inside_active_area(SynapticsPrivate *
444
 
     return inside_area;
445
 
 }
446
 
 
447
 
+static Bool
448
 
+is_inside_rightbutton_area(SynapticsParameters *para, int x, int y)
449
 
+{
450
 
+    Bool inside_area = TRUE;
451
 
+
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)
456
 
+        return FALSE;
457
 
+
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;
470
 
+
471
 
+    return inside_area;
472
 
+}
473
 
+
474
 
+static Bool
475
 
+is_inside_middlebutton_area(SynapticsParameters *para, int x, int y)
476
 
+{
477
 
+    Bool inside_area = TRUE;
478
 
+
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)
483
 
+        return FALSE;
484
 
+
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;
497
 
+
498
 
+    return inside_area;
499
 
+}
500
 
+
501
 
 static CARD32
502
 
 timerFunc(OsTimerPtr timer, CARD32 now, pointer arg)
503
 
 {
504
 
@@ -1411,6 +1590,14 @@ ReadInput(InputInfoPtr pInfo)
505
 
     SynapticsResetTouchHwState(hw);
506
 
 
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;
514
 
+       }
515
 
+
516
 
        SynapticsCopyHwState(priv->hwState, hw);
517
 
        delay = HandleState(pInfo, hw, hw->millis, FALSE);
518
 
        newDelay = TRUE;
519
 
@@ -1692,7 +1879,7 @@ HandleTapProcessing(SynapticsPrivate *pr
520
 
                    Bool inside_active_area)
521
 
 {
522
 
     SynapticsParameters *para = &priv->synpara;
523
 
-    Bool touch, release, is_timeout, move;
524
 
+    Bool touch, release, is_timeout, move, press;
525
 
     int timeleft, timeout;
526
 
     edge_type edge;
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);
533
 
 
534
 
     if (touch) {
535
 
        priv->touch_on.x = hw->x;
536
 
@@ -1728,6 +1916,10 @@ HandleTapProcessing(SynapticsPrivate *pr
537
 
            SetTapState(priv, TS_1, now);
538
 
        break;
539
 
     case TS_1:
540
 
+       if (para->clickpad && press) {
541
 
+           SetTapState(priv, TS_CLICKPAD_MOVE, now);
542
 
+           goto restart;
543
 
+       }
544
 
        if (move) {
545
 
            SetMovingState(priv, MS_TOUCHPAD_RELATIVE, now);
546
 
            SetTapState(priv, TS_MOVE, now);
547
 
@@ -1751,6 +1943,10 @@ HandleTapProcessing(SynapticsPrivate *pr
548
 
        }
549
 
        break;
550
 
     case TS_MOVE:
551
 
+       if (para->clickpad && press) {
552
 
+           SetTapState(priv, TS_CLICKPAD_MOVE, now);
553
 
+           goto restart;
554
 
+       }
555
 
        if (move && priv->moving_state == MS_TRACKSTICK) {
556
 
            SetMovingState(priv, MS_TOUCHPAD_RELATIVE, now);
557
 
        }
558
 
@@ -1805,6 +2001,10 @@ HandleTapProcessing(SynapticsPrivate *pr
559
 
        }
560
 
        break;
561
 
     case TS_DRAG:
562
 
+       if (para->clickpad && press) {
563
 
+           SetTapState(priv, TS_CLICKPAD_MOVE, now);
564
 
+           goto restart;
565
 
+       }
566
 
        if (move)
567
 
            SetMovingState(priv, MS_TOUCHPAD_RELATIVE, now);
568
 
        if (release) {
569
 
@@ -1833,6 +2033,23 @@ HandleTapProcessing(SynapticsPrivate *pr
570
 
            SetTapState(priv, TS_START, now);
571
 
        }
572
 
        break;
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;
579
 
+
580
 
+        /* Assume one touch is only for holding the clickpad button down */
581
 
+       if (hw->numFingers > 1)
582
 
+           hw->numFingers--;
583
 
+       SetMovingState(priv, MS_TOUCHPAD_RELATIVE, now);
584
 
+       if (!press) {
585
 
+           SetMovingState(priv, MS_FALSE, now);
586
 
+           SetTapState(priv, TS_MOVE, now);
587
 
+           priv->count_packet_finger = 0;
588
 
+       }
589
 
+       break;
590
 
     }
591
 
 
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;
596
 
 
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;
602
 
 
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);
608
 
 
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 */
612
 
 
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);
617
 
 
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)
621
 
+    {
622
 
+        if (is_inside_rightbutton_area(para, hw->x, hw->y))
623
 
+        {
624
 
+            hw->left = 0;
625
 
+            hw->right = 1;
626
 
+        }
627
 
+        else if (is_inside_middlebutton_area(para, hw->x, hw->y))
628
 
+        {
629
 
+            hw->left = 0;
630
 
+            hw->middle = 1;
631
 
+        }
632
 
+    }
633
 
+
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--;
639
 
     }
640
 
 
641
 
+    if (priv->has_semi_mt)
642
 
+        goto out;
643
 
+
644
 
     if (priv->num_active_touches < min_touches &&
645
 
         new_active_touches < min_touches)
646
 
     {
647
 
@@ -2752,6 +2987,14 @@ HandleState(InputInfoPtr pInfo, struct S
648
 
        return delay;
649
 
     }
650
 
 
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))
654
 
+    {
655
 
+        hw->x = hw->cumulative_dx;
656
 
+        hw->y = hw->cumulative_dy;
657
 
+    }
658
 
+
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 */
673
 
 };
674
 
 
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;
691
 
 
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 */
697
 
 
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
705
 
     dst->x = src->x;
706
 
     dst->y = src->y;
707
 
     dst->z = src->z;
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 */
723
 
     int numFingers;
724
 
     int fingerWidth;
725
 
 
726
 
@@ -115,4 +117,6 @@ extern void SynapticsCopyHwState(struct
727
 
                                  const struct SynapticsHwState *src);
728
 
 extern void SynapticsResetTouchHwState(struct SynapticsHwState *hw);
729
 
 
730
 
+extern Bool SynapticsIsSoftButtonAreasValid(int *values);
731
 
+
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
738
 
 {
739
 
 }
740
 
 
741
 
+_X_EXPORT int valuator_mask_get(const ValuatorMask *mask, int valuator)
742
 
+{
743
 
+    return 0;
744
 
+}
745
 
+
746
 
 _X_EXPORT void valuator_mask_set(ValuatorMask *mask, int valuator, int data)
747
 
 {
748
 
 }
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
753
 
@@ -38,6 +38,7 @@
754
 
 #include <string.h>
755
 
 #include <stddef.h>
756
 
 #include <math.h>
757
 
+#include <limits.h>
758
 
 
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},
774
 
     { NULL, 0, 0, 0, 0 }
775
 
 };
776