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