logo

drewdevault.com

[mirror] blog and personal website of Drew DeVault git clone https://hacktivis.me/git/mirror/drewdevault.com.git

Status-update-November-2020.md (6630B)


  1. ---
  2. title: Status update, November 2020
  3. date: 2020-11-15
  4. outputs: [html, gemtext]
  5. ---
  6. Greetings, humanoids! Our fleshy vessels have aged by 2.678×10⁶ seconds, and you
  7. know what that means: time for another status update! Pour a cup of your
  8. favorite beverage stimulant and gather 'round for some news.
  9. First off, today is the second anniversary of SourceHut's alpha being opened to
  10. the public, and as such, I've prepared a special [blog post][sr.ht 2 years] for
  11. you to read. I'll leave the sr.ht details out of this post and just send you off
  12. to read about it there.
  13. [sr.ht 2 years]: https://sourcehut.org/blog/2020-11-15-sourcehut-2-year-alpha/
  14. What else is new? Well, a few things. For one, I've been working more on Gemini.
  15. I added CGI support to [gmnisrv](https://sr.ht/~sircmpwn/gmnisrv) and wrote a
  16. few [CGI scripts](https://git.sr.ht/~sircmpwn/cgi-scripts) to do neato Gemini
  17. things with. I've also added regexp routing and URL rewriting support. We can
  18. probably ship gmnisrv 1.0 as soon as the last few bugs are flushed out, and a
  19. couple of minor features are added, and we might switch to another SSL
  20. implementation as well. Thanks to the many contributors who've helped out:
  21. William Casarin, Tom Lebreux, Kenny Levinsen, Eyal Sawady, René Wagner,
  22. dbandstra, and mbays.
  23. In [BARE](https://baremessages.org) news: Elm, Erlang, Java, and Ruby
  24. implementations have appeared, and I have submitted a
  25. [draft RFC](https://datatracker.ietf.org/doc/draft-devault-bare/) to the IETF
  26. for standardization.
  27. Finally, I wrote a new Wayland server for you. Its only dependencies are a POSIX
  28. system and a C11 compiler — and it works with Nvidia GPUs, or even systems
  29. without OpenGL support at all. Here's the code:
  30. ```c
  31. #include <poll.h>
  32. #include <signal.h>
  33. #include <stdint.h>
  34. #include <stdio.h>
  35. #include <stdlib.h>
  36. #include <string.h>
  37. #include <sys/ioctl.h>
  38. #include <sys/mman.h>
  39. #include <sys/socket.h>
  40. #include <sys/un.h>
  41. #include <time.h>
  42. #include <unistd.h>
  43. typedef int16_t i16; typedef int32_t i32; typedef uint16_t u16;
  44. typedef uint32_t u32; typedef uint8_t u8; typedef int I; typedef size_t S;
  45. typedef struct{int b;u32 a,c,d;char*e;i32 x,y,w,h,s,fmt;}O;
  46. typedef struct{char*a;u32 b;I(*c)(I,I,u32,u16);}G;
  47. struct pollfd fds[33];char a[0xFFFF];I b=0,c=1,d=-1;u32 e=0;
  48. O f[128][128];G g[];
  49. #define AR I z,I y,u32 x,u16 c
  50. #define SN(n) (((n)%4)==0?(n):(n)+(4-((n)%4)))
  51. void u8w(FILE*f,u32 ch){char b[4];for (I i=2;i>0;--i){b[i]=(ch&0x3f)|0x80;ch>>=6
  52. ;}b[0]=ch|0xE0;fwrite(b,1,3,f);}void xrgb(u32*data,i32 w,i32 h,i32 s){struct
  53. winsize sz;ioctl(0,TIOCGWINSZ,&sz);--sz.ws_row;printf("\x1b[H\x1b[2J\x1b[3J");
  54. 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
  55. 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[((
  56. y*4+my)*h)/(sz.ws_row*4)*(s/4)+((x*2+mx)*w)/(sz.ws_col*2)];u8 avg=((p&0xFF)+((p
  57. >>8)&0xFF)+((p>>16)&0xFF))/3;if(avg>0x80)c|=1<<f[i++];}u8w(stdout,c);}putchar(
  58. '\n');}fflush(stdout);}O*ao(I z,u32 y,I x){for(S i=0;i<128;++i)if(f[z][i].a==0){
  59. 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<
  60. 128;++i)if(f[z][i].a==y)return &f[z][i];return 0;}void wh(I z,i32 y,i16 x, i16 w
  61. ){write(z,&y,4);i32 u=((w+8)<<16)|x;write(z,&u,4);}void ws(I z,char*y){i32 l=
  62. 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=
  63. 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,
  64. 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
  65. (y,t,0,4);write(y,&s,4);--s;break;case 6:s=0;break;default:return sz;}wh(y,t,0,4
  66. );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);
  67. O *o=ao(z,w,15);o->e=mmap(0,u,PROT_READ,MAP_PRIVATE,t,0);return 8;}I gc(AR){u32
  68. 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
  69. :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
  70. ((u32*)b->e,b->w,b->h,b->s);}wh(y,u,0,0);return 12;case 2:read(y,&u,4);read(y, &
  71. u, 4);read(y, &u, 4);read(y, &u, 4);return 16;case 3:read(y,&w,4);struct timespec
  72. ts={.tv_sec=0,.tv_nsec=1.6e6};nanosleep(&ts,0);wh(y,w,0,4);write(y,&w,4);return
  73. 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
  74. 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);
  75. write(y,&e,4);++e;}break;}return 0;}I ge(AR){u32 w,u;if(c==2){read(y,&w,4);read(
  76. 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
  77. ;switch(c){case 1:read(y,&w,4);O*obj=ao(z,w,13);obj->d=x;go(z,x)->c=w;return 4;
  78. case 4:read(y,&ae,4);return 4;}return 0;}I gg(AR){I sz;switch(c){case 2:sz=rs(y)
  79. ;return sz;}return 0;}I gh(AR){i32 w,u;switch(c){case 0:read(y,&w,4);read(y,&u,4
  80. );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->
  81. s,4);read(y,&b->fmt,4);return 24;}return 0;}
  82. G g[]={{0,0,ga},{"wl_shm",1,gb},{"wl_compositor",1,gc},{"wl_subcompositor",1,0},
  83. {"wl_data_device_manager",3,0},{"wl_output",3,0},{"wl_seat",7,0},{"xdg_wm_base",
  84. 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}};
  85. void gi(AR){u32 w;switch(c){case 0:read(y,&w,4);wh(y,w,0,4);write(y,&w,4);break;
  86. case 1:read(y,&w,4);ao(z,w,0);for(S i=0;i<sizeof(g)/sizeof(g[0]);){G*z=&g[i++];
  87. 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,
  88. z->a);write(y,&z->b,4);}break;}}void si(){c=0;}
  89. I main(I _1,char**_2){I z=socket(AF_UNIX,SOCK_STREAM,0);struct sockaddr_un y={.
  90. sun_family=AF_UNIX};char *x=getenv("XDG_RUNTIME_DIR");if(!x)x="/tmp";do{sprintf(
  91. y.sun_path,"%s/wayland-%d",x,c++);}while(access(y.sun_path,F_OK)==0);bind(z, (
  92. struct sockaddr *)&y,sizeof(y));listen(z,3);for(S i=0;i<sizeof(fds);++i){fds[i].
  93. events=POLLIN|POLLHUP;fds[i].revents=0;fds[i].fd=0;}fds[b++].fd=z;signal(SIGINT,
  94. si);memset(&f,0,sizeof(f));while(poll(fds,b,-1)!=-1&&c){if(fds[0].revents){I u=
  95. accept(z,0,0);fds[b++].fd=u;}for(I i=1;i<b;++i){if(fds[i].revents&POLLHUP){
  96. memmove(&fds[i],&fds[i+1],32-i);memset(f[i-1],0,128*sizeof(**f));--b;continue;}
  97. else if(!fds[i].revents){continue;}I u=i-1;I t=fds[i].fd;u32 s,r;char q[
  98. CMSG_SPACE(8)];struct cmsghdr *p;struct iovec n={.iov_base=&s,.iov_len=4};struct
  99. msghdr m={0};m.msg_iov=&n;m.msg_iovlen=1;m.msg_control=q;m.msg_controllen=sizeof
  100. (q);recvmsg(t,&m,0);p=CMSG_FIRSTHDR(&m);if(p){d=*(I *)CMSG_DATA(p);}read(t,&r,4)
  101. ;u16 o=((r>>16)&0xFFFF)-8,c=r&0xFFFF;if(s==1){gi(u,t,s,c);}else{for(S j=0;j<128;
  102. ++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)
  103. {read(t,a,o);}}}}unlink(y.sun_path);}
  104. ```
  105. You're welcome!