View | Details | Raw Unified | Return to bug 206649 | Differences between
and this patch

Collapse All | Expand All

(-)/usr/src/sys/dev/cyapa/cyapa.c (-21 / +185 lines)
Lines 3-9 Link Here
3
 *
3
 *
4
 * This code is derived from software contributed to The DragonFly Project
4
 * This code is derived from software contributed to The DragonFly Project
5
 * by Matthew Dillon <dillon@backplane.com> and was subsequently ported,
5
 * by Matthew Dillon <dillon@backplane.com> and was subsequently ported,
6
 * modified and enhanced for FreeBSD by Michael Gmelin <freebsd@grem.de>.
6
 * modified and enhanced for FreeBSD by Michael Gmelin <freebsd@grem.de>,
7
 * commonly used gestures added by Alexander Mishurov <ammishurov@gmail.com>.
7
 *
8
 *
8
 * Redistribution and use in source and binary forms, with or without
9
 * Redistribution and use in source and binary forms, with or without
9
 * modification, are permitted provided that the following conditions
10
 * modification, are permitted provided that the following conditions
Lines 34-40 Link Here
34
 */
35
 */
35
36
36
#include <sys/cdefs.h>
37
#include <sys/cdefs.h>
37
__FBSDID("$FreeBSD: head/sys/dev/cyapa/cyapa.c 286918 2015-08-19 09:49:29Z grembo $");
38
__FBSDID("$FreeBSD$");
38
39
39
/*
40
/*
40
 * CYAPA - Cypress APA trackpad with I2C Interface driver
41
 * CYAPA - Cypress APA trackpad with I2C Interface driver
Lines 89-94 Link Here
89
 *                          event. Optional tap support can be enabled
90
 *                          event. Optional tap support can be enabled
90
 *                          and configured using sysctl.
91
 *                          and configured using sysctl.
91
 *
92
 *
93
 * Two finger tap         - Use two finger tap for right click.
94
 *
95
 * Tap and drag           - Drag through short touching and holding
96
 *                          down a finger on a touchpad.
97
 *
92
 *                              WARNINGS
98
 *                              WARNINGS
93
 *
99
 *
94
 * These trackpads get confused when three or more fingers are down on the
100
 * These trackpads get confused when three or more fingers are down on the
Lines 185-190 Link Here
185
	int	finger3_ticks;
191
	int	finger3_ticks;
186
	uint16_t reported_but;
192
	uint16_t reported_but;
187
193
194
	enum	{T_IDLE, T_ONE, T_TWO} tft_state;
195
	int	tft_ticks;
196
	enum	{D_IDLE, D_WAIT, D_DRAG, D_SEND} drag_state;
197
	int	dragwait_ticks;
198
	int	draglock_ticks;
199
	uint16_t send_but;
200
188
	struct cyapa_fifo rfifo;	/* device->host */
201
	struct cyapa_fifo rfifo;	/* device->host */
189
	struct cyapa_fifo wfifo;	/* host->device */
202
	struct cyapa_fifo wfifo;	/* host->device */
190
	uint8_t	ps2_cmd;		/* active p2_cmd waiting for data */
203
	uint8_t	ps2_cmd;		/* active p2_cmd waiting for data */
Lines 266-271 Link Here
266
	    &cyapa_thumbarea_percent, 0,
279
	    &cyapa_thumbarea_percent, 0,
267
	    "Size of bottom thumb area in percent");
280
	    "Size of bottom thumb area in percent");
268
281
282
static int cyapa_enable_tapdrag = 0;
283
SYSCTL_INT(_debug, OID_AUTO, cyapa_enable_tapdrag, CTLFLAG_RW,
284
	    &cyapa_enable_tapdrag, 0,
285
	    "Enable tap'n'drag guesture");
286
static int cyapa_tapdrag_wait_ticks = 15;
287
SYSCTL_INT(_debug, OID_AUTO, cyapa_tapdrag_wait_ticks, CTLFLAG_RW,
288
	    &cyapa_tapdrag_wait_ticks, 0,
289
	    "Lock button and wait if it'll be a second tap to lock for drag");
290
static int cyapa_tapdrag_stick_ticks = 20;
291
SYSCTL_INT(_debug, OID_AUTO, cyapa_tapdrag_stick_ticks, CTLFLAG_RW,
292
	    &cyapa_tapdrag_stick_ticks, 0,
293
	    "Time to keep button locked after stopped moving while drag");
