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; } } }