shithub: pain

ref: 0cd1f6455c02fe0c2ade3e630debb315f054b253
dir: /fs.c/

View raw version
#include <u.h>
#include <libc.h>
#include <fcall.h>
#include <thread.h>
#include <draw.h>
#include <9p.h>

#include "dat.h"
#include "fns.h"

static void fsstart(Srv *);
static void fsend(Srv *);
static void fswrite(Req *);
static void fsread(Req *);

static char * canvasread(Req *);
static char * canvaswrite(Req *);
static int FsPID = -1;

typedef struct FileEntry {
	char * name;
	char * (*read) (Req *);
	char * (*write) (Req *);
	int mode;
} FileEntry;

FileEntry entries[] = {
	{"canvas", canvasread, canvaswrite, 0666 }
};
static Image * CanvasReadImage = nil;
static long CanvasReadReady = 0;
static char * FsName = nil;

Srv s = {
	.start = fsstart,
	.end = fsend,
	.read = fsread,
	.write = fswrite,
};

static void
fsstart(Srv *)
{
	File * r, * t;
	char * u;
	int i;

	u = getuser();
	if ((s.tree = alloctree(u, u, 0555, nil)) == nil)
		sysfatal("alloctree: %r");

	r = s.tree->root;
	if ((t = createfile(r, FsName, u, DMDIR | 0555, nil)) == nil)
		sysfatal("createfile: %r");
	
	for (i = 0; i < ARRLEN(entries); i++)
		if (createfile(t, entries[i].name, u, entries[i].mode, &entries[i]) == nil)
			sysfatal("createfile: %r");
	FsPID = getpid();
}

static void
fsend(Srv *)
{
	exits(nil);
}

static void
fsread(Req * r)
{
	FileEntry * e;
	r->ofcall.count = 0;
	e = r->fid->file->aux;
	respond(r, e->read(r));
}

static void
fswrite(Req * r)
{
	FileEntry * e;
	e = r->fid->file->aux;
	respond(r, e->write(r));
}

static char *
canvasread(Req * r)
{
	uchar * b;
	int n;
	char hdr[11+5*12+1], cbuf[20];
	
	if ((CanvasReadImage = namedimage(display, "pain.view")) == nil) {
		return "no view image";
	}

	sprint(hdr, "%11s %11d %11d %11d %11d ",
			chantostr(cbuf, CanvasReadImage->chan), 
			CanvasReadImage->r.min.x, 
			CanvasReadImage->r.min.y, 
			CanvasReadImage->r.max.x, 
			CanvasReadImage->r.max.y
	);
	
	n = bytesperline(CanvasReadImage->r, CanvasReadImage->depth) * Dy(CanvasReadImage->r);
	b = emalloc9p(n + sizeof(hdr));
	memcpy(b, hdr, sizeof(hdr));
	b += sizeof(hdr);
	if (b != nil) {
		unloadimage(CanvasReadImage, CanvasReadImage->r, b, n);
		b -= sizeof(hdr);
		readbuf(r, b, n + sizeof(hdr));
		free(b);
	}

	return nil;
}

static char *
canvaswrite(Req *)
{
	return nil;
}

int
fsinit(char * name)
{
	FsName = name;
	postmountsrv(&s, name, "/n", MBEFORE);
	return 1;
}

void
fsclose(void)
{
	if (FsPID < 0)
		return;

	postnote(PNGROUP, FsPID, "shutdown");
}