123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125 |
- implement Acme;
- include "common.m";
- sys : Sys;
- bufio : Bufio;
- workdir : Workdir;
- drawm : Draw;
- styx : Styx;
- acme : Acme;
- gui : Gui;
- graph : Graph;
- dat : Dat;
- framem : Framem;
- utils : Utils;
- regx : Regx;
- scrl : Scroll;
- textm : Textm;
- filem : Filem;
- windowm : Windowm;
- rowm : Rowm;
- columnm : Columnm;
- bufferm : Bufferm;
- diskm : Diskm;
- exec : Exec;
- look : Look;
- timerm : Timerm;
- fsys : Fsys;
- xfidm : Xfidm;
- plumbmsg : Plumbmsg;
- editm: Edit;
- editlog: Editlog;
- editcmd: Editcmd;
- styxaux: Styxaux;
- sprint : import sys;
- BACK, HIGH, BORD, TEXT, HTEXT, NCOL : import Framem;
- Point, Rect, Font, Image, Display, Pointer: import drawm;
- TRUE, FALSE, maxtab : import dat;
- Ref, Reffont, Command, Timer, Lock, Cursor : import dat;
- row, reffont, activecol, mouse, typetext, mousetext, barttext, argtext, seltext, button, modbutton, colbutton, arrowcursor, boxcursor, plumbed : import dat;
- Xfid : import xfidm;
- cmouse, ckeyboard, cwait, ccommand, ckill, cxfidalloc, cxfidfree, cerr, cplumb, cedit : import dat;
- font, bflush, balloc, draw : import graph;
- Arg, PNPROC, PNGROUP : import utils;
- arginit, argopt, argf, error, warning, postnote : import utils;
- yellow, green, red, blue, black, white, mainwin, display : import gui;
- Disk : import diskm;
- Row : import rowm;
- Column : import columnm;
- Window : import windowm;
- Text, Tag, Body, Columntag : import textm;
- Buffer : import bufferm;
- snarfbuf : import exec;
- Msg : import plumbmsg;
- tfd : ref Sys->FD;
- lasttime : int;
- init(ctxt : ref Draw->Context, argl : list of string)
- {
- acmectxt = ctxt;
- sys = load Sys Sys->PATH;
- sys->pctl(Sys->NEWPGRP, nil);
- {
- # tfd = sys->create("./time", Sys->OWRITE, 8r600);
- # lasttime = sys->millisec();
- bufio = load Bufio Bufio->PATH;
- workdir = load Workdir Workdir->PATH;
- drawm = load Draw Draw->PATH;
-
- styx = load Styx Styx->PATH;
-
- acme = load Acme SELF;
-
- gui = load Gui path(Gui->PATH);
- graph = load Graph path(Graph->PATH);
- dat = load Dat path(Dat->PATH);
- framem = load Framem path(Framem->PATH);
- utils = load Utils path(Utils->PATH);
- regx = load Regx path(Regx->PATH);
- scrl = load Scroll path(Scroll->PATH);
- textm = load Textm path(Textm->PATH);
- filem = load Filem path(Filem->PATH);
- windowm = load Windowm path(Windowm->PATH);
- rowm = load Rowm path(Rowm->PATH);
- columnm = load Columnm path(Columnm->PATH);
- bufferm = load Bufferm path(Bufferm->PATH);
- diskm = load Diskm path(Diskm->PATH);
- exec = load Exec path(Exec->PATH);
- look = load Look path(Look->PATH);
- timerm = load Timerm path(Timerm->PATH);
- fsys = load Fsys path(Fsys->PATH);
- xfidm = load Xfidm path(Xfidm->PATH);
- plumbmsg = load Plumbmsg Plumbmsg->PATH;
- editm = load Edit path(Edit->PATH);
- editlog = load Editlog path(Editlog->PATH);
- editcmd = load Editcmd path(Editcmd->PATH);
- styxaux = load Styxaux path(Styxaux->PATH);
-
- mods := ref Dat->Mods(sys, bufio, drawm, styx, styxaux,
- acme, gui, graph, dat, framem,
- utils, regx, scrl,
- textm, filem, windowm, rowm, columnm,
- bufferm, diskm, exec, look, timerm,
- fsys, xfidm, plumbmsg, editm, editlog, editcmd);
-
- styx->init();
- styxaux->init();
-
- utils->init(mods);
- gui->init(mods);
- graph->init(mods);
- dat->init(mods);
- framem->init(mods);
- regx->init(mods);
- scrl->init(mods);
- textm->init(mods);
- filem->init(mods);
- windowm->init(mods);
- rowm->init(mods);
- columnm->init(mods);
- bufferm->init(mods);
- diskm->init(mods);
- exec->init(mods);
- look->init(mods);
- timerm->init(mods);
- fsys->init(mods);
- xfidm->init(mods);
- editm->init(mods);
- editlog->init(mods);
- editcmd->init(mods);
-
- utils->debuginit();
-
- if (plumbmsg->init(1, "edit", Dat->PLUMBSIZE) >= 0)
- plumbed = 1;
-
- main(argl);
-
- }
- # exception{
- # * =>
- # sys->fprint(sys->fildes(2), "acme: fatal: %s\n", utils->getexc());
- # sys->print("acme: fatal: %s\n", utils->getexc());
- # shutdown("error");
- # }
- }
- timing(s : string)
- {
- thistime := sys->millisec();
- sys->fprint(tfd, "%s %d\n", s, thistime-lasttime);
- lasttime = thistime;
- }
- path(p : string) : string
- {
- if (RELEASECOPY)
- return p;
- else {
- # inlined strrchr since not loaded yet
- for (n := len p - 1; n >= 0; n--)
- if (p[n] == '/')
- break;
- if (n >= 0)
- p = p[n+1:];
- return "/usr/jrf/acme/" + p;
- }
- }
- waitpid0, waitpid1 : int;
- mainpid : int;
- fontcache : array of ref Reffont;
- nfontcache : int;
- reffonts : array of ref Reffont;
- deffontnames := array[2] of {
- "/fonts/lucidasans/euro.8.font",
- "/fonts/lucm/unicode.9.font",
- };
- command : ref Command;
- WPERCOL : con 8;
- NSnarf : con 32;
- snarfrune : ref Dat->Astring;
- main(argl : list of string)
- {
- i, ac : int;
- loadfile : string;
- p : int;
- c : ref Column;
- arg : ref Arg;
- ncol : int;
- ncol = -1;
- mainpid = sys->pctl(0, nil);
- loadfile = nil;
- fontnames = array[2] of string;
- fontnames[0:] = deffontnames[0:2];
- f := utils->getenv("acme-font");
- if (f != nil)
- fontnames[0] = f;
- f = utils->getenv("acme-Font");
- if (f != nil)
- fontnames[1] = f;
- arg = arginit(argl);
- while(ac = argopt(arg)) case(ac){
- 'b' =>
- dat->bartflag = TRUE;
- 'c' =>
- ncol = int argf(arg);
- 'f' =>
- fontnames[0] = argf(arg);
- 'F' =>
- fontnames[1] = argf(arg);
- 'l' =>
- loadfile = argf(arg);
- }
- dat->home = utils->getenv("home");
- if (dat->home == nil)
- dat->home = utils->gethome(utils->getuser());
- ts := utils->getenv("tabstop");
- if (ts != nil)
- maxtab = int ts;
- if (maxtab <= 0)
- maxtab = 4;
- snarfrune = utils->stralloc(NSnarf);
- sys->pctl(Sys->FORKNS|Sys->FORKENV, nil);
- utils->setenv("font", fontnames[0]);
- sys->bind("/acme/dis", "/dis", Sys->MBEFORE);
- wdir = workdir->init();
- if (wdir == nil)
- wdir = ".";
- workdir = nil;
- graph->binit();
- font = Font.open(display, fontnames[0]);
- if(font == nil){
- fontnames[0] = deffontnames[0];
- font = Font.open(display, fontnames[0]);
- if (font == nil) {
- warning(nil, sprint("can't open font file %s: %r\n", fontnames[0]));
- return;
- }
- }
- reffont = ref Reffont;
- reffont.r = Ref.init();
- reffont.f = font;
- reffonts = array[2] of ref Reffont;
- reffonts[0] = reffont;
- reffont.r.inc(); # one to hold up 'font' variable
- reffont.r.inc(); # one to hold up reffonts[0]
- fontcache = array[1] of ref Reffont;
- nfontcache = 1;
- fontcache[0] = reffont;
- iconinit();
- usercolinit();
- timerm->timerinit();
- regx->rxinit();
- cwait = chan of string;
- ccommand = chan of ref Command;
- ckill = chan of string;
- cxfidalloc = chan of ref Xfid;
- cxfidfree = chan of ref Xfid;
- cerr = chan of string;
- cplumb = chan of ref Msg;
- cedit = chan of int;
- gui->spawnprocs();
- # spawn keyboardproc();
- # spawn mouseproc();
- sync := chan of int;
- spawn waitproc(sys->pctl(0, nil), sync);
- <- sync;
- spawn plumbproc();
- fsys->fsysinit();
- dat->disk = (dat->disk).init();
- row = rowm->newrow();
- if(loadfile != nil) {
- row.qlock.lock(); # tasks->procs now
- row.loadx(loadfile, TRUE);
- row.qlock.unlock();
- }
- else{
- row.init(mainwin.clipr);
- if(ncol < 0){
- if(arg.av == nil)
- ncol = 2;
- else{
- ncol = (len arg.av+(WPERCOL-1))/WPERCOL;
- if(ncol < 2)
- ncol = 2;
- }
- }
- if(ncol == 0)
- ncol = 2;
- for(i=0; i<ncol; i++){
- c = row.add(nil, -1);
- if(c==nil && i==0)
- error("initializing columns");
- }
- c = row.col[row.ncol-1];
- if(arg.av == nil)
- readfile(c, wdir);
- else
- i = 0;
- for( ; arg.av != nil; arg.av = tl arg.av){
- filen := hd arg.av;
- p = utils->strrchr(filen, '/');
- if((p>=0 && filen[p:] == "/guide") || i/WPERCOL>=row.ncol)
- readfile(c, filen);
- else
- readfile(row.col[i/WPERCOL], filen);
- i++;
- }
- }
- bflush();
- spawn keyboardtask();
- spawn mousetask();
- spawn waittask();
- spawn xfidalloctask();
- # notify(shutdown);
- # waitc := chan of int;
- # <-waitc;
- # killprocs();
- exit;
- }
- readfile(c : ref Column, s : string)
- {
- w : ref Window;
- r : string;
- nr : int;
- w = c.add(nil, nil, -1);
- (r, nr) = look->cleanname(s, len s);
- w.setname(r, nr);
- w.body.loadx(0, s, 1);
- w.body.file.mod = FALSE;
- w.dirty = FALSE;
- w.settag();
- scrl->scrdraw(w.body);
- w.tag.setselect(w.tag.file.buf.nc, w.tag.file.buf.nc);
- }
- oknotes := array[6] of {
- "delete",
- "hangup",
- "kill",
- "exit",
- "error",
- nil
- };
- dumping : int;
- shutdown(msg : string)
- {
- i : int;
- # notify(nil);
- if(!dumping && msg != "kill" && msg != "exit" && (1 || sys->pctl(0, nil)==mainpid) && row != nil){
- dumping = TRUE;
- row.dump(nil);
- }
- for(i=0; oknotes[i] != nil; i++)
- if(utils->strncmp(oknotes[i], msg, len oknotes[i]) == 0) {
- killprocs();
- exit;
- }
- # killprocs();
- sys->fprint(sys->fildes(2), "acme: %s\n", msg);
- sys->print("acme: %s\n", msg);
- # exit;
- }
- acmeexit(err: string)
- {
- if(err != nil)
- shutdown(err);
- graph->cursorswitch(nil);
- if (plumbed)
- plumbmsg->shutdown();
- killprocs();
- gui->killwins();
- exit;
- }
- killprocs()
- {
- c : ref Command;
- kill := "kill";
- thispid := sys->pctl(0, nil);
- fsys->fsysclose();
- postnote(PNPROC, thispid, mousepid, kill);
- postnote(PNPROC, thispid, keyboardpid, kill);
- postnote(PNPROC, thispid, timerpid, kill);
- postnote(PNPROC, thispid, waitpid0, kill);
- postnote(PNPROC, thispid, waitpid1, kill);
- postnote(PNPROC, thispid, fsyspid, kill);
- postnote(PNPROC, thispid, mainpid, kill);
- postnote(PNPROC, thispid, keytid, kill);
- postnote(PNPROC, thispid, mousetid, kill);
- postnote(PNPROC, thispid, waittid, kill);
- postnote(PNPROC, thispid, xfidalloctid, kill);
- # postnote(PNPROC, thispid, lockpid, kill);
- postnote(PNPROC, thispid, plumbpid, kill);
- # draw(mainwin, mainwin.r, white, nil, mainwin.r.min);
- for(c=command; c != nil; c=c.next)
- postnote(PNGROUP, thispid, c.pid, "kill");
- xfidm->xfidkill();
- }
- keytid : int;
- mousetid : int;
- waittid : int;
- xfidalloctid : int;
- keyboardtask()
- {
- r : int;
- timer : ref Timer;
- null : ref Timer;
- t : ref Text;
- {
- keytid = sys->pctl(0, nil);
- null = ref Timer;
- null.c = chan of int;
- timer = null;
- typetext = nil;
- for(;;){
- alt{
- <-(timer.c) =>
- timerm->timerstop(timer);
- t = typetext;
- if(t!=nil && t.what==Tag && !t.w.qlock.locked()){
- t.w.lock('K');
- t.w.commit(t);
- t.w.unlock();
- bflush();
- }
- timer = null;
- r = <-ckeyboard =>
- gotkey := 1;
- while (gotkey) {
- typetext = row.typex(r, mouse.xy);
- t = typetext;
- if(t!=nil && t.col!=nil)
- activecol = t.col;
- if(t!=nil && t.w!=nil)
- t.w.body.file.curtext = t.w.body;
- if(timer != null)
- spawn timerm->timerwaittask(timer);
- if(t!=nil && t.what==Tag)
- timer = timerm->timerstart(500);
- else
- timer = null;
- alt {
- r = <- ckeyboard =>
- gotkey = 1; # do this case again
- * =>
- gotkey = 0;
- }
- bflush();
- }
- }
- }
- }
- exception{
- * =>
- shutdown(utils->getexc());
- raise;
- # acmeexit(nil);
- }
- }
- mousetask()
- {
- t, argt : ref Text;
- but, ok : int;
- q0, q1 : int;
- w : ref Window;
- m : ref Msg;
- {
- mousetid = sys->pctl(0, nil);
- sync := chan of int;
- spawn waitproc(mousetid, sync);
- <- sync;
- for(;;){
- alt{
- *mouse = *<-cmouse =>
- row.qlock.lock();
- if (mouse.buttons & M_QUIT) {
- if (row.clean(TRUE))
- acmeexit(nil);
- # shutdown("kill");
- row.qlock.unlock();
- break;
- }
- if (mouse.buttons & M_HELP) {
- warning(nil, "no help provided (yet)");
- bflush();
- row.qlock.unlock();
- break;
- }
- if(mouse.buttons & M_RESIZE){
- draw(mainwin, mainwin.r, white, nil, mainwin.r.min);
- scrl->scrresize();
- row.reshape(mainwin.clipr);
- bflush();
- row.qlock.unlock();
- break;
- }
- t = row.which(mouse.xy);
- if(t!=mousetext && mousetext!=nil && mousetext.w!=nil){
- mousetext.w.lock('M');
- mousetext.eq0 = ~0;
- mousetext.w.commit(mousetext);
- mousetext.w.unlock();
- }
- mousetext = t;
- if(t == nil) {
- bflush();
- row.qlock.unlock();
- break;
- }
- w = t.w;
- if(t==nil || mouse.buttons==0) {
- bflush();
- row.qlock.unlock();
- break;
- }
- if(w != nil)
- w.body.file.curtext = w.body;
- but = 0;
- if(mouse.buttons == 1)
- but = 1;
- else if(mouse.buttons == 2)
- but = 2;
- else if(mouse.buttons == 4)
- but = 3;
- barttext = t;
- if(t.what==Body && mouse.xy.in(t.scrollr)){
- if(but){
- w.lock('M');
- t.eq0 = ~0;
- scrl->scroll(t, but);
- t.w.unlock();
- }
- bflush();
- row.qlock.unlock();
- break;
- }
- if(w != nil && (mouse.buttons &(8|16))){
- if(mouse.buttons & 8)
- but = Dat->Kscrollup;
- else
- but = Dat->Kscrolldown;
- w.lock('M');
- t.eq0 = ~0;
- t.typex(but, 0);
- w.unlock();
- bflush();
- row.qlock.unlock();
- break;
- }
- if(mouse.xy.in(t.scrollr)){
- if(but){
- if(t.what == Columntag)
- row.dragcol(t.col);
- else if(t.what == Tag){
- t.col.dragwin(t.w, but);
- if(t.w != nil)
- barttext = t.w.body;
- }
- if(t.col != nil)
- activecol = t.col;
- }
- bflush();
- row.qlock.unlock();
- break;
- }
- if(mouse.buttons){
- if(w != nil)
- w.lock('M');
- t.eq0 = ~0;
- if(w != nil)
- w.commit(t);
- else
- t.commit(TRUE);
- if(mouse.buttons & 1){
- t.select(0);
- if(w != nil)
- w.settag();
- argtext = t;
- seltext = t;
- if(t.col != nil)
- activecol = t.col; # button 1 only
- if(t.w != nil && t == t.w.body)
- dat->activewin = t.w;
- }else if(mouse.buttons & 2){
- (ok, argt, q0, q1) = t.select2(q0, q1);
- if(ok)
- exec->execute(t, q0, q1, FALSE, argt);
- }else if(mouse.buttons & 4){
- (ok, q0, q1) = t.select3(q0, q1);
- if(ok)
- look->look3(t, q0, q1, FALSE);
- }
- if(w != nil)
- w.unlock();
- bflush();
- row.qlock.unlock();
- break;
- }
- m = <- cplumb =>
- if (m.kind == "text") {
- attrs := plumbmsg->string2attrs(m.attr);
- (found, act) := plumbmsg->lookup(attrs, "action");
- if (!found || act == nil || act == "showfile")
- look->plumblook(m);
- else if (act == "showdata")
- look->plumbshow(m);
- }
- bflush();
- }
- }
- }
- exception{
- * =>
- shutdown(utils->getexc());
- raise;
- # acmeexit(nil);
- }
- }
- # list of processes that have exited but we have not heard of yet
- Pid : adt {
- pid : int;
- msg : string;
- next : cyclic ref Pid;
- };
- waittask()
- {
- status : string;
- c, lc : ref Command;
- pid : int;
- found : int;
- cmd : string;
- err : string;
- t : ref Text;
- pids : ref Pid;
- waittid = sys->pctl(0, nil);
- command = nil;
- for(;;){
- alt{
- err = <-cerr =>
- row.qlock.lock();
- warning(nil, err);
- err = nil;
- bflush();
- row.qlock.unlock();
- break;
- cmd = <-ckill =>
- found = FALSE;
- for(c=command; c != nil; c=c.next){
- # -1 for blank
- if(c.name[0:len c.name - 1] == cmd){
- if(postnote(PNGROUP, waittid, c.pid, "kill") < 0)
- warning(nil, sprint("kill %s: %r\n", cmd));
- found = TRUE;
- }
- }
- if(!found)
- warning(nil, sprint("Kill: no process %s\n", cmd));
- cmd = nil;
- break;
- status = <-cwait =>
- pid = int status;
- lc = nil;
- for(c=command; c != nil; c=c.next){
- if(c.pid == pid){
- if(lc != nil)
- lc.next = c.next;
- else
- command = c.next;
- break;
- }
- lc = c;
- }
- row.qlock.lock();
- t = row.tag;
- t.commit(TRUE);
- if(c == nil){
- # warning(nil, sprint("unknown child pid %d\n", pid));
- p := ref Pid;
- p.pid = pid;
- p.msg = status;
- p.next = pids;
- pids = p;
- }
- else{
- if(look->search(t, c.name, len c.name)){
- t.delete(t.q0, t.q1, TRUE);
- t.setselect(0, 0);
- }
- if(status[len status - 1] != ':')
- warning(c.md, sprint("%s\n", status));
- bflush();
- }
- row.qlock.unlock();
- if(c != nil){
- if(c.iseditcmd)
- cedit <- = 0;
- fsys->fsysdelid(c.md);
- c = nil;
- }
- break;
- c = <-ccommand =>
- lastp : ref Pid = nil;
- for(p := pids; p != nil; p = p.next){
- if(p.pid == c.pid){
- status = p.msg;
- if(status[len status - 1] != ':')
- warning(c.md, sprint("%s\n", status));
- if(lastp == nil)
- pids = p.next;
- else
- lastp.next = p.next;
- if(c.iseditcmd)
- cedit <- = 0;
- fsys->fsysdelid(c.md);
- c = nil;
- break;
- }
- lastp = p;
- }
- c.next = command;
- command = c;
- row.qlock.lock();
- t = row.tag;
- t.commit(TRUE);
- t.insert(0, c.name, len c.name, TRUE, 0);
- t.setselect(0, 0);
- bflush();
- row.qlock.unlock();
- break;
- }
- }
- }
- xfidalloctask()
- {
- xfree, x : ref Xfid;
- xfidalloctid = sys->pctl(0, nil);
- xfree = nil;
- for(;;){
- alt{
- <-cxfidalloc =>
- x = xfree;
- if(x != nil)
- xfree = x.next;
- else{
- x = xfidm->newxfid();
- x.c = chan of int;
- spawn x.ctl();
- }
- cxfidalloc <-= x;
- break;
- x = <-cxfidfree =>
- x.next = xfree;
- xfree = x;
- break;
- }
- }
- }
- frgetmouse()
- {
- bflush();
- *mouse = *<-cmouse;
- }
- waitproc(pid : int, sync: chan of int)
- {
- fd : ref Sys->FD;
- n : int;
- if (waitpid0 == 0)
- waitpid0 = sys->pctl(0, nil);
- else
- waitpid1 = sys->pctl(0, nil);
- sys->pctl(Sys->FORKFD, nil);
- # w := sprint("/prog/%d/wait", pid);
- w := sprint("#p/%d/wait", pid);
- fd = sys->open(w, Sys->OREAD);
- if (fd == nil)
- error("fd == nil in waitproc");
- sync <-= 0;
- buf := array[Sys->WAITLEN] of byte;
- status := "";
- for(;;){
- if ((n = sys->read(fd, buf, len buf))<0)
- error("bad read in waitproc");
- status = string buf[0:n];
- cwait <-= status;
- }
- }
- get(fix : int, save : int, setfont : int, name : string) : ref Reffont
- {
- r : ref Reffont;
- f : ref Font;
- i : int;
- r = nil;
- if(name == nil){
- name = fontnames[fix];
- r = reffonts[fix];
- }
- if(r == nil){
- for(i=0; i<nfontcache; i++)
- if(name == fontcache[i].f.name){
- r = fontcache[i];
- break;
- }
- if (i >= nfontcache) {
- f = Font.open(display, name);
- if(f == nil){
- warning(nil, sprint("can't open font file %s: %r\n", name));
- return nil;
- }
- r = ref Reffont;
- r.r = Ref.init();
- r.f = f;
- ofc := fontcache;
- fontcache = array[nfontcache+1] of ref Reffont;
- fontcache[0:] = ofc[0:nfontcache];
- ofc = nil;
- fontcache[nfontcache++] = r;
- }
- }
- if(save){
- r.r.inc();
- if(reffonts[fix] != nil)
- reffonts[fix].close();
- reffonts[fix] = r;
- fontnames[fix] = name;
- }
- if(setfont){
- reffont.f = r.f;
- r.r.inc();
- reffonts[0].close();
- font = r.f;
- reffonts[0] = r;
- r.r.inc();
- iconinit();
- }
- r.r.inc();
- return r;
- }
- close(r : ref Reffont)
- {
- i : int;
- if(r.r.dec() == 0){
- for(i=0; i<nfontcache; i++)
- if(r == fontcache[i])
- break;
- if(i >= nfontcache)
- warning(nil, "internal error: can't find font in cache\n");
- else{
- fontcache[i:] = fontcache[i+1:nfontcache];
- nfontcache--;
- }
- r.f = nil;
- r = nil;
- }
- }
- arrowbits := array[64] of {
- byte 16rFF, byte 16rE0, byte 16rFF, byte 16rE0,
- byte 16rFF, byte 16rC0, byte 16rFF, byte 16r00,
- byte 16rFF, byte 16r00, byte 16rFF, byte 16r80,
- byte 16rFF, byte 16rC0, byte 16rFF, byte 16rE0,
- byte 16rE7, byte 16rF0, byte 16rE3, byte 16rF8,
- byte 16rC1, byte 16rFC, byte 16r00, byte 16rFE,
- byte 16r00, byte 16r7F, byte 16r00, byte 16r3E,
- byte 16r00, byte 16r1C, byte 16r00, byte 16r08,
- byte 16r00, byte 16r00, byte 16r7F, byte 16rC0,
- byte 16r7F, byte 16r00, byte 16r7C, byte 16r00,
- byte 16r7E, byte 16r00, byte 16r7F, byte 16r00,
- byte 16r6F, byte 16r80, byte 16r67, byte 16rC0,
- byte 16r43, byte 16rE0, byte 16r41, byte 16rF0,
- byte 16r00, byte 16rF8, byte 16r00, byte 16r7C,
- byte 16r00, byte 16r3E, byte 16r00, byte 16r1C,
- byte 16r00, byte 16r08, byte 16r00, byte 16r00,
- };
- # outer boundary of width 1 is white
- # next boundary of width 3 is black
- # next boundary of width 1 is white
- # inner boundary of width 4 is transparent
- boxbits := array[64] of {
- byte 16rFF, byte 16rFF, byte 16rFF, byte 16rFF,
- byte 16rFF, byte 16rFF, byte 16rFF, byte 16rFF,
- byte 16rFF, byte 16rFF, byte 16rF8, byte 16r1F,
- byte 16rF8, byte 16r1F, byte 16rF8, byte 16r1F,
- byte 16rF8, byte 16r1F, byte 16rF8, byte 16r1F,
- byte 16rF8, byte 16r1F, byte 16rFF, byte 16rFF,
- byte 16rFF, byte 16rFF, byte 16rFF, byte 16rFF,
- byte 16rFF, byte 16rFF, byte 16rFF, byte 16rFF,
- byte 16r00, byte 16r00, byte 16r7F, byte 16rFE,
- byte 16r7F, byte 16rFE, byte 16r7F, byte 16rFE,
- byte 16r70, byte 16r0E, byte 16r70, byte 16r0E,
- byte 16r70, byte 16r0E, byte 16r70, byte 16r0E,
- byte 16r70, byte 16r0E, byte 16r70, byte 16r0E,
- byte 16r70, byte 16r0E, byte 16r70, byte 16r0E,
- byte 16r7F, byte 16rFE, byte 16r7F, byte 16rFE,
- byte 16r7F, byte 16rFE, byte 16r00, byte 16r00,
- };
- iconinit()
- {
- r : Rect;
- # Blue
- tagcols = array[NCOL] of ref Draw->Image;
- tagcols[BACK] = display.colormix(Draw->Palebluegreen, Draw->White);
- tagcols[HIGH] = display.color(Draw->Palegreygreen);
- tagcols[BORD] = display.color(Draw->Purpleblue);
- tagcols[TEXT] = black;
- tagcols[HTEXT] = black;
- # Yellow
- textcols = array[NCOL] of ref Draw->Image;
- textcols[BACK] = display.colormix(Draw->Paleyellow, Draw->White);
- textcols[HIGH] = display.color(Draw->Darkyellow);
- textcols[BORD] = display.color(Draw->Yellowgreen);
- textcols[TEXT] = black;
- textcols[HTEXT] = black;
- if(button != nil)
- button = modbutton = colbutton = nil;
- r = ((0, 0), (Dat->Scrollwid+2, font.height+1));
- button = balloc(r, mainwin.chans, Draw->White);
- draw(button, r, tagcols[BACK], nil, r.min);
- r.max.x -= 2;
- draw(button, r, tagcols[BORD], nil, (0, 0));
- r = r.inset(2);
- draw(button, r, tagcols[BACK], nil, (0, 0));
- r = button.r;
- modbutton = balloc(r, mainwin.chans, Draw->White);
- draw(modbutton, r, tagcols[BACK], nil, r.min);
- r.max.x -= 2;
- draw(modbutton, r, tagcols[BORD], nil, (0, 0));
- r = r.inset(2);
- draw(modbutton, r, display.rgb(16r00, 16r00, 16r99), nil, (0, 0)); # was DMedblue
- r = button.r;
- colbutton = balloc(r, mainwin.chans, Draw->White);
- draw(colbutton, r, tagcols[BACK], nil, r.min);
- r.max.x -= 2;
- draw(colbutton, r, tagcols[BORD], nil, (0, 0));
- # arrowcursor = ref Cursor((-1, -1), (16, 32), arrowbits);
- boxcursor = ref Cursor((-7, -7), (16, 32), boxbits);
- but2col = display.rgb(16raa, 16r00, 16r00);
- but3col = display.rgb(16r00, 16r66, 16r00);
- but2colt = white;
- but3colt = white;
- graph->cursorswitch(arrowcursor);
- }
- colrec : adt {
- name : string;
- image : ref Image;
- };
- coltab : array of colrec;
- cinit()
- {
- coltab = array[6] of colrec;
- coltab[0].name = "yellow"; coltab[0].image = yellow;
- coltab[1].name = "green"; coltab[1].image = green;
- coltab[2].name = "red"; coltab[2].image = red;
- coltab[3].name = "blue"; coltab[3].image = blue;
- coltab[4].name = "black"; coltab[4].image = black;
- coltab[5].name = "white"; coltab[5].image = white;
- }
- col(s : string, n : int) : int
- {
- return ((s[n]-'0') << 4) | (s[n+1]-'0');
- }
- rgb(s : string, n : int) : (int, int, int)
- {
- return (col(s, n), col(s, n+2), col(s, n+4));
- }
- cenv(s : string, t : string, but : int, i : ref Image) : ref Image
- {
- c := utils->getenv("acme-" + s + "-" + t + "-" + string but);
- if (c == nil)
- c = utils->getenv("acme-" + s + "-" + string but);
- if (c == nil && but != 0)
- c = utils->getenv("acme-" + s);
- if (c != nil) {
- if (c[0] == '#' && len c >= 7) {
- (r1, g1, b1) := rgb(c, 1);
- if (len c >= 15 && c[7] == '/' && c[8] == '#') {
- (r2, g2, b2) := rgb(c, 9);
- return display.colormix((r1<<24)|(g1<<16)|(b1<<8)|16rFF, (r2<<24)|(g2<<16)|(b2<<8)|16rFF);
- }
- return display.color((r1<<24)|(g1<<16)|(b1<<8)|16rFF);
- }
- for (j := 0; j < len c; j++)
- if (c[j] >= 'A' && c[j] <= 'Z')
- c[j] += 'a'-'A';
- for (j = 0; j < len coltab; j++)
- if (c == coltab[j].name)
- return coltab[j].image;
- }
- return i;
- }
- usercolinit()
- {
- cinit();
- textcols[TEXT] = cenv("fg", "text", 0, textcols[TEXT]);
- textcols[BACK] = cenv("bg", "text", 0, textcols[BACK]);
- textcols[HTEXT] = cenv("fg", "text", 1, textcols[HTEXT]);
- textcols[HIGH] = cenv("bg", "text", 1, textcols[HIGH]);
- but2colt= cenv("fg", "text", 2, but2colt);
- but2col = cenv("bg", "text", 2, but2col);
- but3colt = cenv("fg", "text", 3, but3colt);
- but3col = cenv("bg", "text", 3, but3col);
- tagcols[TEXT] = cenv("fg", "tag", 0, tagcols[TEXT]);
- tagcols[BACK] = cenv("bg", "tag", 0, tagcols[BACK]);
- tagcols[HTEXT] = cenv("fg", "tag", 1, tagcols[HTEXT]);
- tagcols[HIGH] = cenv("bg", "tag", 1, tagcols[HIGH]);
- }
- getsnarf()
- {
- # return;
- fd := sys->open("/chan/snarf", sys->OREAD);
- if(fd == nil)
- return;
- snarfbuf.reset();
- snarfbuf.loadx(0, fd);
- }
- putsnarf()
- {
- n : int;
- # return;
- if(snarfbuf.nc == 0)
- return;
- fd := sys->open("/chan/snarf", sys->OWRITE);
- if(fd == nil)
- return;
- for(i:=0; i<snarfbuf.nc; i+=n){
- n = snarfbuf.nc-i;
- if(n >= NSnarf)
- n = NSnarf;
- snarfbuf.read(i, snarfrune, 0, n);
- sys->fprint(fd, "%s", snarfrune.s[0:n]);
- }
- }
- plumbpid : int;
- plumbproc()
- {
- plumbpid = sys->pctl(0, nil);
- for(;;){
- msg := Msg.recv();
- if(msg == nil){
- sys->print("Acme: can't read /chan/plumb.edit: %r\n");
- plumbpid = 0;
- plumbed = 0;
- return;
- }
- if(msg.kind != "text"){
- sys->print("Acme: can't interpret '%s' kind of message\n", msg.kind);
- continue;
- }
- # sys->print("msg %s\n", string msg.data);
- cplumb <-= msg;
- }
- }
|