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