xref: /freebsd/usr.sbin/moused/moused/moused.c (revision 1335bf5ce1c9f0bf15c1fbed502f49e5a4950e32)
1 /*-
2  * SPDX-License-Identifier: BSD-2-Clause
3  *
4  * Copyright (c) 1997-2000 Kazutaka YOKOTA <yokota@FreeBSD.org>
5  * Copyright (c) 2004-2008 Philip Paeps <philip@FreeBSD.org>
6  * Copyright (c) 2008 Jean-Sebastien Pedron <dumbbell@FreeBSD.org>
7  * Copyright (c) 2021,2024 Vladimir Kondratyev <wulf@FreeBSD.org>
8  *
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted provided that the following conditions
11  * are met:
12  * 1. Redistributions of source code must retain the above copyright
13  *    notice, this list of conditions and the following disclaimer.
14  * 2. Redistributions in binary form must reproduce the above copyright
15  *    notice, this list of conditions and the following disclaimer in the
16  *    documentation and/or other materials provided with the distribution.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
19  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
22  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28  * SUCH DAMAGE.
29  */
30 
31 /*
32  * MOUSED.C
33  *
34  * Mouse daemon : listens to a evdev device node for mouse data stream,
35  * interprets data and passes ioctls off to the console driver.
36  *
37  */
38 
39 #include <sys/param.h>
40 #include <sys/consio.h>
41 #include <sys/event.h>
42 #include <sys/mouse.h>
43 #include <sys/socket.h>
44 #include <sys/time.h>
45 #include <sys/un.h>
46 
47 #include <dev/evdev/input.h>
48 
49 #include <bitstring.h>
50 #include <ctype.h>
51 #include <dirent.h>
52 #include <err.h>
53 #include <errno.h>
54 #include <fcntl.h>
55 #include <fnmatch.h>
56 #include <libutil.h>
57 #include <math.h>
58 #include <setjmp.h>
59 #include <signal.h>
60 #include <stdarg.h>
61 #include <stdbool.h>
62 #include <stddef.h>
63 #include <stdint.h>
64 #include <stdio.h>
65 #include <stdlib.h>
66 #include <string.h>
67 #include <syslog.h>
68 #include <unistd.h>
69 
70 #include "util.h"
71 #include "quirks.h"
72 
73 /*
74  * bitstr_t implementation must be identical to one found in EVIOCG*
75  * libevdev ioctls. Our bitstring(3) API is compatible since r299090.
76  */
77 _Static_assert(sizeof(bitstr_t) == sizeof(unsigned long),
78     "bitstr_t size mismatch");
79 
80 #define MAX_CLICKTHRESHOLD	2000	/* 2 seconds */
81 #define MAX_BUTTON2TIMEOUT	2000	/* 2 seconds */
82 #define DFLT_CLICKTHRESHOLD	 500	/* 0.5 second */
83 #define DFLT_BUTTON2TIMEOUT	 100	/* 0.1 second */
84 #define DFLT_SCROLLTHRESHOLD	   3	/* 3 pixels */
85 #define DFLT_SCROLLSPEED	   2	/* 2 pixels */
86 #define	DFLT_MOUSE_RESOLUTION	   8	/* dpmm, == 200dpi */
87 #define	DFLT_TPAD_RESOLUTION	  40	/* dpmm, typical X res for Synaptics */
88 #define	DFLT_LINEHEIGHT		  10	/* pixels per line */
89 
90 /* Abort 3-button emulation delay after this many movement events. */
91 #define BUTTON2_MAXMOVE	3
92 
93 #define MOUSE_XAXIS	(-1)
94 #define MOUSE_YAXIS	(-2)
95 
96 #define	ZMAP_MAXBUTTON	4	/* Number of zmap items */
97 #define	MAX_FINGERS	10
98 
99 #define ID_NONE		0
100 #define ID_PORT		1
101 #define ID_IF		2
102 #define ID_TYPE		4
103 #define ID_MODEL	8
104 #define ID_ALL		(ID_PORT | ID_IF | ID_TYPE | ID_MODEL)
105 
106 /* Operations on timespecs */
107 #define	tsclr(tvp)		timespecclear(tvp)
108 #define	tscmp(tvp, uvp, cmp)	timespeccmp(tvp, uvp, cmp)
109 #define	tssub(tvp, uvp, vvp)	timespecsub(tvp, uvp, vvp)
110 #define	msec2ts(msec)	(struct timespec) {			\
111 	.tv_sec = (msec) / 1000,				\
112 	.tv_nsec = (msec) % 1000 * 1000000,			\
113 }
114 static inline struct timespec
tsaddms(struct timespec * tsp,u_int ms)115 tsaddms(struct timespec* tsp, u_int ms)
116 {
117 	struct timespec ret;
118 
119 	ret = msec2ts(ms);
120 	timespecadd(tsp, &ret, &ret);
121 
122 	return (ret);
123 };
124 
125 static inline struct timespec
tssubms(struct timespec * tsp,u_int ms)126 tssubms(struct timespec* tsp, u_int ms)
127 {
128 	struct timespec ret;
129 
130 	ret = msec2ts(ms);
131 	timespecsub(tsp, &ret, &ret);
132 
133 	return (ret);
134 };
135 
136 #define debug(...) do {						\
137 	if (debug && nodaemon)					\
138 		warnx(__VA_ARGS__);				\
139 } while (0)
140 
141 #define logerr(e, ...) do {					\
142 	log_or_warn(LOG_DAEMON | LOG_ERR, errno, __VA_ARGS__);	\
143 	exit(e);						\
144 } while (0)
145 
146 #define logerrx(e, ...) do {					\
147 	log_or_warn(LOG_DAEMON | LOG_ERR, 0, __VA_ARGS__);	\
148 	exit(e);						\
149 } while (0)
150 
151 #define logwarn(...)						\
152 	log_or_warn(LOG_DAEMON | LOG_WARNING, errno, __VA_ARGS__)
153 
154 #define logwarnx(...)						\
155 	log_or_warn(LOG_DAEMON | LOG_WARNING, 0, __VA_ARGS__)
156 
157 /* structures */
158 
159 enum gesture {
160 	GEST_IGNORE,
161 	GEST_ACCUMULATE,
162 	GEST_MOVE,
163 	GEST_VSCROLL,
164 	GEST_HSCROLL,
165 };
166 
167 /* interfaces (the table must be ordered by DEVICE_IF_XXX in util.h) */
168 static const struct {
169 	const char *name;
170 	size_t p_size;
171 } rifs[] = {
172 	[DEVICE_IF_EVDEV]	= { "evdev",	sizeof(struct input_event) },
173 	[DEVICE_IF_SYSMOUSE]	= { "sysmouse",	MOUSE_SYS_PACKETSIZE },
174 };
175 
176 /* types (the table must be ordered by DEVICE_TYPE_XXX in util.h) */
177 static const char *rnames[] = {
178 	[DEVICE_TYPE_MOUSE]		= "mouse",
179 	[DEVICE_TYPE_POINTINGSTICK]	= "pointing stick",
180 	[DEVICE_TYPE_TOUCHPAD]		= "touchpad",
181 	[DEVICE_TYPE_TOUCHSCREEN]	= "touchscreen",
182 	[DEVICE_TYPE_TABLET]		= "tablet",
183 	[DEVICE_TYPE_TABLET_PAD]	= "tablet pad",
184 	[DEVICE_TYPE_KEYBOARD]		= "keyboard",
185 	[DEVICE_TYPE_JOYSTICK]		= "joystick",
186 };
187 
188 /* Default phisical to logical button mapping */
189 static const u_int default_p2l[MOUSE_MAXBUTTON] = {
190     MOUSE_BUTTON1DOWN, MOUSE_BUTTON2DOWN, MOUSE_BUTTON3DOWN, MOUSE_BUTTON4DOWN,
191     MOUSE_BUTTON5DOWN, MOUSE_BUTTON6DOWN, MOUSE_BUTTON7DOWN, MOUSE_BUTTON8DOWN,
192     0x00000100,        0x00000200,        0x00000400,        0x00000800,
193     0x00001000,        0x00002000,        0x00004000,        0x00008000,
194     0x00010000,        0x00020000,        0x00040000,        0x00080000,
195     0x00100000,        0x00200000,        0x00400000,        0x00800000,
196     0x01000000,        0x02000000,        0x04000000,        0x08000000,
197     0x10000000,        0x20000000,        0x40000000,
198 };
199 
200 struct tpcaps {
201 	bool	is_clickpad;
202 	bool	is_topbuttonpad;
203 	bool	is_mt;
204 	bool	cap_touch;
205 	bool	cap_pressure;
206 	bool	cap_width;
207 	int	min_x;
208 	int	max_x;
209 	int	min_y;
210 	int	max_y;
211 	int	res_x;	/* dots per mm */
212 	int	res_y;	/* dots per mm */
213 	int	min_p;
214 	int	max_p;
215 };
216 
217 struct tpinfo {
218 	bool	two_finger_scroll;	/* Enable two finger scrolling */
219 	bool	natural_scroll;		/* Enable natural scrolling */
220 	bool	three_finger_drag;	/* Enable dragging with three fingers */
221 	u_int	min_pressure_hi;	/* Min pressure to start an action */
222 	u_int	min_pressure_lo;	/* Min pressure to continue an action */
223 	u_int	max_pressure;		/* Maximum pressure to detect palm */
224 	u_int	max_width;		/* Max finger width to detect palm */
225 	int	margin_top;		/* Top margin */
226 	int	margin_right;		/* Right margin */
227 	int	margin_bottom;		/* Bottom margin */
228 	int	margin_left;		/* Left margin */
229 	u_int	tap_timeout;		/* */
230 	u_int	tap_threshold;		/* Minimum pressure to detect a tap */
231 	double	tap_max_delta;		/* Length of segments above which a tap is ignored */
232 	u_int	taphold_timeout;	/* Maximum elapsed time between two taps to consider a tap-hold action */
233 	double	vscroll_ver_area;	/* Area reserved for vertical virtual scrolling */
234 	double	vscroll_hor_area;	/* Area reserved for horizontal virtual scrolling */
235 	double	vscroll_min_delta;	/* Minimum movement to consider virtual scrolling */
236 	int	softbuttons_y;		/* Vertical size of softbuttons area */
237 	int	softbutton2_x;		/* Horizontal offset of 2-nd softbutton left edge */
238 	int	softbutton3_x;		/* Horizontal offset of 3-rd softbutton left edge */
239 };
240 
241 struct tpstate {
242 	int 		start_x;
243 	int 		start_y;
244 	int 		prev_x;
245 	int 		prev_y;
246 	int		prev_nfingers;
247 	int		fingers_nb;
248 	int		tap_button;
249 	bool		fingerdown;
250 	bool		in_taphold;
251 	int		in_vscroll;
252 	u_int		zmax;           /* maximum pressure value */
253 	struct timespec	taptimeout;     /* tap timeout for touchpads */
254 	int		idletimeout;
255 	bool		timer_armed;
256 };
257 
258 struct tpad {
259 	struct tpcaps	hw;	/* touchpad capabilities */
260 	struct tpinfo	info;	/* touchpad gesture parameters */
261 	struct tpstate	gest;	/* touchpad gesture state */
262 };
263 
264 struct finger {
265 	int	x;
266 	int	y;
267 	int	p;
268 	int	w;
269 	int	id;	/* id=0 - no touch, id>1 - touch id */
270 };
271 
272 struct evstate {
273 	int		buttons;
274 	/* Relative */
275 	int		dx;
276 	int		dy;
277 	int		dz;
278 	int		dw;
279 	int		acc_dx;
280 	int		acc_dy;
281 	/* Absolute single-touch */
282 	int		nfingers;
283 	struct finger	st;
284 	/* Absolute multi-touch */
285 	int		slot;
286 	struct finger	mt[MAX_FINGERS];
287 	bitstr_t bit_decl(key_ignore, KEY_CNT);
288 	bitstr_t bit_decl(rel_ignore, REL_CNT);
289 	bitstr_t bit_decl(abs_ignore, ABS_CNT);
290 	bitstr_t bit_decl(prop_ignore, INPUT_PROP_CNT);
291 };
292 
293 /* button status */
294 struct button_state {
295 	int count;	/* 0: up, 1: single click, 2: double click,... */
296 	struct timespec ts;	/* timestamp on the last button event */
297 };
298 
299 struct btstate {
300 	u_int	wmode;		/* wheel mode button number */
301 	u_int 	clickthreshold;	/* double click speed in msec */
302 	struct button_state	bstate[MOUSE_MAXBUTTON]; /* button state */
303 	struct button_state	*mstate[MOUSE_MAXBUTTON];/* mapped button st.*/
304 	u_int	p2l[MOUSE_MAXBUTTON];/* phisical to logical button mapping */
305 	int	zmap[ZMAP_MAXBUTTON];/* MOUSE_{X|Y}AXIS or a button number */
306 	struct button_state	zstate[ZMAP_MAXBUTTON];	 /* Z/W axis state */
307 };
308 
309 /* state machine for 3 button emulation */
310 
311 enum bt3_emul_state {
312 	S0,		/* start */
313 	S1,		/* button 1 delayed down */
314 	S2,		/* button 3 delayed down */
315 	S3,		/* both buttons down -> button 2 down */
316 	S4,		/* button 1 delayed up */
317 	S5,		/* button 1 down */
318 	S6,		/* button 3 down */
319 	S7,		/* both buttons down */
320 	S8,		/* button 3 delayed up */
321 	S9,		/* button 1 or 3 up after S3 */
322 };
323 
324 #define A(b1, b3)	(((b1) ? 2 : 0) | ((b3) ? 1 : 0))
325 #define A_TIMEOUT	4
326 #define S_DELAYED(st)	(states[st].s[A_TIMEOUT] != (st))
327 
328 static const struct {
329 	enum bt3_emul_state s[A_TIMEOUT + 1];
330 	int buttons;
331 	int mask;
332 	bool timeout;
333 } states[10] = {
334     /* S0 */
335     { { S0, S2, S1, S3, S0 }, 0, ~(MOUSE_BUTTON1DOWN | MOUSE_BUTTON3DOWN), false },
336     /* S1 */
337     { { S4, S2, S1, S3, S5 }, 0, ~MOUSE_BUTTON1DOWN, false },
338     /* S2 */
339     { { S8, S2, S1, S3, S6 }, 0, ~MOUSE_BUTTON3DOWN, false },
340     /* S3 */
341     { { S0, S9, S9, S3, S3 }, MOUSE_BUTTON2DOWN, ~0, false },
342     /* S4 */
343     { { S0, S2, S1, S3, S0 }, MOUSE_BUTTON1DOWN, ~0, true },
344     /* S5 */
345     { { S0, S2, S5, S7, S5 }, MOUSE_BUTTON1DOWN, ~0, false },
346     /* S6 */
347     { { S0, S6, S1, S7, S6 }, MOUSE_BUTTON3DOWN, ~0, false },
348     /* S7 */
349     { { S0, S6, S5, S7, S7 }, MOUSE_BUTTON1DOWN | MOUSE_BUTTON3DOWN, ~0, false },
350     /* S8 */
351     { { S0, S2, S1, S3, S0 }, MOUSE_BUTTON3DOWN, ~0, true },
352     /* S9 */
353     { { S0, S9, S9, S3, S9 }, 0, ~(MOUSE_BUTTON1DOWN | MOUSE_BUTTON3DOWN), false },
354 };
355 
356 struct e3bstate {
357 	bool enabled;
358 	u_int button2timeout;	/* 3 button emulation timeout */
359 	enum bt3_emul_state	mouse_button_state;
360 	struct timespec		mouse_button_state_ts;
361 	int			mouse_move_delayed;
362 	bool timer_armed;
363 };
364 
365 enum scroll_state {
366 	SCROLL_NOTSCROLLING,
367 	SCROLL_PREPARE,
368 	SCROLL_SCROLLING,
369 };
370 
371 struct scroll {
372 	bool	enable_vert;
373 	bool	enable_hor;
374 	u_int	threshold;	/* Movement distance before virtual scrolling */
375 	u_int	speed;		/* Movement distance to rate of scrolling */
376 	enum scroll_state state;
377 	int	movement;
378 	int	hmovement;
379 };
380 
381 struct drift_xy {
382 	int x;
383 	int y;
384 };
385 struct drift {
386 	u_int		distance;	/* max steps X+Y */
387 	u_int		time;		/* ms */
388 	struct timespec	time_ts;
389 	struct timespec	twotime_ts;	/* 2*drift_time */
390 	u_int		after;		/* ms */
391 	struct timespec	after_ts;
392 	bool		terminate;
393 	struct timespec	current_ts;
394 	struct timespec	last_activity;
395 	struct timespec	since;
396 	struct drift_xy	last;		/* steps in last drift_time */
397 	struct drift_xy	previous;	/* steps in prev. drift_time */
398 };
399 
400 struct accel {
401 	bool is_exponential;	/* Exponential acceleration is enabled */
402 	double accelx;		/* Acceleration in the X axis */
403 	double accely;		/* Acceleration in the Y axis */
404 	double accelz;		/* Acceleration in the wheel axis */
405 	double expoaccel;	/* Exponential acceleration */
406 	double expoffset;	/* Movement offset for exponential accel. */
407 	double remainx;		/* Remainder on X, Y and wheel axis, ... */
408 	double remainy;		/*    ...  respectively to compensate */
409 	double remainz;		/*    ... for rounding errors. */
410 	double lastlength[3];
411 };
412 
413 struct rodent {
414 	struct device dev;	/* Device */
415 	int mfd;		/* mouse file descriptor */
416 	struct btstate btstate;	/* button status */
417 	struct e3bstate e3b;	/* 3 button emulation state */
418 	struct drift drift;
419 	struct accel accel;	/* cursor acceleration state */
420 	struct scroll scroll;	/* virtual scroll state */
421 	struct tpad tp;		/* touchpad info and gesture state */
422 	struct evstate ev;	/* event device state */
423 	SLIST_ENTRY(rodent) next;
424 };
425 
426 /* global variables */
427 
428 static SLIST_HEAD(rodent_list, rodent) rodents = SLIST_HEAD_INITIALIZER();
429 
430 static int	debug = 0;
431 static bool	nodaemon = false;
432 static bool	background = false;
433 static bool	paused = false;
434 static bool	opt_grab = false;
435 static int	identify = ID_NONE;
436 static int	cfd = -1;	/* /dev/consolectl file descriptor */
437 static int	kfd = -1;	/* kqueue file descriptor */
438 static int	dfd = -1;	/* devd socket descriptor */
439 static const char *portname = NULL;
440 static const char *pidfile = "/var/run/moused.pid";
441 static struct pidfh *pfh;
442 #ifndef CONFDIR
443 #define CONFDIR	"/etc"
444 #endif
445 static const char *config_file = CONFDIR "/moused.conf";
446 #ifndef QUIRKSDIR
447 #define	QUIRKSDIR	"/usr/share/moused"
448 #endif
449 static const char *quirks_path = QUIRKSDIR;
450 static struct quirks_context *quirks;
451 static enum device_if force_if = DEVICE_IF_UNKNOWN;
452 
453 static int	opt_rate = 0;
454 static int	opt_resolution = MOUSE_RES_UNKNOWN;
455 
456 static u_int	opt_wmode = 0;
457 static int	opt_clickthreshold = -1;
458 static bool	opt_e3b_enabled = false;
459 static int	opt_e3b_button2timeout = -1;
460 static struct btstate opt_btstate;
461 
462 static bool	opt_drift_terminate = false;
463 static u_int	opt_drift_distance = 4;		/* max steps X+Y */
464 static u_int	opt_drift_time = 500;		/* ms */
465 static u_int	opt_drift_after = 4000;		/* ms */
466 
467 static double	opt_accelx = 1.0;
468 static double	opt_accely = 1.0;
469 static bool	opt_exp_accel = false;
470 static double	opt_expoaccel = 1.0;
471 static double	opt_expoffset = 1.0;
472 
473 static bool	opt_virtual_scroll = false;
474 static bool	opt_hvirtual_scroll = false;
475 static int	opt_scroll_speed = -1;
476 static int	opt_scroll_threshold = -1;
477 
478 static jmp_buf env;
479 
480 /* function prototypes */
481 
482 static moused_log_handler	log_or_warn_va;
483 
484 static void	linacc(struct accel *, int, int, int, int*, int*, int*);
485 static void	expoacc(struct accel *, int, int, int, int*, int*, int*);
486 static void	moused(void);
487 static void	reset(int sig);
488 static void	pause_mouse(int sig);
489 static int	connect_devd(void);
490 static void	fetch_and_parse_devd(void);
491 static void	usage(void);
492 static void	log_or_warn(int log_pri, int errnum, const char *fmt, ...)
493 		    __printflike(3, 4);
494 
495 static int	r_daemon(void);
496 static enum device_if	r_identify_if(int fd);
497 static enum device_type	r_identify_evdev(int fd);
498 static enum device_type	r_identify_sysmouse(int fd);
499 static const char *r_if(enum device_if type);
500 static const char *r_name(enum device_type type);
501 static struct rodent *r_init(const char *path);
502 static void	r_init_all(void);
503 static void	r_deinit(struct rodent *r);
504 static void	r_deinit_all(void);
505 static int	r_protocol_evdev(enum device_type type, struct tpad *tp,
506 		    struct evstate *ev, struct input_event *ie,
507 		    mousestatus_t *act);
508 static int	r_protocol_sysmouse(uint8_t *pBuf, mousestatus_t *act);
509 static void	r_vscroll_detect(struct rodent *r, struct scroll *sc,
510 		    mousestatus_t *act);
511 static void	r_vscroll(struct scroll *sc, mousestatus_t *act);
512 static int	r_statetrans(struct rodent *r, mousestatus_t *a1,
513 		    mousestatus_t *a2, int trans);
514 static bool	r_installmap(char *arg, struct btstate *bt);
515 static char *	r_installzmap(char **argv, int argc, int* idx, struct btstate *bt);
516 static void	r_map(mousestatus_t *act1, mousestatus_t *act2,
517 		    struct btstate *bt);
518 static void	r_timestamp(mousestatus_t *act, struct btstate *bt,
519 		    struct e3bstate *e3b, struct drift *drift);
520 static bool	r_timeout(struct e3bstate *e3b);
521 static void	r_move(mousestatus_t *act, struct accel *acc);
522 static void	r_click(mousestatus_t *act, struct btstate *bt);
523 static bool	r_drift(struct drift *, mousestatus_t *);
524 static enum gesture r_gestures(struct tpad *tp, int x0, int y0, u_int z, int w,
525 		    int nfingers, struct timespec *time, mousestatus_t *ms);
526 
527 int
main(int argc,char * argv[])528 main(int argc, char *argv[])
529 {
530 	struct rodent *r;
531 	pid_t mpid;
532 	int c;
533 	u_int i;
534 	int n;
535 	u_long ul;
536 	char *errstr;
537 
538 	while ((c = getopt(argc, argv, "3A:C:E:F:HI:L:T:VU:a:dfghi:l:m:p:r:t:q:w:z:")) != -1) {
539 		switch(c) {
540 
541 		case '3':
542 			opt_e3b_enabled = true;
543 			break;
544 
545 		case 'E':
546 			errno = 0;
547 			ul = strtoul(optarg, NULL, 10);
548 			if ((ul == 0 && errno != 0) ||
549 			     ul > MAX_BUTTON2TIMEOUT) {
550 				warnx("invalid argument `%s'", optarg);
551 				usage();
552 			}
553 			opt_e3b_button2timeout = ul;
554 			break;
555 
556 		case 'a':
557 			n = sscanf(optarg, "%lf,%lf", &opt_accelx, &opt_accely);
558 			if (n == 0) {
559 				warnx("invalid linear acceleration argument "
560 				    "'%s'", optarg);
561 				usage();
562 			}
563 			if (n == 1)
564 				opt_accely = opt_accelx;
565 			break;
566 
567 		case 'A':
568 			opt_exp_accel = true;
569 			n = sscanf(optarg, "%lf,%lf", &opt_expoaccel,
570 			    &opt_expoffset);
571 			if (n == 0) {
572 				warnx("invalid exponential acceleration "
573 				    "argument '%s'", optarg);
574 				usage();
575 			}
576 			if (n == 1)
577 				opt_expoffset = 1.0;
578 			break;
579 
580 		case 'd':
581 			++debug;
582 			break;
583 
584 		case 'f':
585 			nodaemon = true;
586 			break;
587 
588 		case 'g':
589 			opt_grab = true;
590 			break;
591 
592 		case 'i':
593 			if (strcmp(optarg, "all") == 0)
594 				identify = ID_ALL;
595 			else if (strcmp(optarg, "port") == 0)
596 				identify = ID_PORT;
597 			else if (strcmp(optarg, "if") == 0)
598 				identify = ID_IF;
599 			else if (strcmp(optarg, "type") == 0)
600 				identify = ID_TYPE;
601 			else if (strcmp(optarg, "model") == 0)
602 				identify = ID_MODEL;
603 			else {
604 				warnx("invalid argument `%s'", optarg);
605 				usage();
606 			}
607 			nodaemon = true;
608 			break;
609 
610 		case 'l':
611 			ul = strtoul(optarg, NULL, 10);
612 			if (ul != 1)
613 				warnx("ignore mouse level `%s'", optarg);
614 			break;
615 
616 		case 'm':
617 			if (!r_installmap(optarg, &opt_btstate)) {
618 				warnx("invalid argument `%s'", optarg);
619 				usage();
620 			}
621 			break;
622 
623 		case 'p':
624 			/* "auto" is an alias to no portname */
625 			if (strcmp(optarg, "auto") != 0)
626 				portname = optarg;
627 			break;
628 
629 		case 'r':
630 			if (strcmp(optarg, "high") == 0)
631 				opt_resolution = MOUSE_RES_HIGH;
632 			else if (strcmp(optarg, "medium-high") == 0)
633 				opt_resolution = MOUSE_RES_HIGH;
634 			else if (strcmp(optarg, "medium-low") == 0)
635 				opt_resolution = MOUSE_RES_MEDIUMLOW;
636 			else if (strcmp(optarg, "low") == 0)
637 				opt_resolution = MOUSE_RES_LOW;
638 			else if (strcmp(optarg, "default") == 0)
639 				opt_resolution = MOUSE_RES_DEFAULT;
640 			else {
641 				ul= strtoul(optarg, NULL, 10);
642 				if (ul == 0) {
643 					warnx("invalid argument `%s'", optarg);
644 					usage();
645 				}
646 				opt_resolution = ul;
647 			}
648 			break;
649 
650 		case 't':
651 			if (strcmp(optarg, "auto") == 0) {
652 				force_if = DEVICE_IF_UNKNOWN;
653 				break;
654 			}
655 			for (i = 0; i < nitems(rifs); i++)
656 				if (strcmp(optarg, rifs[i].name) == 0) {
657 					force_if = i;
658 					break;
659 				}
660 			if (i == nitems(rifs)) {
661 				warnx("no such interface type `%s'", optarg);
662 				usage();
663 			}
664 			break;
665 
666 		case 'w':
667 			ul = strtoul(optarg, NULL, 10);
668 			if (ul == 0 || ul > MOUSE_MAXBUTTON) {
669 				warnx("invalid argument `%s'", optarg);
670 				usage();
671 			}
672 			opt_wmode = ul;
673 			break;
674 
675 		case 'z':
676 			--optind;
677 			errstr = r_installzmap(argv, argc, &optind, &opt_btstate);
678 			if (errstr != NULL) {
679 				warnx("%s", errstr);
680 				free(errstr);
681 				usage();
682 			}
683 			break;
684 
685 		case 'C':
686 			ul = strtoul(optarg, NULL, 10);
687 			if (ul > MAX_CLICKTHRESHOLD) {
688 				warnx("invalid argument `%s'", optarg);
689 				usage();
690 			}
691 			opt_clickthreshold = ul;
692 			break;
693 
694 		case 'F':
695 			ul = strtoul(optarg, NULL, 10);
696 			if (ul == 0) {
697 				warnx("invalid argument `%s'", optarg);
698 				usage();
699 			}
700 			opt_rate = ul;
701 			break;
702 
703 		case 'H':
704 			opt_hvirtual_scroll = true;
705 			break;
706 
707 		case 'I':
708 			pidfile = optarg;
709 			break;
710 
711 		case 'L':
712 			errno = 0;
713 			ul = strtoul(optarg, NULL, 10);
714 			if ((ul == 0 && errno != 0) || ul > INT_MAX) {
715 				warnx("invalid argument `%s'", optarg);
716 				usage();
717 			}
718 			opt_scroll_speed = ul;
719 			break;
720 
721 		case 'q':
722 			config_file = optarg;
723 			break;
724 
725 		case 'Q':
726 			quirks_path = optarg;
727 			break;
728 
729 		case 'T':
730 			opt_drift_terminate = true;
731 			sscanf(optarg, "%u,%u,%u", &opt_drift_distance,
732 			    &opt_drift_time, &opt_drift_after);
733 			if (opt_drift_distance == 0 ||
734 			    opt_drift_time == 0 ||
735 			    opt_drift_after == 0) {
736 				warnx("invalid argument `%s'", optarg);
737 				usage();
738 			}
739 			break;
740 
741 		case 'V':
742 			opt_virtual_scroll = true;
743 			break;
744 
745 		case 'U':
746 			errno = 0;
747 			ul = strtoul(optarg, NULL, 10);
748 			if ((ul == 0 && errno != 0) || ul > INT_MAX) {
749 				warnx("invalid argument `%s'", optarg);
750 				usage();
751 			}
752 			opt_scroll_threshold = ul;
753 			break;
754 
755 		case 'h':
756 		case '?':
757 		default:
758 			usage();
759 		}
760 	}
761 
762 	if ((cfd = open("/dev/consolectl", O_RDWR, 0)) == -1)
763 		logerr(1, "cannot open /dev/consolectl");
764 	if ((kfd = kqueue()) == -1)
765 		logerr(1, "cannot create kqueue");
766 	if (portname == NULL && (dfd = connect_devd()) == -1)
767 		logwarnx("cannot open devd socket");
768 
769 	switch (setjmp(env)) {
770 	case SIGHUP:
771 		quirks_context_unref(quirks);
772 		r_deinit_all();
773 		/* FALLTHROUGH */
774 	case 0:
775 		break;
776 	case SIGINT:
777 	case SIGQUIT:
778 	case SIGTERM:
779 		exit(0);
780 		/* NOT REACHED */
781 	default:
782 		goto out;
783 	}
784 
785 	signal(SIGHUP , reset);
786 	signal(SIGINT , reset);
787 	signal(SIGQUIT, reset);
788 	signal(SIGTERM, reset);
789 	signal(SIGUSR1, pause_mouse);
790 
791 	quirks = quirks_init_subsystem(quirks_path, config_file,
792 	    log_or_warn_va,
793 	    background ? QLOG_MOUSED_LOGGING : QLOG_CUSTOM_LOG_PRIORITIES);
794 	if (quirks == NULL)
795 		logwarnx("cannot open configuration file %s", config_file);
796 
797 	if (portname == NULL) {
798 		r_init_all();
799 	} else {
800 		if ((r = r_init(portname)) == NULL)
801 			logerrx(1, "Can not initialize device");
802 	}
803 
804 	/* print some information */
805 	if (identify != ID_NONE) {
806 		SLIST_FOREACH(r, &rodents, next) {
807 			if (identify == ID_ALL)
808 				printf("%s %s %s %s\n",
809 				    r->dev.path, r_if(r->dev.iftype),
810 				    r_name(r->dev.type), r->dev.name);
811 			else if (identify & ID_PORT)
812 				printf("%s\n", r->dev.path);
813 			else if (identify & ID_IF)
814 				printf("%s\n", r_if(r->dev.iftype));
815 			else if (identify & ID_TYPE)
816 				printf("%s\n", r_name(r->dev.type));
817 			else if (identify & ID_MODEL)
818 				printf("%s\n", r->dev.name);
819 		}
820 		exit(0);
821 	}
822 
823 	if (!nodaemon && !background) {
824 		pfh = pidfile_open(pidfile, 0600, &mpid);
825 		if (pfh == NULL) {
826 			if (errno == EEXIST)
827 				logerrx(1, "moused already running, pid: %d", mpid);
828 			logwarn("cannot open pid file");
829 		}
830 		if (r_daemon()) {
831 			int saved_errno = errno;
832 			pidfile_remove(pfh);
833 			errno = saved_errno;
834 			logerr(1, "failed to become a daemon");
835 		} else {
836 			background = true;
837 			pidfile_write(pfh);
838 		}
839 	}
840 
841 	moused();
842 
843 out:
844 	quirks_context_unref(quirks);
845 
846 	r_deinit_all();
847 	if (dfd != -1)
848 		close(dfd);
849 	if (kfd != -1)
850 		close(kfd);
851 	if (cfd != -1)
852 		close(cfd);
853 
854 	exit(0);
855 }
856 
857 /*
858  * Function to calculate linear acceleration.
859  *
860  * If there are any rounding errors, the remainder
861  * is stored in the remainx and remainy variables
862  * and taken into account upon the next movement.
863  */
864 
865 static void
linacc(struct accel * acc,int dx,int dy,int dz,int * movex,int * movey,int * movez)866 linacc(struct accel *acc, int dx, int dy, int dz,
867     int *movex, int *movey, int *movez)
868 {
869 	double fdx, fdy, fdz;
870 
871 	if (dx == 0 && dy == 0 && dz == 0) {
872 		*movex = *movey = *movez = 0;
873 		return;
874 	}
875 	fdx = dx * acc->accelx + acc->remainx;
876 	fdy = dy * acc->accely + acc->remainy;
877 	fdz = dz * acc->accelz + acc->remainz;
878 	*movex = lround(fdx);
879 	*movey = lround(fdy);
880 	*movez = lround(fdz);
881 	acc->remainx = fdx - *movex;
882 	acc->remainy = fdy - *movey;
883 	acc->remainz = fdz - *movez;
884 }
885 
886 /*
887  * Function to calculate exponential acceleration.
888  * (Also includes linear acceleration if enabled.)
889  *
890  * In order to give a smoother behaviour, we record the four
891  * most recent non-zero movements and use their average value
892  * to calculate the acceleration.
893  */
894 
895 static void
expoacc(struct accel * acc,int dx,int dy,int dz,int * movex,int * movey,int * movez)896 expoacc(struct accel *acc, int dx, int dy, int dz,
897     int *movex, int *movey, int *movez)
898 {
899 	double fdx, fdy, fdz, length, lbase, accel;
900 
901 	if (dx == 0 && dy == 0 && dz == 0) {
902 		*movex = *movey = *movez = 0;
903 		return;
904 	}
905 	fdx = dx * acc->accelx;
906 	fdy = dy * acc->accely;
907 	fdz = dz * acc->accelz;
908 	length = sqrt((fdx * fdx) + (fdy * fdy));	/* Pythagoras */
909 	length = (length + acc->lastlength[0] + acc->lastlength[1] +
910 	    acc->lastlength[2]) / 4;
911 	lbase = length / acc->expoffset;
912 	accel = pow(lbase, acc->expoaccel) / lbase;
913 	fdx = fdx * accel + acc->remainx;
914 	fdy = fdy * accel + acc->remainy;
915 	*movex = lround(fdx);
916 	*movey = lround(fdy);
917 	*movez = lround(fdz);
918 	acc->remainx = fdx - *movex;
919 	acc->remainy = fdy - *movey;
920 	acc->remainz = fdz - *movez;
921 	acc->lastlength[2] = acc->lastlength[1];
922 	acc->lastlength[1] = acc->lastlength[0];
923 	/* Insert new average, not original length! */
924 	acc->lastlength[0] = length;
925 }
926 
927 static void
moused(void)928 moused(void)
929 {
930 	struct rodent *r = NULL;
931 	mousestatus_t action0;		/* original mouse action */
932 	mousestatus_t action;		/* interim buffer */
933 	mousestatus_t action2;		/* mapped action */
934 	struct kevent ke[3];
935 	int nchanges;
936 	union {
937 		struct input_event ie;
938 		uint8_t se[MOUSE_SYS_PACKETSIZE];
939 	} b;
940 	size_t b_size;
941 	ssize_t r_size;
942 	int flags;
943 	int c;
944 
945 	/* clear mouse data */
946 	bzero(&action0, sizeof(action0));
947 	bzero(&action, sizeof(action));
948 	bzero(&action2, sizeof(action2));
949 	/* process mouse data */
950 	for (;;) {
951 
952 		if (dfd == -1 && portname == NULL)
953 			dfd = connect_devd();
954 		nchanges = 0;
955 		if (r != NULL && r->e3b.enabled &&
956 		    S_DELAYED(r->e3b.mouse_button_state)) {
957 			EV_SET(ke + nchanges, r->mfd << 1, EVFILT_TIMER,
958 			    EV_ADD | EV_ENABLE | EV_DISPATCH, 0, 20, r);
959 			nchanges++;
960 			r->e3b.timer_armed = true;
961 		}
962 		if (r != NULL && r->tp.gest.idletimeout > 0) {
963 			EV_SET(ke + nchanges, r->mfd << 1 | 1, EVFILT_TIMER,
964 			    EV_ADD | EV_ENABLE | EV_DISPATCH,
965 			    0, r->tp.gest.idletimeout, r);
966 			nchanges++;
967 			r->tp.gest.timer_armed = true;
968 		}
969 		if (dfd == -1 && nchanges == 0 && portname == NULL) {
970 			EV_SET(ke + nchanges, UINTPTR_MAX, EVFILT_TIMER,
971 			    EV_ADD | EV_ENABLE | EV_ONESHOT, 0, 1000, NULL);
972 			nchanges++;
973 		}
974 
975 		if (!(r != NULL && r->tp.gest.idletimeout == 0)) {
976 			c = kevent(kfd, ke, nchanges, ke, 1, NULL);
977 			if (c <= 0) {			/* error */
978 				logwarn("failed to read from mouse");
979 				continue;
980 			}
981 		} else
982 			c = 0;
983 		/* Devd event */
984 		if (c > 0 && ke[0].udata == NULL) {
985 			if (ke[0].filter == EVFILT_READ) {
986 				if ((ke[0].flags & EV_EOF) != 0) {
987 					logwarn("devd connection is closed");
988 					close(dfd);
989 					dfd = -1;
990 				} else
991 					fetch_and_parse_devd();
992 			} else if (ke[0].filter == EVFILT_TIMER) {
993 				/* DO NOTHING */
994 			}
995 			continue;
996 		}
997 		if (c > 0)
998 			r = ke[0].udata;
999 		/* E3B timeout */
1000 		if (c > 0 && ke[0].filter == EVFILT_TIMER &&
1001 		    (ke[0].ident & 1) == 0) {
1002 			/* assert(rodent.flags & Emulate3Button) */
1003 			action0.button = action0.obutton;
1004 			action0.dx = action0.dy = action0.dz = 0;
1005 			action0.flags = flags = 0;
1006 			r->e3b.timer_armed = false;
1007 			if (r_timeout(&r->e3b) &&
1008 			    r_statetrans(r, &action0, &action, A_TIMEOUT)) {
1009 				if (debug > 2)
1010 					debug("flags:%08x buttons:%08x obuttons:%08x",
1011 					    action.flags, action.button, action.obutton);
1012 			} else {
1013 				action0.obutton = action0.button;
1014 				continue;
1015 			}
1016 		} else {
1017 			/* mouse movement */
1018 			if (c > 0 && ke[0].filter == EVFILT_READ) {
1019 				b_size = rifs[r->dev.iftype].p_size;
1020 				r_size = read(r->mfd, &b, b_size);
1021 				if (r_size == -1) {
1022 					if (errno == EWOULDBLOCK)
1023 						continue;
1024 					else if (portname == NULL) {
1025 						r_deinit(r);
1026 						r = NULL;
1027 						continue;
1028 					} else
1029 						return;
1030 				}
1031 				if (r_size != (ssize_t)b_size) {
1032 					logwarn("Short read from mouse: "
1033 					    "%zd bytes", r_size);
1034 					continue;
1035 				}
1036 				/* Disarm nonexpired timers */
1037 				nchanges = 0;
1038 				if (r->e3b.timer_armed) {
1039 					EV_SET(ke + nchanges, r->mfd << 1,
1040 					    EVFILT_TIMER, EV_DISABLE, 0, 0, r);
1041 					nchanges++;
1042 					r->e3b.timer_armed = false;
1043 				}
1044 				if (r->tp.gest.timer_armed) {
1045 					EV_SET(ke + nchanges, r->mfd << 1 | 1,
1046 					    EVFILT_TIMER, EV_DISABLE, 0, 0, r);
1047 					nchanges++;
1048 					r->tp.gest.timer_armed = false;
1049 				}
1050 				if (nchanges != 0)
1051 					kevent(kfd, ke, nchanges, NULL, 0, NULL);
1052 			} else {
1053 				/*
1054 				 * Gesture timeout expired.
1055 				 * Notify r_gestures by empty packet.
1056 				 */
1057 #ifdef DONE_RIGHT
1058 				struct timespec ts;
1059 				clock_gettime(CLOCK_REALTIME, &ts);
1060 				b.ie.time.tv_sec = ts.tv_sec;
1061 				b.ie.time.tv_usec = ts.tv_nsec / 1000;
1062 #else
1063 				/* Hacky but cheap */
1064 				b.ie.time.tv_sec =
1065 				    r->tp.gest.idletimeout == 0 ? 0 : LONG_MAX;
1066 				b.ie.time.tv_usec = 0;
1067 #endif
1068 				b.ie.type = EV_SYN;
1069 				b.ie.code = SYN_REPORT;
1070 				b.ie.value = 1;
1071 				if (c > 0)
1072 					r->tp.gest.timer_armed = false;
1073 			}
1074 			r->tp.gest.idletimeout = -1;
1075 			flags = r->dev.iftype == DEVICE_IF_EVDEV ?
1076 			    r_protocol_evdev(r->dev.type,
1077 			        &r->tp, &r->ev, &b.ie, &action0) :
1078 			    r_protocol_sysmouse(b.se, &action0);
1079 			if (flags == 0)
1080 				continue;
1081 
1082 			if (r->scroll.enable_vert || r->scroll.enable_hor) {
1083 				if (action0.button == MOUSE_BUTTON2DOWN) {
1084 					debug("[BUTTON2] flags:%08x buttons:%08x obuttons:%08x",
1085 					    action.flags, action.button, action.obutton);
1086 				} else {
1087 					debug("[NOTBUTTON2] flags:%08x buttons:%08x obuttons:%08x",
1088 					    action.flags, action.button, action.obutton);
1089 				}
1090 				r_vscroll_detect(r, &r->scroll, &action0);
1091 			}
1092 
1093 			r_timestamp(&action0, &r->btstate, &r->e3b, &r->drift);
1094 			r_statetrans(r, &action0, &action,
1095 			    A(action0.button & MOUSE_BUTTON1DOWN,
1096 			      action0.button & MOUSE_BUTTON3DOWN));
1097 			debug("flags:%08x buttons:%08x obuttons:%08x", action.flags,
1098 			    action.button, action.obutton);
1099 		}
1100 		action0.obutton = action0.button;
1101 		flags &= MOUSE_POSCHANGED;
1102 		flags |= action.obutton ^ action.button;
1103 		action.flags = flags;
1104 
1105 		if (flags == 0)
1106 			continue;
1107 
1108 		/* handler detected action */
1109 		r_map(&action, &action2, &r->btstate);
1110 		debug("activity : buttons 0x%08x  dx %d  dy %d  dz %d",
1111 		    action2.button, action2.dx, action2.dy, action2.dz);
1112 
1113 		if (r->scroll.enable_vert || r->scroll.enable_hor) {
1114 			/*
1115 			 * If *only* the middle button is pressed AND we are moving
1116 			 * the stick/trackpoint/nipple, scroll!
1117 			 */
1118 			r_vscroll(&r->scroll, &action2);
1119 		}
1120 
1121 		if (r->drift.terminate) {
1122 			if ((flags & MOUSE_POSCHANGED) == 0 ||
1123 			    action.dz || action2.dz)
1124 				r->drift.last_activity = r->drift.current_ts;
1125 			else {
1126 				if (r_drift (&r->drift, &action2))
1127 					continue;
1128 			}
1129 		}
1130 
1131 		/* Defer clicks until we aren't VirtualScroll'ing. */
1132 		if (r->scroll.state == SCROLL_NOTSCROLLING)
1133 			r_click(&action2, &r->btstate);
1134 
1135 		if (action2.flags & MOUSE_POSCHANGED)
1136 			r_move(&action2, &r->accel);
1137 
1138 		/*
1139 		 * If the Z axis movement is mapped to an imaginary physical
1140 		 * button, we need to cook up a corresponding button `up' event
1141 		 * after sending a button `down' event.
1142 		 */
1143 		if ((r->btstate.zmap[0] > 0) && (action.dz != 0)) {
1144 			action.obutton = action.button;
1145 			action.dx = action.dy = action.dz = 0;
1146 			r_map(&action, &action2, &r->btstate);
1147 			debug("activity : buttons 0x%08x  dx %d  dy %d  dz %d",
1148 			    action2.button, action2.dx, action2.dy, action2.dz);
1149 
1150 			r_click(&action2, &r->btstate);
1151 		}
1152 	}
1153 	/* NOT REACHED */
1154 }
1155 
1156 static void
reset(int sig)1157 reset(int sig)
1158 {
1159 	longjmp(env, sig);
1160 }
1161 
1162 static void
pause_mouse(__unused int sig)1163 pause_mouse(__unused int sig)
1164 {
1165 	paused = !paused;
1166 }
1167 
1168 static int
connect_devd(void)1169 connect_devd(void)
1170 {
1171 	static const struct sockaddr_un sa = {
1172 		.sun_family = AF_UNIX,
1173 		.sun_path = "/var/run/devd.seqpacket.pipe",
1174 	};
1175 	struct kevent kev;
1176 	int fd;
1177 
1178 	fd = socket(AF_UNIX, SOCK_SEQPACKET | SOCK_CLOEXEC, 0);
1179 	if (fd < 0)
1180 		return (-1);
1181 	if (connect(fd, (const struct sockaddr *) &sa, sizeof(sa)) < 0) {
1182 		close(fd);
1183 		return (-1);
1184 	}
1185 	EV_SET(&kev, fd, EVFILT_READ, EV_ADD, 0, 0, 0);
1186 	if (kevent(kfd, &kev, 1, NULL, 0, NULL) < 0) {
1187 		close(fd);
1188 		return (-1);
1189 	}
1190 
1191 	return (fd);
1192 }
1193 
1194 static void
fetch_and_parse_devd(void)1195 fetch_and_parse_devd(void)
1196 {
1197 	char ev[1024];
1198 	char path[22] = "/dev/";
1199 	char *cdev, *cr;
1200 	ssize_t len;
1201 
1202 	if ((len = recv(dfd, ev, sizeof(ev), MSG_WAITALL)) <= 0) {
1203 		close(dfd);
1204 		dfd = -1;
1205 		return;
1206 	}
1207 
1208 	if (ev[0] != '!')
1209 		return;
1210 	if (strnstr(ev, "system=DEVFS", len) == NULL)
1211 		return;
1212 	if (strnstr(ev, "subsystem=CDEV", len) == NULL)
1213 		return;
1214 	if (strnstr(ev, "type=CREATE", len) == NULL)
1215 		return;
1216 	if ((cdev = strnstr(ev, "cdev=input/event", len)) == NULL)
1217 		return;
1218 	cr = strchr(cdev, '\n');
1219 	if (cr != NULL)
1220 		*cr = '\0';
1221 	cr = strchr(cdev, ' ');
1222 	if (cr != NULL)
1223 		*cr = '\0';
1224 	strncpy(path + 5, cdev + 5, 17);
1225 	(void)r_init(path);
1226 	return;
1227 }
1228 
1229 /*
1230  * usage
1231  *
1232  * Complain, and free the CPU for more worthy tasks
1233  */
1234 static void
usage(void)1235 usage(void)
1236 {
1237 	fprintf(stderr, "%s\n%s\n%s\n%s\n%s\n",
1238 	    "usage: moused [-dfg] [-I file] [-F rate] [-r resolution]",
1239 	    "              [-VH [-U threshold]] [-a X[,Y]] [-C threshold] [-m N=M] [-w N]",
1240 	    "              [-z N] [-t <interfacetype>] [-l level] [-3 [-E timeout]]",
1241 	    "              [-T distance[,time[,after]]] -p <port> [-q config] [-Q quirks]",
1242 	    "       moused [-d] -i <port|if|type|model|all> -p <port>");
1243 	exit(1);
1244 }
1245 
1246 /*
1247  * Output an error message to syslog or stderr as appropriate. If
1248  * `errnum' is non-zero, append its string form to the message.
1249  */
1250 static void
log_or_warn_va(int log_pri,int errnum,const char * fmt,va_list ap)1251 log_or_warn_va(int log_pri, int errnum, const char *fmt, va_list ap)
1252 {
1253 	char buf[256];
1254 	size_t len;
1255 
1256 	if (debug == 0 && log_pri > LOG_ERR)
1257 		return;
1258 
1259 	vsnprintf(buf, sizeof(buf), fmt, ap);
1260 
1261 	/* Strip trailing line-feed appended by quirk subsystem */
1262 	len = strlen(buf);
1263 	if (len != 0 && buf[len - 1] == '\n')
1264 		buf[len - 1] = '\0';
1265 
1266 	if (errnum) {
1267 		strlcat(buf, ": ", sizeof(buf));
1268 		strlcat(buf, strerror(errnum), sizeof(buf));
1269 	}
1270 
1271 	if (background)
1272 		syslog(log_pri, "%s", buf);
1273 	else
1274 		warnx("%s", buf);
1275 }
1276 
1277 static void
log_or_warn(int log_pri,int errnum,const char * fmt,...)1278 log_or_warn(int log_pri, int errnum, const char *fmt, ...)
1279 {
1280 	va_list ap;
1281 
1282 	va_start(ap, fmt);
1283 	log_or_warn_va(log_pri, errnum, fmt, ap);
1284 	va_end(ap);
1285 }
1286 
1287 static int
r_daemon(void)1288 r_daemon(void)
1289 {
1290 	struct sigaction osa, sa;
1291 	pid_t newgrp;
1292 	int oerrno;
1293 	int osa_ok;
1294 	int nullfd;
1295 
1296 	/* A SIGHUP may be thrown when the parent exits below. */
1297 	sigemptyset(&sa.sa_mask);
1298 	sa.sa_handler = SIG_IGN;
1299 	sa.sa_flags = 0;
1300 	osa_ok = sigaction(SIGHUP, &sa, &osa);
1301 
1302 	/* Keep kqueue fd alive */
1303 	switch (rfork(RFPROC)) {
1304 	case -1:
1305 		return (-1);
1306 	case 0:
1307 		break;
1308 	default:
1309 		/*
1310 		 * A fine point:  _exit(0), not exit(0), to avoid triggering
1311 		 * atexit(3) processing
1312 		 */
1313 		_exit(0);
1314 	}
1315 
1316 	newgrp = setsid();
1317 	oerrno = errno;
1318 	if (osa_ok != -1)
1319 		sigaction(SIGHUP, &osa, NULL);
1320 
1321 	if (newgrp == -1) {
1322 		errno = oerrno;
1323 		return (-1);
1324 	}
1325 
1326 	(void)chdir("/");
1327 
1328 	nullfd = open("/dev/null", O_RDWR, 0);
1329 	if (nullfd != -1) {
1330 		(void)dup2(nullfd, STDIN_FILENO);
1331 		(void)dup2(nullfd, STDOUT_FILENO);
1332 		(void)dup2(nullfd, STDERR_FILENO);
1333 	}
1334 	if (nullfd > 2)
1335 		close(nullfd);
1336 
1337 	return (0);
1338 }
1339 
1340 static inline int
bit_find(bitstr_t * array,int start,int stop)1341 bit_find(bitstr_t *array, int start, int stop)
1342 {
1343 	int res;
1344 
1345 	bit_ffs_at(array, start, stop + 1, &res);
1346 	return (res != -1);
1347 }
1348 
1349 static enum device_if
r_identify_if(int fd)1350 r_identify_if(int fd)
1351 {
1352 	int dummy;
1353 
1354 	if ((force_if == DEVICE_IF_UNKNOWN || force_if == DEVICE_IF_EVDEV) &&
1355 	    ioctl(fd, EVIOCGVERSION, &dummy) >= 0)
1356 		return (DEVICE_IF_EVDEV);
1357 	if ((force_if == DEVICE_IF_UNKNOWN || force_if == DEVICE_IF_SYSMOUSE) &&
1358 	    ioctl(fd, MOUSE_GETLEVEL, &dummy) >= 0)
1359 		return (DEVICE_IF_SYSMOUSE);
1360 	return (DEVICE_IF_UNKNOWN);
1361 }
1362 
1363 /* Derived from EvdevProbe() function of xf86-input-evdev driver */
1364 static enum device_type
r_identify_evdev(int fd)1365 r_identify_evdev(int fd)
1366 {
1367 	enum device_type type;
1368 	bitstr_t bit_decl(key_bits, KEY_CNT); /* */
1369 	bitstr_t bit_decl(rel_bits, REL_CNT); /* Evdev capabilities */
1370 	bitstr_t bit_decl(abs_bits, ABS_CNT); /* */
1371 	bitstr_t bit_decl(prop_bits, INPUT_PROP_CNT);
1372 	bool has_keys, has_buttons, has_lmr, has_rel_axes, has_abs_axes;
1373 	bool has_mt;
1374 
1375 	/* maybe this is a evdev mouse... */
1376 	if (ioctl(fd, EVIOCGBIT(EV_REL, sizeof(rel_bits)), rel_bits) < 0 ||
1377 	    ioctl(fd, EVIOCGBIT(EV_ABS, sizeof(abs_bits)), abs_bits) < 0 ||
1378 	    ioctl(fd, EVIOCGBIT(EV_KEY, sizeof(key_bits)), key_bits) < 0 ||
1379 	    ioctl(fd, EVIOCGPROP(sizeof(prop_bits)), prop_bits) < 0) {
1380 		return (DEVICE_TYPE_UNKNOWN);
1381 	}
1382 
1383 	has_keys = bit_find(key_bits, 0, BTN_MISC - 1);
1384 	has_buttons = bit_find(key_bits, BTN_MISC, BTN_JOYSTICK - 1);
1385 	has_lmr = bit_find(key_bits, BTN_LEFT, BTN_MIDDLE);
1386 	has_rel_axes = bit_find(rel_bits, 0, REL_MAX);
1387 	has_abs_axes = bit_find(abs_bits, 0, ABS_MAX);
1388 	has_mt = bit_find(abs_bits, ABS_MT_SLOT, ABS_MAX);
1389 	type = DEVICE_TYPE_UNKNOWN;
1390 
1391 	if (has_abs_axes) {
1392 		if (has_mt && !has_buttons) {
1393 			/* TBD:Improve joystick detection */
1394 			if (bit_test(key_bits, BTN_JOYSTICK)) {
1395 				return (DEVICE_TYPE_JOYSTICK);
1396 			} else {
1397 				has_buttons = true;
1398 			}
1399 		}
1400 
1401 		if (bit_test(abs_bits, ABS_X) &&
1402 		    bit_test(abs_bits, ABS_Y)) {
1403 			if (bit_test(key_bits, BTN_TOOL_PEN) ||
1404 			    bit_test(key_bits, BTN_STYLUS) ||
1405 			    bit_test(key_bits, BTN_STYLUS2)) {
1406 				type = DEVICE_TYPE_TABLET;
1407 			} else if (bit_test(abs_bits, ABS_PRESSURE) ||
1408 				   bit_test(key_bits, BTN_TOUCH)) {
1409 				if (has_lmr ||
1410 				    bit_test(key_bits, BTN_TOOL_FINGER)) {
1411 					type = DEVICE_TYPE_TOUCHPAD;
1412 				} else {
1413 					type = DEVICE_TYPE_TOUCHSCREEN;
1414 				}
1415 			/* some touchscreens use BTN_LEFT rather than BTN_TOUCH */
1416 			} else if (!(bit_test(rel_bits, REL_X) &&
1417 				     bit_test(rel_bits, REL_Y)) &&
1418 				     has_lmr) {
1419 				type = DEVICE_TYPE_TOUCHSCREEN;
1420 			}
1421 		}
1422 	}
1423 
1424 	if (type == DEVICE_TYPE_UNKNOWN) {
1425 		if (has_keys)
1426 			type = DEVICE_TYPE_KEYBOARD;
1427 		else if (has_rel_axes || has_buttons)
1428 			type = DEVICE_TYPE_MOUSE;
1429 	}
1430 
1431 	return (type);
1432 }
1433 
1434 static enum device_type
r_identify_sysmouse(int fd __unused)1435 r_identify_sysmouse(int fd __unused)
1436 {
1437 	/* All sysmouse devices act like mices */
1438 	return (DEVICE_TYPE_MOUSE);
1439 }
1440 
1441 static const char *
r_if(enum device_if type)1442 r_if(enum device_if type)
1443 {
1444 	const char *unknown = "unknown";
1445 
1446 	return (type == DEVICE_IF_UNKNOWN || type >= (int)nitems(rifs) ?
1447 	    unknown : rifs[type].name);
1448 }
1449 
1450 static const char *
r_name(enum device_type type)1451 r_name(enum device_type type)
1452 {
1453 	const char *unknown = "unknown";
1454 
1455 	return (type == DEVICE_TYPE_UNKNOWN || type >= (int)nitems(rnames) ?
1456 	    unknown : rnames[type]);
1457 }
1458 
1459 static int
r_init_dev_evdev(int fd,struct device * dev)1460 r_init_dev_evdev(int fd, struct device *dev)
1461 {
1462 	if (ioctl(fd, EVIOCGNAME(sizeof(dev->name) - 1), dev->name) < 0) {
1463 		logwarnx("unable to get device %s name", dev->path);
1464 		return (errno);
1465 	}
1466 	/* Do not loop events */
1467 	if (strncmp(dev->name, "System mouse", sizeof(dev->name)) == 0) {
1468 		return (ENOTSUP);
1469 	}
1470 	if (ioctl(fd, EVIOCGID, &dev->id) < 0) {
1471 		logwarnx("unable to get device %s ID", dev->path);
1472 		return (errno);
1473 	}
1474 	(void)ioctl(fd, EVIOCGUNIQ(sizeof(dev->uniq) - 1), dev->uniq);
1475 
1476 	return (0);
1477 }
1478 
1479 static int
r_init_dev_sysmouse(int fd,struct device * dev)1480 r_init_dev_sysmouse(int fd, struct device *dev)
1481 {
1482 	mousemode_t *mode = &dev->mode;
1483 	int level;
1484 
1485 	level = 1;
1486 	if (ioctl(fd, MOUSE_SETLEVEL, &level) < 0) {
1487 		logwarnx("unable to MOUSE_SETLEVEL for device %s", dev->path);
1488 		return (errno);
1489 	}
1490 	if (ioctl(fd, MOUSE_GETLEVEL, &level) < 0) {
1491 		logwarnx("unable to MOUSE_GETLEVEL for device %s", dev->path);
1492 		return (errno);
1493 	}
1494 	if (level != 1) {
1495 		logwarnx("unable to set level to 1 for device %s", dev->path);
1496 		return (ENOTSUP);
1497 	}
1498 	memset(mode, 0, sizeof(*mode));
1499 	if (ioctl(fd, MOUSE_GETMODE, mode) < 0) {
1500 		logwarnx("unable to MOUSE_GETMODE for device %s", dev->path);
1501 		return (errno);
1502 	}
1503 	if (mode->protocol != MOUSE_PROTO_SYSMOUSE) {
1504 		logwarnx("unable to set sysmouse protocol for device %s",
1505 		    dev->path);
1506 		return (ENOTSUP);
1507 	}
1508 	if (mode->packetsize != MOUSE_SYS_PACKETSIZE) {
1509 		logwarnx("unable to set sysmouse packet size for device %s",
1510 		    dev->path);
1511 		return (ENOTSUP);
1512 	}
1513 
1514 	/* TODO: Fill name, id and uniq from dev.* sysctls */
1515 	strlcpy(dev->name, dev->path, sizeof(dev->name));
1516 
1517 	return (0);
1518 }
1519 
1520 static void
r_init_evstate(struct quirks * q,struct evstate * ev)1521 r_init_evstate(struct quirks *q, struct evstate *ev)
1522 {
1523 	const struct quirk_tuples *t;
1524 	bitstr_t *bitstr;
1525 	int maxbit;
1526 
1527 	if (quirks_get_tuples(q, QUIRK_ATTR_EVENT_CODE, &t)) {
1528 		for (size_t i = 0; i < t->ntuples; i++) {
1529 			int type = t->tuples[i].first;
1530 			int code = t->tuples[i].second;
1531 			bool enable = t->tuples[i].third;
1532 
1533 			switch (type) {
1534 			case EV_KEY:
1535 				bitstr = (bitstr_t *)&ev->key_ignore;
1536 				maxbit = KEY_MAX;
1537 				break;
1538 			case EV_REL:
1539 				bitstr = (bitstr_t *)&ev->rel_ignore;
1540 				maxbit = REL_MAX;
1541 				break;
1542 			case EV_ABS:
1543 				bitstr = (bitstr_t *)&ev->abs_ignore;
1544 				maxbit = ABS_MAX;
1545 				break;
1546 			default:
1547 				continue;
1548 			}
1549 
1550 			if (code == EVENT_CODE_UNDEFINED) {
1551 				if (enable)
1552 					bit_nclear(bitstr, 0, maxbit);
1553 				else
1554 					bit_nset(bitstr, 0, maxbit);
1555 			} else {
1556 				if (code > maxbit)
1557 					continue;
1558 				if (enable)
1559 					bit_clear(bitstr, code);
1560 				else
1561 					bit_set(bitstr, code);
1562 	                }
1563 	        }
1564 	}
1565 
1566 	if (quirks_get_tuples(q, QUIRK_ATTR_INPUT_PROP, &t)) {
1567 		for (size_t idx = 0; idx < t->ntuples; idx++) {
1568 			unsigned int p = t->tuples[idx].first;
1569 			bool enable = t->tuples[idx].second;
1570 
1571 			if (p > INPUT_PROP_MAX)
1572 				continue;
1573 			if (enable)
1574 				bit_clear(ev->prop_ignore, p);
1575 			else
1576 				bit_set(ev->prop_ignore, p);
1577                 }
1578         }
1579 }
1580 
1581 static void
r_init_buttons(struct quirks * q,struct btstate * bt,struct e3bstate * e3b)1582 r_init_buttons(struct quirks *q, struct btstate *bt, struct e3bstate *e3b)
1583 {
1584 	struct timespec ts;
1585 	int i, j;
1586 
1587 	*bt = (struct btstate) {
1588 		.clickthreshold = DFLT_CLICKTHRESHOLD,
1589 		.zmap = { 0, 0, 0, 0 },
1590 	};
1591 
1592 	memcpy(bt->p2l, default_p2l, sizeof(bt->p2l));
1593 	for (i = 0; i < MOUSE_MAXBUTTON; ++i) {
1594 		j = i;
1595 		if (opt_btstate.p2l[i] != 0)
1596 			bt->p2l[i] = opt_btstate.p2l[i];
1597 		if (opt_btstate.mstate[i] != NULL)
1598 			j = opt_btstate.mstate[i] - opt_btstate.bstate;
1599 		bt->mstate[i] = bt->bstate + j;
1600 	}
1601 
1602 	if (opt_btstate.zmap[0] != 0)
1603 		memcpy(bt->zmap, opt_btstate.zmap, sizeof(bt->zmap));
1604 	if (opt_clickthreshold >= 0)
1605 		bt->clickthreshold = opt_clickthreshold;
1606 	else
1607 		quirks_get_uint32(q, MOUSED_CLICK_THRESHOLD, &bt->clickthreshold);
1608 	if (opt_wmode != 0)
1609 		bt->wmode = opt_wmode;
1610 	else
1611 		quirks_get_uint32(q, MOUSED_WMODE, &bt->wmode);
1612 	if (bt->wmode != 0)
1613 		bt->wmode = 1 << (bt->wmode - 1);
1614 
1615 	/* fix Z axis mapping */
1616 	for (i = 0; i < ZMAP_MAXBUTTON; ++i) {
1617 		if (bt->zmap[i] <= 0)
1618 			continue;
1619 		for (j = 0; j < MOUSE_MAXBUTTON; ++j) {
1620 			if (bt->mstate[j] == &bt->bstate[bt->zmap[i] - 1])
1621 				bt->mstate[j] = &bt->zstate[i];
1622 		}
1623 		bt->zmap[i] = 1 << (bt->zmap[i] - 1);
1624 	}
1625 
1626 	clock_gettime(CLOCK_MONOTONIC_FAST, &ts);
1627 
1628 	*e3b = (struct e3bstate) {
1629 		.enabled = false,
1630 		.button2timeout = DFLT_BUTTON2TIMEOUT,
1631 	};
1632 	e3b->enabled = opt_e3b_enabled;
1633 	if (!e3b->enabled)
1634 		quirks_get_bool(q, MOUSED_EMULATE_THIRD_BUTTON, &e3b->enabled);
1635 	if (opt_e3b_button2timeout >= 0)
1636 		e3b->button2timeout = opt_e3b_button2timeout;
1637 	else
1638 		quirks_get_uint32(q, MOUSED_EMULATE_THIRD_BUTTON_TIMEOUT,
1639 		    &e3b->button2timeout);
1640 	e3b->mouse_button_state = S0;
1641 	e3b->mouse_button_state_ts = ts;
1642 	e3b->mouse_move_delayed = 0;
1643 
1644 	for (i = 0; i < MOUSE_MAXBUTTON; ++i) {
1645 		bt->bstate[i].count = 0;
1646 		bt->bstate[i].ts = ts;
1647 	}
1648 	for (i = 0; i < ZMAP_MAXBUTTON; ++i) {
1649 		bt->zstate[i].count = 0;
1650 		bt->zstate[i].ts = ts;
1651 	}
1652 }
1653 
1654 static void
r_init_touchpad_hw(int fd,struct quirks * q,struct tpcaps * tphw,struct evstate * ev)1655 r_init_touchpad_hw(int fd, struct quirks *q, struct tpcaps *tphw,
1656      struct evstate *ev)
1657 {
1658 	struct input_absinfo ai;
1659 	bitstr_t bit_decl(key_bits, KEY_CNT);
1660 	bitstr_t bit_decl(abs_bits, ABS_CNT);
1661 	bitstr_t bit_decl(prop_bits, INPUT_PROP_CNT);
1662 	struct quirk_range r;
1663 	struct quirk_dimensions dim;
1664 	u_int u;
1665 
1666 	ioctl(fd, EVIOCGBIT(EV_ABS, sizeof(abs_bits)), abs_bits);
1667 	ioctl(fd, EVIOCGBIT(EV_KEY, sizeof(key_bits)), key_bits);
1668 
1669 	if (!bit_test(ev->abs_ignore, ABS_X) &&
1670 	     ioctl(fd, EVIOCGABS(ABS_X), &ai) >= 0) {
1671 		tphw->min_x = (ai.maximum > ai.minimum) ? ai.minimum : INT_MIN;
1672 		tphw->max_x = (ai.maximum > ai.minimum) ? ai.maximum : INT_MAX;
1673 		tphw->res_x = ai.resolution == 0 ?
1674 		    DFLT_TPAD_RESOLUTION : ai.resolution;
1675 	}
1676 	if (!bit_test(ev->abs_ignore, ABS_Y) &&
1677 	     ioctl(fd, EVIOCGABS(ABS_Y), &ai) >= 0) {
1678 		tphw->min_y = (ai.maximum > ai.minimum) ? ai.minimum : INT_MIN;
1679 		tphw->max_y = (ai.maximum > ai.minimum) ? ai.maximum : INT_MAX;
1680 		tphw->res_y = ai.resolution == 0 ?
1681 		    DFLT_TPAD_RESOLUTION : ai.resolution;
1682 	}
1683 	if (quirks_get_dimensions(q, QUIRK_ATTR_RESOLUTION_HINT, &dim)) {
1684 		tphw->res_x = dim.x;
1685 		tphw->res_y = dim.y;
1686 	} else if (tphw->max_x != INT_MAX && tphw->max_y != INT_MAX &&
1687 		   quirks_get_dimensions(q, QUIRK_ATTR_SIZE_HINT, &dim)) {
1688 		tphw->res_x = (tphw->max_x - tphw->min_x) / dim.x;
1689 		tphw->res_y = (tphw->max_y - tphw->min_y) / dim.y;
1690 	}
1691 	if (!bit_test(ev->key_ignore, BTN_TOUCH) &&
1692 	     bit_test(key_bits, BTN_TOUCH))
1693 		tphw->cap_touch = true;
1694 	/* XXX: libinput uses ABS_MT_PRESSURE where available */
1695 	if (!bit_test(ev->abs_ignore, ABS_PRESSURE) &&
1696 	     bit_test(abs_bits, ABS_PRESSURE) &&
1697 	     ioctl(fd, EVIOCGABS(ABS_PRESSURE), &ai) >= 0) {
1698 		tphw->cap_pressure = true;
1699 		tphw->min_p = ai.minimum;
1700 		tphw->max_p = ai.maximum;
1701 	}
1702 	if (tphw->cap_pressure &&
1703 	    quirks_get_range(q, QUIRK_ATTR_PRESSURE_RANGE, &r)) {
1704 		if (r.upper == 0 && r.lower == 0) {
1705 			debug("pressure-based touch detection disabled");
1706 			tphw->cap_pressure = false;
1707 		} else if (r.upper > tphw->max_p || r.upper < tphw->min_p ||
1708 			   r.lower > tphw->max_p || r.lower < tphw->min_p) {
1709 			debug("discarding out-of-bounds pressure range %d:%d",
1710 			    r.lower, r.upper);
1711 			tphw->cap_pressure = false;
1712 		}
1713 	}
1714 	/* XXX: libinput uses ABS_MT_TOUCH_MAJOR where available */
1715 	if (!bit_test(ev->abs_ignore, ABS_TOOL_WIDTH) &&
1716 	     bit_test(abs_bits, ABS_TOOL_WIDTH) &&
1717 	     quirks_get_uint32(q, QUIRK_ATTR_PALM_SIZE_THRESHOLD, &u) &&
1718 	     u != 0)
1719 		tphw->cap_width = true;
1720 	if (!bit_test(ev->abs_ignore, ABS_MT_SLOT) &&
1721 	     bit_test(abs_bits, ABS_MT_SLOT) &&
1722 	    !bit_test(ev->abs_ignore, ABS_MT_TRACKING_ID) &&
1723 	     bit_test(abs_bits, ABS_MT_TRACKING_ID) &&
1724 	    !bit_test(ev->abs_ignore, ABS_MT_POSITION_X) &&
1725 	     bit_test(abs_bits, ABS_MT_POSITION_X) &&
1726 	    !bit_test(ev->abs_ignore, ABS_MT_POSITION_Y) &&
1727 	     bit_test(abs_bits, ABS_MT_POSITION_Y))
1728 		tphw->is_mt = true;
1729 	if ( ioctl(fd, EVIOCGPROP(sizeof(prop_bits)), prop_bits) >= 0 &&
1730 	    !bit_test(ev->prop_ignore, INPUT_PROP_BUTTONPAD) &&
1731 	     bit_test(prop_bits, INPUT_PROP_BUTTONPAD))
1732 		tphw->is_clickpad = true;
1733 	if ( tphw->is_clickpad &&
1734 	    !bit_test(ev->prop_ignore, INPUT_PROP_TOPBUTTONPAD) &&
1735 	     bit_test(prop_bits, INPUT_PROP_TOPBUTTONPAD))
1736 		tphw->is_topbuttonpad = true;
1737 }
1738 
1739 static void
r_init_touchpad_info(struct quirks * q,struct tpcaps * tphw,struct tpinfo * tpinfo)1740 r_init_touchpad_info(struct quirks *q, struct tpcaps *tphw,
1741     struct tpinfo *tpinfo)
1742 {
1743 	struct quirk_range r;
1744 	int i;
1745 	u_int u;
1746 	int sz_x, sz_y;
1747 
1748 	*tpinfo = (struct tpinfo) {
1749 		.two_finger_scroll = true,
1750 		.natural_scroll = false,
1751 		.three_finger_drag = false,
1752 		.min_pressure_hi = 1,
1753 		.min_pressure_lo = 1,
1754 		.max_pressure = 130,
1755 		.max_width = 16,
1756 		.tap_timeout = 180,		/* ms */
1757 		.tap_threshold = 0,
1758 		.tap_max_delta = 1.3,		/* mm */
1759 		.taphold_timeout = 300,		/* ms */
1760 		.vscroll_min_delta = 1.25,	/* mm */
1761 		.vscroll_hor_area = 0.0,	/* mm */
1762 		.vscroll_ver_area = -15.0,	/* mm */
1763 	};
1764 
1765 	quirks_get_bool(q, MOUSED_TWO_FINGER_SCROLL, &tpinfo->two_finger_scroll);
1766 	quirks_get_bool(q, MOUSED_NATURAL_SCROLL, &tpinfo->natural_scroll);
1767 	quirks_get_bool(q, MOUSED_THREE_FINGER_DRAG, &tpinfo->three_finger_drag);
1768 	quirks_get_uint32(q, MOUSED_TAP_TIMEOUT, &tpinfo->tap_timeout);
1769 	quirks_get_double(q, MOUSED_TAP_MAX_DELTA, &tpinfo->tap_max_delta);
1770 	quirks_get_uint32(q, MOUSED_TAPHOLD_TIMEOUT, &tpinfo->taphold_timeout);
1771 	quirks_get_double(q, MOUSED_VSCROLL_MIN_DELTA, &tpinfo->vscroll_min_delta);
1772 	quirks_get_double(q, MOUSED_VSCROLL_HOR_AREA, &tpinfo->vscroll_hor_area);
1773 	quirks_get_double(q, MOUSED_VSCROLL_VER_AREA, &tpinfo->vscroll_ver_area);
1774 
1775 	if (tphw->cap_pressure &&
1776 	    quirks_get_range(q, QUIRK_ATTR_PRESSURE_RANGE, &r)) {
1777 		tpinfo->min_pressure_lo = r.lower;
1778 		tpinfo->min_pressure_hi = r.upper;
1779 		quirks_get_uint32(q, QUIRK_ATTR_PALM_PRESSURE_THRESHOLD,
1780 		    &tpinfo->max_pressure);
1781 		quirks_get_uint32(q, MOUSED_TAP_PRESSURE_THRESHOLD,
1782 		    &tpinfo->tap_threshold);
1783 	}
1784 	if (tphw->cap_width)
1785 		quirks_get_uint32(q, QUIRK_ATTR_PALM_SIZE_THRESHOLD,
1786 		     &tpinfo->max_width);
1787 	/* Set bottom quarter as 42% - 16% - 42% sized softbuttons */
1788 	if (tphw->is_clickpad) {
1789 		sz_x = tphw->max_x - tphw->min_x;
1790 		sz_y = tphw->max_y - tphw->min_y;
1791 		i = 25;
1792 		if (tphw->is_topbuttonpad)
1793 			i = -i;
1794 		quirks_get_int32(q, MOUSED_SOFTBUTTONS_Y, &i);
1795 		tpinfo->softbuttons_y = sz_y * i / 100;
1796 		u = 42;
1797 		quirks_get_uint32(q, MOUSED_SOFTBUTTON2_X, &u);
1798 		tpinfo->softbutton2_x = sz_x * u / 100;
1799 		u = 58;
1800 		quirks_get_uint32(q, MOUSED_SOFTBUTTON3_X, &u);
1801 		tpinfo->softbutton3_x = sz_x * u / 100;
1802 	}
1803 }
1804 
1805 static void
r_init_touchpad_accel(struct tpcaps * tphw,struct accel * accel)1806 r_init_touchpad_accel(struct tpcaps *tphw, struct accel *accel)
1807 {
1808 	/* Normalize pointer movement to match 200dpi mouse */
1809 	accel->accelx *= DFLT_MOUSE_RESOLUTION;
1810 	accel->accelx /= tphw->res_x;
1811 	accel->accely *= DFLT_MOUSE_RESOLUTION;
1812 	accel->accely /= tphw->res_y;
1813 	accel->accelz *= DFLT_MOUSE_RESOLUTION;
1814 	accel->accelz /= (tphw->res_x * DFLT_LINEHEIGHT);
1815 }
1816 
1817 static void
r_init_touchpad_gesture(struct tpstate * gest)1818 r_init_touchpad_gesture(struct tpstate *gest)
1819 {
1820 	gest->idletimeout = -1;
1821 }
1822 
1823 static void
r_init_drift(struct quirks * q,struct drift * d)1824 r_init_drift(struct quirks *q, struct drift *d)
1825 {
1826 	if (opt_drift_terminate) {
1827 		d->terminate = true;
1828 		d->distance = opt_drift_distance;
1829 		d->time = opt_drift_time;
1830 		d->after = opt_drift_after;
1831 	} else if (quirks_get_bool(q, MOUSED_DRIFT_TERMINATE, &d->terminate) &&
1832 		   d->terminate) {
1833 		quirks_get_uint32(q, MOUSED_DRIFT_DISTANCE, &d->distance);
1834 		quirks_get_uint32(q, MOUSED_DRIFT_TIME, &d->time);
1835 		quirks_get_uint32(q, MOUSED_DRIFT_AFTER, &d->after);
1836 	} else
1837 		return;
1838 
1839 	if (d->distance == 0 || d->time == 0 || d->after == 0) {
1840 		warnx("invalid drift parameter");
1841 		exit(1);
1842 	}
1843 
1844 	debug("terminate drift: distance %d, time %d, after %d",
1845 	    d->distance, d->time, d->after);
1846 
1847 	d->time_ts = msec2ts(d->time);
1848 	d->twotime_ts = msec2ts(d->time * 2);
1849 	d->after_ts = msec2ts(d->after);
1850 }
1851 
1852 static void
r_init_accel(struct quirks * q,struct accel * acc)1853 r_init_accel(struct quirks *q, struct accel *acc)
1854 {
1855 	bool r1, r2;
1856 
1857 	acc->accelx = opt_accelx;
1858 	if (opt_accelx == 1.0)
1859 		 quirks_get_double(q, MOUSED_LINEAR_ACCEL_X, &acc->accelx);
1860 	acc->accely = opt_accely;
1861 	if (opt_accely == 1.0)
1862 		 quirks_get_double(q, MOUSED_LINEAR_ACCEL_Y, &acc->accely);
1863 	if (!quirks_get_double(q, MOUSED_LINEAR_ACCEL_Z, &acc->accelz))
1864 		acc->accelz = 1.0;
1865 	acc->lastlength[0] = acc->lastlength[1] = acc->lastlength[2] = 0.0;
1866 	if (opt_exp_accel) {
1867 		acc->is_exponential = true;
1868 		acc->expoaccel = opt_expoaccel;
1869 		acc->expoffset = opt_expoffset;
1870 		return;
1871 	}
1872 	acc->expoaccel = acc->expoffset = 1.0;
1873 	r1 = quirks_get_double(q, MOUSED_EXPONENTIAL_ACCEL, &acc->expoaccel);
1874 	r2 = quirks_get_double(q, MOUSED_EXPONENTIAL_OFFSET, &acc->expoffset);
1875 	if (r1 || r2)
1876 		acc->is_exponential = true;
1877 }
1878 
1879 static void
r_init_scroll(struct quirks * q,struct scroll * scroll)1880 r_init_scroll(struct quirks *q, struct scroll *scroll)
1881 {
1882 	*scroll = (struct scroll) {
1883 		.threshold = DFLT_SCROLLTHRESHOLD,
1884 		.speed = DFLT_SCROLLSPEED,
1885 		.state = SCROLL_NOTSCROLLING,
1886 	};
1887 	scroll->enable_vert = opt_virtual_scroll;
1888 	if (!opt_virtual_scroll)
1889 		quirks_get_bool(q, MOUSED_VIRTUAL_SCROLL_ENABLE, &scroll->enable_vert);
1890 	scroll->enable_hor = opt_hvirtual_scroll;
1891 	if (!opt_hvirtual_scroll)
1892 		quirks_get_bool(q, MOUSED_HOR_VIRTUAL_SCROLL_ENABLE, &scroll->enable_hor);
1893 	if (opt_scroll_speed >= 0)
1894 		scroll->speed = opt_scroll_speed;
1895 	else
1896 		quirks_get_uint32(q, MOUSED_VIRTUAL_SCROLL_SPEED, &scroll->speed);
1897 	if (opt_scroll_threshold >= 0)
1898 		scroll->threshold = opt_scroll_threshold;
1899 	else
1900 		quirks_get_uint32(q, MOUSED_VIRTUAL_SCROLL_THRESHOLD, &scroll->threshold);
1901 }
1902 
1903 static struct rodent *
r_init(const char * path)1904 r_init(const char *path)
1905 {
1906 	struct rodent *r;
1907 	struct device dev;
1908 	struct quirks *q;
1909 	struct kevent kev;
1910 	enum device_if iftype;
1911 	enum device_type type;
1912 	int fd, err;
1913 	bool grab;
1914 	bool ignore;
1915 	bool qvalid;
1916 
1917 	fd = open(path, O_RDWR | O_NONBLOCK);
1918 	if (fd == -1) {
1919 		logwarnx("unable to open %s", path);
1920 		return (NULL);
1921 	}
1922 
1923 	iftype =  r_identify_if(fd);
1924 	switch (iftype) {
1925 	case DEVICE_IF_UNKNOWN:
1926 		debug("cannot determine interface type on %s", path);
1927 		close(fd);
1928 		errno = ENOTSUP;
1929 		return (NULL);
1930 	case DEVICE_IF_EVDEV:
1931 		type = r_identify_evdev(fd);
1932 		break;
1933 	case DEVICE_IF_SYSMOUSE:
1934 		type = r_identify_sysmouse(fd);
1935 		break;
1936 	default:
1937 		debug("unsupported interface type: %s on %s",
1938 		    r_if(iftype), path);
1939 		close(fd);
1940 		errno = ENXIO;
1941 		return (NULL);
1942 	}
1943 
1944 	switch (type) {
1945 	case DEVICE_TYPE_UNKNOWN:
1946 		debug("cannot determine device type on %s", path);
1947 		close(fd);
1948 		errno = ENOTSUP;
1949 		return (NULL);
1950 	case DEVICE_TYPE_MOUSE:
1951 	case DEVICE_TYPE_TOUCHPAD:
1952 		break;
1953 	default:
1954 		debug("unsupported device type: %s on %s",
1955 		    r_name(type), path);
1956 		close(fd);
1957 		errno = ENXIO;
1958 		return (NULL);
1959 	}
1960 
1961 	memset(&dev, 0, sizeof(struct device));
1962 	strlcpy(dev.path, path, sizeof(dev.path));
1963 	dev.iftype = iftype;
1964 	dev.type = type;
1965 	switch (iftype) {
1966 	case DEVICE_IF_EVDEV:
1967 		err = r_init_dev_evdev(fd, &dev);
1968 		break;
1969 	case DEVICE_IF_SYSMOUSE:
1970 		err = r_init_dev_sysmouse(fd, &dev);
1971 		break;
1972 	default:
1973 		debug("unsupported interface type: %s on %s",
1974 		    r_if(iftype), path);
1975 		err = ENXIO;
1976 	}
1977 	if (err != 0) {
1978 		debug("failed to initialize device: %s %s on %s",
1979 		    r_if(iftype), r_name(type), path);
1980 		close(fd);
1981 		errno = err;
1982 		return (NULL);
1983 	}
1984 
1985 	debug("port: %s  interface: %s  type: %s  model: %s",
1986 	    path, r_if(iftype), r_name(type), dev.name);
1987 
1988 	q = quirks_fetch_for_device(quirks, &dev);
1989 
1990 	qvalid = quirks_get_bool(q, MOUSED_IGNORE_DEVICE, &ignore);
1991 	if (qvalid && ignore) {
1992 		debug("%s: device ignored", path);
1993 		close(fd);
1994 		quirks_unref(q);
1995 		errno = EPERM;
1996 		return (NULL);
1997 	}
1998 
1999 	switch (iftype) {
2000 	case DEVICE_IF_EVDEV:
2001 		grab = opt_grab;
2002 		if (!grab)
2003 			qvalid = quirks_get_bool(q, MOUSED_GRAB_DEVICE, &grab);
2004 		if (qvalid && grab && ioctl(fd, EVIOCGRAB, 1) == -1) {
2005 			logwarnx("failed to grab %s", path);
2006 			err = errno;
2007 		}
2008 		break;
2009 	case DEVICE_IF_SYSMOUSE:
2010 		if (opt_resolution == MOUSE_RES_UNKNOWN && opt_rate == 0)
2011 			break;
2012 		if (opt_resolution != MOUSE_RES_UNKNOWN)
2013 			dev.mode.resolution = opt_resolution;
2014 		if (opt_resolution != 0)
2015 			dev.mode.rate = opt_rate;
2016 		if (ioctl(fd, MOUSE_SETMODE, &dev.mode) < 0)
2017 			debug("failed to MOUSE_SETMODE for device %s", path);
2018 		break;
2019 	default:
2020 		debug("unsupported interface type: %s on %s",
2021 		    r_if(iftype), path);
2022 		err = ENXIO;
2023 	}
2024 	if (err != 0) {
2025 		debug("failed to initialize device: %s %s on %s",
2026 		    r_if(iftype), r_name(type), path);
2027 		close(fd);
2028 		quirks_unref(q);
2029 		errno = err;
2030 		return (NULL);
2031 	}
2032 
2033 	r = calloc(1, sizeof(struct rodent));
2034 	memcpy(&r->dev, &dev, sizeof(struct device));
2035 	r->mfd = fd;
2036 
2037 	EV_SET(&kev, fd, EVFILT_READ, EV_ADD, 0, 0, r);
2038 	err = kevent(kfd, &kev, 1, NULL, 0, NULL);
2039 	if (err == -1) {
2040 		logwarnx("failed to register kevent on %s", path);
2041 		close(fd);
2042 		free(r);
2043 		quirks_unref(q);
2044 		return (NULL);
2045 	}
2046 
2047 	if (iftype == DEVICE_IF_EVDEV)
2048 		r_init_evstate(q, &r->ev);
2049 	r_init_buttons(q, &r->btstate, &r->e3b);
2050 	r_init_scroll(q, &r->scroll);
2051 	r_init_accel(q, &r->accel);
2052 	switch (type) {
2053 	case DEVICE_TYPE_TOUCHPAD:
2054 		r_init_touchpad_hw(fd, q, &r->tp.hw, &r->ev);
2055 		r_init_touchpad_info(q, &r->tp.hw, &r->tp.info);
2056 		r_init_touchpad_accel(&r->tp.hw, &r->accel);
2057 		r_init_touchpad_gesture(&r->tp.gest);
2058 		break;
2059 
2060 	case DEVICE_TYPE_MOUSE:
2061 		r_init_drift(q, &r->drift);
2062 		break;
2063 
2064 	default:
2065 		debug("unsupported device type: %s", r_name(type));
2066 		break;
2067 	}
2068 
2069 	quirks_unref(q);
2070 
2071 	SLIST_INSERT_HEAD(&rodents, r, next);
2072 
2073 	return (r);
2074 }
2075 
2076 static void
r_init_all(void)2077 r_init_all(void)
2078 {
2079 	char path[22] = "/dev/input/";
2080 	DIR *dirp;
2081 	struct dirent *dp;
2082 
2083 	dirp = opendir("/dev/input");
2084 	if (dirp == NULL)
2085 		logerr(1, "Failed to open /dev/input");
2086 
2087 	while ((dp = readdir(dirp)) != NULL) {
2088 		if (fnmatch("event[0-9]*", dp->d_name, 0) == 0) {
2089 			strncpy(path + 11, dp->d_name, 10);
2090 			(void)r_init(path);
2091 		}
2092 	}
2093 	(void)closedir(dirp);
2094 
2095 	return;
2096 }
2097 
2098 static void
r_deinit(struct rodent * r)2099 r_deinit(struct rodent *r)
2100 {
2101 	struct kevent ke[3];
2102 
2103 	if (r == NULL)
2104 		return;
2105 	if (r->mfd != -1) {
2106 		EV_SET(ke, r->mfd, EVFILT_READ, EV_DELETE, 0, 0, r);
2107 		EV_SET(ke + 1, r->mfd << 1, EVFILT_TIMER, EV_DELETE, 0, 0, r);
2108 		EV_SET(ke + 2, r->mfd << 1 | 1,
2109 		    EVFILT_TIMER, EV_DELETE, 0, 0, r);
2110 		kevent(kfd, ke, nitems(ke), NULL, 0, NULL);
2111 		close(r->mfd);
2112 	}
2113 	SLIST_REMOVE(&rodents, r, rodent, next);
2114 	debug("destroy device: port: %s  model: %s", r->dev.path, r->dev.name);
2115 	free(r);
2116 }
2117 
2118 static void
r_deinit_all(void)2119 r_deinit_all(void)
2120 {
2121 	while (!SLIST_EMPTY(&rodents))
2122 		r_deinit(SLIST_FIRST(&rodents));
2123 }
2124 
2125 static int
r_protocol_evdev(enum device_type type,struct tpad * tp,struct evstate * ev,struct input_event * ie,mousestatus_t * act)2126 r_protocol_evdev(enum device_type type, struct tpad *tp, struct evstate *ev,
2127     struct input_event *ie, mousestatus_t *act)
2128 {
2129 	const struct tpcaps *tphw = &tp->hw;
2130 	const struct tpinfo *tpinfo = &tp->info;
2131 
2132 	static int butmapev[8] = {	/* evdev */
2133 	    0,
2134 	    MOUSE_BUTTON1DOWN,
2135 	    MOUSE_BUTTON3DOWN,
2136 	    MOUSE_BUTTON1DOWN | MOUSE_BUTTON3DOWN,
2137 	    MOUSE_BUTTON2DOWN,
2138 	    MOUSE_BUTTON1DOWN | MOUSE_BUTTON2DOWN,
2139 	    MOUSE_BUTTON2DOWN | MOUSE_BUTTON3DOWN,
2140 	    MOUSE_BUTTON1DOWN | MOUSE_BUTTON2DOWN | MOUSE_BUTTON3DOWN
2141 	};
2142 	struct timespec ietime;
2143 
2144 	/* Drop ignored codes */
2145 	switch (ie->type) {
2146 	case EV_REL:
2147 		if (bit_test(ev->rel_ignore, ie->code))
2148 			return (0);
2149 	case EV_ABS:
2150 		if (bit_test(ev->abs_ignore, ie->code))
2151 			return (0);
2152 	case EV_KEY:
2153 		if (bit_test(ev->key_ignore, ie->code))
2154 			return (0);
2155 	}
2156 
2157 	if (debug > 1)
2158 		debug("received event 0x%02x, 0x%04x, %d",
2159 		    ie->type, ie->code, ie->value);
2160 
2161 	switch (ie->type) {
2162 	case EV_REL:
2163 		switch (ie->code) {
2164 		case REL_X:
2165 			ev->dx += ie->value;
2166 			break;
2167 		case REL_Y:
2168 			ev->dy += ie->value;
2169 			break;
2170 		case REL_WHEEL:
2171 			ev->dz += ie->value;
2172 			break;
2173 		case REL_HWHEEL:
2174 			ev->dw += ie->value;
2175 			break;
2176 		}
2177 		break;
2178 	case EV_ABS:
2179 		switch (ie->code) {
2180 		case ABS_X:
2181 			if (!tphw->is_mt)
2182 				ev->dx += ie->value - ev->st.x;
2183 			ev->st.x = ie->value;
2184 			break;
2185 		case ABS_Y:
2186 			if (!tphw->is_mt)
2187 				ev->dy += ie->value - ev->st.y;
2188 			ev->st.y = ie->value;
2189 			break;
2190 		case ABS_PRESSURE:
2191 			ev->st.p = ie->value;
2192 			break;
2193 		case ABS_TOOL_WIDTH:
2194 			ev->st.w = ie->value;
2195 			break;
2196 		case ABS_MT_SLOT:
2197 			if (tphw->is_mt)
2198 				ev->slot = ie->value;
2199 			break;
2200 		case ABS_MT_TRACKING_ID:
2201 			if (tphw->is_mt &&
2202 			    ev->slot >= 0 && ev->slot < MAX_FINGERS) {
2203 				if (ie->value != -1 && ev->mt[ev->slot].id > 0 &&
2204 				    ie->value + 1 != ev->mt[ev->slot].id) {
2205 					debug("tracking id changed %d->%d",
2206 					    ie->value, ev->mt[ev->slot].id - 1);
2207 					ev->mt[ev->slot].id = 0;
2208 				} else
2209 					ev->mt[ev->slot].id = ie->value + 1;
2210 			}
2211 			break;
2212 		case ABS_MT_POSITION_X:
2213 			if (tphw->is_mt &&
2214 			    ev->slot >= 0 && ev->slot < MAX_FINGERS) {
2215 			    	/* Find fastest finger */
2216 			        int dx = ie->value - ev->mt[ev->slot].x;
2217 				if (abs(dx) > abs(ev->dx))
2218 					ev->dx = dx;
2219 				ev->mt[ev->slot].x = ie->value;
2220 			}
2221 			break;
2222 		case ABS_MT_POSITION_Y:
2223 			if (tphw->is_mt &&
2224 			    ev->slot >= 0 && ev->slot < MAX_FINGERS) {
2225 			    	/* Find fastest finger */
2226 				int dy = ie->value - ev->mt[ev->slot].y;
2227 				if (abs(dy) > abs(ev->dy))
2228 					ev->dy = dy;
2229 				ev->mt[ev->slot].y = ie->value;
2230 			}
2231 			break;
2232 		}
2233 		break;
2234 	case EV_KEY:
2235 		switch (ie->code) {
2236 		case BTN_TOUCH:
2237 			ev->st.id = ie->value != 0 ? 1 : 0;
2238 			break;
2239 		case BTN_TOOL_FINGER:
2240 			ev->nfingers = ie->value != 0 ? 1 : ev->nfingers;
2241 			break;
2242 		case BTN_TOOL_DOUBLETAP:
2243 			ev->nfingers = ie->value != 0 ? 2 : ev->nfingers;
2244 			break;
2245 		case BTN_TOOL_TRIPLETAP:
2246 			ev->nfingers = ie->value != 0 ? 3 : ev->nfingers;
2247 			break;
2248 		case BTN_TOOL_QUADTAP:
2249 			ev->nfingers = ie->value != 0 ? 4 : ev->nfingers;
2250 			break;
2251 		case BTN_TOOL_QUINTTAP:
2252 			ev->nfingers = ie->value != 0 ? 5 : ev->nfingers;
2253 			break;
2254 		case BTN_LEFT ... BTN_LEFT + 7:
2255 			ev->buttons &= ~(1 << (ie->code - BTN_LEFT));
2256 			ev->buttons |= ((!!ie->value) << (ie->code - BTN_LEFT));
2257 			break;
2258 		}
2259 		break;
2260 	}
2261 
2262 	if ( ie->type != EV_SYN ||
2263 	    (ie->code != SYN_REPORT && ie->code != SYN_DROPPED))
2264 		return (0);
2265 
2266 	/*
2267 	 * assembly full package
2268 	 */
2269 
2270 	ietime.tv_sec = ie->time.tv_sec;
2271 	ietime.tv_nsec = ie->time.tv_usec * 1000;
2272 
2273 	if (!tphw->cap_pressure && ev->st.id != 0)
2274 		ev->st.p = MAX(tpinfo->min_pressure_hi, tpinfo->tap_threshold);
2275 	if (tphw->cap_touch && ev->st.id == 0)
2276 		ev->st.p = 0;
2277 
2278 	act->obutton = act->button;
2279 	act->button = butmapev[ev->buttons & MOUSE_SYS_STDBUTTONS];
2280 	act->button |= (ev->buttons & ~MOUSE_SYS_STDBUTTONS);
2281 
2282 	if (type == DEVICE_TYPE_TOUCHPAD) {
2283 		if (debug > 1)
2284 			debug("absolute data %d,%d,%d,%d", ev->st.x, ev->st.y,
2285 			    ev->st.p, ev->st.w);
2286 		switch (r_gestures(tp, ev->st.x, ev->st.y, ev->st.p, ev->st.w,
2287 		    ev->nfingers, &ietime, act)) {
2288 		case GEST_IGNORE:
2289 			ev->dx = 0;
2290 			ev->dy = 0;
2291 			ev->dz = 0;
2292 			ev->acc_dx = ev->acc_dy = 0;
2293 			debug("gesture IGNORE");
2294 			break;
2295 		case GEST_ACCUMULATE:	/* Revertable pointer movement. */
2296 			ev->acc_dx += ev->dx;
2297 			ev->acc_dy += ev->dy;
2298 			debug("gesture ACCUMULATE %d,%d", ev->dx, ev->dy);
2299 			ev->dx = 0;
2300 			ev->dy = 0;
2301 			break;
2302 		case GEST_MOVE:		/* Pointer movement. */
2303 			ev->dx += ev->acc_dx;
2304 			ev->dy += ev->acc_dy;
2305 			ev->acc_dx = ev->acc_dy = 0;
2306 			debug("gesture MOVE %d,%d", ev->dx, ev->dy);
2307 			break;
2308 		case GEST_VSCROLL:	/* Vertical scrolling. */
2309 			if (tpinfo->natural_scroll)
2310 				ev->dz = -ev->dy;
2311 			else
2312 				ev->dz = ev->dy;
2313 			ev->dx = -ev->acc_dx;
2314 			ev->dy = -ev->acc_dy;
2315 			ev->acc_dx = ev->acc_dy = 0;
2316 			debug("gesture VSCROLL %d", ev->dz);
2317 			break;
2318 		case GEST_HSCROLL:	/* Horizontal scrolling. */
2319 /*
2320 			if (ev.dx != 0) {
2321 				if (tpinfo->natural_scroll)
2322 					act->button |= (ev.dx > 0)
2323 					    ? MOUSE_BUTTON6DOWN
2324 					    : MOUSE_BUTTON7DOWN;
2325 				else
2326 					act->button |= (ev.dx > 0)
2327 					    ? MOUSE_BUTTON7DOWN
2328 					    : MOUSE_BUTTON6DOWN;
2329 			}
2330 */
2331 			ev->dx = -ev->acc_dx;
2332 			ev->dy = -ev->acc_dy;
2333 			ev->acc_dx = ev->acc_dy = 0;
2334 			debug("gesture HSCROLL %d", ev->dw);
2335 			break;
2336 		}
2337 	}
2338 
2339 	debug("assembled full packet %d,%d,%d", ev->dx, ev->dy, ev->dz);
2340 	act->dx = ev->dx;
2341 	act->dy = ev->dy;
2342 	act->dz = ev->dz;
2343 	ev->dx = ev->dy = ev->dz = ev->dw = 0;
2344 
2345 	/* has something changed? */
2346 	act->flags = ((act->dx || act->dy || act->dz) ? MOUSE_POSCHANGED : 0)
2347 	    | (act->obutton ^ act->button);
2348 
2349 	return (act->flags);
2350 }
2351 
2352 static int
r_protocol_sysmouse(uint8_t * pBuf,mousestatus_t * act)2353 r_protocol_sysmouse(uint8_t *pBuf, mousestatus_t *act)
2354 {
2355 	static int butmapmsc[8] = { /* sysmouse */
2356 	    0,
2357 	    MOUSE_BUTTON3DOWN,
2358 	    MOUSE_BUTTON2DOWN,
2359 	    MOUSE_BUTTON2DOWN | MOUSE_BUTTON3DOWN,
2360 	    MOUSE_BUTTON1DOWN,
2361 	    MOUSE_BUTTON1DOWN | MOUSE_BUTTON3DOWN,
2362 	    MOUSE_BUTTON1DOWN | MOUSE_BUTTON2DOWN,
2363 	    MOUSE_BUTTON1DOWN | MOUSE_BUTTON2DOWN | MOUSE_BUTTON3DOWN
2364 	};
2365 
2366 	debug("%02x %02x %02x %02x %02x %02x %02x %02x", pBuf[0], pBuf[1],
2367 	    pBuf[2], pBuf[3], pBuf[4], pBuf[5], pBuf[6], pBuf[7]);
2368 
2369 	if ((pBuf[0] & MOUSE_SYS_SYNCMASK) != MOUSE_SYS_SYNC)
2370 		return (0);
2371 
2372 	act->button = butmapmsc[(~pBuf[0]) & MOUSE_SYS_STDBUTTONS];
2373 	act->dx =    (signed char)(pBuf[1]) + (signed char)(pBuf[3]);
2374 	act->dy = - ((signed char)(pBuf[2]) + (signed char)(pBuf[4]));
2375 	act->dz = ((signed char)(pBuf[5] << 1) + (signed char)(pBuf[6] << 1)) >> 1;
2376 	act->button |= ((~pBuf[7] & MOUSE_SYS_EXTBUTTONS) << 3);
2377 
2378 	/* has something changed? */
2379 	act->flags = ((act->dx || act->dy || act->dz) ? MOUSE_POSCHANGED : 0)
2380 	    | (act->obutton ^ act->button);
2381 
2382 	return (act->flags);
2383 }
2384 
2385 static void
r_vscroll_detect(struct rodent * r,struct scroll * sc,mousestatus_t * act)2386 r_vscroll_detect(struct rodent *r, struct scroll *sc, mousestatus_t *act)
2387 {
2388 	mousestatus_t newaction;
2389 
2390 	/* Allow middle button drags to scroll up and down */
2391 	if (act->button == MOUSE_BUTTON2DOWN) {
2392 		if (sc->state == SCROLL_NOTSCROLLING) {
2393 			sc->state = SCROLL_PREPARE;
2394 			sc->movement = sc->hmovement = 0;
2395 			debug("PREPARING TO SCROLL");
2396 		}
2397 		return;
2398 	}
2399 
2400 	/* This isn't a middle button down... move along... */
2401 	switch (sc->state) {
2402 	case SCROLL_SCROLLING:
2403 		/*
2404 		 * We were scrolling, someone let go of button 2.
2405 		 * Now turn autoscroll off.
2406 		 */
2407 		sc->state = SCROLL_NOTSCROLLING;
2408 		debug("DONE WITH SCROLLING / %d", sc->state);
2409 		break;
2410 	case SCROLL_PREPARE:
2411 		newaction = *act;
2412 
2413 		/* We were preparing to scroll, but we never moved... */
2414 		r_timestamp(act, &r->btstate, &r->e3b, &r->drift);
2415 		r_statetrans(r, act, &newaction,
2416 			     A(newaction.button & MOUSE_BUTTON1DOWN,
2417 			       act->button & MOUSE_BUTTON3DOWN));
2418 
2419 		/* Send middle down */
2420 		newaction.button = MOUSE_BUTTON2DOWN;
2421 		r_click(&newaction, &r->btstate);
2422 
2423 		/* Send middle up */
2424 		r_timestamp(&newaction, &r->btstate, &r->e3b, &r->drift);
2425 		newaction.obutton = newaction.button;
2426 		newaction.button = act->button;
2427 		r_click(&newaction, &r->btstate);
2428 		break;
2429 	default:
2430 		break;
2431 	}
2432 }
2433 
2434 static void
r_vscroll(struct scroll * sc,mousestatus_t * act)2435 r_vscroll(struct scroll *sc, mousestatus_t *act)
2436 {
2437 	switch (sc->state) {
2438 	case SCROLL_PREPARE:
2439 		/* Middle button down, waiting for movement threshold */
2440 		if (act->dy == 0 && act->dx == 0)
2441 			break;
2442 		if (sc->enable_vert) {
2443 			sc->movement += act->dy;
2444 			if ((u_int)abs(sc->movement) > sc->threshold)
2445 				sc->state = SCROLL_SCROLLING;
2446 		}
2447 		if (sc->enable_hor) {
2448 			sc->hmovement += act->dx;
2449 			if ((u_int)abs(sc->hmovement) > sc->threshold)
2450 				sc->state = SCROLL_SCROLLING;
2451 		}
2452 		if (sc->state == SCROLL_SCROLLING)
2453 			sc->movement = sc->hmovement = 0;
2454 		break;
2455 	case SCROLL_SCROLLING:
2456 		if (sc->enable_vert) {
2457 			sc->movement += act->dy;
2458 			debug("SCROLL: %d", sc->movement);
2459 			if (sc->movement < -(int)sc->speed) {
2460 				/* Scroll down */
2461 				act->dz = -1;
2462 				sc->movement = 0;
2463 			}
2464 			else if (sc->movement > (int)sc->speed) {
2465 				/* Scroll up */
2466 				act->dz = 1;
2467 				sc->movement = 0;
2468 			}
2469 		}
2470 		if (sc->enable_hor) {
2471 			sc->hmovement += act->dx;
2472 			debug("HORIZONTAL SCROLL: %d", sc->hmovement);
2473 
2474 			if (sc->hmovement < -(int)sc->speed) {
2475 				act->dz = -2;
2476 				sc->hmovement = 0;
2477 			}
2478 			else if (sc->hmovement > (int)sc->speed) {
2479 				act->dz = 2;
2480 				sc->hmovement = 0;
2481 			}
2482 		}
2483 
2484 		/* Don't move while scrolling */
2485 		act->dx = act->dy = 0;
2486 		break;
2487 	default:
2488 		break;
2489 	}
2490 }
2491 
2492 static bool
r_drift(struct drift * drift,mousestatus_t * act)2493 r_drift (struct drift *drift, mousestatus_t *act)
2494 {
2495 	struct timespec tmp;
2496 
2497 	/* X or/and Y movement only - possibly drift */
2498 	tssub(&drift->current_ts, &drift->last_activity, &tmp);
2499 	if (tscmp(&tmp, &drift->after_ts, >)) {
2500 		tssub(&drift->current_ts, &drift->since, &tmp);
2501 		if (tscmp(&tmp, &drift->time_ts, <)) {
2502 			drift->last.x += act->dx;
2503 			drift->last.y += act->dy;
2504 		} else {
2505 			/* discard old accumulated steps (drift) */
2506 			if (tscmp(&tmp, &drift->twotime_ts, >))
2507 				drift->previous.x = drift->previous.y = 0;
2508 			else
2509 				drift->previous = drift->last;
2510 			drift->last.x = act->dx;
2511 			drift->last.y = act->dy;
2512 			drift->since = drift->current_ts;
2513 		}
2514 		if ((u_int)abs(drift->last.x) + abs(drift->last.y) > drift->distance) {
2515 			/* real movement, pass all accumulated steps */
2516 			act->dx = drift->previous.x + drift->last.x;
2517 			act->dy = drift->previous.y + drift->last.y;
2518 			/* and reset accumulators */
2519 			tsclr(&drift->since);
2520 			drift->last.x = drift->last.y = 0;
2521 			/* drift_previous will be cleared at next movement*/
2522 			drift->last_activity = drift->current_ts;
2523 		} else {
2524 			return (true);	/* don't pass current movement to
2525 					 * console driver */
2526 		}
2527 	}
2528 	return (false);
2529 }
2530 
2531 static int
r_statetrans(struct rodent * r,mousestatus_t * a1,mousestatus_t * a2,int trans)2532 r_statetrans(struct rodent *r, mousestatus_t *a1, mousestatus_t *a2, int trans)
2533 {
2534 	struct e3bstate *e3b = &r->e3b;
2535 	bool changed;
2536 	int flags;
2537 
2538 	a2->dx = a1->dx;
2539 	a2->dy = a1->dy;
2540 	a2->dz = a1->dz;
2541 	a2->obutton = a2->button;
2542 	a2->button = a1->button;
2543 	a2->flags = a1->flags;
2544 	changed = false;
2545 
2546 	if (!e3b->enabled)
2547 		return (false);
2548 
2549 	if (debug > 2)
2550 		debug("state:%d, trans:%d -> state:%d",
2551 		    e3b->mouse_button_state, trans,
2552 		    states[e3b->mouse_button_state].s[trans]);
2553 	/*
2554 	 * Avoid re-ordering button and movement events. While a button
2555 	 * event is deferred, throw away up to BUTTON2_MAXMOVE movement
2556 	 * events to allow for mouse jitter. If more movement events
2557 	 * occur, then complete the deferred button events immediately.
2558 	 */
2559 	if ((a2->dx != 0 || a2->dy != 0) &&
2560 	    S_DELAYED(states[e3b->mouse_button_state].s[trans])) {
2561 		if (++e3b->mouse_move_delayed > BUTTON2_MAXMOVE) {
2562 			e3b->mouse_move_delayed = 0;
2563 			e3b->mouse_button_state =
2564 			    states[e3b->mouse_button_state].s[A_TIMEOUT];
2565 			changed = true;
2566 		} else
2567 			a2->dx = a2->dy = 0;
2568 	} else
2569 		e3b->mouse_move_delayed = 0;
2570 	if (e3b->mouse_button_state != states[e3b->mouse_button_state].s[trans])
2571 		changed = true;
2572 	if (changed)
2573 		clock_gettime(CLOCK_MONOTONIC_FAST,
2574 		   &e3b->mouse_button_state_ts);
2575 	e3b->mouse_button_state = states[e3b->mouse_button_state].s[trans];
2576 	a2->button &= ~(MOUSE_BUTTON1DOWN | MOUSE_BUTTON2DOWN |
2577 	    MOUSE_BUTTON3DOWN);
2578 	a2->button &= states[e3b->mouse_button_state].mask;
2579 	a2->button |= states[e3b->mouse_button_state].buttons;
2580 	flags = a2->flags & MOUSE_POSCHANGED;
2581 	flags |= a2->obutton ^ a2->button;
2582 	if (flags & MOUSE_BUTTON2DOWN) {
2583 		a2->flags = flags & MOUSE_BUTTON2DOWN;
2584 		r_timestamp(a2, &r->btstate, e3b, &r->drift);
2585 	}
2586 	a2->flags = flags;
2587 
2588 	return (changed);
2589 }
2590 
2591 static char *
skipspace(char * s)2592 skipspace(char *s)
2593 {
2594 	while(isspace(*s))
2595 		++s;
2596 	return (s);
2597 }
2598 
2599 static bool
r_installmap(char * arg,struct btstate * bt)2600 r_installmap(char *arg, struct btstate *bt)
2601 {
2602 	u_long pbutton;
2603 	u_long lbutton;
2604 	char *s;
2605 
2606 	while (*arg) {
2607 		arg = skipspace(arg);
2608 		s = arg;
2609 		while (isdigit(*arg))
2610 			++arg;
2611 		arg = skipspace(arg);
2612 		if ((arg <= s) || (*arg != '='))
2613 			return (false);
2614 		lbutton = strtoul(s, NULL, 10);
2615 
2616 		arg = skipspace(++arg);
2617 		s = arg;
2618 		while (isdigit(*arg))
2619 			++arg;
2620 		if ((arg <= s) || (!isspace(*arg) && (*arg != '\0')))
2621 			return (false);
2622 		pbutton = strtoul(s, NULL, 10);
2623 
2624 		if (lbutton == 0 || lbutton > MOUSE_MAXBUTTON)
2625 			return (false);
2626 		if (pbutton == 0 || pbutton > MOUSE_MAXBUTTON)
2627 			return (false);
2628 		bt->p2l[pbutton - 1] = 1 << (lbutton - 1);
2629 		bt->mstate[lbutton - 1] = &bt->bstate[pbutton - 1];
2630 	}
2631 
2632 	return (true);
2633 }
2634 
2635 static char *
r_installzmap(char ** argv,int argc,int * idx,struct btstate * bt)2636 r_installzmap(char **argv, int argc, int* idx, struct btstate *bt)
2637 {
2638 	char *arg, *errstr;
2639 	u_long i, j;
2640 
2641 	arg = argv[*idx];
2642 	++*idx;
2643 	if (strcmp(arg, "x") == 0) {
2644 		bt->zmap[0] = MOUSE_XAXIS;
2645 		return (NULL);
2646 	}
2647 	if (strcmp(arg, "y") == 0) {
2648 		bt->zmap[0] = MOUSE_YAXIS;
2649 		return (NULL);
2650 	}
2651 	i = strtoul(arg, NULL, 10);
2652 	/*
2653 	 * Use button i for negative Z axis movement and
2654 	 * button (i + 1) for positive Z axis movement.
2655 	 */
2656 	if (i == 0 || i >= MOUSE_MAXBUTTON) {
2657 		asprintf(&errstr, "invalid argument `%s'", arg);
2658 		return (errstr);
2659 	}
2660 	bt->zmap[0] = i;
2661 	bt->zmap[1] = i + 1;
2662 	debug("optind: %d, optarg: '%s'", *idx, arg);
2663 	for (j = 1; j < ZMAP_MAXBUTTON; ++j) {
2664 		if ((*idx >= argc) || !isdigit(*argv[*idx]))
2665 			break;
2666 		i = strtoul(argv[*idx], NULL, 10);
2667 		if (i == 0 || i >= MOUSE_MAXBUTTON) {
2668 			asprintf(&errstr, "invalid argument `%s'", argv[*idx]);
2669 			return (errstr);
2670 		}
2671 		bt->zmap[j] = i;
2672 		++*idx;
2673 	}
2674 	if ((bt->zmap[2] != 0) && (bt->zmap[3] == 0))
2675 		bt->zmap[3] = bt->zmap[2] + 1;
2676 
2677 	return (NULL);
2678 }
2679 
2680 static void
r_map(mousestatus_t * act1,mousestatus_t * act2,struct btstate * bt)2681 r_map(mousestatus_t *act1, mousestatus_t *act2, struct btstate *bt)
2682 {
2683 	int pb;
2684 	int pbuttons;
2685 	int lbuttons;
2686 
2687 	pbuttons = act1->button;
2688 	lbuttons = 0;
2689 
2690 	act2->obutton = act2->button;
2691 	if (pbuttons & bt->wmode) {
2692 		pbuttons &= ~bt->wmode;
2693 		act1->dz = act1->dy;
2694 		act1->dx = 0;
2695 		act1->dy = 0;
2696 	}
2697 	act2->dx = act1->dx;
2698 	act2->dy = act1->dy;
2699 	act2->dz = act1->dz;
2700 
2701 	switch (bt->zmap[0]) {
2702 	case 0:	/* do nothing */
2703 		break;
2704 	case MOUSE_XAXIS:
2705 		if (act1->dz != 0) {
2706 			act2->dx = act1->dz;
2707 			act2->dz = 0;
2708 		}
2709 		break;
2710 	case MOUSE_YAXIS:
2711 		if (act1->dz != 0) {
2712 			act2->dy = act1->dz;
2713 			act2->dz = 0;
2714 		}
2715 		break;
2716 	default:	/* buttons */
2717 		pbuttons &= ~(bt->zmap[0] | bt->zmap[1]
2718 			    | bt->zmap[2] | bt->zmap[3]);
2719 		if ((act1->dz < -1) && bt->zmap[2]) {
2720 			pbuttons |= bt->zmap[2];
2721 			bt->zstate[2].count = 1;
2722 		} else if (act1->dz < 0) {
2723 			pbuttons |= bt->zmap[0];
2724 			bt->zstate[0].count = 1;
2725 		} else if ((act1->dz > 1) && bt->zmap[3]) {
2726 			pbuttons |= bt->zmap[3];
2727 			bt->zstate[3].count = 1;
2728 		} else if (act1->dz > 0) {
2729 			pbuttons |= bt->zmap[1];
2730 			bt->zstate[1].count = 1;
2731 		}
2732 		act2->dz = 0;
2733 		break;
2734 	}
2735 
2736 	for (pb = 0; (pb < MOUSE_MAXBUTTON) && (pbuttons != 0); ++pb) {
2737 		lbuttons |= (pbuttons & 1) ? bt->p2l[pb] : 0;
2738 		pbuttons >>= 1;
2739 	}
2740 	act2->button = lbuttons;
2741 
2742 	act2->flags =
2743 	    ((act2->dx || act2->dy || act2->dz) ? MOUSE_POSCHANGED : 0)
2744 	    | (act2->obutton ^ act2->button);
2745 }
2746 
2747 static void
r_timestamp(mousestatus_t * act,struct btstate * bt,struct e3bstate * e3b,struct drift * drift)2748 r_timestamp(mousestatus_t *act, struct btstate *bt, struct e3bstate *e3b,
2749     struct drift *drift)
2750 {
2751 	struct timespec ts;
2752 	struct timespec ts1;
2753 	struct timespec ts2;
2754 	int button;
2755 	int mask;
2756 	int i;
2757 
2758 	mask = act->flags & MOUSE_BUTTONS;
2759 #if 0
2760 	if (mask == 0)
2761 		return;
2762 #endif
2763 
2764 	clock_gettime(CLOCK_MONOTONIC_FAST, &ts1);
2765 	drift->current_ts = ts1;
2766 
2767 	/* double click threshold */
2768 	ts = tssubms(&ts1, bt->clickthreshold);
2769 	debug("ts:  %jd %ld", (intmax_t)ts.tv_sec, ts.tv_nsec);
2770 
2771 	/* 3 button emulation timeout */
2772 	ts2 = tssubms(&ts1, e3b->button2timeout);
2773 
2774 	button = MOUSE_BUTTON1DOWN;
2775 	for (i = 0; (i < MOUSE_MAXBUTTON) && (mask != 0); ++i) {
2776 		if (mask & 1) {
2777 			if (act->button & button) {
2778 				/* the button is down */
2779 				debug("  :  %jd %ld",
2780 				    (intmax_t)bt->bstate[i].ts.tv_sec,
2781 				    bt->bstate[i].ts.tv_nsec);
2782 				if (tscmp(&ts, &bt->bstate[i].ts, >)) {
2783 					bt->bstate[i].count = 1;
2784 				} else {
2785 					++bt->bstate[i].count;
2786 				}
2787 				bt->bstate[i].ts = ts1;
2788 			} else {
2789 				/* the button is up */
2790 				bt->bstate[i].ts = ts1;
2791 			}
2792 		} else {
2793 			if (act->button & button) {
2794 				/* the button has been down */
2795 				if (tscmp(&ts2, &bt->bstate[i].ts, >)) {
2796 					bt->bstate[i].count = 1;
2797 					bt->bstate[i].ts = ts1;
2798 					act->flags |= button;
2799 					debug("button %d timeout", i + 1);
2800 				}
2801 			} else {
2802 				/* the button has been up */
2803 			}
2804 		}
2805 		button <<= 1;
2806 		mask >>= 1;
2807 	}
2808 }
2809 
2810 static bool
r_timeout(struct e3bstate * e3b)2811 r_timeout(struct e3bstate *e3b)
2812 {
2813 	struct timespec ts;
2814 	struct timespec ts1;
2815 
2816 	if (states[e3b->mouse_button_state].timeout)
2817 		return (true);
2818 	clock_gettime(CLOCK_MONOTONIC_FAST, &ts1);
2819 	ts = tssubms(&ts1, e3b->button2timeout);
2820 	return (tscmp(&ts, &e3b->mouse_button_state_ts, >));
2821 }
2822 
2823 static void
r_move(mousestatus_t * act,struct accel * acc)2824 r_move(mousestatus_t *act, struct accel *acc)
2825 {
2826 	struct mouse_info mouse;
2827 
2828 	bzero(&mouse, sizeof(mouse));
2829 	if (acc->is_exponential) {
2830 		expoacc(acc, act->dx, act->dy, act->dz,
2831 		    &mouse.u.data.x, &mouse.u.data.y, &mouse.u.data.z);
2832 	} else {
2833 		linacc(acc, act->dx, act->dy, act->dz,
2834 		    &mouse.u.data.x, &mouse.u.data.y, &mouse.u.data.z);
2835 	}
2836 	mouse.operation = MOUSE_MOTION_EVENT;
2837 	mouse.u.data.buttons = act->button;
2838 	if (debug < 2 && !paused)
2839 		ioctl(cfd, CONS_MOUSECTL, &mouse);
2840 }
2841 
2842 static void
r_click(mousestatus_t * act,struct btstate * bt)2843 r_click(mousestatus_t *act, struct btstate *bt)
2844 {
2845 	struct mouse_info mouse;
2846 	int button;
2847 	int mask;
2848 	int i;
2849 
2850 	mask = act->flags & MOUSE_BUTTONS;
2851 	if (mask == 0)
2852 		return;
2853 
2854 	button = MOUSE_BUTTON1DOWN;
2855 	for (i = 0; (i < MOUSE_MAXBUTTON) && (mask != 0); ++i) {
2856 		if (mask & 1) {
2857 			debug("mstate[%d]->count:%d", i, bt->mstate[i]->count);
2858 			if (act->button & button) {
2859 				/* the button is down */
2860 				mouse.u.event.value = bt->mstate[i]->count;
2861 			} else {
2862 				/* the button is up */
2863 				mouse.u.event.value = 0;
2864 			}
2865 			mouse.operation = MOUSE_BUTTON_EVENT;
2866 			mouse.u.event.id = button;
2867 			if (debug < 2 && !paused)
2868 				ioctl(cfd, CONS_MOUSECTL, &mouse);
2869 			debug("button %d  count %d", i + 1,
2870 			    mouse.u.event.value);
2871 		}
2872 		button <<= 1;
2873 		mask >>= 1;
2874 	}
2875 }
2876 
2877 static enum gesture
r_gestures(struct tpad * tp,int x0,int y0,u_int z,int w,int nfingers,struct timespec * time,mousestatus_t * ms)2878 r_gestures(struct tpad *tp, int x0, int y0, u_int z, int w, int nfingers,
2879     struct timespec *time, mousestatus_t *ms)
2880 {
2881 	struct tpstate *gest = &tp->gest;
2882 	const struct tpcaps *tphw = &tp->hw;
2883 	const struct tpinfo *tpinfo = &tp->info;
2884 	int tap_timeout = tpinfo->tap_timeout;
2885 
2886 	/*
2887 	 * Check pressure to detect a real wanted action on the
2888 	 * touchpad.
2889 	 */
2890 	if (z >= tpinfo->min_pressure_hi ||
2891 	    (gest->fingerdown && z >= tpinfo->min_pressure_lo)) {
2892 		/* XXX Verify values? */
2893 		bool two_finger_scroll = tpinfo->two_finger_scroll;
2894 		bool three_finger_drag = tpinfo->three_finger_drag;
2895 		int max_width = tpinfo->max_width;
2896 		u_int max_pressure = tpinfo->max_pressure;
2897 		int margin_top = tpinfo->margin_top;
2898 		int margin_right = tpinfo->margin_right;
2899 		int margin_bottom = tpinfo->margin_bottom;
2900 		int margin_left = tpinfo->margin_left;
2901 		int vscroll_hor_area = tpinfo->vscroll_hor_area * tphw->res_x;
2902 		int vscroll_ver_area = tpinfo->vscroll_ver_area * tphw->res_y;;
2903 
2904 		int max_x = tphw->max_x;
2905 		int max_y = tphw->max_y;
2906 		int min_x = tphw->min_x;
2907 		int min_y = tphw->min_y;
2908 
2909 		int dx, dy;
2910 		int start_x, start_y;
2911 		int tap_max_delta_x, tap_max_delta_y;
2912 		int prev_nfingers;
2913 
2914 		/* Palm detection. */
2915 		if (nfingers == 1 &&
2916 		    ((tphw->cap_width && w > max_width) ||
2917 		     (tphw->cap_pressure && z > max_pressure))) {
2918 			/*
2919 			 * We consider the packet irrelevant for the current
2920 			 * action when:
2921 			 *  - there is a single active touch
2922 			 *  - the width isn't comprised in:
2923 			 *    [0; max_width]
2924 			 *  - the pressure isn't comprised in:
2925 			 *    [min_pressure; max_pressure]
2926 			 *
2927 			 *  Note that this doesn't terminate the current action.
2928 			 */
2929 			debug("palm detected! (%d)", z);
2930 			return(GEST_IGNORE);
2931 		}
2932 
2933 		/*
2934 		 * Limit the coordinates to the specified margins because
2935 		 * this area isn't very reliable.
2936 		 */
2937 		if (margin_left != 0 && x0 <= min_x + margin_left)
2938 			x0 = min_x + margin_left;
2939 		else if (margin_right != 0 && x0 >= max_x - margin_right)
2940 			x0 = max_x - margin_right;
2941 		if (margin_bottom != 0 && y0 <= min_y + margin_bottom)
2942 			y0 = min_y + margin_bottom;
2943 		else if (margin_top != 0 && y0 >= max_y - margin_top)
2944 			y0 = max_y - margin_top;
2945 
2946 		debug("packet: [%d, %d], %d, %d", x0, y0, z, w);
2947 
2948 		/*
2949 		 * If the action is just beginning, init the structure and
2950 		 * compute tap timeout.
2951 		 */
2952 		if (!gest->fingerdown) {
2953 			debug("----");
2954 
2955 			/* Reset pressure peak. */
2956 			gest->zmax = 0;
2957 
2958 			/* Reset fingers count. */
2959 			gest->fingers_nb = 0;
2960 
2961 			/* Reset virtual scrolling state. */
2962 			gest->in_vscroll = 0;
2963 
2964 			/* Compute tap timeout. */
2965 			if (tap_timeout != 0)
2966 				gest->taptimeout = tsaddms(time, tap_timeout);
2967 			else
2968 				tsclr(&gest->taptimeout);
2969 
2970 			gest->fingerdown = true;
2971 
2972 			gest->start_x = x0;
2973 			gest->start_y = y0;
2974 		}
2975 
2976 		prev_nfingers = gest->prev_nfingers;
2977 
2978 		gest->prev_x = x0;
2979 		gest->prev_y = y0;
2980 		gest->prev_nfingers = nfingers;
2981 
2982 		start_x = gest->start_x;
2983 		start_y = gest->start_y;
2984 
2985 		/* Process ClickPad softbuttons */
2986 		if (tphw->is_clickpad && ms->button & MOUSE_BUTTON1DOWN) {
2987 			int y_ok, center_bt, center_x, right_bt, right_x;
2988 			y_ok = tpinfo->softbuttons_y < 0
2989 			    ? start_y < min_y - tpinfo->softbuttons_y
2990 			    : start_y > max_y - tpinfo->softbuttons_y;
2991 
2992 			center_bt = MOUSE_BUTTON2DOWN;
2993 			center_x = min_x + tpinfo->softbutton2_x;
2994 			right_bt = MOUSE_BUTTON3DOWN;
2995 			right_x = min_x + tpinfo->softbutton3_x;
2996 
2997 			if (center_x > 0 && right_x > 0 && center_x > right_x) {
2998 				center_bt = MOUSE_BUTTON3DOWN;
2999 				center_x = min_x + tpinfo->softbutton3_x;
3000 				right_bt = MOUSE_BUTTON2DOWN;
3001 				right_x = min_x + tpinfo->softbutton2_x;
3002 			}
3003 
3004 			if (right_x > 0 && start_x > right_x && y_ok)
3005 				ms->button = (ms->button &
3006 				    ~MOUSE_BUTTON1DOWN) | right_bt;
3007 			else if (center_x > 0 && start_x > center_x && y_ok)
3008 				ms->button = (ms->button &
3009 				    ~MOUSE_BUTTON1DOWN) | center_bt;
3010 		}
3011 
3012 		/* If in tap-hold or three fingers, add the recorded button. */
3013 		if (gest->in_taphold || (nfingers == 3 && three_finger_drag))
3014 			ms->button |= gest->tap_button;
3015 
3016 		/*
3017 		 * For tap, we keep the maximum number of fingers and the
3018 		 * pressure peak.
3019 		 */
3020 		gest->fingers_nb = MAX(nfingers, gest->fingers_nb);
3021 		gest->zmax = MAX(z, gest->zmax);
3022 
3023 		dx = abs(x0 - start_x);
3024 		dy = abs(y0 - start_y);
3025 
3026 		/*
3027 		 * A scrolling action must not conflict with a tap action.
3028 		 * Here are the conditions to consider a scrolling action:
3029 		 *  - the action in a configurable area
3030 		 *  - one of the following:
3031 		 *     . the distance between the last packet and the
3032 		 *       first should be above a configurable minimum
3033 		 *     . tap timed out
3034 		 */
3035 		if (!gest->in_taphold && !ms->button &&
3036 		    (!gest->in_vscroll || two_finger_scroll) &&
3037 		    (tscmp(time, &gest->taptimeout, >) ||
3038 		    ((gest->fingers_nb == 2 || !two_finger_scroll) &&
3039 		    (dx >= tpinfo->vscroll_min_delta * tphw->res_x ||
3040 		     dy >= tpinfo->vscroll_min_delta * tphw->res_y)))) {
3041 			/*
3042 			 * Handle two finger scrolling.
3043 			 * Note that we don't rely on fingers_nb
3044 			 * as that keeps the maximum number of fingers.
3045 			 */
3046 			if (two_finger_scroll) {
3047 				if (nfingers == 2) {
3048 					gest->in_vscroll += dy ? 2 : 0;
3049 					gest->in_vscroll += dx ? 1 : 0;
3050 				}
3051 			} else {
3052 				/* Check for horizontal scrolling. */
3053 				if ((vscroll_hor_area > 0 &&
3054 				     start_y <= min_y + vscroll_hor_area) ||
3055 				    (vscroll_hor_area < 0 &&
3056 				     start_y >= max_y + vscroll_hor_area))
3057 					gest->in_vscroll += 2;
3058 
3059 				/* Check for vertical scrolling. */
3060 				if ((vscroll_ver_area > 0 &&
3061 				     start_x <= min_x + vscroll_ver_area) ||
3062 				    (vscroll_ver_area < 0 &&
3063 				     start_x >= max_x + vscroll_ver_area))
3064 					gest->in_vscroll += 1;
3065 			}
3066 			/* Avoid conflicts if area overlaps. */
3067 			if (gest->in_vscroll >= 3)
3068 				gest->in_vscroll = (dx > dy) ? 2 : 1;
3069 		}
3070 		/*
3071 		 * Reset two finger scrolling when the number of fingers
3072 		 * is different from two or any button is pressed.
3073 		 */
3074 		if (two_finger_scroll && gest->in_vscroll != 0 &&
3075 		    (nfingers != 2 || ms->button))
3076 			gest->in_vscroll = 0;
3077 
3078 		debug("virtual scrolling: %s "
3079 			"(direction=%d, dx=%d, dy=%d, fingers=%d)",
3080 			gest->in_vscroll != 0 ? "YES" : "NO",
3081 			gest->in_vscroll, dx, dy, gest->fingers_nb);
3082 
3083 		/* Workaround cursor jump on finger set changes */
3084 		if (prev_nfingers != nfingers)
3085 			return (GEST_IGNORE);
3086 
3087 		switch (gest->in_vscroll) {
3088 		case 1:
3089 			return (GEST_VSCROLL);
3090 		case 2:
3091 			return (GEST_HSCROLL);
3092 		default:
3093 			/* NO-OP */;
3094 		}
3095 
3096 		/* Max delta is disabled for multi-fingers tap. */
3097 		if (gest->fingers_nb == 1 &&
3098 		    tscmp(time, &gest->taptimeout, <=)) {
3099 			tap_max_delta_x = tpinfo->tap_max_delta * tphw->res_x;
3100 			tap_max_delta_y = tpinfo->tap_max_delta * tphw->res_y;
3101 
3102 			debug("dx=%d, dy=%d, deltax=%d, deltay=%d",
3103 			    dx, dy, tap_max_delta_x, tap_max_delta_y);
3104 			if (dx > tap_max_delta_x || dy > tap_max_delta_y) {
3105 				debug("not a tap");
3106 				tsclr(&gest->taptimeout);
3107 			}
3108 		}
3109 
3110 		if (tscmp(time, &gest->taptimeout, <=))
3111 			return (gest->fingers_nb > 1 ?
3112 			    GEST_IGNORE : GEST_ACCUMULATE);
3113 		else
3114 			return (GEST_MOVE);
3115 	}
3116 
3117 	/*
3118 	 * Handle a case when clickpad pressure drops before than
3119 	 * button up event when surface is released after click.
3120 	 * It interferes with softbuttons.
3121 	 */
3122 	if (tphw->is_clickpad && tpinfo->softbuttons_y != 0)
3123 		ms->button &= ~MOUSE_BUTTON1DOWN;
3124 
3125 	gest->prev_nfingers = 0;
3126 
3127 	if (gest->fingerdown) {
3128 		/*
3129 		 * An action is currently taking place but the pressure
3130 		 * dropped under the minimum, putting an end to it.
3131 		 */
3132 
3133 		gest->fingerdown = false;
3134 
3135 		/* Check for tap. */
3136 		debug("zmax=%d fingers=%d", gest->zmax, gest->fingers_nb);
3137 		if (!gest->in_vscroll && gest->zmax >= tpinfo->tap_threshold &&
3138 		    tscmp(time, &gest->taptimeout, <=)) {
3139 			/*
3140 			 * We have a tap if:
3141 			 *   - the maximum pressure went over tap_threshold
3142 			 *   - the action ended before tap_timeout
3143 			 *
3144 			 * To handle tap-hold, we must delay any button push to
3145 			 * the next action.
3146 			 */
3147 			if (gest->in_taphold) {
3148 				/*
3149 				 * This is the second and last tap of a
3150 				 * double tap action, not a tap-hold.
3151 				 */
3152 				gest->in_taphold = false;
3153 
3154 				/*
3155 				 * For double-tap to work:
3156 				 *   - no button press is emitted (to
3157 				 *     simulate a button release)
3158 				 *   - PSM_FLAGS_FINGERDOWN is set to
3159 				 *     force the next packet to emit a
3160 				 *     button press)
3161 				 */
3162 				debug("button RELEASE: %d", gest->tap_button);
3163 				gest->fingerdown = true;
3164 
3165 				/* Schedule button press on next event */
3166 				gest->idletimeout = 0;
3167 			} else {
3168 				/*
3169 				 * This is the first tap: we set the
3170 				 * tap-hold state and notify the button
3171 				 * down event.
3172 				 */
3173 				gest->in_taphold = true;
3174 				gest->idletimeout = tpinfo->taphold_timeout;
3175 				gest->taptimeout = tsaddms(time, tap_timeout);
3176 
3177 				switch (gest->fingers_nb) {
3178 				case 3:
3179 					gest->tap_button =
3180 					    MOUSE_BUTTON2DOWN;
3181 					break;
3182 				case 2:
3183 					gest->tap_button =
3184 					    MOUSE_BUTTON3DOWN;
3185 					break;
3186 				default:
3187 					gest->tap_button =
3188 					    MOUSE_BUTTON1DOWN;
3189 				}
3190 				debug("button PRESS: %d", gest->tap_button);
3191 				ms->button |= gest->tap_button;
3192 			}
3193 		} else {
3194 			/*
3195 			 * Not enough pressure or timeout: reset
3196 			 * tap-hold state.
3197 			 */
3198 			if (gest->in_taphold) {
3199 				debug("button RELEASE: %d", gest->tap_button);
3200 				gest->in_taphold = false;
3201 			} else {
3202 				debug("not a tap-hold");
3203 			}
3204 		}
3205 	} else if (!gest->fingerdown && gest->in_taphold) {
3206 		/*
3207 		 * For a tap-hold to work, the button must remain down at
3208 		 * least until timeout (where the in_taphold flags will be
3209 		 * cleared) or during the next action.
3210 		 */
3211 		if (tscmp(time, &gest->taptimeout, <=)) {
3212 			ms->button |= gest->tap_button;
3213 		} else {
3214 			debug("button RELEASE: %d", gest->tap_button);
3215 			gest->in_taphold = false;
3216 		}
3217 	}
3218 
3219 	return (GEST_IGNORE);
3220 }
3221