From: hiro <23hiro@gmail.com>
To: 9front@9front.org
Subject: Re: [9front] hidpi
Date: Mon, 20 Dec 2021 17:34:10 +0100 [thread overview]
Message-ID: <CAFSF3XOJmR4QwNf4764kvq4PorjSB7WEpbh_AVBzA-8wKYiULQ@mail.gmail.com> (raw)
In-Reply-To: <fY4WlDcUa0tGFTLGmEv-NDWLzJwXsUPnq2RK3-w9N1E35Bo3N8nIXTI-BwvNAmMRQtDb_oIH63c0uucUhbK38DilSs3LuWfGeJ1vAluIggw=@protonmail.com>
you didn't document this in the devdraw man page. are you sure though
that we need to do this on devdraw level?
On 12/20/21, Philip Silva <philip.silva@protonmail.com> wrote:
> I've been creating patches to enable hidpi to make scrollbars bigger when
> using > 100 dpi. It's basically 3 patches: 1st one for adding int
> displaydpi, 2nd one for adding an entry to plan9.ini and a 3rd very
> experimental one that changes scrollbar and border widths including some
> glitches. (And a 4th one that hardcodes 200 dpi in drawterm-metal-cocoa) The
> extra fields and most code is just copied from plan9port. (d0e0701, c96d832)
> I'm using this since a few months now and it works, the only problems I
> had:
>
> - system wouldn't boot anymore when only applying the libdraw part of the
> 1st patch (I fixed that and checked in a fresh install in a VM that it would
> just ignore when the new draw command q1d isn't present in devdraw)
> - glitches: the borders aren't calculated correctly (3rd patch for rio and
> acme is very wip)
> - despite the glitches it works reasonably well with acme and rio but some
> applications are quite small then. Not sure how much effort it would be to
> patch for compat. with dpi != 100
>
> There is also the field forcedpi that is left largely ignored but generally
> is supposed to override displaydpi when necessary.
>
> Greetings, Philip
>
>
> --
>
>
> 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<a[1]; 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<sdraw.nclient; 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("<unnamed>");
> - 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<a[1]; 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] */
>
>
>
next prev parent reply other threads:[~2021-12-20 16:40 UTC|newest]
Thread overview: 20+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-12-20 16:13 Philip Silva
2021-12-20 16:34 ` hiro [this message]
2021-12-20 17:04 ` [9front] hidpi Philip Silva
2021-12-20 17:29 ` hiro
2021-12-20 19:15 ` Noam Preil
2021-12-20 19:34 ` ori
2021-12-20 20:50 ` ori
2021-12-20 21:10 ` hiro
2021-12-20 21:19 ` ori
2021-12-20 22:02 ` sirjofri
2021-12-21 0:29 ` Philip Silva
2021-12-21 8:37 ` hiro
2021-12-20 21:47 ` Noam Preil
2021-12-20 17:59 ` [9front] hidpi igor
2021-12-20 18:28 ` hiro
2021-12-20 19:27 ` Noam Preil
2021-12-20 19:02 ` Philip Silva
2021-12-22 8:39 ` igor
2021-12-22 11:31 ` Philip Silva
2021-12-23 13:11 igor
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=CAFSF3XOJmR4QwNf4764kvq4PorjSB7WEpbh_AVBzA-8wKYiULQ@mail.gmail.com \
--to=23hiro@gmail.com \
--cc=9front@9front.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
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).