702
714
pars->tap_move = xf86SetIntOption(opts, "MaxTapMove", tapMove);
703
715
pars->tap_time_2 = xf86SetIntOption(opts, "MaxDoubleTapTime", 180);
704
716
pars->click_time = xf86SetIntOption(opts, "ClickTime", 100);
705
pars->clickpad = xf86SetBoolOption(opts, "ClickPad", pars->clickpad); /* Probed */
717
pars->clickpad = xf86SetBoolOption(opts, "ClickPad", pars->clickpad); /* Probed */
706
718
pars->fast_taps = xf86SetBoolOption(opts, "FastTaps", FALSE);
707
719
/* middle mouse button emulation on a clickpad? nah, you're joking */
708
720
middle_button_timeout = pars->clickpad ? 0 : 75;
709
pars->emulate_mid_button_time = xf86SetIntOption(opts, "EmulateMidButtonTime", middle_button_timeout);
710
pars->emulate_twofinger_z = xf86SetIntOption(opts, "EmulateTwoFingerMinZ", emulateTwoFingerMinZ);
711
pars->emulate_twofinger_w = xf86SetIntOption(opts, "EmulateTwoFingerMinW", emulateTwoFingerMinW);
712
pars->scroll_dist_vert = xf86SetIntOption(opts, "VertScrollDelta", vertScrollDelta);
713
pars->scroll_dist_horiz = xf86SetIntOption(opts, "HorizScrollDelta", horizScrollDelta);
714
pars->scroll_edge_vert = xf86SetBoolOption(opts, "VertEdgeScroll", vertEdgeScroll);
715
pars->scroll_edge_horiz = xf86SetBoolOption(opts, "HorizEdgeScroll", horizEdgeScroll);
721
pars->emulate_mid_button_time =
722
xf86SetIntOption(opts, "EmulateMidButtonTime", middle_button_timeout);
723
pars->emulate_twofinger_z =
724
xf86SetIntOption(opts, "EmulateTwoFingerMinZ", emulateTwoFingerMinZ);
725
pars->emulate_twofinger_w =
726
xf86SetIntOption(opts, "EmulateTwoFingerMinW", emulateTwoFingerMinW);
727
pars->scroll_dist_vert =
728
xf86SetIntOption(opts, "VertScrollDelta", vertScrollDelta);
729
pars->scroll_dist_horiz =
730
xf86SetIntOption(opts, "HorizScrollDelta", horizScrollDelta);
731
pars->scroll_edge_vert =
732
xf86SetBoolOption(opts, "VertEdgeScroll", vertEdgeScroll);
733
pars->scroll_edge_horiz =
734
xf86SetBoolOption(opts, "HorizEdgeScroll", horizEdgeScroll);
716
735
pars->scroll_edge_corner = xf86SetBoolOption(opts, "CornerCoasting", FALSE);
717
pars->scroll_twofinger_vert = xf86SetBoolOption(opts, "VertTwoFingerScroll", vertTwoFingerScroll);
718
pars->scroll_twofinger_horiz = xf86SetBoolOption(opts, "HorizTwoFingerScroll", horizTwoFingerScroll);
719
pars->edge_motion_min_z = xf86SetIntOption(opts, "EdgeMotionMinZ", edgeMotionMinZ);
720
pars->edge_motion_max_z = xf86SetIntOption(opts, "EdgeMotionMaxZ", edgeMotionMaxZ);
721
pars->edge_motion_min_speed = xf86SetIntOption(opts, "EdgeMotionMinSpeed", edgeMotionMinSpeed);
722
pars->edge_motion_max_speed = xf86SetIntOption(opts, "EdgeMotionMaxSpeed", edgeMotionMaxSpeed);
723
pars->edge_motion_use_always = xf86SetBoolOption(opts, "EdgeMotionUseAlways", FALSE);
736
pars->scroll_twofinger_vert =
737
xf86SetBoolOption(opts, "VertTwoFingerScroll", vertTwoFingerScroll);
738
pars->scroll_twofinger_horiz =
739
xf86SetBoolOption(opts, "HorizTwoFingerScroll", horizTwoFingerScroll);
740
pars->edge_motion_min_z =
741
xf86SetIntOption(opts, "EdgeMotionMinZ", edgeMotionMinZ);
742
pars->edge_motion_max_z =
743
xf86SetIntOption(opts, "EdgeMotionMaxZ", edgeMotionMaxZ);
744
pars->edge_motion_min_speed =
745
xf86SetIntOption(opts, "EdgeMotionMinSpeed", edgeMotionMinSpeed);
746
pars->edge_motion_max_speed =
747
xf86SetIntOption(opts, "EdgeMotionMaxSpeed", edgeMotionMaxSpeed);
748
pars->edge_motion_use_always =
749
xf86SetBoolOption(opts, "EdgeMotionUseAlways", FALSE);
724
750
if (priv->has_scrollbuttons) {
725
pars->updown_button_scrolling = xf86SetBoolOption(opts, "UpDownScrolling", TRUE);
726
pars->leftright_button_scrolling = xf86SetBoolOption(opts, "LeftRightScrolling", TRUE);
727
pars->updown_button_repeat = xf86SetBoolOption(opts, "UpDownScrollRepeat", TRUE);
728
pars->leftright_button_repeat = xf86SetBoolOption(opts, "LeftRightScrollRepeat", TRUE);
751
pars->updown_button_scrolling =
752
xf86SetBoolOption(opts, "UpDownScrolling", TRUE);
753
pars->leftright_button_scrolling =
754
xf86SetBoolOption(opts, "LeftRightScrolling", TRUE);
755
pars->updown_button_repeat =
756
xf86SetBoolOption(opts, "UpDownScrollRepeat", TRUE);
757
pars->leftright_button_repeat =
758
xf86SetBoolOption(opts, "LeftRightScrollRepeat", TRUE);
730
pars->scroll_button_repeat = xf86SetIntOption(opts,"ScrollButtonRepeat", 100);
760
pars->scroll_button_repeat =
761
xf86SetIntOption(opts, "ScrollButtonRepeat", 100);
731
762
pars->touchpad_off = xf86SetIntOption(opts, "TouchpadOff", 0);
732
763
pars->locked_drags = xf86SetBoolOption(opts, "LockedDrags", FALSE);
733
764
pars->locked_drag_time = xf86SetIntOption(opts, "LockedDragTimeout", 5000);
735
766
pars->tap_action[RB_TAP] = xf86SetIntOption(opts, "RBCornerButton", 0);
736
767
pars->tap_action[LT_TAP] = xf86SetIntOption(opts, "LTCornerButton", 0);
737
768
pars->tap_action[LB_TAP] = xf86SetIntOption(opts, "LBCornerButton", 0);
738
pars->tap_action[F1_TAP] = xf86SetIntOption(opts, "TapButton1", tapButton1);
739
pars->tap_action[F2_TAP] = xf86SetIntOption(opts, "TapButton2", tapButton2);
740
pars->tap_action[F3_TAP] = xf86SetIntOption(opts, "TapButton3", tapButton3);
741
pars->click_action[F1_CLICK1] = xf86SetIntOption(opts, "ClickFinger1", clickFinger1);
742
pars->click_action[F2_CLICK1] = xf86SetIntOption(opts, "ClickFinger2", clickFinger2);
743
pars->click_action[F3_CLICK1] = xf86SetIntOption(opts, "ClickFinger3", clickFinger3);
744
pars->circular_scrolling = xf86SetBoolOption(opts, "CircularScrolling", FALSE);
745
pars->circular_trigger = xf86SetIntOption(opts, "CircScrollTrigger", 0);
746
pars->circular_pad = xf86SetBoolOption(opts, "CircularPad", FALSE);
747
pars->palm_detect = xf86SetBoolOption(opts, "PalmDetect", FALSE);
748
pars->palm_min_width = xf86SetIntOption(opts, "PalmMinWidth", palmMinWidth);
749
pars->palm_min_z = xf86SetIntOption(opts, "PalmMinZ", palmMinZ);
769
pars->tap_action[F1_TAP] = xf86SetIntOption(opts, "TapButton1", tapButton1);
770
pars->tap_action[F2_TAP] = xf86SetIntOption(opts, "TapButton2", tapButton2);
771
pars->tap_action[F3_TAP] = xf86SetIntOption(opts, "TapButton3", tapButton3);
772
pars->click_action[F1_CLICK1] =
773
xf86SetIntOption(opts, "ClickFinger1", clickFinger1);
774
pars->click_action[F2_CLICK1] =
775
xf86SetIntOption(opts, "ClickFinger2", clickFinger2);
776
pars->click_action[F3_CLICK1] =
777
xf86SetIntOption(opts, "ClickFinger3", clickFinger3);
778
pars->circular_scrolling =
779
xf86SetBoolOption(opts, "CircularScrolling", FALSE);
780
pars->circular_trigger = xf86SetIntOption(opts, "CircScrollTrigger", 0);
781
pars->circular_pad = xf86SetBoolOption(opts, "CircularPad", FALSE);
782
pars->palm_detect = xf86SetBoolOption(opts, "PalmDetect", FALSE);
783
pars->palm_min_width = xf86SetIntOption(opts, "PalmMinWidth", palmMinWidth);
784
pars->palm_min_z = xf86SetIntOption(opts, "PalmMinZ", palmMinZ);
750
785
pars->single_tap_timeout = xf86SetIntOption(opts, "SingleTapTimeout", 180);
751
pars->press_motion_min_z = xf86SetIntOption(opts, "PressureMotionMinZ", pressureMotionMinZ);
752
pars->press_motion_max_z = xf86SetIntOption(opts, "PressureMotionMaxZ", pressureMotionMaxZ);
786
pars->press_motion_min_z =
787
xf86SetIntOption(opts, "PressureMotionMinZ", pressureMotionMinZ);
788
pars->press_motion_max_z =
789
xf86SetIntOption(opts, "PressureMotionMaxZ", pressureMotionMaxZ);
754
791
pars->min_speed = xf86SetRealOption(opts, "MinSpeed", 0.4);
755
792
pars->max_speed = xf86SetRealOption(opts, "MaxSpeed", 0.7);
1321
1362
* acceleration.
1323
1364
if (NULL != (pVel = GetDevicePredictableAccelData(dev))) {
1324
SetDeviceSpecificAccelerationProfile(pVel,
1325
SynapticsAccelerationProfile);
1327
/* float property type */
1328
float_type = XIGetKnownProperty(XATOM_FLOAT);
1330
/* translate MinAcc to constant deceleration.
1331
* May be overridden in xf86InitValuatorDefaults */
1332
tmpf = 1.0 / priv->synpara.min_speed;
1334
xf86IDrvMsg(pInfo, X_CONFIG, "(accel) MinSpeed is now constant deceleration "
1336
prop = XIGetKnownProperty(ACCEL_PROP_CONSTANT_DECELERATION);
1337
XIChangeDeviceProperty(dev, prop, float_type, 32,
1338
PropModeReplace, 1, &tmpf, FALSE);
1340
/* adjust accordingly */
1341
priv->synpara.max_speed /= priv->synpara.min_speed;
1342
priv->synpara.min_speed = 1.0;
1344
/* synaptics seems to report 80 packet/s, but dix scales for
1345
* 100 packet/s by default. */
1346
pVel->corr_mul = 12.5f; /*1000[ms]/80[/s] = 12.5 */
1348
xf86IDrvMsg(pInfo, X_CONFIG, "MaxSpeed is now %.2f\n",
1349
priv->synpara.max_speed);
1350
xf86IDrvMsg(pInfo, X_CONFIG, "AccelFactor is now %.3f\n",
1351
priv->synpara.accl);
1353
prop = XIGetKnownProperty(ACCEL_PROP_PROFILE_NUMBER);
1354
i = AccelProfileDeviceSpecific;
1355
XIChangeDeviceProperty(dev, prop, XA_INTEGER, 32,
1356
PropModeReplace, 1, &i, FALSE);
1365
SetDeviceSpecificAccelerationProfile(pVel,
1366
SynapticsAccelerationProfile);
1368
/* float property type */
1369
float_type = XIGetKnownProperty(XATOM_FLOAT);
1371
/* translate MinAcc to constant deceleration.
1372
* May be overridden in xf86InitValuatorDefaults */
1373
tmpf = 1.0 / priv->synpara.min_speed;
1375
xf86IDrvMsg(pInfo, X_CONFIG,
1376
"(accel) MinSpeed is now constant deceleration " "%.1f\n",
1378
prop = XIGetKnownProperty(ACCEL_PROP_CONSTANT_DECELERATION);
1379
XIChangeDeviceProperty(dev, prop, float_type, 32,
1380
PropModeReplace, 1, &tmpf, FALSE);
1382
/* adjust accordingly */
1383
priv->synpara.max_speed /= priv->synpara.min_speed;
1384
priv->synpara.min_speed = 1.0;
1386
/* synaptics seems to report 80 packet/s, but dix scales for
1387
* 100 packet/s by default. */
1388
pVel->corr_mul = 12.5f; /*1000[ms]/80[/s] = 12.5 */
1390
xf86IDrvMsg(pInfo, X_CONFIG, "MaxSpeed is now %.2f\n",
1391
priv->synpara.max_speed);
1392
xf86IDrvMsg(pInfo, X_CONFIG, "AccelFactor is now %.3f\n",
1393
priv->synpara.accl);
1395
prop = XIGetKnownProperty(ACCEL_PROP_PROFILE_NUMBER);
1396
i = AccelProfileDeviceSpecific;
1397
XIChangeDeviceProperty(dev, prop, XA_INTEGER, 32,
1398
PropModeReplace, 1, &i, FALSE);
1359
1401
/* X valuator */
1360
if (priv->minx < priv->maxx)
1402
if (priv->minx < priv->maxx) {
1362
1403
min = priv->minx;
1363
1404
max = priv->maxx;
1370
1411
xf86InitValuatorAxisStruct(dev, 0, axes_labels[0],
1371
min, max, priv->resx * 1000, 0, priv->resx * 1000
1412
min, max, priv->resx * 1000, 0, priv->resx * 1000
1372
1413
#if GET_ABI_MAJOR(ABI_XINPUT_VERSION) >= 12
1376
1417
xf86InitValuatorDefaults(dev, 0);
1378
1419
/* Y valuator */
1379
if (priv->miny < priv->maxy)
1420
if (priv->miny < priv->maxy) {
1381
1421
min = priv->miny;
1382
1422
max = priv->maxy;
1389
1429
xf86InitValuatorAxisStruct(dev, 1, axes_labels[1],
1390
min, max, priv->resy * 1000, 0, priv->resy * 1000
1430
min, max, priv->resy * 1000, 0, priv->resy * 1000
1391
1431
#if GET_ABI_MAJOR(ABI_XINPUT_VERSION) >= 12
1395
1435
xf86InitValuatorDefaults(dev, 1);
1397
1437
#ifdef HAVE_SMOOTH_SCROLL
1991
2054
switch (priv->tap_state) {
1994
SetTapState(priv, TS_1, now);
2057
SetTapState(priv, TS_1, now);
1997
if (para->clickpad && press) {
1998
SetTapState(priv, TS_CLICKPAD_MOVE, now);
2002
SetMovingState(priv, MS_TOUCHPAD_RELATIVE, now);
2003
SetTapState(priv, TS_MOVE, now);
2005
} else if (is_timeout) {
2006
if (finger == FS_TOUCHED) {
2007
SetMovingState(priv, MS_TOUCHPAD_RELATIVE, now);
2008
} else if (finger == FS_PRESSED) {
2009
SetMovingState(priv, MS_TRACKSTICK, now);
2011
SetTapState(priv, TS_MOVE, now);
2013
} else if (release) {
2014
edge = edge_detection(priv, priv->touch_on.x, priv->touch_on.y);
2015
SelectTapButton(priv, edge);
2016
/* Disable taps outside of the active area */
2017
if (!inside_active_area) {
2018
priv->tap_button = 0;
2020
SetTapState(priv, TS_2A, now);
2060
if (para->clickpad && press) {
2061
SetTapState(priv, TS_CLICKPAD_MOVE, now);
2065
SetMovingState(priv, MS_TOUCHPAD_RELATIVE, now);
2066
SetTapState(priv, TS_MOVE, now);
2069
else if (is_timeout) {
2070
if (finger == FS_TOUCHED) {
2071
SetMovingState(priv, MS_TOUCHPAD_RELATIVE, now);
2073
else if (finger == FS_PRESSED) {
2074
SetMovingState(priv, MS_TRACKSTICK, now);
2076
SetTapState(priv, TS_MOVE, now);
2080
edge = edge_detection(priv, priv->touch_on.x, priv->touch_on.y);
2081
SelectTapButton(priv, edge);
2082
/* Disable taps outside of the active area */
2083
if (!inside_active_area) {
2084
priv->tap_button = 0;
2086
SetTapState(priv, TS_2A, now);
2024
if (para->clickpad && press) {
2025
SetTapState(priv, TS_CLICKPAD_MOVE, now);
2028
if (move && priv->moving_state == MS_TRACKSTICK) {
2029
SetMovingState(priv, MS_TOUCHPAD_RELATIVE, now);
2032
SetMovingState(priv, MS_FALSE, now);
2033
SetTapState(priv, TS_START, now);
2090
if (para->clickpad && press) {
2091
SetTapState(priv, TS_CLICKPAD_MOVE, now);
2094
if (move && priv->moving_state == MS_TRACKSTICK) {
2095
SetMovingState(priv, MS_TOUCHPAD_RELATIVE, now);
2098
SetMovingState(priv, MS_FALSE, now);
2099
SetTapState(priv, TS_START, now);
2038
SetTapState(priv, TS_3, now);
2039
else if (is_timeout)
2040
SetTapState(priv, TS_SINGLETAP, now);
2104
SetTapState(priv, TS_3, now);
2105
else if (is_timeout)
2106
SetTapState(priv, TS_SINGLETAP, now);
2044
SetTapState(priv, TS_3, now);
2045
} else if (is_timeout) {
2046
SetTapState(priv, TS_START, now);
2047
priv->tap_button_state = TBS_BUTTON_DOWN_UP;
2110
SetTapState(priv, TS_3, now);
2112
else if (is_timeout) {
2113
SetTapState(priv, TS_START, now);
2114
priv->tap_button_state = TBS_BUTTON_DOWN_UP;
2050
2117
case TS_SINGLETAP:
2052
SetTapState(priv, TS_1, now);
2053
else if (is_timeout)
2054
SetTapState(priv, TS_START, now);
2119
SetTapState(priv, TS_1, now);
2120
else if (is_timeout)
2121
SetTapState(priv, TS_START, now);
2058
if (para->tap_and_drag_gesture) {
2059
SetMovingState(priv, MS_TOUCHPAD_RELATIVE, now);
2060
SetTapState(priv, TS_DRAG, now);
2062
SetTapState(priv, TS_1, now);
2065
} else if (is_timeout) {
2066
if (para->tap_and_drag_gesture) {
2067
if (finger == FS_TOUCHED) {
2068
SetMovingState(priv, MS_TOUCHPAD_RELATIVE, now);
2069
} else if (finger == FS_PRESSED) {
2070
SetMovingState(priv, MS_TRACKSTICK, now);
2072
SetTapState(priv, TS_DRAG, now);
2074
SetTapState(priv, TS_1, now);
2077
} else if (release) {
2078
SetTapState(priv, TS_2B, now);
2125
if (para->tap_and_drag_gesture) {
2126
SetMovingState(priv, MS_TOUCHPAD_RELATIVE, now);
2127
SetTapState(priv, TS_DRAG, now);
2130
SetTapState(priv, TS_1, now);
2134
else if (is_timeout) {
2135
if (para->tap_and_drag_gesture) {
2136
if (finger == FS_TOUCHED) {
2137
SetMovingState(priv, MS_TOUCHPAD_RELATIVE, now);
2139
else if (finger == FS_PRESSED) {
2140
SetMovingState(priv, MS_TRACKSTICK, now);
2142
SetTapState(priv, TS_DRAG, now);
2145
SetTapState(priv, TS_1, now);
2150
SetTapState(priv, TS_2B, now);
2082
if (para->clickpad && press) {
2083
SetTapState(priv, TS_CLICKPAD_MOVE, now);
2087
SetMovingState(priv, MS_TOUCHPAD_RELATIVE, now);
2089
SetMovingState(priv, MS_FALSE, now);
2090
if (para->locked_drags) {
2091
SetTapState(priv, TS_4, now);
2093
SetTapState(priv, TS_START, now);
2154
if (para->clickpad && press) {
2155
SetTapState(priv, TS_CLICKPAD_MOVE, now);
2159
SetMovingState(priv, MS_TOUCHPAD_RELATIVE, now);
2161
SetMovingState(priv, MS_FALSE, now);
2162
if (para->locked_drags) {
2163
SetTapState(priv, TS_4, now);
2166
SetTapState(priv, TS_START, now);
2099
SetTapState(priv, TS_START, now);
2103
SetTapState(priv, TS_5, now);
2172
SetTapState(priv, TS_START, now);
2176
SetTapState(priv, TS_5, now);
2106
if (is_timeout || move) {
2107
SetTapState(priv, TS_DRAG, now);
2109
} else if (release) {
2110
SetMovingState(priv, MS_FALSE, now);
2111
SetTapState(priv, TS_START, now);
2179
if (is_timeout || move) {
2180
SetTapState(priv, TS_DRAG, now);
2184
SetMovingState(priv, MS_FALSE, now);
2185
SetTapState(priv, TS_START, now);
2114
2188
case TS_CLICKPAD_MOVE:
2115
/* Disable scrolling once a button is pressed on a clickpad */
2116
priv->vert_scroll_edge_on = FALSE;
2117
priv->horiz_scroll_edge_on = FALSE;
2118
priv->vert_scroll_twofinger_on = FALSE;
2119
priv->horiz_scroll_twofinger_on = FALSE;
2189
/* Disable scrolling once a button is pressed on a clickpad */
2190
priv->vert_scroll_edge_on = FALSE;
2191
priv->horiz_scroll_edge_on = FALSE;
2192
priv->vert_scroll_twofinger_on = FALSE;
2193
priv->horiz_scroll_twofinger_on = FALSE;
2121
2195
/* Assume one touch is only for holding the clickpad button down */
2122
if (hw->numFingers > 1)
2124
SetMovingState(priv, MS_TOUCHPAD_RELATIVE, now);
2126
SetMovingState(priv, MS_FALSE, now);
2127
SetTapState(priv, TS_MOVE, now);
2128
priv->count_packet_finger = 0;
2196
if (hw->numFingers > 1)
2198
SetMovingState(priv, MS_TOUCHPAD_RELATIVE, now);
2200
SetMovingState(priv, MS_FALSE, now);
2201
SetTapState(priv, TS_MOVE, now);
2202
priv->count_packet_finger = 0;
2133
2207
timeout = GetTimeOut(priv);
2134
2208
if (timeout >= 0) {
2135
timeleft = TIME_DIFF(priv->touch_on.millis + timeout, now);
2136
delay = clamp(timeleft, 1, delay);
2209
timeleft = TIME_DIFF(priv->touch_on.millis + timeout, now);
2210
delay = clamp(timeleft, 1, delay);
2416
HandleScrolling(SynapticsPrivate *priv, struct SynapticsHwState *hw,
2417
edge_type edge, Bool finger)
2514
HandleScrolling(SynapticsPrivate * priv, struct SynapticsHwState *hw,
2515
edge_type edge, Bool finger)
2419
2517
SynapticsParameters *para = &priv->synpara;
2420
2518
int delay = 1000000000;
2422
2520
if ((priv->synpara.touchpad_off == 2) || (priv->finger_state == FS_BLOCKED)) {
2423
stop_coasting(priv);
2424
priv->circ_scroll_on = FALSE;
2425
priv->vert_scroll_edge_on = FALSE;
2426
priv->horiz_scroll_edge_on = FALSE;
2427
priv->vert_scroll_twofinger_on = FALSE;
2428
priv->horiz_scroll_twofinger_on = FALSE;
2521
stop_coasting(priv);
2522
priv->circ_scroll_on = FALSE;
2523
priv->vert_scroll_edge_on = FALSE;
2524
priv->horiz_scroll_edge_on = FALSE;
2525
priv->vert_scroll_twofinger_on = FALSE;
2526
priv->horiz_scroll_twofinger_on = FALSE;
2432
2530
/* scroll detection */
2433
2531
if (finger && priv->finger_state == FS_UNTOUCHED) {
2434
stop_coasting(priv);
2532
stop_coasting(priv);
2435
2533
priv->scroll.delta_y = 0;
2436
2534
priv->scroll.delta_x = 0;
2437
if (para->circular_scrolling) {
2438
if ((para->circular_trigger == 0 && edge) ||
2439
(para->circular_trigger == 1 && edge & TOP_EDGE) ||
2440
(para->circular_trigger == 2 && edge & TOP_EDGE && edge & RIGHT_EDGE) ||
2441
(para->circular_trigger == 3 && edge & RIGHT_EDGE) ||
2442
(para->circular_trigger == 4 && edge & RIGHT_EDGE && edge & BOTTOM_EDGE) ||
2443
(para->circular_trigger == 5 && edge & BOTTOM_EDGE) ||
2444
(para->circular_trigger == 6 && edge & BOTTOM_EDGE && edge & LEFT_EDGE) ||
2445
(para->circular_trigger == 7 && edge & LEFT_EDGE) ||
2446
(para->circular_trigger == 8 && edge & LEFT_EDGE && edge & TOP_EDGE)) {
2447
priv->circ_scroll_on = TRUE;
2448
priv->circ_scroll_vert = TRUE;
2449
priv->scroll.last_a = angle(priv, hw->x, hw->y);
2450
DBG(7, "circular scroll detected on edge\n");
2535
if (para->circular_scrolling) {
2536
if ((para->circular_trigger == 0 && edge) ||
2537
(para->circular_trigger == 1 && edge & TOP_EDGE) ||
2538
(para->circular_trigger == 2 && edge & TOP_EDGE &&
2539
edge & RIGHT_EDGE) || (para->circular_trigger == 3 &&
2540
edge & RIGHT_EDGE) ||
2541
(para->circular_trigger == 4 && edge & RIGHT_EDGE &&
2542
edge & BOTTOM_EDGE) || (para->circular_trigger == 5 &&
2543
edge & BOTTOM_EDGE) ||
2544
(para->circular_trigger == 6 && edge & BOTTOM_EDGE &&
2545
edge & LEFT_EDGE) || (para->circular_trigger == 7 &&
2546
edge & LEFT_EDGE) ||
2547
(para->circular_trigger == 8 && edge & LEFT_EDGE &&
2549
priv->circ_scroll_on = TRUE;
2550
priv->circ_scroll_vert = TRUE;
2551
priv->scroll.last_a = angle(priv, hw->x, hw->y);
2552
DBG(7, "circular scroll detected on edge\n");
2454
2556
if (!priv->circ_scroll_on) {
2456
if (hw->numFingers == 2) {
2457
if (!priv->vert_scroll_twofinger_on &&
2458
(para->scroll_twofinger_vert) && (para->scroll_dist_vert != 0)) {
2459
stop_coasting(priv);
2460
priv->vert_scroll_twofinger_on = TRUE;
2461
priv->vert_scroll_edge_on = FALSE;
2462
priv->scroll.last_y = hw->y;
2463
DBG(7, "vert two-finger scroll detected\n");
2465
if (!priv->horiz_scroll_twofinger_on &&
2466
(para->scroll_twofinger_horiz) && (para->scroll_dist_horiz != 0)) {
2467
stop_coasting(priv);
2468
priv->horiz_scroll_twofinger_on = TRUE;
2469
priv->horiz_scroll_edge_on = FALSE;
2470
priv->scroll.last_x = hw->x;
2471
DBG(7, "horiz two-finger scroll detected\n");
2475
if (finger && priv->finger_state == FS_UNTOUCHED) {
2476
if (!priv->vert_scroll_twofinger_on && !priv->horiz_scroll_twofinger_on) {
2477
if ((para->scroll_edge_vert) && (para->scroll_dist_vert != 0) &&
2478
(edge & RIGHT_EDGE)) {
2479
priv->vert_scroll_edge_on = TRUE;
2480
priv->scroll.last_y = hw->y;
2481
DBG(7, "vert edge scroll detected on right edge\n");
2483
if ((para->scroll_edge_horiz) && (para->scroll_dist_horiz != 0) &&
2484
(edge & BOTTOM_EDGE)) {
2485
priv->horiz_scroll_edge_on = TRUE;
2486
priv->scroll.last_x = hw->x;
2487
DBG(7, "horiz edge scroll detected on bottom edge\n");
2558
if (hw->numFingers == 2) {
2559
if (!priv->vert_scroll_twofinger_on &&
2560
(para->scroll_twofinger_vert) &&
2561
(para->scroll_dist_vert != 0)) {
2562
stop_coasting(priv);
2563
priv->vert_scroll_twofinger_on = TRUE;
2564
priv->vert_scroll_edge_on = FALSE;
2565
priv->scroll.last_y = hw->y;
2566
DBG(7, "vert two-finger scroll detected\n");
2568
if (!priv->horiz_scroll_twofinger_on &&
2569
(para->scroll_twofinger_horiz) &&
2570
(para->scroll_dist_horiz != 0)) {
2571
stop_coasting(priv);
2572
priv->horiz_scroll_twofinger_on = TRUE;
2573
priv->horiz_scroll_edge_on = FALSE;
2574
priv->scroll.last_x = hw->x;
2575
DBG(7, "horiz two-finger scroll detected\n");
2579
if (finger && priv->finger_state == FS_UNTOUCHED) {
2580
if (!priv->vert_scroll_twofinger_on &&
2581
!priv->horiz_scroll_twofinger_on) {
2582
if ((para->scroll_edge_vert) && (para->scroll_dist_vert != 0) &&
2583
(edge & RIGHT_EDGE)) {
2584
priv->vert_scroll_edge_on = TRUE;
2585
priv->scroll.last_y = hw->y;
2586
DBG(7, "vert edge scroll detected on right edge\n");
2588
if ((para->scroll_edge_horiz) && (para->scroll_dist_horiz != 0)
2589
&& (edge & BOTTOM_EDGE)) {
2590
priv->horiz_scroll_edge_on = TRUE;
2591
priv->scroll.last_x = hw->x;
2592
DBG(7, "horiz edge scroll detected on bottom edge\n");
2493
Bool oldv = priv->vert_scroll_twofinger_on || priv->vert_scroll_edge_on ||
2494
(priv->circ_scroll_on && priv->circ_scroll_vert);
2496
Bool oldh = priv->horiz_scroll_twofinger_on || priv->horiz_scroll_edge_on ||
2497
(priv->circ_scroll_on && !priv->circ_scroll_vert);
2499
Bool oldc = priv->circ_scroll_on;
2501
if (priv->circ_scroll_on && !finger) {
2502
/* circular scroll locks in until finger is raised */
2503
DBG(7, "cicular scroll off\n");
2504
priv->circ_scroll_on = FALSE;
2507
if (!finger || hw->numFingers != 2) {
2508
if (priv->vert_scroll_twofinger_on) {
2509
DBG(7, "vert two-finger scroll off\n");
2510
priv->vert_scroll_twofinger_on = FALSE;
2512
if (priv->horiz_scroll_twofinger_on) {
2513
DBG(7, "horiz two-finger scroll off\n");
2514
priv->horiz_scroll_twofinger_on = FALSE;
2518
if (priv->vert_scroll_edge_on && (!(edge & RIGHT_EDGE) || !finger)) {
2519
DBG(7, "vert edge scroll off\n");
2520
priv->vert_scroll_edge_on = FALSE;
2522
if (priv->horiz_scroll_edge_on && (!(edge & BOTTOM_EDGE) || !finger)) {
2523
DBG(7, "horiz edge scroll off\n");
2524
priv->horiz_scroll_edge_on = FALSE;
2526
/* If we were corner edge scrolling (coasting),
2527
* but no longer in corner or raised a finger, then stop coasting. */
2528
if (para->scroll_edge_corner && (priv->scroll.coast_speed_x || priv->scroll.coast_speed_y)) {
2530
((edge & RIGHT_EDGE) && (edge & (TOP_EDGE | BOTTOM_EDGE))) ||
2531
((edge & BOTTOM_EDGE) && (edge & (LEFT_EDGE | RIGHT_EDGE))) ;
2532
if (!is_in_corner || !finger) {
2533
DBG(7, "corner edge scroll off\n");
2534
stop_coasting(priv);
2537
/* if we were scrolling, but couldn't corner edge scroll,
2538
* and are no longer scrolling, then start coasting */
2539
oldv = oldv && !(priv->vert_scroll_twofinger_on || priv->vert_scroll_edge_on ||
2540
(priv->circ_scroll_on && priv->circ_scroll_vert));
2542
oldh = oldh && !(priv->horiz_scroll_twofinger_on || priv->horiz_scroll_edge_on ||
2543
(priv->circ_scroll_on && !priv->circ_scroll_vert));
2545
oldc = oldc && !priv->circ_scroll_on;
2547
if ((oldv || oldh) && !para->scroll_edge_corner) {
2548
start_coasting(priv, hw, oldv, oldh, oldc);
2598
Bool oldv = priv->vert_scroll_twofinger_on || priv->vert_scroll_edge_on
2599
|| (priv->circ_scroll_on && priv->circ_scroll_vert);
2601
Bool oldh = priv->horiz_scroll_twofinger_on ||
2602
priv->horiz_scroll_edge_on || (priv->circ_scroll_on &&
2603
!priv->circ_scroll_vert);
2605
Bool oldc = priv->circ_scroll_on;
2607
if (priv->circ_scroll_on && !finger) {
2608
/* circular scroll locks in until finger is raised */
2609
DBG(7, "cicular scroll off\n");
2610
priv->circ_scroll_on = FALSE;
2613
if (!finger || hw->numFingers != 2) {
2614
if (priv->vert_scroll_twofinger_on) {
2615
DBG(7, "vert two-finger scroll off\n");
2616
priv->vert_scroll_twofinger_on = FALSE;
2618
if (priv->horiz_scroll_twofinger_on) {
2619
DBG(7, "horiz two-finger scroll off\n");
2620
priv->horiz_scroll_twofinger_on = FALSE;
2624
if (priv->vert_scroll_edge_on && (!(edge & RIGHT_EDGE) || !finger)) {
2625
DBG(7, "vert edge scroll off\n");
2626
priv->vert_scroll_edge_on = FALSE;
2628
if (priv->horiz_scroll_edge_on && (!(edge & BOTTOM_EDGE) || !finger)) {
2629
DBG(7, "horiz edge scroll off\n");
2630
priv->horiz_scroll_edge_on = FALSE;
2632
/* If we were corner edge scrolling (coasting),
2633
* but no longer in corner or raised a finger, then stop coasting. */
2634
if (para->scroll_edge_corner &&
2635
(priv->scroll.coast_speed_x || priv->scroll.coast_speed_y)) {
2636
Bool is_in_corner = ((edge & RIGHT_EDGE) &&
2637
(edge & (TOP_EDGE | BOTTOM_EDGE))) ||
2638
((edge & BOTTOM_EDGE) && (edge & (LEFT_EDGE | RIGHT_EDGE)));
2639
if (!is_in_corner || !finger) {
2640
DBG(7, "corner edge scroll off\n");
2641
stop_coasting(priv);
2644
/* if we were scrolling, but couldn't corner edge scroll,
2645
* and are no longer scrolling, then start coasting */
2646
oldv = oldv && !(priv->vert_scroll_twofinger_on ||
2647
priv->vert_scroll_edge_on || (priv->circ_scroll_on &&
2648
priv->circ_scroll_vert));
2650
oldh = oldh && !(priv->horiz_scroll_twofinger_on ||
2651
priv->horiz_scroll_edge_on || (priv->circ_scroll_on &&
2655
oldc = oldc && !priv->circ_scroll_on;
2657
if ((oldv || oldh) && !para->scroll_edge_corner) {
2658
start_coasting(priv, hw, oldv, oldh, oldc);
2552
2662
/* if hitting a corner (top right or bottom right) while vertical
2553
2663
* scrolling is active, consider starting corner edge scrolling or
2554
2664
* switching over to circular scrolling smoothly */
2555
2665
if (priv->vert_scroll_edge_on && !priv->horiz_scroll_edge_on &&
2556
(edge & RIGHT_EDGE) && (edge & (TOP_EDGE | BOTTOM_EDGE))) {
2557
if (para->scroll_edge_corner) {
2558
if (priv->scroll.coast_speed_y == 0) {
2559
/* FYI: We can generate multiple start_coasting requests if
2560
* we're in the corner, but we were moving so slowly when we
2561
* got here that we didn't actually start coasting. */
2562
DBG(7, "corner edge scroll on\n");
2563
start_coasting(priv, hw, TRUE, FALSE, FALSE);
2565
} else if (para->circular_scrolling) {
2566
priv->vert_scroll_edge_on = FALSE;
2567
priv->circ_scroll_on = TRUE;
2568
priv->circ_scroll_vert = TRUE;
2569
priv->scroll.last_a = angle(priv, hw->x, hw->y);
2570
DBG(7, "switching to circular scrolling\n");
2666
(edge & RIGHT_EDGE) && (edge & (TOP_EDGE | BOTTOM_EDGE))) {
2667
if (para->scroll_edge_corner) {
2668
if (priv->scroll.coast_speed_y == 0) {
2669
/* FYI: We can generate multiple start_coasting requests if
2670
* we're in the corner, but we were moving so slowly when we
2671
* got here that we didn't actually start coasting. */
2672
DBG(7, "corner edge scroll on\n");
2673
start_coasting(priv, hw, TRUE, FALSE, FALSE);
2676
else if (para->circular_scrolling) {
2677
priv->vert_scroll_edge_on = FALSE;
2678
priv->circ_scroll_on = TRUE;
2679
priv->circ_scroll_vert = TRUE;
2680
priv->scroll.last_a = angle(priv, hw->x, hw->y);
2681
DBG(7, "switching to circular scrolling\n");
2573
2684
/* Same treatment for horizontal scrolling */
2574
2685
if (priv->horiz_scroll_edge_on && !priv->vert_scroll_edge_on &&
2575
(edge & BOTTOM_EDGE) && (edge & (LEFT_EDGE | RIGHT_EDGE))) {
2576
if (para->scroll_edge_corner) {
2577
if (priv->scroll.coast_speed_x == 0) {
2578
/* FYI: We can generate multiple start_coasting requests if
2579
* we're in the corner, but we were moving so slowly when we
2580
* got here that we didn't actually start coasting. */
2581
DBG(7, "corner edge scroll on\n");
2582
start_coasting(priv, hw, FALSE, TRUE, FALSE);
2584
} else if (para->circular_scrolling) {
2585
priv->horiz_scroll_edge_on = FALSE;
2586
priv->circ_scroll_on = TRUE;
2587
priv->circ_scroll_vert = FALSE;
2588
priv->scroll.last_a = angle(priv, hw->x, hw->y);
2589
DBG(7, "switching to circular scrolling\n");
2686
(edge & BOTTOM_EDGE) && (edge & (LEFT_EDGE | RIGHT_EDGE))) {
2687
if (para->scroll_edge_corner) {
2688
if (priv->scroll.coast_speed_x == 0) {
2689
/* FYI: We can generate multiple start_coasting requests if
2690
* we're in the corner, but we were moving so slowly when we
2691
* got here that we didn't actually start coasting. */
2692
DBG(7, "corner edge scroll on\n");
2693
start_coasting(priv, hw, FALSE, TRUE, FALSE);
2696
else if (para->circular_scrolling) {
2697
priv->horiz_scroll_edge_on = FALSE;
2698
priv->circ_scroll_on = TRUE;
2699
priv->circ_scroll_vert = FALSE;
2700
priv->scroll.last_a = angle(priv, hw->x, hw->y);
2701
DBG(7, "switching to circular scrolling\n");
2593
2705
if (priv->vert_scroll_edge_on || priv->horiz_scroll_edge_on ||
2594
priv->vert_scroll_twofinger_on || priv->horiz_scroll_twofinger_on ||
2595
priv->circ_scroll_on) {
2596
priv->scroll.packets_this_scroll++;
2706
priv->vert_scroll_twofinger_on || priv->horiz_scroll_twofinger_on ||
2707
priv->circ_scroll_on) {
2708
priv->scroll.packets_this_scroll++;
2599
2711
if (priv->vert_scroll_edge_on || priv->vert_scroll_twofinger_on) {
2600
/* + = down, - = up */
2601
if (para->scroll_dist_vert != 0 && hw->y != priv->scroll.last_y) {
2602
priv->scroll.delta_y += (hw->y - priv->scroll.last_y);
2603
priv->scroll.last_y = hw->y;
2712
/* + = down, - = up */
2713
if (para->scroll_dist_vert != 0 && hw->y != priv->scroll.last_y) {
2714
priv->scroll.delta_y += (hw->y - priv->scroll.last_y);
2715
priv->scroll.last_y = hw->y;
2606
2718
if (priv->horiz_scroll_edge_on || priv->horiz_scroll_twofinger_on) {
2607
/* + = right, - = left */
2608
if (para->scroll_dist_horiz != 0 && hw->x != priv->scroll.last_x) {
2609
priv->scroll.delta_x += (hw->x - priv->scroll.last_x);
2610
priv->scroll.last_x = hw->x;
2719
/* + = right, - = left */
2720
if (para->scroll_dist_horiz != 0 && hw->x != priv->scroll.last_x) {
2721
priv->scroll.delta_x += (hw->x - priv->scroll.last_x);
2722
priv->scroll.last_x = hw->x;
2613
2725
if (priv->circ_scroll_on) {
2614
/* + = counter clockwise, - = clockwise */
2615
double delta = para->scroll_dist_circ;
2616
double diff = diffa(priv->scroll.last_a, angle(priv, hw->x, hw->y));
2617
if (delta >= 0.005 && diff != 0.0) {
2618
if (priv->circ_scroll_vert)
2619
priv->scroll.delta_y -= diff / delta * para->scroll_dist_vert;
2621
priv->scroll.delta_x -= diff / delta * para->scroll_dist_horiz;
2622
priv->scroll.last_a = angle(priv, hw->x, hw->y);
2726
/* + = counter clockwise, - = clockwise */
2727
double delta = para->scroll_dist_circ;
2728
double diff = diffa(priv->scroll.last_a, angle(priv, hw->x, hw->y));
2730
if (delta >= 0.005 && diff != 0.0) {
2731
if (priv->circ_scroll_vert)
2732
priv->scroll.delta_y -= diff / delta * para->scroll_dist_vert;
2734
priv->scroll.delta_x -= diff / delta * para->scroll_dist_horiz;
2735
priv->scroll.last_a = angle(priv, hw->x, hw->y);
2626
2739
if (priv->scroll.coast_speed_y) {
2627
double dtime = (hw->millis - priv->scroll.last_millis) / 1000.0;
2628
double ddy = para->coasting_friction * dtime * abs(para->scroll_dist_vert);
2740
double dtime = (hw->millis - priv->scroll.last_millis) / 1000.0;
2741
double ddy = para->coasting_friction * dtime;
2630
priv->scroll.delta_y += priv->scroll.coast_speed_y * dtime;
2631
delay = MIN(delay, POLL_MS);
2632
if (abs(priv->scroll.coast_speed_y) < ddy) {
2633
priv->scroll.coast_speed_y = 0;
2634
priv->scroll.packets_this_scroll = 0;
2636
priv->scroll.coast_speed_y += (priv->scroll.coast_speed_y < 0 ? ddy : -ddy);
2743
priv->scroll.delta_y += priv->scroll.coast_speed_y * dtime * para->scroll_dist_vert;
2744
delay = MIN(delay, POLL_MS);
2745
if (abs(priv->scroll.coast_speed_y) < ddy) {
2746
priv->scroll.coast_speed_y = 0;
2747
priv->scroll.packets_this_scroll = 0;
2750
priv->scroll.coast_speed_y +=
2751
(priv->scroll.coast_speed_y < 0 ? ddy : -ddy);
2640
2755
if (priv->scroll.coast_speed_x) {
2641
double dtime = (hw->millis - priv->scroll.last_millis) / 1000.0;
2642
double ddx = para->coasting_friction * dtime * abs(para->scroll_dist_horiz);
2643
priv->scroll.delta_x += priv->scroll.coast_speed_x * dtime;
2644
delay = MIN(delay, POLL_MS);
2645
if (abs(priv->scroll.coast_speed_x) < ddx) {
2646
priv->scroll.coast_speed_x = 0;
2647
priv->scroll.packets_this_scroll = 0;
2649
priv->scroll.coast_speed_x += (priv->scroll.coast_speed_x < 0 ? ddx : -ddx);
2756
double dtime = (hw->millis - priv->scroll.last_millis) / 1000.0;
2757
double ddx = para->coasting_friction * dtime;
2758
priv->scroll.delta_x += priv->scroll.coast_speed_x * dtime * para->scroll_dist_vert;
2759
delay = MIN(delay, POLL_MS);
2760
if (abs(priv->scroll.coast_speed_x) < ddx) {
2761
priv->scroll.coast_speed_x = 0;
2762
priv->scroll.packets_this_scroll = 0;
2765
priv->scroll.coast_speed_x +=
2766
(priv->scroll.coast_speed_x < 0 ? ddx : -ddx);
3183
3290
/* now we know that these _coordinates_ aren't in the area.
3184
3291
invalid are: x, y, z, numFingers, fingerWidth
3185
3292
valid are: millis, left/right/middle/up/down/etc.
3187
if (!inside_active_area)
3294
if (!inside_active_area) {
3191
/* FIXME: if finger accidentally moves into the area and doesn't
3192
* really release, the finger should remain down. */
3297
/* FIXME: if finger accidentally moves into the area and doesn't
3298
* really release, the finger should remain down. */
3195
3301
/* these two just update hw->left, right, etc. */
3196
3302
update_hw_button_state(pInfo, hw, priv->old_hw_state, now, &delay);
3197
3303
if (priv->has_scrollbuttons)
3198
double_click = adjust_state_from_scrollbuttons(pInfo, hw);
3304
double_click = adjust_state_from_scrollbuttons(pInfo, hw);
3200
3306
/* no edge or finger detection outside of area */
3201
3307
if (inside_active_area) {
3202
edge = edge_detection(priv, hw->x, hw->y);
3204
finger = SynapticsDetectFinger(priv, hw);
3206
finger = priv->finger_state;
3308
edge = edge_detection(priv, hw->x, hw->y);
3310
finger = SynapticsDetectFinger(priv, hw);
3312
finger = priv->finger_state;
3209
3315
/* tap and drag detection. Needs to be performed even if the finger is in
3210
3316
* the dead area to reset the state. */
3211
3317
timeleft = HandleTapProcessing(priv, hw, now, finger, inside_active_area);
3212
3318
if (timeleft > 0)
3213
delay = MIN(delay, timeleft);
3215
if (inside_active_area)
3217
/* Don't bother about scrolling in the dead area of the touchpad. */
3218
timeleft = HandleScrolling(priv, hw, edge, (finger >= FS_TOUCHED));
3220
delay = MIN(delay, timeleft);
3223
* Compensate for unequal x/y resolution. This needs to be done after
3224
* calculations that require unadjusted coordinates, for example edge
3227
ScaleCoordinates(priv, hw);
3319
delay = MIN(delay, timeleft);
3321
if (inside_active_area) {
3322
/* Don't bother about scrolling in the dead area of the touchpad. */
3323
timeleft = HandleScrolling(priv, hw, edge, (finger >= FS_TOUCHED));
3325
delay = MIN(delay, timeleft);
3328
* Compensate for unequal x/y resolution. This needs to be done after
3329
* calculations that require unadjusted coordinates, for example edge
3332
ScaleCoordinates(priv, hw);
3232
3337
if (!priv->absolute_events) {
3233
timeleft = ComputeDeltas(priv, hw, edge, &dx, &dy, inside_active_area);
3234
delay = MIN(delay, timeleft);
3338
timeleft = ComputeDeltas(priv, hw, edge, &dx, &dy, inside_active_area);
3339
delay = MIN(delay, timeleft);
3238
buttons = ((hw->left ? 0x01 : 0) |
3239
(hw->middle ? 0x02 : 0) |
3240
(hw->right ? 0x04 : 0) |
3241
(hw->up ? 0x08 : 0) |
3242
(hw->down ? 0x10 : 0) |
3243
(hw->multi[2] ? 0x20 : 0) |
3244
(hw->multi[3] ? 0x40 : 0));
3342
buttons = ((hw->left ? 0x01 : 0) |
3343
(hw->middle ? 0x02 : 0) |
3344
(hw->right ? 0x04 : 0) |
3345
(hw->up ? 0x08 : 0) |
3346
(hw->down ? 0x10 : 0) |
3347
(hw->multi[2] ? 0x20 : 0) | (hw->multi[3] ? 0x40 : 0));
3246
3349
if (priv->tap_button > 0) {
3247
int tap_mask = 1 << (priv->tap_button - 1);
3248
if (priv->tap_button_state == TBS_BUTTON_DOWN_UP) {
3249
if (tap_mask != (priv->lastButtons & tap_mask)) {
3250
xf86PostButtonEvent(pInfo->dev, FALSE, priv->tap_button, TRUE, 0, 0);
3251
priv->lastButtons |= tap_mask;
3253
priv->tap_button_state = TBS_BUTTON_UP;
3255
if (priv->tap_button_state == TBS_BUTTON_DOWN)
3256
buttons |= tap_mask;
3350
int tap_mask = 1 << (priv->tap_button - 1);
3352
if (priv->tap_button_state == TBS_BUTTON_DOWN_UP) {
3353
if (tap_mask != (priv->lastButtons & tap_mask)) {
3354
xf86PostButtonEvent(pInfo->dev, FALSE, priv->tap_button, TRUE,
3356
priv->lastButtons |= tap_mask;
3358
priv->tap_button_state = TBS_BUTTON_UP;
3360
if (priv->tap_button_state == TBS_BUTTON_DOWN)
3361
buttons |= tap_mask;
3259
3364
/* Post events */
3260
3365
if (finger >= FS_TOUCHED) {
3261
3366
if (priv->absolute_events && inside_active_area) {
3262
3367
xf86PostMotionEvent(pInfo->dev, 1, 0, 2, hw->x, hw->y);
3263
} else if (dx || dy) {
3369
else if (dx || dy) {
3264
3370
xf86PostMotionEvent(pInfo->dev, 0, 0, 2, dx, dy);
3268
if (priv->mid_emu_state == MBE_LEFT_CLICK)
3270
post_button_click(pInfo, 1);
3271
priv->mid_emu_state = MBE_OFF;
3272
} else if (priv->mid_emu_state == MBE_RIGHT_CLICK)
3274
post_button_click(pInfo, 3);
3275
priv->mid_emu_state = MBE_OFF;
3374
if (priv->mid_emu_state == MBE_LEFT_CLICK) {
3375
post_button_click(pInfo, 1);
3376
priv->mid_emu_state = MBE_OFF;
3378
else if (priv->mid_emu_state == MBE_RIGHT_CLICK) {
3379
post_button_click(pInfo, 3);
3380
priv->mid_emu_state = MBE_OFF;
3278
3383
change = buttons ^ priv->lastButtons;
3279
3384
while (change) {
3280
id = ffs(change); /* number of first set bit 1..32 is returned */
3281
change &= ~(1 << (id - 1));
3282
xf86PostButtonEvent(pInfo->dev, FALSE, id, (buttons & (1 << (id - 1))), 0, 0);
3385
id = ffs(change); /* number of first set bit 1..32 is returned */
3386
change &= ~(1 << (id - 1));
3387
xf86PostButtonEvent(pInfo->dev, FALSE, id, (buttons & (1 << (id - 1))),
3285
3391
if (priv->has_scrollbuttons)
3286
delay = repeat_scrollbuttons(pInfo, hw, buttons, now, delay);
3392
delay = repeat_scrollbuttons(pInfo, hw, buttons, now, delay);
3288
3394
/* Process scroll events only if coordinates are
3289
3395
* in the Synaptics Area
3291
3397
if (inside_active_area &&
3292
3398
(priv->scroll.delta_x != 0.0 || priv->scroll.delta_y != 0.0)) {
3293
post_scroll_events(pInfo);
3294
priv->scroll.last_millis = hw->millis;
3399
post_scroll_events(pInfo);
3400
priv->scroll.last_millis = hw->millis;
3297
3403
if (double_click) {
3298
post_button_click(pInfo, 1);
3299
post_button_click(pInfo, 1);
3404
post_button_click(pInfo, 1);
3405
post_button_click(pInfo, 1);
3302
3408
HandleTouches(pInfo, hw);