shithub: drawfs

ref: 798897c28e191cd4c2513afb658fa196b3fbb95c
dir: /mousefs/cmd.c/

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

enum {
	Qroot,
	Qmouse,
};

static void
mkqid(Qid* q, int p)
{
	q->path = p;
	q->vers = 0;
	q->type = p == Qroot ? QTDIR : QTFILE;
}

static void
mkqdir(Dir *d, int p)
{
	mkqid(&d->qid, p);
	d->mode = 0666;
	if (d->qid.type & QTDIR)
		d->mode |= DMDIR;
	
	d->atime = d->mtime = time(0);
	d->length = 0;
	d->uid = estrdup9p(getuser());
	d->gid = estrdup9p(d->uid);
	d->muid = estrdup9p(d->uid);
	switch (p) {
	case Qroot:
		d->name = estrdup9p(".");
		break;
	case Qmouse:
		d->name = estrdup9p("mouse");
		break;
	}
}

static void
ctlattach(Req *r)
{
	mkqid(&r->fid->qid, Qroot);
	r->ofcall.qid = r->fid->qid;
	respond(r, nil);
}

static char*
ctlwalk(Fid *fid, char *name, Qid *qid)
{
	switch (fid->qid.path) {
	case Qroot:
		if (strcmp(name, "..") == 0) {
			*qid = fid->qid;
			return nil;
		}
		if (strcmp(name, "mouse") == 0) {
			mkqid(qid, Qmouse);
			fid->qid = *qid;
			return nil;
		}
	}
	return "no file";
}

static void
ctlstat(Req *r)
{
	if (r->fid->qid.path != Qroot && r->fid->qid.path != Qmouse) {
		respond(r, "no file");
		return;
	}
	mkqdir(&r->d, r->fid->qid.path);
	respond(r, nil);
}

static int
genroot(int n, Dir *d, void*)
{
	if (n != 0)
		return -1;
	mkqdir(d, Qmouse);
	return 0;
}

static void
ctlread(Req *r)
{
	switch (r->fid->qid.path) {
	case Qroot:
		dirread9p(r, genroot, nil);
		respond(r, nil);
		return;
	case Qmouse:
		respond(r, "no read");
		return;
	}
	respond(r, "ctlread: no file");
}

typedef struct Mousedata Mousedata;
struct Mousedata {
	int x;
	int y;
	int b;
	ulong msec;
};
Mousedata prev;

static void
ctlwrite(Req *r)
{
	Mousedata d;
	
	switch (r->fid->qid.path) {
	case Qmouse:
		break;
	default:
		respond(r, "no file");
		return;
	}
	
	if (r->ifcall.count != 49) {
		respond(r, "invalid request size");
		return;
	}
	
	d.x = atoi(r->ifcall.data + 1+0*12);
	d.y = atoi(r->ifcall.data + 1+1*12);
	d.b = atoi(r->ifcall.data + 1+2*12);
	d.msec = strtoll(r->ifcall.data + 1+3*12, 0, 0);
	
	absmousetrack(d.x, d.y, d.b, d.msec);
	prev = d;
	r->ofcall.count = r->ifcall.count;
	respond(r, nil);
	return;
}

Srv ctl = {
	.attach = ctlattach,
	.walk1 = ctlwalk,
	.stat = ctlstat,
	.read = ctlread,
	.write = ctlwrite,
};

void
initcmdfs(char *name)
{
	char *srvname;
	
	srvname = smprint("mousefs.%s.cmd", name);
	if (!srvname)
		sysfatal("%r");
	postsrv(&ctl, srvname);
}