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.2 required=5.0 tests=DKIM_INVALID,DKIM_SIGNED autolearn=no autolearn_force=no version=3.4.4 Received: (qmail 2531 invoked from network); 22 Dec 2021 08:47:03 -0000 Received: from 4ess.inri.net (216.126.196.42) by inbox.vuxu.org with ESMTPUTF8; 22 Dec 2021 08:47:03 -0000 Received: from mail.9lab.org ([168.119.8.41]) by 4ess; Wed Dec 22 03:39:29 -0500 2021 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=9lab.org; s=20210803; t=1640162355; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to; bh=+VYawDxq0y8pq/PmS0cd9f1V9LXGdV6Cw7jHdME23EQ=; b=XJH3LYaDfxubRbgBQVn7Rr/y4QEjbQAqmdV34Js9wSRiS7Q2W4hJ9rr+hrbb/gi+HsfU2g U1UOZ2XRuyVzi19BicIcnS++kCrDItyjSTaPhEw443m4fP1thS9Gw8C7JyM7P9oFUD1wJo xfymDCcclQeVP74B0RBOqgtKL4ZDGE0= Received: from pjw (host-185-64-155-70.ecsnet.at [185.64.155.70]) by mail.9lab.org (OpenSMTPD) with ESMTPSA id a2677c6c (TLSv1.2:ECDHE-RSA-CHACHA20-POLY1305:256:NO) for <9front@9front.org>; Wed, 22 Dec 2021 09:39:15 +0100 (CET) Message-ID: To: 9front@9front.org Date: Wed, 22 Dec 2021 09:39:14 +0100 From: igor@9lab.org In-Reply-To: MIME-Version: 1.0 Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: 8bit List-ID: <9front.9front.org> List-Help: X-Glyph: ➈ X-Bullshit: mobile strategy callback framework Subject: Re: [9front] hidpi Reply-To: 9front@9front.org Precedence: bulk Quoth Philip Silva : […] > - glitches: the borders aren't calculated correctly (3rd patch for rio and acme is very wip) […] By glitches, do you mean issues like the one here: • https://9lab.org/img/plan9/acid.png …where there is an issue in computing the column growth ⁽¹⁾ (I think) manifesting itself as an artefact that looks like a white line at the bottom of an acme column. On small res displays this isn't noticeable, however, on high-res screens it is annoying. I stopped half way through due to lack of time debugging this (still on my todo list), and was wondering if you observed the same glitch. ⁽¹⁾ … https://9lab.org/plan9/debugging-with-acid/ > -- > > > 1st Patch for libdraw and devdraw: > > diff c7dcc82b0be805717efbe77c98eaadf3ee1e31af uncommitted > --- a/sys/include/ape/draw.h > +++ b/sys/include/ape/draw.h > @@ -208,6 +208,7 @@ > Image *windows; > Image *screenimage; > int _isnewdisplay; > + int dpi; > }; > > struct Image > --- a/sys/include/draw.h > +++ b/sys/include/draw.h > @@ -200,6 +200,7 @@ > Image *windows; > Image *screenimage; > int _isnewdisplay; > + int dpi; > }; > > struct Image > --- a/sys/src/9/port/devdraw.c > +++ b/sys/src/9/port/devdraw.c > @@ -77,6 +77,8 @@ > int refreshme; > int infoid; > int op; > + int displaydpi; > + int forcedpi; > }; > > struct Refresh > @@ -785,6 +789,7 @@ > cl->slot = i; > cl->clientid = ++sdraw.clientid; > cl->op = SoverD; > + cl->displaydpi=100; > sdraw.client[i] = cl; > return cl; > } > @@ -1396,6 +1401,7 @@ > int c, repl, m, y, dstid, scrnid, ni, ci, j, nw, e0, e1, op, ox, oy, oesize, esize, doflush; > uchar *u, *a, refresh; > char *fmt; > + Fmt f; > ulong value, chan; > Rectangle r, clipr; > Point p, q, *pp, sp; > @@ -1643,6 +1649,35 @@ > font->nfchar = ni; > font->ascent = a[9]; > continue; > + > + /* query: 'Q' n[1] queryspec[n] */ > + case 'q': > + if(n < 2){ > + error(Eshortdraw); > + } > + m = 1+1+a[1]; > + if(n < m){ > + error(Eshortdraw); > + } > + fmtstrinit(&f); > + for(c=0; c + switch(a[2+c]){ > + default: > + error("unknown query"); > + case 'd': /* dpi */ > + if(client->forcedpi) > + fmtprint(&f, "%11d ", client->forcedpi); > + else > + fmtprint(&f, "%11d ", client->displaydpi); > + break; > + } > + } > + client->readdata = (uchar*)fmtstrflush(&f); > + if(client->readdata == nil) > + error(Enomem); > + client->nreaddata = strlen((char*)client->readdata); > + continue; > + > > /* load character: 'l' fontid[4] srcid[4] index[2] R[4*4] P[2*4] left[1] width[1] */ > case 'l': > --- a/sys/src/libdraw/init.c > +++ b/sys/src/libdraw/init.c > @@ -197,6 +197,7 @@ > Display* > initdisplay(char *dev, char *win, void(*error)(Display*, char*)) > { > + uchar *a; > char buf[128], info[NINFO+1], *t, isnew; > int n, datafd, ctlfd, reffd; > Display *disp; > @@ -319,6 +320,18 @@ > if(dir!=nil && dir->qid.vers==1) /* other way to tell */ > disp->_isnewdisplay = 1; > free(dir); > + > + a = bufimage(disp, 3); > + if(a == nil) > + goto Error5; > + a[0] = 'q'; > + a[1] = 1; > + a[2] = 'd'; > + disp->dpi = 100; > + if(flushimage(disp, 0) >= 0){ > + if((read(datafd, info, sizeof info)) == 12) > + disp->dpi = atoi(info); > + } > > return disp; > } > > -- > > 2nd Patch for plan9.ini: > > diff c7dcc82b0be805717efbe77c98eaadf3ee1e31af uncommitted > --- a/sys/man/8/plan9.ini > +++ b/sys/man/8/plan9.ini > @@ -971,6 +971,8 @@ > .BR off . > The first two specify differing levels of power saving; > the third turns the monitor off completely. > +.SS \fL*dpi=\fIvalue\fP > +This is used to specify the screen dpi. > .SS NVRAM > .SS \fLnvram=\fIfile\fP > .SS \fLnvrlen=\fIlength\fP > --- a/sys/src/9/port/devdraw.c > +++ b/sys/src/9/port/devdraw.c > @@ -765,6 +765,7 @@ > drawnewclient(void) > { > Client *cl, **cp; > + char *p; > int i; > > for(i=0; i @@ -789,7 +790,9 @@ > cl->slot = i; > cl->clientid = ++sdraw.clientid; > cl->op = SoverD; > - cl->displaydpi=100; > + if((p = getconf("dpi")) == nil || (cl->displaydpi = atoi(p)) == 0){ > + cl->displaydpi=100; > + } > sdraw.client[i] = cl; > return cl; > } > > -- > > 3rd Patch for rio/acme (proof-of-concept, just to provide an example) > > diff 75d8e460a00505c2b21a0d06ceb4300c93d9c4d6 uncommitted > --- a/sys/include/ape/draw.h > +++ b/sys/include/ape/draw.h > @@ -69,6 +69,7 @@ > Displaybufsize = 8000, > ICOSSCALE = 1024, > Borderwidth = 4, > + DefaultDPI = 100, > }; > > enum > @@ -358,6 +359,7 @@ > extern Image* namedimage(Display*, char*); > extern int nameimage(Image*, char*, int); > extern Image* allocimagemix(Display*, ulong, ulong); > +extern int scalesize(Display*, int); > > /* > * Colors > --- a/sys/include/draw.h > +++ b/sys/include/draw.h > @@ -61,6 +61,7 @@ > Displaybufsize = 8000, > ICOSSCALE = 1024, > Borderwidth = 4, > + DefaultDPI = 100, > }; > > enum > @@ -354,6 +355,7 @@ > extern Image* namedimage(Display*, char*); > extern int nameimage(Image*, char*, int); > extern Image* allocimagemix(Display*, ulong, ulong); > +extern int scalesize(Display*, int); > > /* > * Colors > --- a/sys/src/cmd/acme/dat.h > +++ b/sys/src/cmd/acme/dat.h > @@ -473,11 +473,14 @@ > BUFSIZE = Maxblock+IOHDRSZ, /* size from fbufalloc() */ > RBUFSIZE = BUFSIZE/sizeof(Rune), > EVENTSIZE = 256, > - Scrollwid = 12, /* width of scroll bar */ > - Scrollgap = 4, /* gap right of scroll bar */ > - Margin = 4, /* margin around text */ > - Border = 2, /* line between rows, cols, windows */ > }; > + > +// like in p9p c96d832 > +#define Scrollwid scalesize(display, 12) /* width of scroll bar */ > +#define Scrollgap scalesize(display, 4) /* gap right of scroll bar */ > +#define Margin scalesize(display, 4) /* margin around text */ > +#define Border scalesize(display, 2) /* line between rows, cols, windows */ > +#define ButtonBorder scalesize(display, 2) > > #define QID(w,q) ((w<<8)|(q)) > #define WIN(q) ((((ulong)(q).path)>>8) & 0xFFFFFF) > --- a/sys/src/cmd/rio/wind.c > +++ b/sys/src/cmd/rio/wind.c > @@ -12,6 +12,14 @@ > #include "dat.h" > #include "fns.h" > > +static int > +wscale(Window *w, int n) > +{ > + if(w == nil || w->i == nil) > + return n; > + return scalesize(w->i->display, n); > +} > + > Window* > wlookid(int id) > { > @@ -308,7 +316,7 @@ > else > col = lighttitlecol; > } > - border(w->i, w->i->r, Selborder, col, ZP); > + border(w->i, w->i->r, wscale(w, Selborder), col, ZP); > } > > static void > @@ -353,17 +361,17 @@ > > w->i = i; > w->mc.image = i; > - r = insetrect(i->r, Selborder+1); > + r = insetrect(i->r, wscale(w, Selborder)+wscale(w, 1)); > w->scrollr = r; > - w->scrollr.max.x = r.min.x+Scrollwid; > + w->scrollr.max.x = r.min.x+wscale(w, Scrollwid); > w->lastsr = ZR; > - r.min.x += Scrollwid+Scrollgap; > + r.min.x += wscale(w, Scrollwid)+wscale(w, Scrollgap); > frclear(w, FALSE); > frinit(w, r, w->font, w->i, cols); > wsetcols(w, w == input); > w->maxtab = maxtab*stringwidth(w->font, "0"); > if(!w->mouseopen || !w->winnameread){ > - r = insetrect(w->i->r, Selborder); > + r = insetrect(w->i->r, wscale(w, Selborder)); > draw(w->i, r, cols[BACK], nil, w->entire.min); > wfill(w); > wsetselect(w, w->q0, w->q1); > @@ -370,7 +378,7 @@ > wscrdraw(w); > } > if(w == input) > - wborder(w, Selborder); > + wborder(w, wscale(w, Selborder)); > else > wborder(w, Unselborder); > flushimage(display, 1); > @@ -390,9 +398,9 @@ > if(!w->mouseopen || !w->winnameread) > frredraw(w); > if(w == input) > - wborder(w, Selborder); > + wborder(w, wscale(w, Selborder)); > else > - wborder(w, Unselborder); > + wborder(w, wscale(w, Unselborder)); > } > > static void > @@ -401,9 +409,9 @@ > Rectangle r; > > if(w == input) > - wborder(w, Selborder); > + wborder(w, wscale(w, Selborder)); > else > - wborder(w, Unselborder); > + wborder(w, wscale(w, Unselborder)); > r = insetrect(w->i->r, Selborder); > draw(w->i, r, w->cols[BACK], nil, w->entire.min); > wfill(w); > @@ -1249,7 +1257,7 @@ > > w = emalloc(sizeof(Window)); > w->screenr = i->r; > - r = insetrect(i->r, Selborder+1); > + r = insetrect(i->r, wscale(w, Selborder)+wscale(w, 1)); > w->i = i; > w->mc = *mc; > w->ck = ck; > @@ -1263,9 +1271,9 @@ > w->complete = chancreate(sizeof(Completion*), 0); > w->gone = chancreate(sizeof(char*), 0); > w->scrollr = r; > - w->scrollr.max.x = r.min.x+Scrollwid; > + w->scrollr.max.x = r.min.x+wscale(w, Scrollwid); > w->lastsr = ZR; > - r.min.x += Scrollwid+Scrollgap; > + r.min.x += wscale(w, Scrollwid)+wscale(w, Scrollgap); > frinit(w, r, font, i, cols); > w->maxtab = maxtab*stringwidth(font, "0"); > w->topped = ++topped; > @@ -1274,9 +1282,9 @@ > w->scrolling = scrolling; > w->dir = estrdup(startdir); > w->label = estrdup(""); > - r = insetrect(w->i->r, Selborder); > + r = insetrect(w->i->r, wscale(w, Selborder)); > draw(w->i, r, cols[BACK], nil, w->entire.min); > - wborder(w, Selborder); > + wborder(w, wscale(w, Selborder)); > wscrdraw(w); > incref(w); /* ref will be removed after mounting; avoids delete before ready to be deleted */ > return w; > --- a/sys/src/libdraw/init.c > +++ b/sys/src/libdraw/init.c > @@ -452,5 +465,13 @@ > p = d->bufp; > d->bufp += n; > return p; > +} > + > +int > +scalesize(Display *d, int n) > +{ > + if(d == nil || d->dpi <= DefaultDPI) > + return n; > + return (n*d->dpi+DefaultDPI/2)/DefaultDPI; > } > > -- > > 4th Patch (drawterm-metal-cocoa - I've been using this most of the time): > > diff 0b7990cf2b84e7a80cf3f3a9e7eadca10d51a2c5 uncommitted > --- a/include/draw.h > +++ b/include/draw.h > @@ -193,6 +193,7 @@ > Image *windows; > Image *screenimage; > int _isnewdisplay; > + int dpi; > }; > > struct Image > --- a/kern/devdraw.c > +++ b/kern/devdraw.c > @@ -76,6 +76,8 @@ > int refreshme; > int infoid; > int op; > + int displaydpi; > + int forcedpi; > }; > > struct Refresh > @@ -166,6 +168,8 @@ > Client* drawclientofpath(ulong); > DImage* allocdimage(Memimage*); > > +int displaydpi = 200; > + > static char Enodrawimage[] = "unknown id for draw image"; > static char Enodrawscreen[] = "unknown id for draw screen"; > static char Eshortdraw[] = "short draw message"; > @@ -783,6 +787,7 @@ > cl->slot = i; > cl->clientid = ++sdraw.clientid; > cl->op = SoverD; > + cl->displaydpi = displaydpi; > sdraw.client[i] = cl; > return cl; > } > @@ -1408,6 +1413,7 @@ > int c, repl, m, y, dstid, scrnid, ni, ci, j, nw, e0, e1, op, ox, oy, oesize, esize, doflush; > uchar *u, *a, refresh; > char *fmt; > + Fmt f; > ulong value, chan; > Rectangle r, clipr; > Point p, q, *pp, sp; > @@ -1654,6 +1660,34 @@ > memset(font->fchar, 0, ni*sizeof(FChar)); > font->nfchar = ni; > font->ascent = a[9]; > + continue; > + > + /* query: 'Q' n[1] queryspec[n] */ > + case 'q': > + if(n < 2) > + error(Eshortdraw); > + m = 1+1+a[1]; > + if(n < m) > + error(Eshortdraw); > + fmtstrinit(&f); > + for(c=0; c + switch(a[2+c]){ > + default: > + error("unknown query"); > + break; > + case 'd': /* dpi */ > + if(client->forcedpi) > + fmtprint(&f, "%11d ", client->forcedpi); > + else { > + fmtprint(&f, "%11d ", client->displaydpi); > + } > + break; > + } > + } > + client->readdata = (uchar*)fmtstrflush(&f); > + if(client->readdata == nil) > + error(Enomem); > + client->nreaddata = strlen((char*)client->readdata); > continue; > > /* load character: 'l' fontid[4] srcid[4] index[2] R[4*4] P[2*4] left[1] width[1] */ > >