1implement WmTask; 2 3include "sys.m"; 4 sys: Sys; 5 Dir: import sys; 6 7include "draw.m"; 8 draw: Draw; 9 10include "tk.m"; 11 tk: Tk; 12 Toplevel: import tk; 13 14include "tkclient.m"; 15 tkclient: Tkclient; 16 17include "dialog.m"; 18 dialog: Dialog; 19 20Prog: adt 21{ 22 pid: int; 23 pgrp: int; 24 size: int; 25 state: string; 26 mod: string; 27}; 28 29WmTask: module 30{ 31 init: fn(ctxt: ref Draw->Context, argv: list of string); 32}; 33 34Wm: module 35{ 36 init: fn(ctxt: ref Draw->Context, argv: list of string); 37}; 38 39task_cfg := array[] of { 40 "frame .fl", 41 "scrollbar .fl.scroll -command {.fl.l yview}", 42 "listbox .fl.l -width 40w -yscrollcommand {.fl.scroll set}", 43 "frame .b", 44 "button .b.ref -text Refresh -command {send cmd r}", 45 "button .b.deb -text Debug -command {send cmd d}", 46 "button .b.files -text Files -command {send cmd f}", 47 "button .b.kill -text Kill -command {send cmd k}", 48 "button .b.killg -text {Kill Group} -command {send cmd kg}", 49 "pack .b.ref .b.deb .b.files .b.kill .b.killg -side left -padx 2 -pady 2", 50 "pack .b -fill x", 51 "pack .fl.scroll -side left -fill y", 52 "pack .fl.l -fill both -expand 1", 53 "pack .fl -fill both -expand 1", 54 "pack propagate . 0", 55}; 56 57init(ctxt: ref Draw->Context, nil: list of string) 58{ 59 sys = load Sys Sys->PATH; 60 if (ctxt == nil) { 61 sys->fprint(sys->fildes(2), "task: no window context\n"); 62 raise "fail:bad context"; 63 } 64 draw = load Draw Draw->PATH; 65 tk = load Tk Tk->PATH; 66 tkclient= load Tkclient Tkclient->PATH; 67 dialog = load Dialog Dialog->PATH; 68 69 tkclient->init(); 70 dialog->init(); 71 72 sysnam := sysname(); 73 74 (t, wmctl) := tkclient->toplevel(ctxt, "", sysnam, Tkclient->Appl); 75 if(t == nil) 76 return; 77 78 cmd := chan of string; 79 tk->namechan(t, cmd, "cmd"); 80 81 for (c:=0; c<len task_cfg; c++) 82 tk->cmd(t, task_cfg[c]); 83 84 readprog(t); 85 86 tk->cmd(t, ".fl.l see end;update"); 87 tkclient->onscreen(t, nil); 88 tkclient->startinput(t, "kbd"::"ptr"::nil); 89 90 for(;;) alt { 91 s := <-t.ctxt.kbd => 92 tk->keyboard(t, s); 93 s := <-t.ctxt.ptr => 94 tk->pointer(t, *s); 95 s := <-t.ctxt.ctl or 96 s = <-t.wreq => 97 tkclient->wmctl(t, s); 98 menu := <-wmctl => 99 case menu { 100 "exit" => 101 return; 102 "task" => 103 tkclient->wmctl(t, menu); 104 tk->cmd(t, ".fl.l delete 0 end"); 105 readprog(t); 106 tk->cmd(t, ".fl.l see end;update"); 107 * => 108 tkclient->wmctl(t, menu); 109 } 110 bcmd := <-cmd => 111 case bcmd { 112 "d" => 113 sel := tk->cmd(t, ".fl.l curselection"); 114 if(sel == "") 115 break; 116 pid := int tk->cmd(t, ".fl.l get "+sel); 117 stk := load Wm "/dis/wm/deb.dis"; 118 if(stk == nil) 119 break; 120 spawn stk->init(ctxt, "wm/deb" :: "-p "+string pid :: nil); 121 stk = nil; 122 "k" or "kg" => 123 sel := tk->cmd(t, ".fl.l curselection"); 124 if(sel == "") 125 break; 126 pid := int tk->cmd(t, ".fl.l get "+sel); 127 what := "opening ctl file"; 128 cfile := "/prog/"+string pid+"/ctl"; 129 cfd := sys->open(cfile, sys->OWRITE); 130 if(cfd != nil) { 131 if(bcmd == "kg"){ 132 if(sys->fprint(cfd, "killgrp") > 0){ 133 cfd = nil; 134 refresh(t); 135 break; 136 } 137 }else if(sys->fprint(cfd, "kill") > 0){ 138 tk->cmd(t, ".fl.l delete "+sel); 139 cfd = nil; 140 break; 141 } 142 cfd = nil; 143 what = "sending kill request"; 144 } 145 if(bcmd == "k" && sys->sprint("%r") == "file does not exist") { 146 refresh(t); 147 break; 148 } 149 dialog->prompt(ctxt, t.image, "error -fg red", "Kill", 150 "Error "+what+"\n"+ 151 "System: "+sys->sprint("%r"), 152 0, "OK" :: nil); 153 "r" => 154 refresh(t); 155 "f" => 156 sel := tk->cmd(t, ".fl.l curselection"); 157 if(sel == "") 158 break; 159 pid := int tk->cmd(t, ".fl.l get "+sel); 160 fi := load Wm "/dis/wm/edit.dis"; 161 if(fi == nil) 162 break; 163 spawn fi->init(ctxt, 164 "edit" :: 165 "/prog/"+string pid+"/fd" :: nil); 166 fi = nil; 167 } 168 } 169} 170 171refresh(t: ref Tk->Toplevel) 172{ 173 tk->cmd(t, ".fl.l delete 0 end"); 174 readprog(t); 175 tk->cmd(t, ".fl.l see end;update"); 176} 177 178mkprog(file: string): ref Prog 179{ 180 fd := sys->open("/prog/"+file+"/status", sys->OREAD); 181 if(fd == nil) 182 return nil; 183 184 buf := array[256] of byte; 185 n := sys->read(fd, buf, len buf); 186 if(n <= 0) 187 return nil; 188 189 (v, l) := sys->tokenize(string buf[0:n], " "); 190 if(v < 6) 191 return nil; 192 193 prg := ref Prog; 194 prg.pid = int hd l; 195 l = tl l; 196 prg.pgrp = int hd l; 197 l = tl l; 198 l = tl l; 199 # eat blanks in user name 200 while(len l > 3) 201 l = tl l; 202 prg.state = hd l; 203 l = tl l; 204 prg.size = int hd l; 205 l = tl l; 206 prg.mod = hd l; 207 208 return prg; 209} 210 211readprog(t: ref Toplevel) 212{ 213 fd := sys->open("/prog", sys->OREAD); 214 if(fd == nil) 215 return; 216 for(;;) { 217 (n, d) := sys->dirread(fd); 218 if(n <= 0) 219 break; 220 for(i := 0; i < n; i++) { 221 p := mkprog(d[i].name); 222 if(p != nil){ 223 l := sys->sprint("%4d %4d %3dK %-7s %s", p.pid, p.pgrp, p.size, p.state, p.mod); 224 tk->cmd(t, ".fl.l insert end '"+l); 225 } 226 } 227 } 228} 229 230sysname(): string 231{ 232 fd := sys->open("#c/sysname", sys->OREAD); 233 if(fd == nil) 234 return "Anon"; 235 buf := array[128] of byte; 236 n := sys->read(fd, buf, len buf); 237 if(n < 0) 238 return "Anon"; 239 return string buf[0:n]; 240} 241