summaryrefslogtreecommitdiff
path: root/appl/wm/task.b
diff options
context:
space:
mode:
authorCharles.Forsyth <devnull@localhost>2006-12-22 17:07:39 +0000
committerCharles.Forsyth <devnull@localhost>2006-12-22 17:07:39 +0000
commit37da2899f40661e3e9631e497da8dc59b971cbd0 (patch)
treecbc6d4680e347d906f5fa7fca73214418741df72 /appl/wm/task.b
parent54bc8ff236ac10b3eaa928fd6bcfc0cdb2ba46ae (diff)
20060303a
Diffstat (limited to 'appl/wm/task.b')
-rw-r--r--appl/wm/task.b240
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];
+}