294
static int cyapa_tapdrag_doubleclick_ticks = 30;
295
SYSCTL_INT(_debug, OID_AUTO, cyapa_tapdrag_doubleclick_ticks, CTLFLAG_RW,
296
	    &cyapa_tapdrag_doubleclick_ticks, 0,
297
	    "Duration when second finger release can send double click");
298
269
static int cyapa_debug = 0;
299
static int cyapa_debug = 0;
270
SYSCTL_INT(_debug, OID_AUTO, cyapa_debug, CTLFLAG_RW,
300
SYSCTL_INT(_debug, OID_AUTO, cyapa_debug, CTLFLAG_RW,
271
	    &cyapa_debug, 0, "Enable debugging");
301
	    &cyapa_debug, 0, "Enable debugging");
Lines 524-529 Link Here
524
	sc->mode.level = 0;
554
	sc->mode.level = 0;
525
	sc->mode.packetsize = MOUSE_PS2_PACKETSIZE;
555
	sc->mode.packetsize = MOUSE_PS2_PACKETSIZE;
526
556
557
	sc->drag_state = D_IDLE;
558
	sc->draglock_ticks = -1;
559
	sc->dragwait_ticks = -1;
560
	sc->tft_state = D_IDLE;
561
	sc->tft_ticks = -1;
562
	sc->send_but = 0;
563
527
	/* Setup input event tracking */
564
	/* Setup input event tracking */
528
	cyapa_set_power_mode(sc, CMD_POWER_MODE_IDLE);
565
	cyapa_set_power_mode(sc, CMD_POWER_MODE_IDLE);
529
566
Lines 536-541 Link Here
536
573
537
	sc->devnode->si_drv1 = sc;
574
	sc->devnode->si_drv1 = sc;
538
575
576
539
	return (0);
577
	return (0);
540
}
578
}
541
579
Lines 1256-1263 Link Here
1256
	int x;
1294
	int x;
1257
	int y;
1295
	int y;
1258
	int z;
1296
	int z;
1259
	int newfinger;
1297
	int deltafingers;
1260
	int lessfingers;
1261
	int click_x;
1298
	int click_x;
1262
	int click_y;
1299
	int click_y;
1263
	uint16_t but;	/* high bits used for simulated but4/but5 */
1300
	uint16_t but;	/* high bits used for simulated but4/but5 */
Lines 1341-1348 Link Here
1341
			sc->finger3_ticks = sc->poll_ticks;
1378
			sc->finger3_ticks = sc->poll_ticks;
1342
		break;
1379
		break;
1343
	}
1380
	}
1344
	newfinger = sc->track_nfingers < afingers;
1381
	deltafingers = afingers - sc->track_nfingers;
1345
	lessfingers = sc->track_nfingers > afingers;
1346
	sc->track_nfingers = afingers;
1382
	sc->track_nfingers = afingers;
1347
1383
1348
	/*
1384
	/*
Lines 1392-1406 Link Here
1392
			sc->track_id = regs->touch[i].id;
1428
			sc->track_id = regs->touch[i].id;
1393
		}
1429
		}
1394
		else if ((sc->track_but ||
1430
		else if ((sc->track_but ||
1395
		     CYAPA_TOUCH_Y(regs, i) >= thumbarea_begin) &&
1431
		    CYAPA_TOUCH_Y(regs, i) >= thumbarea_begin) &&
1396
		    newfinger && afingers == 2) {
1432
		    deltafingers > 0 && afingers == 2) {
1397
			j = regs->touch[0].id == sc->track_id ? 1 : 0;
1433
			j = regs->touch[0].id == sc->track_id ? 1 : 0;
1398
			if (CYAPA_TOUCH_Y(regs, j) < thumbarea_begin) {
1434
			if (CYAPA_TOUCH_Y(regs, j) < thumbarea_begin) {
1399
			    i = j;
1435
				i = j;
1400
			    sc->track_x = -1;
1436
				sc->track_x = -1;
1401
			    sc->track_y = -1;
1437
				sc->track_y = -1;
1402
			    sc->track_z = -1;
1438
				sc->track_z = -1;
1403
			    sc->track_id = regs->touch[i].id;
1439
				sc->track_id = regs->touch[i].id;
1404
			}
1440
			}
1405
		}
1441
		}
1406
	}
1442
	}
Lines 1466-1479 Link Here
1466
		sc->track_y = y;
1502
		sc->track_y = y;
1467
	}
1503
	}
1468
1504
1505
	/*
1506
	 * Double down
1507
	 * Because it's hard every time touch and release fingers
1508
	 * in exact same moment, there's some time range to detect
1509
	 * random sequence of 0-1-2-1-0 touches and interpret them as
1510
	 * right click then make some additional checks to
1511
	 * don't confuse touches with two finger scroll
1512
	 */
