ref: d2a70ae3ee19a6e74e3ad1fcc568c26d1dbe227b
parent: 6ac9d2d939ba0a61aacc3c7772ee512c3b2d6b6a
author: sirjofri <sirjofri@sirjofri.de>
date: Mon Jan 6 17:08:59 EST 2025
first working drawfs
--- a/drawfs/fns.h
+++ b/drawfs/fns.h
@@ -1,1 +1,3 @@
-void initfs(char *srvname);
+void initfs(char *srvname, Channel *chan);
+void initcmd(char *srvname, Channel *chan);
+void readscreenimage(Req *r, int full);
--- a/drawfs/fs.c
+++ b/drawfs/fs.c
@@ -17,9 +17,10 @@
#define nexterror()
#define poperror()
+Channel *fschannel = nil;
+
enum {
Qroot,
- /* potential files like cons and mouse */
Qwinname,
Qdevdraw,
Qnew,
@@ -232,6 +233,72 @@
qunlock(&drawlock);
}
+static uchar *fullimage = nil;
+static ulong fullimagelen = 0;
+static uchar *rectimage = nil;
+static ulong rectimagelen = 0;
+
+void
+prepscreenimage(int full)
+{
+ Rectangle r;
+ uchar *ptr, *p;
+ int bpl, nlines, n;
+ char cbuf[20];
+ ulong nbytes;
+
+ r = full ? screenimage->r : flushrect;
+ bpl = bytesperline(r, screenimage->depth);
+ nlines = Dy(r);
+
+ nbytes = 5*12 + bpl*nlines;
+
+ ptr = malloc(nbytes);
+ if (!ptr)
+ sysfatal("not enough memory: %r");
+
+ if (full) {
+ fullimage = ptr;
+ fullimagelen = nbytes;
+ } else {
+ rectimage = ptr;
+ rectimagelen = nbytes;
+ }
+
+ n = sprint((char*)ptr, "%11s %11d %11d %11d %11d ",
+ chantostr(cbuf, screenimage->chan), r.min.x, r.min.y, r.max.x, r.max.y);
+
+ p = ptr + n;
+
+ fprint(2, "copying: %R\n", r);
+
+ for (; r.min.y < r.max.y; r.min.y++) {
+ memcpy(p, byteaddr(screenimage, r.min), bpl);
+ p += bpl;
+ }
+ fprint(2, "copied %ulld bytes\n", p - ptr);
+}
+
+void
+readscreenimage(Req *r, int full)
+{
+ uchar *data;
+ ulong len;
+
+ if (!screenimage)
+ return;
+ data = full ? fullimage : rectimage;
+ if (!data) {
+ dlock();
+ prepscreenimage(full);
+ dunlock();
+ data = full ? fullimage : rectimage;
+ }
+ len = full ? fullimagelen : rectimagelen;
+
+ readbuf(r, data, len);
+}
+
static int
drawcmp(char *a, char *b, int n)
{
@@ -326,10 +393,21 @@
}
void
-flushmemscreen(Rectangle)
+flushmemscreen(Rectangle r)
{
// stub
// TODO: send update message?
+
+ if (fullimage)
+ free(fullimage);
+ if (rectimage)
+ free(rectimage);
+ fullimage = nil;
+ rectimage = nil;
+ fullimagelen = 0;
+ rectimagelen = 0;
+
+ chanprint(fschannel, "r%R\n", r);
}
static void
@@ -416,6 +494,7 @@
i = allocmemimage(r, chan);
if (!i)
return nil;
+ memfillcolor(i, 0x00ffeeff);
di = allocdimage(i);
if (!di) {
@@ -2168,7 +2247,7 @@
}
void
-initfs(char *srvname)
+initfs(char *srvname, Channel *chan)
{
if (memimageinit() != 0) {
werrstr("memimageinit: %r");
@@ -2182,5 +2261,7 @@
}
dunlock();
- postsrv(&fs, srvname);
+ fschannel = chan;
+
+ threadpostsrv(&fs, srvname);
}
--- a/drawfs/main.c
+++ b/drawfs/main.c
@@ -1,7 +1,8 @@
#include <u.h>
#include <libc.h>
-#include <draw.h>
-#include <memdraw.h>
+#include <thread.h>
+#include <fcall.h>
+#include <9p.h>
#include "dat.h"
#include "fns.h"
@@ -14,16 +15,13 @@
exits("usage");
}
-int fscmdfd;
-int fsdispfd;
+char *name = nil;
+char srvname[256];
void
-main(int argc, char **argv)
+threadmain(int argc, char **argv)
{
- char file[256];
- char *name = nil;
- int p[2];
- int fd;
+ Channel *c;
ARGBEGIN{
case 'n':
@@ -41,24 +39,10 @@
name = smprint("%d", getpid());
}
- snprint(file, sizeof file, "drawfs.%s", name);
- initfs(file);
+ snprint(srvname, sizeof srvname, "drawfs.%s", name);
- exits(0);
+ c = chancreate(sizeof(char*), 0);
- pipe(p);
- snprint(file, sizeof file, "/srv/drawfs.%s.cmd", name);
- fd = create(file, OWRITE|ORCLOSE, 0666);
- fprint(fd, "%d", p[0]);
- fscmdfd = p[1];
- close(fd);
- close(p[0]);
-
- pipe(p);
- snprint(file, sizeof file, "/srv/drawfs.%s.display", name);
- fd = create(file, OWRITE|ORCLOSE, 0666);
- fprint(fd, "%d", p[0]);
- fsdispfd = p[1];
- close(fd);
- close(p[0]);
+ initfs(srvname, c);
+ initcmd(srvname, c);
}
--- a/drawfs/mkfile
+++ b/drawfs/mkfile
@@ -5,6 +5,7 @@
main.$O\
fs.$O\
draw.$O\
+ cmd.$O\
HFILES=\
fns.h\
--- a/mkfile
+++ b/mkfile
@@ -1,7 +1,9 @@
+DIRS=drawfs consfs mousefs drawmgr
+
all:V:
- @{ cd drawfs && mk $MKFLAGS }
- @{ cd drawmgr && mk $MKFLAGS }
+ for (d in $DIRS)
+ @{ cd $d && mk $MKFLAGS }
install:V:
- @{ cd drawfs && mk $MKFLAGS install }
- @{ cd drawmgr && mk $MKFLAGS install }
+ for (d in $DIRS)
+ @{ cd $d && mk $MKFLAGS install }
--- a/words
+++ b/words
@@ -22,20 +22,30 @@
FILESYSTEM
+A
- default /dev/draw layout (basically copy devdraw.c code)
-- (additional cons+mouse stuff)
- post fs to /srv/drawfs.NAME
+B
+- ctl (message pipe)
+- display (screen image)
+- refresh (updated rectangle)
+- post fs to /srv/drawfs.NAME.cmd
THREADS
- filesystem thread (/srv/drawfs.NAME+mount)
-- display image (/srv/drawfs.NAME.display)
-- console access (/srv/drawfs.NAME.cmd)
+
+MESSAGE PIPE (ctl file)
+
- note when display changes (refresh)
+ - refresh rectangle
- resize events
- - how to syncronize pipe? when to read/write? poll?
+ - how to syncronize pipe?
RESIZE
-mgr -----> fs.cmd
+ctl -------------> fs.cmd
r x[4] y[4] (resize x, y)
+
+fs.cmd ----------> ctl
+r refresh from refresh image (Rectangle)
--
⑨