## diffname bitsy/devpenmouse.c 2000/1021
## diff -e /dev/null /n/emeliedump/2000/1021/sys/src/9/bitsy/devpenmouse.c
0a
#include "u.h"
#include "../port/lib.h"
#include "mem.h"
#include "dat.h"
#include "fns.h"
#include "../port/error.h"
#define Image IMAGE
#include <draw.h>
#include <memdraw.h>
#include <cursor.h>
#include "screen.h"
typedef struct Mouseinfo Mouseinfo;
typedef struct Mousestate Mousestate;
typedef struct Calibration Calibration;
struct Calibration
{
long scalex;
long scaley;
long transx;
long transy;
} calibration = {
-0x10000*0x400/320,
-0x10000*0x400/240,
320,
240
};
struct Mousestate
{
Point xy; /* mouse.xy */
int buttons; /* mouse.buttons */
ulong counter; /* increments every update */
ulong msec; /* time of last event */
};
struct Mouseinfo
{
Mousestate;
ulong lastcounter; /* value when /dev/mouse read */
Rendez r;
Ref;
QLock;
int open;
int inopen;
Mousestate queue[16]; /* circular buffer of click events */
int ri; /* read index into queue */
int wi; /* write index into queue */
uchar qfull; /* queue is full */
};
Mouseinfo mouse;
int mouseshifted;
int penmousechanged(void*);
static void penmousetrack(int b, int x, int y);
enum{
Qdir,
Qmouse,
Qmousein,
Qmousectl,
};
static Dirtab mousedir[]={
"mouse", {Qmouse}, 0, 0666,
"mousein", {Qmousein}, 0, 0220,
"mousectl", {Qmousectl}, 0, 0220,
};
static uchar buttonmap[8] = {
0, 1, 2, 3, 4, 5, 6, 7,
};
static int mouseswap;
extern Memimage* gscreen;
void
penbutton(int up, int b) {
if (up)
mouse.buttons &= ~ (1 << b);
else
mouse.buttons |= 1 << b;
penmousetrack(mouse.buttons, -1, -1);
}
void
pentrackxy(int x, int y) {
if (x == -1) {
/* pen up. associate with button 1, 2, 3 up */
if (mouse.buttons & 0x7)
mouse.buttons &= ~0x7;
} else {
x = (x<<16)/calibration.scalex + calibration.transx;
y = (y<<16)/calibration.scaley + calibration.transy;
}
penmousetrack(mouse.buttons, x, y);
}
static void
penmousereset(void)
{
if(!conf.monitor)
return;
}
static void
penmouseinit(void)
{
if(!conf.monitor)
return;
}
static Chan*
penmouseattach(char *spec)
{
if(!conf.monitor)
error(Egreg);
return devattach('m', spec);
}
static Chan*
penmouseclone(Chan *c, Chan *nc)
{
nc = devclone(c, nc);
if(c->qid.path != CHDIR)
incref(&mouse);
return nc;
}
static int
penmousewalk(Chan *c, char *name)
{
return devwalk(c, name, mousedir, nelem(mousedir), devgen);
}
static void
penmousestat(Chan *c, char *db)
{
devstat(c, db, mousedir, nelem(mousedir), devgen);
}
static Chan*
penmouseopen(Chan *c, int omode)
{
switch(c->qid.path){
case CHDIR:
if(omode != OREAD)
error(Eperm);
break;
case Qmouse:
lock(&mouse);
if(mouse.open){
unlock(&mouse);
error(Einuse);
}
mouse.open = 1;
mouse.ref++;
unlock(&mouse);
break;
case Qmousein:
/* error("disabled"); */
lock(&mouse);
if(mouse.inopen){
unlock(&mouse);
error(Einuse);
}
mouse.inopen = 1;
unlock(&mouse);
break;
default:
incref(&mouse);
}
c->mode = openmode(omode);
c->flag |= COPEN;
c->offset = 0;
return c;
}
static void
penmousecreate(Chan*, char*, int, ulong)
{
if(!conf.monitor)
error(Egreg);
error(Eperm);
}
static void
penmouseclose(Chan *c)
{
if(c->qid.path!=CHDIR && (c->flag&COPEN)){
lock(&mouse);
if(c->qid.path == Qmouse)
mouse.open = 0;
else if(c->qid.path == Qmousein){
mouse.inopen = 0;
unlock(&mouse);
return;
}
--mouse.ref;
unlock(&mouse);
}
}
static long
penmouseread(Chan *c, void *va, long n, vlong)
{
char buf[4*12+1];
static int map[8] = {0, 4, 2, 6, 1, 5, 3, 7 };
Mousestate m;
int b;
switch(c->qid.path){
case CHDIR:
return devdirread(c, va, n, mousedir, nelem(mousedir), devgen);
case Qmouse:
while(penmousechanged(0) == 0)
sleep(&mouse.r, penmousechanged, 0);
mouse.qfull = 0;
/*
* No lock of the indicies is necessary here, because ri is only
* updated by us, and there is only one mouse reader
* at a time. I suppose that more than one process
* could try to read the fd at one time, but such behavior
* is degenerate and already violates the calling
* conventions for sleep above.
*/
if(mouse.ri != mouse.wi) {
m = mouse.queue[mouse.ri];
if(++mouse.ri == nelem(mouse.queue))
mouse.ri = 0;
} else {
m = mouse.Mousestate;
}
b = buttonmap[m.buttons&7];
/* put buttons 4 and 5 back in */
b |= m.buttons & (3<<3);
sprint(buf, "m%11d %11d %11d %11lud",
m.xy.x, m.xy.y,
b,
m.msec);
mouse.lastcounter = m.counter;
if(n > 1+4*12)
n = 1+4*12;
memmove(va, buf, n);
return n;
}
return 0;
}
static void
setbuttonmap(char* map)
{
int i, x, one, two, three;
one = two = three = 0;
for(i = 0; i < 3; i++){
if(map[i] == 0)
error(Ebadarg);
if(map[i] == '1'){
if(one)
error(Ebadarg);
one = 1<<i;
}
else if(map[i] == '2'){
if(two)
error(Ebadarg);
two = 1<<i;
}
else if(map[i] == '3'){
if(three)
error(Ebadarg);
three = 1<<i;
}
else
error(Ebadarg);
}
if(map[i])
error(Ebadarg);
memset(buttonmap, 0, 8);
for(i = 0; i < 8; i++){
x = 0;
if(i & 1)
x |= one;
if(i & 2)
x |= two;
if(i & 4)
x |= three;
buttonmap[x] = i;
}
}
static long
penmousewrite(Chan *c, void *va, long n, vlong)
{
char *p;
Point pt;
char buf[64], *field[3];
int nf, b;
p = va;
switch(c->qid.path){
case CHDIR:
error(Eisdir);
case Qmousectl:
if(n >= sizeof(buf))
n = sizeof(buf)-1;
strncpy(buf, va, n);
if(buf[n - 1] == '\n')
buf[n-1] = 0;
else
buf[n] = 0;
nf = getfields(buf, field, 3, 1, " ");
if(strcmp(field[0], "swap") == 0){
if(mouseswap)
setbuttonmap("123");
else
setbuttonmap("321");
mouseswap ^= 1;
}
else if(strcmp(field[0], "calibrate") == 0){
if (nf == 1) {
calibration.scalex = 1;
calibration.scaley = 1;
calibration.transx = 0;
calibration.transy = 0;
} else if (nf == 5) {
calibration.scalex = strtol(field[1], nil, 0);
calibration.scaley = strtol(field[2], nil, 0);
calibration.transx = strtol(field[3], nil, 0);
calibration.transy = strtol(field[4], nil, 0);
}
}
return n;
case Qmousein:
if(n > sizeof buf-1)
n = sizeof buf -1;
memmove(buf, va, n);
buf[n] = 0;
p = 0;
pt.x = strtol(buf+1, &p, 0);
if(p == 0)
error(Eshort);
pt.y = strtol(p, &p, 0);
if(p == 0)
error(Eshort);
b = strtol(p, &p, 0);
penmousetrack(b, pt.x, pt.y);
return n;
case Qmouse:
if(n > sizeof buf-1)
n = sizeof buf -1;
memmove(buf, va, n);
buf[n] = 0;
p = 0;
pt.x = strtoul(buf+1, &p, 0);
if(p == 0)
error(Eshort);
pt.y = strtoul(p, 0, 0);
qlock(&mouse);
if(ptinrect(pt, gscreen->r))
penmousetrack(mouse.buttons, pt.x, pt.y);
qunlock(&mouse);
return n;
}
error(Egreg);
return -1;
}
Dev penmousedevtab = {
'm',
"penmouse",
penmousereset,
penmouseinit,
penmouseattach,
penmouseclone,
penmousewalk,
penmousestat,
penmouseopen,
penmousecreate,
penmouseclose,
penmouseread,
devbread,
penmousewrite,
devbwrite,
devremove,
devwstat,
};
/*
* called at interrupt level to update the structure and
* awaken any waiting procs.
*/
static void
penmousetrack(int b, int x, int y)
{
int lastb;
if(gscreen==nil)
return;
if (x >= 0) {
mouse.xy = Pt(x, y);
}
lastb = mouse.buttons;
mouse.buttons = b;
mouse.counter++;
mouse.msec = TK2MS(MACHP(0)->ticks);
/*
* if the queue fills, we discard the entire queue and don't
* queue any more events until a reader polls the mouse.
*/
if(!mouse.qfull && lastb != b) { /* add to ring */
mouse.queue[mouse.wi] = mouse.Mousestate;
if(++mouse.wi == nelem(mouse.queue))
mouse.wi = 0;
if(mouse.wi == mouse.ri)
mouse.qfull = 1;
}
wakeup(&mouse.r);
}
int
penmousechanged(void*)
{
return mouse.lastcounter != mouse.counter;
}
Point
penmousexy(void)
{
return mouse.xy;
}
.
## diffname bitsy/devpenmouse.c 2000/1024
## diff -e /n/emeliedump/2000/1021/sys/src/9/bitsy/devpenmouse.c /n/emeliedump/2000/1024/sys/src/9/bitsy/devpenmouse.c
341c
} else
print("calibrate %d fields\n", nf);
.
322c
nf = getfields(buf, field, 5, 1, " ");
.
306c
char buf[64], *field[5];
.
247c
m.buttons,
.
242,244d
214d
207d
97a
if ((mouse.buttons & 0x7) == 0)
mouse.buttons |= 0x1;
.
93,94c
mouse.buttons &= ~0x7;
.
## diffname bitsy/devpenmouse.c 2000/1025
## diff -e /n/emeliedump/2000/1024/sys/src/9/bitsy/devpenmouse.c /n/emeliedump/2000/1025/sys/src/9/bitsy/devpenmouse.c
414d
409,412c
if (x >= 0)
.
85c
mouse.buttons |= b;
.
83c
mouse.buttons &= ~b;
.
## diffname bitsy/devpenmouse.c 2000/1101
## diff -e /n/emeliedump/2000/1025/sys/src/9/bitsy/devpenmouse.c /n/emeliedump/2000/1101/sys/src/9/bitsy/devpenmouse.c
328,329c
calibration.scalex = 1<<16;
calibration.scaley = 1<<16;
.
95,96c
x = ((x*calibration.scalex)>>16) + calibration.transx;
y = ((y*calibration.scaley)>>16) + calibration.transy;
.
## diffname bitsy/devpenmouse.c 2000/1102
## diff -e /n/emeliedump/2000/1101/sys/src/9/bitsy/devpenmouse.c /n/emeliedump/2000/1102/sys/src/9/bitsy/devpenmouse.c
25,28c
-23540,
-16858,
342,
252
.
## diffname bitsy/devpenmouse.c 2000/1104
## diff -e /n/emeliedump/2000/1102/sys/src/9/bitsy/devpenmouse.c /n/emeliedump/2000/1104/sys/src/9/bitsy/devpenmouse.c
27,28c
23540,
252,
342
.
25d
## diffname bitsy/devpenmouse.c 2000/1120
## diff -e /n/emeliedump/2000/1104/sys/src/9/bitsy/devpenmouse.c /n/emeliedump/2000/1120/sys/src/9/bitsy/devpenmouse.c
25,28c
-16435,
23275,
253,
-23
.
## diffname bitsy/devpenmouse.c 2000/1130
## diff -e /n/emeliedump/2000/1120/sys/src/9/bitsy/devpenmouse.c /n/emeliedump/2000/1130/sys/src/9/bitsy/devpenmouse.c
427a
drawactive(1);
.
## diffname bitsy/devpenmouse.c 2000/1206
## diff -e /n/emeliedump/2000/1130/sys/src/9/bitsy/devpenmouse.c /n/emeliedump/2000/1206/sys/src/9/bitsy/devpenmouse.c
226c
* No lock of the indices is necessary here, because ri is only
.
## diffname bitsy/devpenmouse.c 2000/1207
## diff -e /n/emeliedump/2000/1206/sys/src/9/bitsy/devpenmouse.c /n/emeliedump/2000/1207/sys/src/9/bitsy/devpenmouse.c
97,98c
if ((mouse.buttons & 0x1f) == 0) {
if (mouse.modifiers)
mouse.buttons |= mouse.modifiers;
else
mouse.buttons |= 0x1;
}
.
92,93c
/* pen up. associate with button 1 through 5 up */
mouse.buttons &= ~0x1f;
.
82,86c
if (b & 0x20) {
if (up)
mouse.buttons &= ~b;
else
mouse.buttons |= b;
penmousetrack(mouse.buttons, -1, -1);
} else {
if (up)
mouse.modifiers &= ~b;
else
mouse.modifiers |= b;
}
.
34a
int modifiers; /* state of physical buttons 2, 3, 4, 5 */
.
30a
/* The pen goes down, tracks some and goes up again. The pen alone can
* only simulate a one-button mouse.
* To simulate a more-button (five, in this case) mouse, we use the four
* keys along the the bottom of the iPaq as modifiers.
* When one (or more) of the modifier keys is (are) down, a pen-down event
* causes the corresponding bottons to go down. If no modifier key is
* depressed, a pen-down event is translated into a button-one down event.
* Releasing the modifier keys has no direct effect. The pen-up event is
* the one that triggers mouse-up events.
*/
.
## diffname bitsy/devpenmouse.c 2000/1214
## diff -e /n/emeliedump/2000/1207/sys/src/9/bitsy/devpenmouse.c /n/emeliedump/2000/1214/sys/src/9/bitsy/devpenmouse.c
239a
case Qmousectl:
sprint(buf, "c%11ld %11ld %11ld %11ld",
calibration.scalex, calibration.scaley,
calibration.transx, calibration.transy);
if(n > 1+4*12)
n = 1+4*12;
memmove(va, buf, n);
return n;
.
81c
"mousectl", {Qmousectl}, 0, 0660,
.
## diffname bitsy/devpenmouse.c 2000/1215
## diff -e /n/emeliedump/2000/1214/sys/src/9/bitsy/devpenmouse.c /n/emeliedump/2000/1215/sys/src/9/bitsy/devpenmouse.c
363a
if ((!isdigit(*field[1]) && *field[1] != '-')
|| (!isdigit(*field[2]) && *field[2] != '-')
|| (!isdigit(*field[3]) && *field[3] != '-')
|| (!isdigit(*field[4]) && *field[4] != '-'))
error(Ectlsyntax);
.
12a
#include <ctype.h>
.
## diffname bitsy/devpenmouse.c 2000/1216
## diff -e /n/emeliedump/2000/1215/sys/src/9/bitsy/devpenmouse.c /n/emeliedump/2000/1216/sys/src/9/bitsy/devpenmouse.c
272d
## diffname bitsy/devpenmouse.c 2001/0115
## diff -e /n/emeliedump/2000/1216/sys/src/9/bitsy/devpenmouse.c /n/emeliedump/2001/0115/sys/src/9/bitsy/devpenmouse.c
368c
error("bad syntax in control file message");
.
## diffname bitsy/devpenmouse.c 2001/0529
## diff -e /n/emeliedump/2001/0115/sys/src/9/bitsy/devpenmouse.c /n/emeliedump/2001/0529/sys/src/9/bitsy/devpenmouse.c
422d
337,338c
switch((ulong)c->qid.path){
case Qdir:
.
238,239c
switch((ulong)c->qid.path){
case Qdir:
.
217c
if(c->qid.path != Qdir && (c->flag&COPEN)){
.
172,173c
switch((ulong)c->qid.path){
case Qdir:
.
163,168d
160c
return devstat(c, db, n, mousedir, nelem(mousedir), devgen);
.
158c
penmousestat(Chan *c, uchar *db, int n)
.
151,154c
return devwalk(c, nc, name, nname, mousedir, nelem(mousedir), devgen);
.
148,149c
static Walkqid*
penmousewalk(Chan *c, Chan *nc, char **name, int nname)
.
80,82c
".", {Qdir, 0, QTDIR}, 0, DMDIR|0555,
"mouse", {Qmouse}, 0, 0666,
"mousein", {Qmousein}, 0, 0220,
"mousectl", {Qmousectl}, 0, 0660,
.
## diffname bitsy/devpenmouse.c 2001/0822
## diff -e /n/emeliedump/2001/0529/sys/src/9/bitsy/devpenmouse.c /n/emeliedump/2001/0822/sys/src/9/bitsy/devpenmouse.c
95c
// button 5 (side button) immediately causes an event
// when the pen is down (button 1), other buttons also
// cause events, allowing chording with button 1
if ((b & 0x20) || (mouse.buttons & 0x1)) {
.
## diffname bitsy/devpenmouse.c 2001/1117
## diff -e /n/emeliedump/2001/0822/sys/src/9/bitsy/devpenmouse.c /n/emeliedump/2001/1117/sys/src/9/bitsy/devpenmouse.c
344c
nf = tokenize(buf, field, 5);
.
## diffname bitsy/devpenmouse.c 2001/1121
## diff -e /n/emeliedump/2001/1117/sys/src/9/bitsy/devpenmouse.c /n/emeliedump/2001/1121/sys/src/9/bitsy/devpenmouse.c
370a
free(cb);
poperror();
.
369c
cmderror(cb, Ecmdargs);
break;
.
358c
} else if (cb->nf == 5) {
.
351,353c
break;
case CMcalibrate:
if (cb->nf == 1) {
.
337,345c
cb = parsecmd(va, n);
if(waserror()){
free(cb);
nexterror();
}
ct = lookupcmd(cb, penmousecmd, nelem(penmousecmd));
switch(ct->index){
case CMswap:
.
327a
Cmdbuf *cb;
Cmdtab *ct;
.
85a
enum
{
CMcalibrate,
CMswap,
};
static Cmdtab penmousecmd[] =
{
CMcalibrate, "calibrate", 0,
CMswap, "swap", 1,
};
.
## diffname bitsy/devpenmouse.c 2001/1130
## diff -e /n/emeliedump/2001/1121/sys/src/9/bitsy/devpenmouse.c /n/emeliedump/2001/1130/sys/src/9/bitsy/devpenmouse.c
377,380c
calibration.scalex = strtol(cb->f[1], nil, 0);
calibration.scaley = strtol(cb->f[2], nil, 0);
calibration.transx = strtol(cb->f[3], nil, 0);
calibration.transy = strtol(cb->f[4], nil, 0);
.
372,375c
if ((!isdigit(*cb->f[1]) && *cb->f[1] != '-')
|| (!isdigit(*cb->f[2]) && *cb->f[2] != '-')
|| (!isdigit(*cb->f[3]) && *cb->f[3] != '-')
|| (!isdigit(*cb->f[4]) && *cb->f[4] != '-'))
.
342,343c
char buf[64];
int b;
.
125a
.
## diffname bitsy/devpenmouse.c 2002/0109
## diff -e /n/emeliedump/2001/1130/sys/src/9/bitsy/devpenmouse.c /n/emeliedump/2002/0109/sys/src/9/bitsy/devpenmouse.c
432a
devshutdown,
.
## diffname bitsy/devpenmouse.c 2002/1112
## diff -e /n/emeliedump/2002/0109/sys/src/9/bitsy/devpenmouse.c /n/emeliedump/2002/1112/sys/src/9/bitsy/devpenmouse.c
476a
resetsuspendtimer();
.
|