logo

drewdevault.com

[mirror] blog and personal website of Drew DeVault
commit: e5735e169fda7e27f613fa63764870eac43d8871
parent 43288a41ca6d88df07ee39ec10f364170f16108c
Author: Drew DeVault <sir@cmpwn.com>
Date:   Sun, 15 Nov 2020 10:21:50 -0500

Status update

Diffstat:

Acontent/blog/Status-update-November-2020.md120+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 120 insertions(+), 0 deletions(-)

diff --git a/content/blog/Status-update-November-2020.md b/content/blog/Status-update-November-2020.md @@ -0,0 +1,120 @@ +--- +title: Status update, November 2020 +date: 2020-11-15 +#outputs: [html, gemtext] +--- + +Greetings, humanoids! Our fleshy vessels have aged by 2.678×10⁶ seconds, and you +know what that means: time for another status update! Pour a cup of your +favorite beverage stimulant and gather 'round for some news. + +First off, today is the second anniversary of SourceHut's alpha being opened to +the public, and as such, I've prepared a special [blog post][sr.ht 2 years] for +you to read. I'll leave the sr.ht details out of this post and just send you off +to read about it there. + +[sr.ht 2 years]: https://sourcehut.org/blog/2020-11-15-sourcehut-2-year-alpha/ + +What else is new? Well, a few things. For one, I've been working more on Gemini. +I added CGI support to [gmnisrv](https://sr.ht/~sircmpwn/gmnisrv) and wrote a +few [CGI scripts](https://git.sr.ht/~sircmpwn/cgi-scripts) to do neato Gemini +things with. I've also added regexp routing and URL rewriting support. We can +probably ship gmnisrv 1.0 as soon as the last few bugs are flushed out, and a +couple of minor features are added, and we might switch to another SSL +implementation as well. Thanks to the many contributors who've helped out: +William Casarin, Tom Lebreux, Kenny Levinsen, Eyal Sawady, René Wagner, +dbandstra, and mbays. + +In [BARE](https://baremessages.org) news: Elm, Erlang, Ruby, Java, and Ruby +implementations have appeared, and I have submitted a +[draft RFC](https://datatracker.ietf.org/doc/draft-devault-bare/) to the IETF +for standardization. + +Finally, I wrote a new Wayland server for you. Its only dependencies are a POSIX +system and a C11 compiler &mdash; and it works with Nvidia GPUs, or even systems +without OpenGL support at all. Here's the code: + +```c +#include <poll.h> +#include <signal.h> +#include <stdint.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <sys/ioctl.h> +#include <sys/mman.h> +#include <sys/socket.h> +#include <sys/un.h> +#include <time.h> +#include <unistd.h> + + typedef int16_t i16; typedef int32_t i32; typedef uint16_t u16; + typedef uint32_t u32; typedef uint8_t u8; typedef int I; typedef size_t S; + typedef struct{int b;u32 a,c,d;char*e;i32 x,y,w,h,s,fmt;}O; + typedef struct{char*a;u32 b;I(*c)(I,I,u32,u16);}G; + + struct pollfd fds[33];char a[0xFFFF];I b=0,c=1,d=-1;u32 e=0; + O f[128][128];G g[]; + +#define AR I z,I y,u32 x,u16 c +#define SN(n) (((n)%4)==0?(n):(n)+(4-((n)%4))) + +void u8w(FILE*f,u32 ch){char b[4];for (I i=2;i>0;--i){b[i]=(ch&0x3f)|0x80;ch>>=6 +;}b[0]=ch|0xE0;fwrite(b,1,3,f);}void xrgb(u32*data,i32 w,i32 h,i32 s){struct +winsize sz;ioctl(0,TIOCGWINSZ,&sz);--sz.ws_row;printf("\x1b[H\x1b[2J\x1b[3J"); +for(I y=0;y<sz.ws_row;++y){for(I x=0;x<sz.ws_col;++x){I i=0;u32 c = 0x2800;const +I f[]={0,3,1,4,2,5,6,7};for(I my=0;my<4;++my)for(I mx=0;mx<2;++mx){u32 p=data[(( +y*4+my)*h)/(sz.ws_row*4)*(s/4)+((x*2+mx)*w)/(sz.ws_col*2)];u8 avg=((p&0xFF)+((p +>>8)&0xFF)+((p>>16)&0xFF))/3;if(avg>0x80)c|=1<<f[i++];}u8w(stdout,c);}putchar( +'\n');}fflush(stdout);}O*ao(I z,u32 y,I x){for(S i=0;i<128;++i)if(f[z][i].a==0){ +f[z][i].a=y;f[z][i].b=x;return &f[z][i];}return 0;}O*go(I z,u32 y){for(S i=0;i< +128;++i)if(f[z][i].a==y)return &f[z][i];return 0;}void wh(I z,i32 y,i16 x, i16 w +){write(z,&y,4);i32 u=((w+8)<<16)|x;write(z,&u,4);}void ws(I z,char*y){i32 l= +strlen(y)+1;write(z,&l,4);l=SN(l);write(z,y,l);}I rs(I z){u32 l;read(z,&l,4);l= +SN(l);read(z,a,l);return l+4;}I ga(I z,I y,u32 x,u16 w){u32 b,u,t,s=0;read(y,&u, +4);I sz=rs(y)+12;read(y,&b,4);read(y,&t,4);--u;ao(z,t,u);switch(u){case 1:++s;wh +(y,t,0,4);write(y,&s,4);--s;break;case 6:s=0;break;default:return sz;}wh(y,t,0,4 +);write(y,&s,4);return sz;}I gb(AR){u32 w,u;read(y,&w,4);I t=d;d=-1;read(y,&u,4); +O *o=ao(z,w,15);o->e=mmap(0,u,PROT_READ,MAP_PRIVATE,t,0);return 8;}I gc(AR){u32 +w;read(y,&w,4);ao(z,w,8+c);return 4;}I gd(AR){O*o,*r,*t;i32 u,w;switch(c){case 1 +:read(y,&u,4);read(y,&w,4);read(y,&w,4);go(z,x)->d=u;if(!u==0){O *b=go(z,u);xrgb +((u32*)b->e,b->w,b->h,b->s);}wh(y,u,0,0);return 12;case 2:read(y,&u,4);read(y, & +u, 4);read(y, &u, 4);read(y, &u, 4);return 16;case 3:read(y,&w,4);struct timespec +ts={.tv_sec=0,.tv_nsec=1.6e6};nanosleep(&ts,0);wh(y,w,0,4);write(y,&w,4);return +4;case 6:o=go(z,x);r=go(z,o->c);if(r&&r->b==12){t=go(z,r->c);if(t->b==13){u32 +s=0; wh(y,t->a,0,12);write(y,&s,4);write(y,&s,4);write(y,&s,4);}wh(y,r->a,0,4); +write(y,&e,4);++e;}break;}return 0;}I ge(AR){u32 w,u;if(c==2){read(y,&w,4);read( +y,&u,4);O*o=ao(z,w,12);o->d=u;go(z,u)->c=w;return 8;}return 0;}I gf(AR){u32 w,ae +;switch(c){case 1:read(y,&w,4);O*obj=ao(z,w,13);obj->d=x;go(z,x)->c=w;return 4; +case 4:read(y,&ae,4);return 4;}return 0;}I gg(AR){I sz;switch(c){case 2:sz=rs(y) +;return sz;}return 0;}I gh(AR){i32 w,u;switch(c){case 0:read(y,&w,4);read(y,&u,4 +);O*b=ao(z,w,10);b->e=&go(z,x)->e[u];read(y,&b->w,4);read(y,&b->h,4);read(y,&b-> + s,4);read(y,&b->fmt,4);return 24;}return 0;} + +G g[]={{0,0,ga},{"wl_shm",1,gb},{"wl_compositor",1,gc},{"wl_subcompositor",1,0}, +{"wl_data_device_manager",3,0},{"wl_output",3,0},{"wl_seat",7,0},{"xdg_wm_base", +2,ge},{0,0,gd},{0,0,0},{0,0,0},{0,0,0},{0,0,gf},{0,0,gg},{0,0,0},{0,0,gh}}; + +void gi(AR){u32 w;switch(c){case 0:read(y,&w,4);wh(y,w,0,4);write(y,&w,4);break; +case 1:read(y,&w,4);ao(z,w,0);for(S i=0;i<sizeof(g)/sizeof(g[0]);){G*z=&g[i++]; +if(!z->b)continue;I gl=strlen(z->a)+1;wh(y,w,0,4+SN(gl)+4+4);write(y,&i,4);ws(y, + z->a);write(y,&z->b,4);}break;}}void si(){c=0;} + +I main(I _1,char**_2){I z=socket(AF_UNIX,SOCK_STREAM,0);struct sockaddr_un y={. +sun_family=AF_UNIX};char *x=getenv("XDG_RUNTIME_DIR");if(!x)x="/tmp";do{sprintf( + y.sun_path,"%s/wayland-%d",x,c++);}while(access(y.sun_path,F_OK)==0);bind(z, ( +struct sockaddr *)&y,sizeof(y));listen(z,3);for(S i=0;i<sizeof(fds);++i){fds[i]. +events=POLLIN|POLLHUP;fds[i].revents=0;fds[i].fd=0;}fds[b++].fd=z;signal(SIGINT, +si);memset(&f,0,sizeof(f));while(poll(fds,b,-1)!=-1&&c){if(fds[0].revents){I u= +accept(z,0,0);fds[b++].fd=u;}for(I i=1;i<b;++i){if(fds[i].revents&POLLHUP){ +memmove(&fds[i],&fds[i+1],32-i);memset(f[i-1],0,128*sizeof(**f));--b;continue;} +else if(!fds[i].revents){continue;}I u=i-1;I t=fds[i].fd;u32 s,r;char q[ +CMSG_SPACE(8)];struct cmsghdr *p;struct iovec n={.iov_base=&s,.iov_len=4};struct +msghdr m={0};m.msg_iov=&n;m.msg_iovlen=1;m.msg_control=q;m.msg_controllen=sizeof +(q);recvmsg(t,&m,0);p=CMSG_FIRSTHDR(&m);if(p){d=*(I *)CMSG_DATA(p);}read(t,&r,4) +;u16 o=((r>>16)&0xFFFF)-8,c=r&0xFFFF;if(s==1){gi(u,t,s,c);}else{for(S j=0;j<128; +++j){if(f[u][j].a==s&&g[f[u][j].b].c){o-=g[f[u][j].b].c(u,t,s,c);break;}}if(o>0) + {read(t,a,o);}}}}unlink(y.sun_path);} +``` + +You're welcome!