1513
	int is_tapclick = 0;
1514
1515
	if (cyapa_enable_tapclick == 4) {
1516
		switch(sc->tft_state) {
1517
		case T_IDLE:
1518
			if (deltafingers > 0 && sc->track_z == -1 &&
1519
			    sc->delta_z == 0) {
1520
				if (deltafingers == 1 && afingers == 1) {
1521
					sc->tft_ticks = sc->poll_ticks;
1522
					sc->tft_state = T_ONE;
1523
				} else if (deltafingers == 2 && afingers == 2) {
1524
					sc->tft_ticks = sc->poll_ticks;
1525
					sc->tft_state = T_TWO;
1526
				}
1527
			}
1528
			break;
1529
		case T_ONE:
1530
			if (sc->poll_ticks - sc->tft_ticks >
1531
			    cyapa_tapclick_max_ticks || afingers == 0 ||
1532
			    sc->delta_z != 0) {
1533
				sc->tft_ticks = -1;
1534
				sc->tft_state = T_IDLE;
1535
			} else if (deltafingers == 1 && afingers == 2) {
1536
				sc->tft_state = T_TWO;
1537
			}
1538
			break;
1539
		case T_TWO:
1540
			if (sc->poll_ticks - sc->tft_ticks >
1541
			    cyapa_tapclick_max_ticks || sc->delta_z != 0) {
1542
				sc->tft_ticks = -1;
1543
				sc->tft_state = T_IDLE;
1544
			} else if (deltafingers < 0 && afingers == 0 &&
1545
			    sc->track_z == -1 && sc->poll_ticks -
1546
			    sc->tft_ticks >= cyapa_tapclick_min_ticks) {
1547
				sc->tft_ticks = -1;
1548
				sc->tft_state = T_IDLE;
1549
				is_tapclick = 2;
1550
			}
1551
			break;
1552
		}
1553
	}
1554
1469
	/* Select finger (L = 2/3x, M = 1/3u, R = 1/3d) */
1555
	/* Select finger (L = 2/3x, M = 1/3u, R = 1/3d) */
1470
	int is_tapclick = (cyapa_enable_tapclick && lessfingers &&
1556
	if (cyapa_enable_tapclick && is_tapclick == 0 && deltafingers == -1 &&
1471
	    afingers == 0 && sc->poll_ticks - sc->finger1_ticks
1557
	    afingers == 0 && sc->poll_ticks - sc->finger1_ticks
1472
	    >= cyapa_tapclick_min_ticks &&
1558
	    >= cyapa_tapclick_min_ticks && sc->poll_ticks - sc->finger1_ticks
1473
	    sc->poll_ticks - sc->finger1_ticks < cyapa_tapclick_max_ticks);
1559
	    < cyapa_tapclick_max_ticks)
1560
		is_tapclick = 1;
