From mboxrd@z Thu Jan 1 00:00:00 1970 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on inbox.vuxu.org X-Spam-Level: X-Spam-Status: No, score=-0.1 required=5.0 tests=DKIM_SIGNED,DKIM_VALID, DKIM_VALID_AU autolearn=ham autolearn_force=no version=3.4.4 Received: (qmail 11390 invoked from network); 12 Apr 2021 07:13:03 -0000 Received: from 1ess.inri.net (216.126.196.35) by inbox.vuxu.org with ESMTPUTF8; 12 Apr 2021 07:13:03 -0000 Received: from wout2-smtp.messagingengine.com ([64.147.123.25]) by 1ess; Sun Apr 11 21:51:29 -0400 2021 Received: from compute2.internal (compute2.nyi.internal [10.202.2.42]) by mailout.west.internal (Postfix) with ESMTP id 1879712B3 for <9front@9front.org>; Sun, 11 Apr 2021 11:39:56 -0400 (EDT) Received: from imap21 ([10.202.2.71]) by compute2.internal (MEProxy); Sun, 11 Apr 2021 11:39:56 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=biobuf.link; h= mime-version:message-id:in-reply-to:references:date:from:to :subject:content-type; s=fm2; bh=0nqWxX/OmNNfmXiFhW/xa6fEJcIgF8p catF9TBGQ0wM=; b=thFD+Df5tFXA6kmzC4i3+TNjKRxGK1X95F2V4Zxh6tELvs7 wegdg6vK8HfRoYqogHLMtJV89oKhaJ1A7Lr6ZnzIS380fJHtExdarG4mLbhLekuC ZIOfB5KuJGnbB/NsK15FX9gZGAzr4QCvgnSZZ3wB4qXuSgwk4ZMqU8LROk+BteKI qvnMEVH2+yX0aTVGwP0H9kkYDT2ALFSTQpPipgwExpCMry3zwr+iihT0NuK+m/N1 9Oatk0cPWtq+DH2DGcnbKR39pTATTaSSY/lYjBbfLSdo8nfKXb5J7FVaVjb4U5vg tmZTnY3KT7jbdvmR1fP5muwEIg+75SG09L8o8+w== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=content-type:date:from:in-reply-to :message-id:mime-version:references:subject:to:x-me-proxy :x-me-proxy:x-me-sender:x-me-sender:x-sasl-enc; s=fm2; bh=0nqWxX /OmNNfmXiFhW/xa6fEJcIgF8pcatF9TBGQ0wM=; b=hLJWKmyUAut4vo8B3Fud+t xqch4ATY9LAdJcWnAyMB/EdYtz2SchxUdh+SkDldwSOBLz9GdSwCY/oDPHR+pu+N uJeyx45Yl4BGd1DcbNqcYFW6rTFHr5uOZxKvnWswcQwq4/gfe/pnqkeo4fH3kzZ7 zukzAW9kE6fN4v46j+cseoOyL6QHIQWDIPBPreiDriOL1C2RV8H5QQnZQW1mymZt 03+8zJGJaYL6dvZzSeg5oub65LhCCYZ+ZCuKnGo70mVlbuN3eCeEIOsmnqU0pNu1 xBuLaxGjrBA3UJqzeWDdmGwT+Tm14Rib4sXDxaalzHrEVkQ2Gezlds0KukEQXfsg == X-ME-Sender: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgeduledrudekhedgvdduucetufdoteggodetrfdotf fvucfrrhhofhhilhgvmecuhfgrshhtofgrihhlpdfqfgfvpdfurfetoffkrfgpnffqhgen uceurghilhhouhhtmecufedttdenucesvcftvggtihhpihgvnhhtshculddquddttddmne cujfgurhepofgfggfkjghffffhvffutgesthdtredtreerjeenucfhrhhomhepfdhjrghm vghsuchprghlmhgvrhdfuceojhgrmhgvshessghiohgsuhhfrdhlihhnkheqnecuggftrf grthhtvghrnhepgfehueevjeehieeftdelhfefudeltdegffevuefhudetleefjefhteff vdejgfdtnecuvehluhhsthgvrhfuihiivgeptdenucfrrghrrghmpehmrghilhhfrhhomh epjhgrmhgvshessghiohgsuhhfrdhlihhnkh X-ME-Proxy: Received: by mailuser.nyi.internal (Postfix, from userid 501) id 6756351C005F; Sun, 11 Apr 2021 11:39:55 -0400 (EDT) X-Mailer: MessagingEngine.com Webmail Interface User-Agent: Cyrus-JMAP/3.5.0-alpha0-273-g8500d2492d-fm-20210323.002-g8500d249 Mime-Version: 1.0 Message-Id: In-Reply-To: References: Date: Sun, 11 Apr 2021 16:39:49 +0100 From: "james palmer" To: "9front mailing list" <9front@9front.org> Content-Type: text/plain List-ID: <9front.9front.org> List-Help: X-Glyph: ➈ X-Bullshit: abstract package template-based AJAX over ActivityPub database package Subject: =?UTF-8?Q?Re:_[9front]_[patch]_aux/wacom:_prevent_"no_concurrent_reads_p?= =?UTF-8?Q?lease"_error_when_moving_the_pen_too_fast_and_support_screen_?= =?UTF-8?Q?tilt?= Reply-To: 9front@9front.org Precedence: bulk seems like the updated version of this got lost. i fixed walks of /dev blocking by launching a new proc for each 9p request. (i should probably convert this to use a Reqqueue, that will come soon) patch is below because the ml keeps marking attached diffs as suspicious - james # HG changeset patch # User foura # Date 1618069652 -3600 # Node ID 0ce7cfc958df8ae0d2ff641f15251600795a48b5 # Parent 936eda80a52f65994713fc017d26bec3f6d72c8c aux/wacom: rewrite to use multiple procs and support screen tilt. diff -r 936eda80a52f -r 0ce7cfc958df sys/src/cmd/aux/wacom.c --- a/sys/src/cmd/aux/wacom.c Sat Apr 10 15:01:09 2021 +0200 +++ b/sys/src/cmd/aux/wacom.c Sat Apr 10 16:47:32 2021 +0100 @@ -1,352 +1,335 @@ #include #include +#include +#include #include -#include #include <9p.h> -typedef struct Tablet Tablet; -typedef struct Message Message; -typedef struct QItem QItem; -typedef struct Queue Queue; -typedef struct Reader Reader; +enum { + None, + Left, + Right, + Inverted, - -enum { MAX = 1000 }; - -struct Tablet { - int ser; - int xmax, ymax, pmax, version; - int sx, sy; + MAX = 1000, + STACK = 2048, }; -struct Message { - Ref; - int b, x, y, p; - char *msg; +typedef struct Tablet Tablet; +struct Tablet { + + int fd; + char dev[64]; + int version; + + int x, y, b, p; + int xmax, ymax, pmax; + + int sx, sy, srot; }; -Tablet* -newtablet(char* dev) +void +threadfatal(char *fmt, ...) { - int serctl; - char* ctl; - Tablet* t; + va_list arg; + char buf[1024]; + + va_start(arg, fmt); + vseprint(buf, buf+sizeof(buf), fmt, arg); + va_end(arg); - 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); + if(argv0) + fprint(2, "%s: %s\n", argv0, buf); + else + fprint(2, "%s: %s\n", argv0, buf); + + threadexitsall(buf); +} + +void +setuptablet(Tablet *t) +{ + int ctlfd; + char *ctl; + + ctl = smprint("%sctl", t->dev); + t->fd = open(t->dev, ORDWR); + if(t->fd < 0) + threadfatal("%r", t->dev); + + ctlfd = open(ctl, OWRITE); + if(ctlfd < 0) + threadfatal("%r", ctl); 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; + + if(fprint(ctlfd, "b19200\n") < 0) + threadfatal("set baud rate: %r"); } int -query(Tablet* t) +query(Tablet *t) { uchar buf[11]; - if(write(t->ser, "&0*", 3) < 3) return -1; + if(write(t->fd, "&0*", 3) < 3) return 0; do { - if(read(t->ser, buf, 1) < 1) return -1; + if(read(t->fd, buf, 1) < 1) return 0; } while(buf[0] != 0xC0); - if(readn(t->ser, buf+1, 10) < 10) return -1; + + if(readn(t->fd, buf+1, 10) < 10) return 0; + 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; + + if(write(t->fd, "1", 1) < 1) return 0; + return 1; } int -screensize(Tablet* t) +findheader(Tablet *t) +{ + uchar c; + + do { + if(read(t->fd, &c, 1) < 1) return -1; + } while((c & 0x80) == 0); + + return c; +} + +void +readpacket(Tablet *t) +{ + uchar buf[9]; + int head; + + head = findheader(t); + if(head < 0) threadfatal("%r"); + if(readn(t->fd, buf, 9) < 9) threadfatal("%r"); + + t->b = head & 7; + t->x = (buf[0] << 9) | (buf[1] << 2) | ((buf[5] >> 5) & 3); + t->y = (buf[2] << 9) | (buf[3] << 2) | ((buf[5] >> 3) & 3); + t->p = ((buf[5] & 7) << 7) | buf[4]; +} + +void +screensize(Tablet *t) { int fd; char buf[189], buf2[12], *p; - + fd = open("/dev/draw/new", OREAD); - if(fd < 0) return -1; + if(fd < 0) threadfatal("%r"); 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; + threadfatal("invalid resolution read from /dev/draw/new"); } - + 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) +screenrot(Tablet *t) { - if(decref(m) == 0) { - free(m->msg); - free(m); + char *ln; + Biobuf *fd; + + fd = Bopen("/dev/vgactl", OREAD); + if(!fd) { + t->srot = None; + return; } -} -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; + while(ln = Brdstr(fd, '\n', 1)) { + if(strncmp("tilt ", ln, 5) == 0) + switch(ln[5]) { + case 'l': + t->srot = Left; + break; + case 'r': + t->srot = Right; + break; + case 'i': + t->srot = Inverted; + break; + default: + t->srot = None; + } + free(ln); } - 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; + Bterm(fd); } void -freequeue(Queue *q) +updateproc(void *aux) { - Message *m; - - while(m = qget(q)) - msgdecref(m); - free(q); -} + Tablet t; + Channel *c; -struct Reader { - Queue *e; - Reader *prev, *next; - Req* req; -}; + c = aux; + recv(c, &t); + t.b = 0; + t.x = 0; + t.y = 0; + t.p = 0; -Lock readers; -Reader *rfirst, *rlast; + setuptablet(&t); + query(&t); -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; + for(;;) { + screensize(&t); + screenrot(&t); + readpacket(&t); + send(c, &t); } } void -tabletread(Req* req) +scaleinput(Tablet *t) { - 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; - } + int temp; + + t->p *= MAX; + t->p /= t->pmax; + + switch(t->srot) { + case Left: + /* flip */ + t->y = t->ymax - t->y; + /* scale */ + t->x *= t->sx; + t->x /= t->ymax; + t->y *= t->sy; + t->y /= t->xmax; + /* swap */ + temp = t->x; + t->x = t->y; + t->y = temp; + break; + case Right: + /* flip */ + t->x = t->xmax - t->x; + /* scale */ + t->x *= t->sx; + t->x /= t->ymax; + t->y *= t->sy; + t->y /= t->xmax; + /* swap */ + temp = t->x; + t->x = t->y; + t->y = temp; + break; + case Inverted: + /* flip */ + t->y = t->ymax - t->y; + t->x = t->xmax - t->x; + /* scale */ + t->x *= t->sx; + t->x /= t->xmax; + t->y *= t->sy; + t->y /= t->ymax; + break; + default: + /* scale */ + t->x *= t->sx; + t->x /= t->xmax; + t->y *= t->sy; + t->y /= t->ymax; } } -Srv tabletsrv = { - .open = tabletopen, - .read = tabletread, - .destroyfid = tabletdestroyfid, - .destroyreq = tabletdestroyreq, +void +replyproc(void *aux) +{ + Req *req; + Channel *c; + Tablet t; + char *reply; + + req = aux; + c = req->srv->aux; + recv(c, &t); + scaleinput(&t); + + reply = smprint("m %d %d %d %d\n", + t.x, t.y, t.b, t.p); + + req->ofcall.count = strlen(reply); + if(req->ofcall.count > req->ifcall.count) + req->ofcall.count = req->ifcall.count; + memmove(req->ofcall.data, reply, req->ofcall.count); + respond(req, nil); + + free(reply); +} + +void +fsread(Req *req) +{ + proccreate(replyproc, req, STACK); +} + +void +fsflush(Req *req) +{ + proccreate(replyproc, req->oldreq, STACK); +} + +Srv fs = { + .read = fsread, + .flush = fsflush, }; -File *tfile; +void +srvproc(void *aux) +{ + Channel *c; + + c = aux; + fs.aux = c; + fs.tree = alloctree(getuser(), getuser(), 0555, nil); + createfile(fs.tree->root, "tablet", getuser(), 0400, nil); + threadpostmountsrv(&fs, nil, "/dev", MAFTER); +} void -main() +usage(void) { - 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); - } -} \ No newline at end of file + fprint(2, "usage: %s [-d dev]\n", argv0); + exits("usage"); +} + +void +threadmain(int argc, char *argv[]) +{ + Channel *c; + Tablet t; + + ARGBEGIN { + case 'd': + strncmp(t.dev, EARGF(usage()), sizeof(t.dev)); + break; + default: + usage(); + } ARGEND + + c = chancreate(sizeof(Tablet), 10); + strncpy(t.dev, "/dev/eia2", sizeof(t.dev)); + + proccreate(updateproc, c, STACK); + send(c, &t); + proccreate(srvproc, c, STACK); +}