ref: aea23b76b347d68d5c75d51065c1982acd23ee07
dir: /fs.c/
#include <u.h>
#include <libc.h>
#include <fcall.h>
#include <thread.h>
#include <draw.h>
#include <9p.h>
#include <stdio.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 char * colorread(Req *);
static char * colorwrite(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 },
{"color", colorread, colorwrite, 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);
}
freeimage(CanvasReadImage);
return nil;
}
static char *
canvaswrite(Req *)
{
return nil;
}
static char *
colorread(Req * r)
{
char b[10];
u32int p[4];
Image * br;
br = namedimage(display, "pain.brush");
if (br == nil) {
return "failed to get brush image";
}
unloadimage(br, br->r, (uchar*)p, sizeof(p));
snprint(b, sizeof(b), "%08ux\n", p[0]);
readbuf(r, b, sizeof(b));
freeimage(br);
return nil;
}
static char *
colorwrite(Req *r)
{
u32int c;
Image * i, * br;
br = namedimage(display, "pain.brush");
if (br == nil) {
return "failed to get brush image";
}
if(r->ifcall.count == 0) {
c = DNofill;
} else {
sscanf(r->ifcall.data, "%x", &c);
}
i = allocimage(display, br->r, RGBA32, 0, c);
if (i == nil) {
freeimage(br);
return "failed to allocate image";
}
drawop(br, br->r, i, nil, ZP, S);
freeimage(i);
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");
}