1474
1561
1475
	if (regs->fngr & CYAPA_FNGR_LEFT || is_tapclick) {
1562
	if (regs->fngr & CYAPA_FNGR_LEFT || is_tapclick) {
1476
		if (sc->track_but) {
1563
		if (is_tapclick == 2) {
1564
			but = CYAPA_FNGR_RIGHT;
1565
		} else if (sc->track_but) {
1477
			but = sc->track_but;
1566
			but = sc->track_but;
1478
		} else if (afingers == 1) {
1567
		} else if (afingers == 1) {
1479
			if (click_x < sc->cap_resx * 2 / 3)
1568
			if (click_x < sc->cap_resx * 2 / 3)
Lines 1482-1490 Link Here
1482
				but = CYAPA_FNGR_MIDDLE;
1571
				but = CYAPA_FNGR_MIDDLE;
1483
			else
1572
			else
1484
				but = CYAPA_FNGR_RIGHT;
1573
				but = CYAPA_FNGR_RIGHT;
1485
		} else if (is_tapclick) {
1574
		} else if (is_tapclick == 1) {
1486
			if (click_x < sc->cap_resx * 2 / 3 ||
1575
			if (click_x < sc->cap_resx * 2 / 3 ||
1487
			    cyapa_enable_tapclick < 2)
1576
			    cyapa_enable_tapclick < 2 ||
1577
			    cyapa_enable_tapclick == 4)
1488
				but = CYAPA_FNGR_LEFT;
1578
				but = CYAPA_FNGR_LEFT;
1489
			else if (click_y < sc->cap_resy / 2 &&
1579
			else if (click_y < sc->cap_resy / 2 &&
1490
			    cyapa_enable_tapclick > 2)
1580
			    cyapa_enable_tapclick > 2)
Lines 1499-1510 Link Here
1499
	}
1589
	}
1500
1590
1501
	/*
1591
	/*
1592
	 * Drag n Lock
1593
	 * Finit-state machine states (sc->drag_state):
1594
	 * IDLE - idle mode, waits any event
1595
	 * WAIT - locks button and waits for second tap, releases if timeout
1596
	 * DRAG - locks button and drags, releases if moves stopped or finger up
1597
	 * SEND - sends double click sequence if double click instead drag
1598
	 * In WAIT or DRAG mode double click could be sent if touch and release
1599
	 */
1600
1601
	if (cyapa_enable_tapdrag) {
1602
		/* Handle double click the same way in two states */
1603
		if (sc->drag_state == D_SEND) {
1604
			but = sc->send_but;
1605
			sc->send_but = 0;
1606
		}
1607
		/* User can lock any button only with left button mouse */
1608
		if ((sc->drag_state == D_WAIT || sc->drag_state == D_DRAG) &&
1609
		    ((sc->poll_ticks - sc->dragwait_ticks <=
1610
		    cyapa_tapdrag_doubleclick_ticks && but ==
1611
		    CYAPA_FNGR_LEFT) || (but == CYAPA_FNGR_RIGHT ||
1612
		    but == CYAPA_FNGR_MIDDLE))) {
1613
			sc->draglock_ticks = -1;
1614
			sc->dragwait_ticks = -1;
1615
			sc->send_but = but;
1616
			sc->drag_state = D_SEND;
1617
			but = 0;
1618
		}
1619
1620
		/* Handle particular states */
1621
		switch(sc->drag_state) {
1622
		case D_IDLE:
1623
			if (but == CYAPA_FNGR_LEFT || but == CYAPA_FNGR_RIGHT ||
1624
			    but == CYAPA_FNGR_MIDDLE) {
1625
				sc->send_but = but;
1626
				sc->dragwait_ticks = sc->poll_ticks;
1627
				sc->drag_state = D_WAIT;
1628
			}
1629
			break;
1630
		case D_WAIT:
1631
			if (sc->poll_ticks - sc->dragwait_ticks >
1632
			    cyapa_tapdrag_wait_ticks || sc->delta_z != 0) {
1633
				sc->dragwait_ticks = -1;
1634
				sc->send_but = 0;
1635
				sc->drag_state = D_IDLE;
1636
			} else if (deltafingers == 1 && afingers == 1) {
1637
				sc->draglock_ticks = sc->poll_ticks;
1638
				sc->drag_state = D_DRAG;
1639
				but = sc->send_but;
1640
			} else {
1641
				but = sc->send_but;
1642
			}
1643
			break;
1644
		case D_DRAG:
1645
			if (sc->poll_ticks - sc->draglock_ticks >
1646
			    cyapa_tapdrag_stick_ticks || deltafingers < 0 ||
1647
			    sc->delta_z != 0) {
1648
				sc->dragwait_ticks = -1;
1649
				sc->draglock_ticks = -1;
1650
				sc->send_but = 0;
1651
				sc->drag_state = D_IDLE;
1652
			} else {
1653
				if (sc->delta_x || sc->delta_y)
1654
					sc->draglock_ticks = sc->poll_ticks;
1655
				but = sc->send_but;
1656
			}
1657
			break;
1658
		case D_SEND:
1659
			if (sc->send_but == 0)
1660
				sc->drag_state = D_IDLE;
1661
			break;
1662
		}
1663
	}
1664
1665
	/*
1502
	 * Detect state change from last reported state and
1666
	 * Detect state change from last reported state and
1503
	 * determine if we have gone idle.
1667
	 * determine if we have gone idle.
1504
	 */
1668
	 */
1505
	sc->track_but = but;
1669
	sc->track_but = but;
1506
	if (sc->delta_x || sc->delta_y || sc->delta_z ||
1670
	if (sc->delta_z || sc->delta_y || sc->delta_x ||
1507
	    sc->track_but != sc->reported_but) {
1671
	    sc->track_but != sc->reported_but || sc->send_but != 0) {
1508
		sc->active_tick = ticks;
1672
		sc->active_tick = ticks;
1509
		if (sc->remote_mode == 0 && sc->reporting_mode)
1673
		if (sc->remote_mode == 0 && sc->reporting_mode)
1510
			sc->data_signal = 1;
1674
			sc->data_signal = 1;
(-)/usr/src/share/man/man4/cyapa.4 (-1 / +23 lines)
Lines 1-4 Link Here
1
.\" Copyright (c) 2015 Michael Gmelin <freebsd@grem.de>
1
.\" Copyright (c) 2015 Michael Gmelin <freebsd@grem.de>
2
.\" Copyright (c) 2016 Alexander Mishurov <ammishurov@gmail.com>
2
.\" All rights reserved.
3
.\" All rights reserved.
3
.\"
4
.\"
4
.\" Redistribution and use in source and binary forms, with or without
5
.\" Redistribution and use in source and binary forms, with or without
Lines 22-28 Link Here
22
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
23
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
23
.\" SUCH DAMAGE.
24
.\" SUCH DAMAGE.
24
.\"
25
.\"
25
.\" $FreeBSD: head/share/man/man4/cyapa.4 285876 2015-07-25 18:14:35Z grembo $
26
.\" $FreeBSD$
26
.\"
27
.\"
27
.Dd July 25, 2015
28
.Dd July 25, 2015
28
.Dt CYAPA 4
29
.Dt CYAPA 4
Lines 85-90 Link Here
85
The upper right corner issues a MIDDLE button event.
86
The upper right corner issues a MIDDLE button event.
86
The lower right corner issues a RIGHT button.
87
The lower right corner issues a RIGHT button.
87
Optionally, tap to click can be enabled (see below).
88
Optionally, tap to click can be enabled (see below).
89
.It Va Two finger tap
90
Use two finger tap for right click.
91
.It Va Tap and drag
92
Drag through short touching and holding down a finger on a touchpad.
88
.El
93
.El
89
.Sh SYSCTL VARIABLES
94
.Sh SYSCTL VARIABLES
90
These
95
These
Lines 116-121 Link Here
116
pressed (see
121
pressed (see
117
.Sx DESCRIPTION
122
.Sx DESCRIPTION
118
above).
123
above).
124
.It 4
125
One finger tap generates a left mouse button event. Two finger tap
126
generates a right mouse button event.
119
.El
127
.El
120
.It Va debug.cyapa_tapclick_min_ticks
128
.It Va debug.cyapa_tapclick_min_ticks
121
Minimum tap duration in ticks to create a click, the default is 1.
129
Minimum tap duration in ticks to create a click, the default is 1.
Lines 130-135 Link Here
130
the default is 15.
138
the default is 15.
131
.It Va debug.cyapa_thumbarea_percent
139
.It Va debug.cyapa_thumbarea_percent
132
Size of bottom thumb area in percent, the default is 15.
140
Size of bottom thumb area in percent, the default is 15.
141
.It Va debug.cyapa_enable_tapdrag
142
Enable "tap and drag" gesture. First tap can be any button, second touch
143
can be only left button to lock first tap's button for dragging,
144
the default is 0.
145
.It Va debug.cyapa_tapdrag_wait_ticks
146
Ticks range to lock button and wait for second touch to start dragging or
147
when time is out, release button like usual "tap to click" behaviour,
148
the default is 15.
149
.It Va debug.cyapa_tapdrag_stick_ticks
150
Ticks range in drag mode after movings have finished and before sending button
151
release event, the default is 20.
152
.It Va debug.cyapa_tapdrag_doubleclick_ticks
153
Duration when second tap can send double click instead of start or stop
154
draggig, the default is 30.
133
.It Va debug.cyapa_debug
155
.It Va debug.cyapa_debug
134
Setting this to a non-zero value enables debug output to console and syslog,
156
Setting this to a non-zero value enables debug output to console and syslog,
135
the default is 0.
157
the default is 0.

Return to bug 206649