9front - general discussion about 9front
 help / color / mirror / Atom feed
* [9front] [patch] aux/wacom: prevent "no concurrent reads please" error when moving the pen too fast and support screen tilt
@ 2021-04-10 15:39 james palmer
       [not found] ` <b0646909-d59a-4423-8467-32c4c96ef5d3@www.fastmail.com>
  2021-04-11 15:39 ` [9front] " james palmer
  0 siblings, 2 replies; 13+ messages in thread
From: james palmer @ 2021-04-10 15:39 UTC (permalink / raw)
  To: 9front mailing list

[-- Attachment #1: Type: text/plain, Size: 270 bytes --]

attached is a patch for my rewrite of aux/wacom.
it prevents the "no concurrent reads please" error when moving the pen too fast,
as well as rotating the pen input to match the screen tilt.
i have kept the same format for /dev/tablet to keep aux/tablet working.

- james

[-- Attachment #2.1: Type: text/plain, Size: 329 bytes --]

from postmaster@1ess:
The following attachment had content that we can't
prove to be harmless.  To avoid possible automatic
execution, we changed the content headers.
The original header was:

	Content-Disposition: attachment;filename="wacom.diff"
	Content-Type: text/x-patch; name="wacom.diff"
	Content-Transfer-Encoding: BASE64

[-- Attachment #2.2: wacom.diff.suspect --]
[-- Type: application/octet-stream, Size: 10675 bytes --]

# HG changeset patch
# User foura <james@biobuf.link>
# Date 1618064393 -3600
# Node ID 2eeed04af3e8d4378ff3615872dfb27fac6fff59
# Parent  936eda80a52f65994713fc017d26bec3f6d72c8c
aux/wacom: prevent "no concurrent reads please" error when pen is moved too fast and support screen tilt.

diff -r 936eda80a52f -r 2eeed04af3e8 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 15:19:53 2021 +0100
@@ -1,352 +1,317 @@
 #include <u.h>
 #include <libc.h>
+#include <bio.h>
+#include <thread.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 {
+	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
+fsread(Req *req)
+{
+	Channel *c;
+	Tablet t;
+	char *reply;
+	
+	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);
+}
+
+Srv fs = {
+	.read = fsread,
 };
 
-File *tfile;
+void
+srvproc(void *aux)
+{
+	fs.aux = aux;
+	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);
+}

^ permalink raw reply	[flat|nested] 13+ messages in thread

end of thread, other threads:[~2021-04-25  2:49 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-04-10 15:39 [9front] [patch] aux/wacom: prevent "no concurrent reads please" error when moving the pen too fast and support screen tilt james palmer
     [not found] ` <b0646909-d59a-4423-8467-32c4c96ef5d3@www.fastmail.com>
2021-04-10 16:49   ` [9front] " james palmer
2021-04-11 15:39 ` [9front] " james palmer
2021-04-12  7:37   ` hiro
2021-04-12 10:00     ` james palmer
2021-04-12 17:03       ` hiro
2021-04-15 21:09         ` cinap_lenrek
2021-04-16  9:25           ` hiro
2021-04-17  3:32             ` cinap_lenrek
2021-04-24 19:57         ` Michael Enders
2021-04-12  8:12   ` cinap_lenrek
2021-04-12  9:57     ` james palmer
2021-04-19 15:49     ` james palmer

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).