diff options
Diffstat (limited to 'appl/wm/task.b')
| -rw-r--r-- | appl/wm/task.b | 240 |
1 files changed, 240 insertions, 0 deletions
diff --git a/appl/wm/task.b b/appl/wm/task.b new file mode 100644 index 00000000..762d1262 --- /dev/null +++ b/appl/wm/task.b @@ -0,0 +1,240 @@ +implement WmTask; + +include "sys.m"; + sys: Sys; + Dir: import sys; + +include "draw.m"; + draw: Draw; + +include "tk.m"; + tk: Tk; + Toplevel: import tk; + +include "tkclient.m"; + tkclient: Tkclient; + +include "dialog.m"; + dialog: Dialog; + +Prog: adt +{ + pid: int; + pgrp: int; + size: int; + state: string; + mod: string; +}; + +WmTask: module +{ + init: fn(ctxt: ref Draw->Context, argv: list of string); +}; + +Wm: module +{ + init: fn(ctxt: ref Draw->Context, argv: list of string); +}; + +task_cfg := array[] of { + "frame .fl", + "scrollbar .fl.scroll -command {.fl.l yview}", + "listbox .fl.l -width 40w -yscrollcommand {.fl.scroll set}", + "frame .b", + "button .b.ref -text Refresh -command {send cmd r}", + "button .b.deb -text Debug -command {send cmd d}", + "button .b.files -text Files -command {send cmd f}", + "button .b.kill -text Kill -command {send cmd k}", + "button .b.killg -text {Kill Group} -command {send cmd kg}", + "pack .b.ref .b.deb .b.files .b.kill .b.killg -side left -padx 2 -pady 2", + "pack .b -fill x", + "pack .fl.scroll -side left -fill y", + "pack .fl.l -fill both -expand 1", + "pack .fl -fill both -expand 1", + "pack propagate . 0", +}; + +init(ctxt: ref Draw->Context, nil: list of string) +{ + sys = load Sys Sys->PATH; + if (ctxt == nil) { + sys->fprint(sys->fildes(2), "task: no window context\n"); + raise "fail:bad context"; + } + draw = load Draw Draw->PATH; + tk = load Tk Tk->PATH; + tkclient= load Tkclient Tkclient->PATH; + dialog = load Dialog Dialog->PATH; + + tkclient->init(); + dialog->init(); + + sysnam := sysname(); + + (t, wmctl) := tkclient->toplevel(ctxt, "", sysnam, Tkclient->Appl); + if(t == nil) + return; + + cmd := chan of string; + tk->namechan(t, cmd, "cmd"); + + for (c:=0; c<len task_cfg; c++) + tk->cmd(t, task_cfg[c]); + + readprog(t); + + tk->cmd(t, ".fl.l see end;update"); + tkclient->onscreen(t, nil); + tkclient->startinput(t, "kbd"::"ptr"::nil); + + for(;;) alt { + s := <-t.ctxt.kbd => + tk->keyboard(t, s); + s := <-t.ctxt.ptr => + tk->pointer(t, *s); + s := <-t.ctxt.ctl or + s = <-t.wreq => + tkclient->wmctl(t, s); + menu := <-wmctl => + case menu { + "exit" => + return; + "task" => + tkclient->wmctl(t, menu); + tk->cmd(t, ".fl.l delete 0 end"); + readprog(t); + tk->cmd(t, ".fl.l see end;update"); + * => + tkclient->wmctl(t, menu); + } + bcmd := <-cmd => + case bcmd { + "d" => + sel := tk->cmd(t, ".fl.l curselection"); + if(sel == "") + break; + pid := int tk->cmd(t, ".fl.l get "+sel); + stk := load Wm "/dis/wm/deb.dis"; + if(stk == nil) + break; + spawn stk->init(ctxt, "wm/deb" :: "-p "+string pid :: nil); + stk = nil; + "k" or "kg" => + sel := tk->cmd(t, ".fl.l curselection"); + if(sel == "") + break; + pid := int tk->cmd(t, ".fl.l get "+sel); + what := "opening ctl file"; + cfile := "/prog/"+string pid+"/ctl"; + cfd := sys->open(cfile, sys->OWRITE); + if(cfd != nil) { + if(bcmd == "kg"){ + if(sys->fprint(cfd, "killgrp") > 0){ + cfd = nil; + refresh(t); + break; + } + }else if(sys->fprint(cfd, "kill") > 0){ + tk->cmd(t, ".fl.l delete "+sel); + cfd = nil; + break; + } + cfd = nil; + what = "sending kill request"; + } + if(bcmd == "k" && sys->sprint("%r") == "file does not exist") { + refresh(t); + break; + } + dialog->prompt(ctxt, t.image, "error -fg red", "Kill", + "Error "+what+"\n"+ + "System: "+sys->sprint("%r"), + 0, "OK" :: nil); + "r" => + refresh(t); + "f" => + sel := tk->cmd(t, ".fl.l curselection"); + if(sel == "") + break; + pid := int tk->cmd(t, ".fl.l get "+sel); + fi := load Wm "/dis/wm/edit.dis"; + if(fi == nil) + break; + spawn fi->init(ctxt, + "edit" :: + "/prog/"+string pid+"/fd" :: nil); + fi = nil; + } + } +} + +refresh(t: ref Tk->Toplevel) +{ + tk->cmd(t, ".fl.l delete 0 end"); + readprog(t); + tk->cmd(t, ".fl.l see end;update"); +} + +mkprog(file: string): ref Prog +{ + fd := sys->open("/prog/"+file+"/status", sys->OREAD); + if(fd == nil) + return nil; + + buf := array[256] of byte; + n := sys->read(fd, buf, len buf); + if(n <= 0) + return nil; + + (v, l) := sys->tokenize(string buf[0:n], " "); + if(v < 6) + return nil; + + prg := ref Prog; + prg.pid = int hd l; + l = tl l; + prg.pgrp = int hd l; + l = tl l; + l = tl l; + # eat blanks in user name + while(len l > 3) + l = tl l; + prg.state = hd l; + l = tl l; + prg.size = int hd l; + l = tl l; + prg.mod = hd l; + + return prg; +} + +readprog(t: ref Toplevel) +{ + fd := sys->open("/prog", sys->OREAD); + if(fd == nil) + return; + for(;;) { + (n, d) := sys->dirread(fd); + if(n <= 0) + break; + for(i := 0; i < n; i++) { + p := mkprog(d[i].name); + if(p != nil){ + l := sys->sprint("%4d %4d %3dK %-7s %s", p.pid, p.pgrp, p.size, p.state, p.mod); + tk->cmd(t, ".fl.l insert end '"+l); + } + } + } +} + +sysname(): string +{ + fd := sys->open("#c/sysname", sys->OREAD); + if(fd == nil) + return "Anon"; + buf := array[128] of byte; + n := sys->read(fd, buf, len buf); + if(n < 0) + return "Anon"; + return string buf[0:n]; +} |
