code: purgatorio

ref: eb0e026c241bd3afc6a10a6e2c7417de1b91f7e8
dir: /appl/wm/sam.b/

View raw version
implement Samterm;

include "sys.m";
sys: Sys;
fprint, sprint, FD: import sys;
stderr, logfd: ref FD;

include "draw.m";
draw:	Draw;

include "samterm.m";

include "samtk.m";
samtk: Samtk;

include "samstub.m";
samstub: Samstub;
Samio, Sammsg: import samstub;

samio: ref Samio;

ctxt: ref Context;

init(context: ref draw->Context, nil: list of string)
{
	recvsam: chan of ref Sammsg;

	sys = load Sys Sys->PATH;
	draw = load Draw Draw->PATH;
	stderr = sys->fildes(2);

	logfd = sys->create("/fd/1", sys->OWRITE, 8r666);
	if (logfd == nil) {
		fprint(stderr, "Can't create samterm.log\n");
		logfd = stderr;
	}

	fprint(logfd, "Samterm started\n");

	pgrp := sys->pctl(sys->NEWPGRP, nil);

	ctxt = ref Context(
		context,
		1000,		# initial tag

		0,		# lock

		nil,		# keysel
		nil,		# scrollsel
		nil,		# buttonsel
		nil,		# menu2sel
		nil,		# menu3sel
		nil,		# titlesel
		nil,		# tags

		nil,		# menus
		nil,		# texts

		nil,		# cmd
		nil,		# which
		nil,		# work
		pgrp,		# pgrp
		logfd		# logging file descriptor
	);

	samtk = load Samtk Samtk->PATH;
	if (samtk == nil) {
		fprint(stderr, "Can't load %s\n", Samtk->PATH);
		return;
	}
	samtk->init(ctxt);

	samstub = load Samstub Samstub->PATH;
	if (samstub == nil) {
		fprint(stderr, "Can't load %s\n", Samstub->PATH);
		return;
	}
	samstub->init(ctxt);

	(samio, recvsam) = samstub->start();
	if (samio == nil) {
		fprint(stderr, "couldn't start samstub\n");
		return;
	}
	samstub->outTs(samstub->Tversion, samstub->VERSION);

	samstub->startcmdfile();

	samstub->setlock();

	for(;;) if (ctxt.lock == 0) alt {
	(win, menu) := <-ctxt.titlesel =>
		samstub->cleanout();
		fl := ctxt.flayers[win];
		tag := fl.tag;
		if ((i := samtk->whichtext(tag)) < 0)
			samtk->panic("samterm: whichtext");
		t := ctxt.texts[i];
		samtk->newcur(t, fl);
		case menu {
		"exit" =>
			if (ctxt.flayers[win].tag == 0) {
				samstub->outT0(samstub->Texit);
				f := sprint("#p/%d/ctl", pgrp);
				if ((fd := sys->open(f, sys->OWRITE)) != nil)
					sys->write(fd, array of byte "killgrp\n", 8);
				return;
			}
			samstub->close(win, tag);
		"resize" =>
			samtk->resize(fl);
			samstub->scrollto(fl, fl.scope.first);
		"task" =>
			spawn samtk->titlectl(win, menu);
		* =>
			samtk->titlectl(win, menu);
		}


	(win, m1) := <-ctxt.buttonsel =>
		samstub->cleanout();
		fl := ctxt.flayers[win];
		tag := fl.tag;
		if (samtk->buttonselect(fl, m1)) {
			samstub->outTsl(samstub->Tdclick, tag, fl.dot.first);
			samstub->setlock();
		}
	(win, m2) := <-ctxt.menu2sel =>
		samstub->cleanout();
		fl := ctxt.flayers[win];
		tag := fl.tag;
		if ((i := samtk->whichtext(tag)) < 0)
			samtk->panic("samterm: whichtext");
		t := ctxt.texts[i];
		samtk->newcur(t, fl);
		case m2 {
		"cut" =>
			samstub->cut(t, fl);
		"paste" =>
			samstub->paste(t, fl);
		"snarf" =>
			samstub->snarf(t, fl);
		"look" =>
			samstub->look(t, fl);
		"exch" =>
			fprint(ctxt.logfd, "debug -- exch: %d, %s\n", win, m2);
		"send" =>
			samstub->send(t, fl);
		"search" =>
			samstub->search(t, fl);
		* =>
			samtk->panic("samterm: editmenu");
		}
	(win, m3) := <-ctxt.menu3sel =>
		samstub->cleanout();
		fl := ctxt.flayers[win];
		tag := fl.tag;
		if ((i := samtk->whichtext(tag)) < 0)
			samtk->panic("samterm: whichtext");
		t := ctxt.texts[i];
		samtk->newcur(t, fl);
		case m3 {
		"new" =>
			samstub->startnewfile();
		"zerox" =>
			samstub->zerox(t);
		"close" =>
			if (win != 0) {
				samstub->close(win, tag);
			}
		"write" =>
			samstub->outTs(samstub->Twrite, tag);
			samstub->setlock();
		* =>
			for (i = 0; i < len ctxt.menus; i++) {
				if (ctxt.menus[i].name == m3) {
					break;
				}
			}
			if (i == len ctxt.menus)
				samtk->panic("init: can't find m3");
			t = ctxt.menus[i].text;
			t.flayers = samtk->append(tl t.flayers, hd t.flayers);
			samtk->newcur(t, hd t.flayers);
			
		}
	(win, c) := <-ctxt.keysel =>
		if (ctxt.which != ctxt.flayers[win]) {
			fprint(ctxt.logfd, "probably can't happen\n");
			samstub->cleanout();
			tag := ctxt.flayers[win].tag;
			if ((i := samtk->whichtext(tag)) < 0)
				samtk->panic("samterm: whichtext");
			samtk->newcur(ctxt.texts[i], ctxt.flayers[win]);
		}
		samstub->keypress(c[1:len c -1]);
	(win, c) := <-ctxt.scrollsel =>
		if (ctxt.which != ctxt.flayers[win]) {
			samstub->cleanout();
			tag := ctxt.flayers[win].tag;
			if ((i := samtk->whichtext(tag)) < 0)
				samtk->panic("samterm: whichtext");
			samtk->newcur(ctxt.texts[i], ctxt.flayers[win]);
		}
		(pos, lines) := samtk->scroll(ctxt.which, c);
		if (lines > 0) {
			samstub->outTsll(samstub->Torigin,
				ctxt.which.tag, pos, lines);
			samstub->setlock();
		} else if (pos != -1)
			samstub->scrollto(ctxt.which, pos);
	h := <-recvsam =>
		if (samstub->inmesg(h)) {
			samstub->outT0(samstub->Texit);
			fname := sprint("#p/%d/ctl", pgrp);
			if ((fdesc := sys->open(fname, sys->OWRITE)) != nil)
				sys->write(fdesc, array of byte "killgrp\n", 8);
			return;
		}
	} else {
		h := <-recvsam;
		if (samstub->inmesg(h)) {
			samstub->outT0(samstub->Texit);
			fname := sprint("#p/%d/ctl", pgrp);
			if ((fdesc := sys->open(fname, sys->OWRITE)) != nil)
				sys->write(fdesc, array of byte "killgrp\n", 8);
			return;
		}
	}
}