#include <u.h>
#include <libc.h>
#include <draw.h>
#include <event.h>
/*
* Convert AccuPoint buttons 4 and 5 to a simulation of button 2.
* The buttons generate down events, repeat, and have no up events,
* so it's a struggle. This program turns the left button into a near-as-
* possible simulation of a regular button 2, but it can only sense up
* events by timeout, so it's sluggish. Thus it also turns the right button
* into a click on button 2, useful for acme and chords.
*/
typedef struct M M;
struct M
{
Mouse;
int byte;
};
int button2;
int interrupted;
int
readmouse(M *m)
{
char buf[1+4*12];
int n;
n = read(0, buf, sizeof buf);
if(n < 0)
return n;
if(n != sizeof buf)
return 0;
m->byte = buf[0];
m->xy.x = atoi(buf+1+0*12);
m->xy.y = atoi(buf+1+1*12);
m->buttons = atoi(buf+1+2*12);
m->msec = atoi(buf+1+3*12);
return 1;
}
void
writemouse(M *m)
{
print("%c%11d %11d %11d %11ld ",
m->byte,
m->xy.x,
m->xy.y,
m->buttons&7,
m->msec);
}
void
notifyf(void*, char *s)
{
if(strcmp(s, "alarm") == 0)
interrupted = 1;
noted(NCONT);
}
void
main(void)
{
M m, om;
int n;
notify(notifyf);
memset(&m, 0, sizeof m);
om = m;
for(;;){
interrupted = 0;
/* first click waits 500ms before repeating; after that they're 150, but that's ok */
if(button2)
alarm(550);
n = readmouse(&m);
if(button2)
alarm(0);
if(interrupted){
/* timed out; clear button 2 */
om.buttons &= ~2;
button2 = 0;
writemouse(&om);
continue;
}
if(n <= 0)
break;
/* avoid bounce caused by button 5 click */
if((om.buttons&16) && (m.buttons&16)){
om.buttons &= ~16;
continue;
}
if(m.buttons & 2)
button2 = 0;
else{
/* only check 4 and 5 if 2 isn't down of its own accord */
if(m.buttons & 16){
/* generate quick button 2 click */
button2 = 0;
m.buttons |= 2;
writemouse(&m);
m.buttons &= ~2;
/* fall through to generate up event */
}else if(m.buttons & 8){
/* press and hold button 2 */
button2 = 1;
}
}
if(button2)
m.buttons |= 2;
if(m.byte!=om.byte || m.buttons!=om.buttons || !eqpt(m.xy, om.xy))
writemouse(&m);
om = m;
}
}
|