118 lines
2.1 KiB
C
118 lines
2.1 KiB
C
|
#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;
|
||
|
}
|
||
|
}
|