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