ref: babf901b4a508c3ec5d1f89655f10377bbdf9637
dir: /appl/wm/task.b/
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];
}