xref: /plan9/sys/src/cmd/aux/accupoint.c (revision 59cc4ca53493a3c6d2349fe2b7f7c40f7dce7294)
1*59cc4ca5SDavid du Colombier #include <u.h>
2*59cc4ca5SDavid du Colombier #include <libc.h>
3*59cc4ca5SDavid du Colombier #include <draw.h>
4*59cc4ca5SDavid du Colombier #include <event.h>
5*59cc4ca5SDavid du Colombier 
6*59cc4ca5SDavid du Colombier /*
7*59cc4ca5SDavid du Colombier  * Convert AccuPoint buttons 4 and 5 to a simulation of button 2.
8*59cc4ca5SDavid du Colombier  * The buttons generate down events, repeat, and have no up events,
9*59cc4ca5SDavid du Colombier  * so it's a struggle. This program turns the left button into a near-as-
10*59cc4ca5SDavid du Colombier  * possible simulation of a regular button 2, but it can only sense up
11*59cc4ca5SDavid du Colombier  * events by timeout, so it's sluggish.  Thus it also turns the right button
12*59cc4ca5SDavid du Colombier  * into a click on button 2, useful for acme and chords.
13*59cc4ca5SDavid du Colombier  */
14*59cc4ca5SDavid du Colombier 
15*59cc4ca5SDavid du Colombier typedef struct M M;
16*59cc4ca5SDavid du Colombier 
17*59cc4ca5SDavid du Colombier struct M
18*59cc4ca5SDavid du Colombier {
19*59cc4ca5SDavid du Colombier 	Mouse;
20*59cc4ca5SDavid du Colombier 	int	byte;
21*59cc4ca5SDavid du Colombier };
22*59cc4ca5SDavid du Colombier 
23*59cc4ca5SDavid du Colombier int	button2;
24*59cc4ca5SDavid du Colombier int	interrupted;
25*59cc4ca5SDavid du Colombier 
26*59cc4ca5SDavid du Colombier int
27*59cc4ca5SDavid du Colombier readmouse(M *m)
28*59cc4ca5SDavid du Colombier {
29*59cc4ca5SDavid du Colombier 	char buf[1+4*12];
30*59cc4ca5SDavid du Colombier 	int n;
31*59cc4ca5SDavid du Colombier 
32*59cc4ca5SDavid du Colombier 	n = read(0, buf, sizeof buf);
33*59cc4ca5SDavid du Colombier 	if(n < 0)
34*59cc4ca5SDavid du Colombier 		return n;
35*59cc4ca5SDavid du Colombier 	if(n != sizeof buf)
36*59cc4ca5SDavid du Colombier 		return 0;
37*59cc4ca5SDavid du Colombier 	m->byte = buf[0];
38*59cc4ca5SDavid du Colombier 	m->xy.x =  atoi(buf+1+0*12);
39*59cc4ca5SDavid du Colombier 	m->xy.y =  atoi(buf+1+1*12);
40*59cc4ca5SDavid du Colombier 	m->buttons =  atoi(buf+1+2*12);
41*59cc4ca5SDavid du Colombier 	m->msec =  atoi(buf+1+3*12);
42*59cc4ca5SDavid du Colombier 	return 1;
43*59cc4ca5SDavid du Colombier }
44*59cc4ca5SDavid du Colombier 
45*59cc4ca5SDavid du Colombier void
46*59cc4ca5SDavid du Colombier writemouse(M *m)
47*59cc4ca5SDavid du Colombier {
48*59cc4ca5SDavid du Colombier 	print("%c%11d %11d %11d %11ld ",
49*59cc4ca5SDavid du Colombier 		m->byte,
50*59cc4ca5SDavid du Colombier 		m->xy.x,
51*59cc4ca5SDavid du Colombier 		m->xy.y,
52*59cc4ca5SDavid du Colombier 		m->buttons,
53*59cc4ca5SDavid du Colombier 		m->msec);
54*59cc4ca5SDavid du Colombier }
55*59cc4ca5SDavid du Colombier 
56*59cc4ca5SDavid du Colombier void
57*59cc4ca5SDavid du Colombier notifyf(void*, char *s)
58*59cc4ca5SDavid du Colombier {
59*59cc4ca5SDavid du Colombier 	if(strcmp(s, "alarm") == 0)
60*59cc4ca5SDavid du Colombier 		interrupted = 1;
61*59cc4ca5SDavid du Colombier 	noted(NCONT);
62*59cc4ca5SDavid du Colombier }
63*59cc4ca5SDavid du Colombier 
64*59cc4ca5SDavid du Colombier void
65*59cc4ca5SDavid du Colombier main(void)
66*59cc4ca5SDavid du Colombier {
67*59cc4ca5SDavid du Colombier 	M m, om;
68*59cc4ca5SDavid du Colombier 	int n;
69*59cc4ca5SDavid du Colombier 
70*59cc4ca5SDavid du Colombier 	notify(notifyf);
71*59cc4ca5SDavid du Colombier 	memset(&m, 0, sizeof m);
72*59cc4ca5SDavid du Colombier 	om = m;
73*59cc4ca5SDavid du Colombier 	for(;;){
74*59cc4ca5SDavid du Colombier 		interrupted = 0;
75*59cc4ca5SDavid du Colombier 		/* first click waits 500ms before repeating; after that they're 150, but that's ok */
76*59cc4ca5SDavid du Colombier 		if(button2)
77*59cc4ca5SDavid du Colombier 			alarm(550);
78*59cc4ca5SDavid du Colombier 		n = readmouse(&m);
79*59cc4ca5SDavid du Colombier 		if(button2)
80*59cc4ca5SDavid du Colombier 			alarm(0);
81*59cc4ca5SDavid du Colombier 		if(interrupted){
82*59cc4ca5SDavid du Colombier 			/* timed out; clear button 2 */
83*59cc4ca5SDavid du Colombier 			om.buttons &= ~2;
84*59cc4ca5SDavid du Colombier 			button2 = 0;
85*59cc4ca5SDavid du Colombier 			writemouse(&om);
86*59cc4ca5SDavid du Colombier 			continue;
87*59cc4ca5SDavid du Colombier 		}
88*59cc4ca5SDavid du Colombier 		if(n <= 0)
89*59cc4ca5SDavid du Colombier 			break;
90*59cc4ca5SDavid du Colombier 		/* avoid bounce caused by button 5 click */
91*59cc4ca5SDavid du Colombier 		if((om.buttons&16) && (m.buttons&16)){
92*59cc4ca5SDavid du Colombier 			om.buttons &= ~16;
93*59cc4ca5SDavid du Colombier 			continue;
94*59cc4ca5SDavid du Colombier 		}
95*59cc4ca5SDavid du Colombier 		if(m.buttons & 2)
96*59cc4ca5SDavid du Colombier 			button2 = 0;
97*59cc4ca5SDavid du Colombier 		else{
98*59cc4ca5SDavid du Colombier 			/* only check 4 and 5 if 2 isn't down of its own accord */
99*59cc4ca5SDavid du Colombier 			if(m.buttons & 16){
100*59cc4ca5SDavid du Colombier 				/* generate quick button 2 click */
101*59cc4ca5SDavid du Colombier 				button2 = 0;
102*59cc4ca5SDavid du Colombier 				m.buttons |= 2;
103*59cc4ca5SDavid du Colombier 				writemouse(&m);
104*59cc4ca5SDavid du Colombier 				m.buttons &= ~2;
105*59cc4ca5SDavid du Colombier 				/* fall through to generate up event */
106*59cc4ca5SDavid du Colombier 			}else if(m.buttons & 8){
107*59cc4ca5SDavid du Colombier 				/* press and hold button 2 */
108*59cc4ca5SDavid du Colombier 				button2 = 1;
109*59cc4ca5SDavid du Colombier 			}
110*59cc4ca5SDavid du Colombier 		}
111*59cc4ca5SDavid du Colombier 		if(button2)
112*59cc4ca5SDavid du Colombier 			m.buttons |= 2;
113*59cc4ca5SDavid du Colombier 		writemouse(&m);
114*59cc4ca5SDavid du Colombier 		om = m;
115*59cc4ca5SDavid du Colombier 	}
116*59cc4ca5SDavid du Colombier }
117