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 */
|
/* devmouse.c */
|
||||||
extern void mousetrack(int, int, int, int);
|
extern void mousetrack(int, int, int, int);
|
||||||
|
extern void absmousetrack(int, int, int, int);
|
||||||
extern Point mousexy(void);
|
extern Point mousexy(void);
|
||||||
|
|
||||||
extern void mouseaccelerate(int);
|
extern void mouseaccelerate(int);
|
||||||
|
|
|
@ -454,16 +454,19 @@ mousewrite(Chan *c, void *va, long n, vlong)
|
||||||
buf[n] = 0;
|
buf[n] = 0;
|
||||||
p = 0;
|
p = 0;
|
||||||
pt.x = strtol(buf+1, &p, 0);
|
pt.x = strtol(buf+1, &p, 0);
|
||||||
if(p == 0)
|
if(*p == 0)
|
||||||
error(Eshort);
|
error(Eshort);
|
||||||
pt.y = strtol(p, &p, 0);
|
pt.y = strtol(p, &p, 0);
|
||||||
if(p == 0)
|
if(*p == 0)
|
||||||
error(Eshort);
|
error(Eshort);
|
||||||
b = strtol(p, &p, 0);
|
b = strtol(p, &p, 0);
|
||||||
msec = strtol(p, &p, 0);
|
msec = strtol(p, &p, 0);
|
||||||
if(msec == 0)
|
if(msec == 0)
|
||||||
msec = TK2MS(MACHP(0)->ticks);
|
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;
|
return n;
|
||||||
|
|
||||||
case Qmouse:
|
case Qmouse:
|
||||||
|
@ -620,6 +623,45 @@ mousetrack(int dx, int dy, int b, int msec)
|
||||||
drawactive(1);
|
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
|
* microsoft 3 button, 7 bit bytes
|
||||||
*
|
*
|
||||||
|
|
|
@ -41,7 +41,7 @@ extern char Enoswap[]; /* swap space full */
|
||||||
extern char Esoverlap[]; /* segments overlap */
|
extern char Esoverlap[]; /* segments overlap */
|
||||||
extern char Emouseset[]; /* mouse type already set */
|
extern char Emouseset[]; /* mouse type already set */
|
||||||
extern char Eshort[]; /* i/o count too small */
|
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 Ebadspec[]; /* bad attach specifier */
|
||||||
extern char Enoreg[]; /* process has no saved registers */
|
extern char Enoreg[]; /* process has no saved registers */
|
||||||
extern char Enoattach[]; /* mount/attach disallowed */
|
extern char Enoattach[]; /* mount/attach disallowed */
|
||||||
|
|
|
@ -34,11 +34,13 @@ TARG=\
|
||||||
searchfs\
|
searchfs\
|
||||||
statusbar\
|
statusbar\
|
||||||
stub\
|
stub\
|
||||||
|
tablet\
|
||||||
timesync\
|
timesync\
|
||||||
trampoline\
|
trampoline\
|
||||||
unbflz\
|
unbflz\
|
||||||
usage\
|
usage\
|
||||||
write\
|
write\
|
||||||
|
wacom\
|
||||||
zerotrunc\
|
zerotrunc\
|
||||||
|
|
||||||
BIN=/$objtype/bin/aux
|
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…
Add table
Add a link
Reference in a new issue