merge
This commit is contained in:
commit
d763dcc91b
6 changed files with 433 additions and 4 deletions
|
@ -7,6 +7,7 @@ struct Cursorinfo {
|
|||
|
||||
/* devmouse.c */
|
||||
extern void mousetrack(int, int, int, int);
|
||||
extern void absmousetrack(int, int, int, int);
|
||||
extern Point mousexy(void);
|
||||
|
||||
extern void mouseaccelerate(int);
|
||||
|
|
|
@ -454,16 +454,19 @@ mousewrite(Chan *c, void *va, long n, vlong)
|
|||
buf[n] = 0;
|
||||
p = 0;
|
||||
pt.x = strtol(buf+1, &p, 0);
|
||||
if(p == 0)
|
||||
if(*p == 0)
|
||||
error(Eshort);
|
||||
pt.y = strtol(p, &p, 0);
|
||||
if(p == 0)
|
||||
if(*p == 0)
|
||||
error(Eshort);
|
||||
b = strtol(p, &p, 0);
|
||||
msec = strtol(p, &p, 0);
|
||||
if(msec == 0)
|
||||
msec = TK2MS(MACHP(0)->ticks);
|
||||
mousetrack(pt.x, pt.y, b, msec);
|
||||
if(buf[0] == 'A')
|
||||
absmousetrack(pt.x, pt.y, b, msec);
|
||||
else
|
||||
mousetrack(pt.x, pt.y, b, msec);
|
||||
return n;
|
||||
|
||||
case Qmouse:
|
||||
|
@ -620,6 +623,45 @@ mousetrack(int dx, int dy, int b, int msec)
|
|||
drawactive(1);
|
||||
}
|
||||
|
||||
void
|
||||
absmousetrack(int x, int y, int b, int msec)
|
||||
{
|
||||
int lastb;
|
||||
|
||||
if(gscreen==nil)
|
||||
return;
|
||||
|
||||
if(x < gscreen->clipr.min.x)
|
||||
x = gscreen->clipr.min.x;
|
||||
if(x >= gscreen->clipr.max.x)
|
||||
x = gscreen->clipr.max.x;
|
||||
if(y < gscreen->clipr.min.y)
|
||||
y = gscreen->clipr.min.y;
|
||||
if(y >= gscreen->clipr.max.y)
|
||||
y = gscreen->clipr.max.y;
|
||||
|
||||
lastb = mouse.buttons;
|
||||
mouse.xy = Pt(x, y);
|
||||
mouse.buttons = b|kbdbuttons;
|
||||
mouse.redraw = 1;
|
||||
mouse.counter++;
|
||||
mouse.msec = msec;
|
||||
|
||||
/*
|
||||
* 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);
|
||||
drawactive(1);
|
||||
}
|
||||
|
||||
/*
|
||||
* microsoft 3 button, 7 bit bytes
|
||||
*
|
||||
|
|
|
@ -41,7 +41,7 @@ extern char Enoswap[]; /* swap space full */
|
|||
extern char Esoverlap[]; /* segments overlap */
|
||||
extern char Emouseset[]; /* mouse type already set */
|
||||
extern char Eshort[]; /* i/o count too small */
|
||||
extern char Egreg[]; /* jmk added reentrancy for threads */
|
||||
extern char Egreg[]; /* the front fell off */
|
||||
extern char Ebadspec[]; /* bad attach specifier */
|
||||
extern char Enoreg[]; /* process has no saved registers */
|
||||
extern char Enoattach[]; /* mount/attach disallowed */
|
||||
|
|
|
@ -34,11 +34,13 @@ TARG=\
|
|||
searchfs\
|
||||
statusbar\
|
||||
stub\
|
||||
tablet\
|
||||
timesync\
|
||||
trampoline\
|
||||
unbflz\
|
||||
usage\
|
||||
write\
|
||||
wacom\
|
||||
zerotrunc\
|
||||
|
||||
BIN=/$objtype/bin/aux
|
||||
|
|
32
sys/src/cmd/aux/tablet.c
Normal file
32
sys/src/cmd/aux/tablet.c
Normal file
|
@ -0,0 +1,32 @@
|
|||
#include <u.h>
|
||||
#include <libc.h>
|
||||
#include <bio.h>
|
||||
|
||||
Biobuf *tablet;
|
||||
int mouseout;
|
||||
|
||||
int
|
||||
main()
|
||||
{
|
||||
mouseout = open("/dev/mousein", OWRITE);
|
||||
if(mouseout < 0) sysfatal("%r");
|
||||
tablet = Bopen("/dev/tablet", OREAD);
|
||||
if(tablet == nil) sysfatal("%r");
|
||||
while(1) {
|
||||
char *line, *p;
|
||||
int x, y, b;
|
||||
|
||||
line = Brdline(tablet, 10);
|
||||
if(!line) sysfatal("%r");
|
||||
p = line;
|
||||
if(*p++ != 'm') continue;
|
||||
if(*p++ != ' ') continue;
|
||||
x = strtol(p, &p, 10);
|
||||
if(*p++ != ' ') continue;
|
||||
y = strtol(p, &p, 10);
|
||||
if(*p++ != ' ') continue;
|
||||
b = strtol(p, &p, 10);
|
||||
if(*p++ != ' ') continue;
|
||||
fprint(mouseout, "A %d %d %d\n", x, y, b);
|
||||
}
|
||||
}
|
352
sys/src/cmd/aux/wacom.c
Normal file
352
sys/src/cmd/aux/wacom.c
Normal file
|
@ -0,0 +1,352 @@
|
|||
#include <u.h>
|
||||
#include <libc.h>
|
||||
#include <fcall.h>
|
||||
#include <thread.h>
|
||||
#include <9p.h>
|
||||
|
||||
typedef struct Tablet Tablet;
|
||||
typedef struct Message Message;
|
||||
typedef struct QItem QItem;
|
||||
typedef struct Queue Queue;
|
||||
typedef struct Reader Reader;
|
||||
|
||||
|
||||
enum { MAX = 1000 };
|
||||
|
||||
struct Tablet {
|
||||
int ser;
|
||||
int xmax, ymax, pmax, version;
|
||||
int sx, sy;
|
||||
};
|
||||
|
||||
struct Message {
|
||||
Ref;
|
||||
int b, x, y, p;
|
||||
char *msg;
|
||||
};
|
||||
|
||||
Tablet*
|
||||
newtablet(char* dev)
|
||||
{
|
||||
int serctl;
|
||||
char* ctl;
|
||||
Tablet* t;
|
||||
|
||||
ctl = smprint("%sctl", dev);
|
||||
t = calloc(sizeof(Tablet), 1);
|
||||
t->ser = open(dev, ORDWR);
|
||||
if(t->ser < 0) {
|
||||
free(t);
|
||||
return 0;
|
||||
}
|
||||
serctl = open(ctl, OWRITE);
|
||||
free(ctl);
|
||||
if(serctl < 0) {
|
||||
free(t);
|
||||
close(t->ser);
|
||||
return 0;
|
||||
}
|
||||
if(fprint(serctl, "b19200\n") < 0) {
|
||||
free(t);
|
||||
close(t->ser);
|
||||
close(serctl);
|
||||
return 0;
|
||||
}
|
||||
close(serctl);
|
||||
return t;
|
||||
}
|
||||
|
||||
int
|
||||
query(Tablet* t)
|
||||
{
|
||||
uchar buf[11];
|
||||
|
||||
if(write(t->ser, "&0*", 3) < 3) return -1;
|
||||
do {
|
||||
if(read(t->ser, buf, 1) < 1) return -1;
|
||||
} while(buf[0] != 0xC0);
|
||||
if(readn(t->ser, buf+1, 10) < 10) return -1;
|
||||
t->xmax = (buf[1] << 9) | (buf[2] << 2) | ((buf[6] >> 5) & 3);
|
||||
t->ymax = (buf[3] << 9) | (buf[4] << 2) | ((buf[6] >> 3) & 3);
|
||||
t->pmax = buf[5] | (buf[6] & 7);
|
||||
t->version = (buf[9] << 7) | buf[10];
|
||||
if(write(t->ser, "1", 1) < 1) return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
screensize(Tablet* t)
|
||||
{
|
||||
int fd;
|
||||
char buf[189], buf2[12], *p;
|
||||
|
||||
fd = open("/dev/draw/new", OREAD);
|
||||
if(fd < 0) return -1;
|
||||
read(fd, buf, 189);
|
||||
memcpy(buf2, buf + 72, 11);
|
||||
buf2[11] = 0;
|
||||
for(p = buf2; *p == ' '; p++);
|
||||
t->sx = atoi(p);
|
||||
memcpy(buf2, buf + 84, 11);
|
||||
for(p = buf2; *p == ' '; p++);
|
||||
t->sy = atoi(p);
|
||||
if(t->sx == 0 || t->sy == 0) {
|
||||
close(fd);
|
||||
werrstr("invalid resolution read from /dev/draw/new");
|
||||
return -1;
|
||||
}
|
||||
|
||||
close(fd);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
findheader(Tablet* t)
|
||||
{
|
||||
uchar c;
|
||||
|
||||
do {
|
||||
if(read(t->ser, &c, 1) < 1) return -1;
|
||||
} while((c & 0x80) == 0);
|
||||
return c;
|
||||
}
|
||||
|
||||
Message*
|
||||
readpacket(Tablet* t)
|
||||
{
|
||||
uchar buf[9];
|
||||
int head;
|
||||
Message *m;
|
||||
|
||||
head = findheader(t);
|
||||
if(head < 0) return 0;
|
||||
if(readn(t->ser, buf, 9) < 9) return 0;
|
||||
|
||||
m = calloc(sizeof(Message), 1);
|
||||
incref(m);
|
||||
|
||||
m->b = head & 7;
|
||||
m->x = (buf[0] << 9) | (buf[1] << 2) | ((buf[5] >> 5) & 3);
|
||||
m->y = (buf[2] << 9) | (buf[3] << 2) | ((buf[5] >> 3) & 3);
|
||||
m->p = ((buf[5] & 7) << 7) | buf[4];
|
||||
|
||||
m->p *= MAX;
|
||||
m->p /= t->pmax;
|
||||
m->x *= t->sx;
|
||||
m->x /= t->xmax;
|
||||
m->y *= t->sy;
|
||||
m->y /= t->ymax;
|
||||
|
||||
m->msg = smprint("m %d %d %d %d\n", m->x, m->y, m->b, m->p);
|
||||
return m;
|
||||
}
|
||||
|
||||
void
|
||||
msgdecref(Message *m)
|
||||
{
|
||||
if(decref(m) == 0) {
|
||||
free(m->msg);
|
||||
free(m);
|
||||
}
|
||||
}
|
||||
|
||||
struct QItem {
|
||||
Message *m;
|
||||
QItem *next;
|
||||
};
|
||||
|
||||
struct Queue {
|
||||
Lock;
|
||||
QItem *first, *last;
|
||||
};
|
||||
|
||||
void
|
||||
qput(Queue* q, Message* m)
|
||||
{
|
||||
QItem *i;
|
||||
|
||||
lock(q);
|
||||
i = malloc(sizeof(QItem));
|
||||
i->m = m;
|
||||
i->next = 0;
|
||||
if(q->last == nil) {
|
||||
q->last = q->first = i;
|
||||
} else {
|
||||
q->last->next = i;
|
||||
q->last = i;
|
||||
}
|
||||
unlock(q);
|
||||
}
|
||||
|
||||
Message*
|
||||
qget(Queue* q)
|
||||
{
|
||||
QItem *i;
|
||||
Message *m;
|
||||
|
||||
if(q->first == nil) return nil;
|
||||
lock(q);
|
||||
i = q->first;
|
||||
if(q->first == q->last) {
|
||||
q->first = q->last = nil;
|
||||
} else {
|
||||
q->first = i->next;
|
||||
}
|
||||
m = i->m;
|
||||
free(i);
|
||||
unlock(q);
|
||||
return m;
|
||||
}
|
||||
|
||||
void
|
||||
freequeue(Queue *q)
|
||||
{
|
||||
Message *m;
|
||||
|
||||
while(m = qget(q))
|
||||
msgdecref(m);
|
||||
free(q);
|
||||
}
|
||||
|
||||
struct Reader {
|
||||
Queue *e;
|
||||
Reader *prev, *next;
|
||||
Req* req;
|
||||
};
|
||||
|
||||
Lock readers;
|
||||
Reader *rfirst, *rlast;
|
||||
|
||||
void
|
||||
reply(Req *req, Message *m)
|
||||
{
|
||||
req->ofcall.count = strlen(m->msg);
|
||||
if(req->ofcall.count > req->ifcall.count)
|
||||
req->ofcall.count = req->ifcall.count;
|
||||
memmove(req->ofcall.data, m->msg, req->ofcall.count);
|
||||
respond(req, nil);
|
||||
}
|
||||
|
||||
void
|
||||
sendout(Message *m)
|
||||
{
|
||||
Reader *r;
|
||||
|
||||
lock(&readers);
|
||||
for(r = rfirst; r; r = r->next) {
|
||||
if(r->req) {
|
||||
reply(r->req, m);
|
||||
r->req = nil;
|
||||
} else {
|
||||
incref(m);
|
||||
qput(r->e, m);
|
||||
}
|
||||
}
|
||||
unlock(&readers);
|
||||
}
|
||||
|
||||
void
|
||||
tabletopen(Req *req)
|
||||
{
|
||||
Reader *r;
|
||||
|
||||
lock(&readers);
|
||||
r = calloc(sizeof(Reader), 1);
|
||||
r->e = calloc(sizeof(Queue), 1);
|
||||
if(rlast) rlast->next = r;
|
||||
r->prev = rlast;
|
||||
rlast = r;
|
||||
if(rfirst == nil) rfirst = r;
|
||||
unlock(&readers);
|
||||
req->fid->aux = r;
|
||||
respond(req, nil);
|
||||
}
|
||||
|
||||
void
|
||||
tabletdestroyfid(Fid *fid)
|
||||
{
|
||||
Reader *r;
|
||||
|
||||
r = fid->aux;
|
||||
if(r == nil) return;
|
||||
lock(&readers);
|
||||
if(r->prev) r->prev->next = r->next;
|
||||
if(r->next) r->next->prev = r->prev;
|
||||
if(r == rfirst) rfirst = r->next;
|
||||
if(r == rlast) rlast = r->prev;
|
||||
freequeue(r->e);
|
||||
free(r);
|
||||
unlock(&readers);
|
||||
}
|
||||
|
||||
void
|
||||
tabletdestroyreq(Req *req)
|
||||
{
|
||||
Reader *r;
|
||||
|
||||
if(req->fid == nil) return;
|
||||
r = req->fid->aux;
|
||||
if(r == nil) return;
|
||||
if(req == r->req) {
|
||||
r->req = nil;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
tabletread(Req* req)
|
||||
{
|
||||
Reader *r;
|
||||
Message *m;
|
||||
|
||||
r = req->fid->aux;
|
||||
if(m = qget(r->e)) {
|
||||
reply(req, m);
|
||||
msgdecref(m);
|
||||
} else {
|
||||
if(r->req) {
|
||||
respond(req, "no concurrent reads, please");
|
||||
} else {
|
||||
r->req = req;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Srv tabletsrv = {
|
||||
.open = tabletopen,
|
||||
.read = tabletread,
|
||||
.destroyfid = tabletdestroyfid,
|
||||
.destroyreq = tabletdestroyreq,
|
||||
};
|
||||
|
||||
File *tfile;
|
||||
|
||||
void
|
||||
main()
|
||||
{
|
||||
Tablet *t;
|
||||
Message *m;
|
||||
int fd[2];
|
||||
|
||||
pipe(fd);
|
||||
tabletsrv.infd = tabletsrv.outfd = fd[0];
|
||||
tabletsrv.srvfd = fd[1];
|
||||
tabletsrv.tree = alloctree(getuser(), getuser(), 0555, 0);
|
||||
tfile = createfile(tabletsrv.tree->root, "tablet", getuser(), 0400, 0);
|
||||
if(rfork(RFPROC | RFMEM | RFNOWAIT | RFNOTEG) > 0) exits(nil);
|
||||
if(rfork(RFPROC | RFMEM) == 0) {
|
||||
srv(&tabletsrv);
|
||||
exits(nil);
|
||||
}
|
||||
mount(fd[1], -1, "/dev", MAFTER, "");
|
||||
|
||||
t = newtablet("/dev/eia2");
|
||||
if(!t) sysfatal("%r");
|
||||
if(screensize(t) < 0) sysfatal("%r");
|
||||
if(query(t) < 0) sysfatal("%r");
|
||||
while(1) {
|
||||
m = readpacket(t);
|
||||
if(!m) sysfatal("%r");
|
||||
sendout(m);
|
||||
msgdecref(m);
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue