1*37da2899SCharles.Forsythimplement Query; 2*37da2899SCharles.Forsyth 3*37da2899SCharles.Forsyth# 4*37da2899SCharles.Forsyth# Copyright © 2003 Vita Nuova Holdings Limited. All rights reserved. 5*37da2899SCharles.Forsyth# 6*37da2899SCharles.Forsyth 7*37da2899SCharles.Forsyth 8*37da2899SCharles.Forsythinclude "sys.m"; 9*37da2899SCharles.Forsyth sys : Sys; 10*37da2899SCharles.Forsythinclude "draw.m"; 11*37da2899SCharles.Forsyth draw: Draw; 12*37da2899SCharles.Forsyth Display, Rect, Image: import draw; 13*37da2899SCharles.Forsythinclude "tk.m"; 14*37da2899SCharles.Forsyth tk: Tk; 15*37da2899SCharles.Forsythinclude "tkclient.m"; 16*37da2899SCharles.Forsyth tkclient: Tkclient; 17*37da2899SCharles.Forsythinclude "readdir.m"; 18*37da2899SCharles.Forsyth readdir: Readdir; 19*37da2899SCharles.Forsythinclude "sh.m"; 20*37da2899SCharles.Forsythinclude "workdir.m"; 21*37da2899SCharles.Forsythinclude "registries.m"; 22*37da2899SCharles.Forsyth registries: Registries; 23*37da2899SCharles.Forsyth Service: import registries; 24*37da2899SCharles.Forsythinclude "grid/pathreader.m"; 25*37da2899SCharles.Forsyth reader: PathReader; 26*37da2899SCharles.Forsythinclude "grid/browser.m"; 27*37da2899SCharles.Forsyth browser: Browser; 28*37da2899SCharles.Forsyth Browse, File: import browser; 29*37da2899SCharles.Forsythinclude "grid/srvbrowse.m"; 30*37da2899SCharles.Forsyth srvbrowse: Srvbrowse; 31*37da2899SCharles.Forsythinclude "grid/fbrowse.m"; 32*37da2899SCharles.Forsythinclude "grid/announce.m"; 33*37da2899SCharles.Forsyth announce: Announce; 34*37da2899SCharles.Forsyth 35*37da2899SCharles.Forsythsrvfilter : list of list of (string, string); 36*37da2899SCharles.Forsyth 37*37da2899SCharles.ForsythQuery : module { 38*37da2899SCharles.Forsyth init : fn (context : ref Draw->Context, nil : list of string); 39*37da2899SCharles.Forsyth readpath: fn (dir: File): (array of ref sys->Dir, int); 40*37da2899SCharles.Forsyth}; 41*37da2899SCharles.Forsyth 42*37da2899SCharles.Forsythrealinit() 43*37da2899SCharles.Forsyth{ 44*37da2899SCharles.Forsyth sys = load Sys Sys->PATH; 45*37da2899SCharles.Forsyth if (sys == nil) 46*37da2899SCharles.Forsyth badmod(Sys->PATH); 47*37da2899SCharles.Forsyth readdir = load Readdir Readdir->PATH; 48*37da2899SCharles.Forsyth if (readdir == nil) 49*37da2899SCharles.Forsyth badmod(Readdir->PATH); 50*37da2899SCharles.Forsyth draw = load Draw Draw->PATH; 51*37da2899SCharles.Forsyth if (draw == nil) 52*37da2899SCharles.Forsyth badmod(Draw->PATH); 53*37da2899SCharles.Forsyth tk = load Tk Tk->PATH; 54*37da2899SCharles.Forsyth if (tk == nil) 55*37da2899SCharles.Forsyth badmod(Tk->PATH); 56*37da2899SCharles.Forsyth tkclient = load Tkclient Tkclient->PATH; 57*37da2899SCharles.Forsyth if (tkclient == nil) 58*37da2899SCharles.Forsyth badmod(Tkclient->PATH); 59*37da2899SCharles.Forsyth tkclient->init(); 60*37da2899SCharles.Forsyth workdir := load Workdir Workdir->PATH; 61*37da2899SCharles.Forsyth if (workdir == nil) 62*37da2899SCharles.Forsyth badmod(Workdir->PATH); 63*37da2899SCharles.Forsyth registries = load Registries Registries->PATH; 64*37da2899SCharles.Forsyth if (registries == nil) 65*37da2899SCharles.Forsyth badmod(Registries->PATH); 66*37da2899SCharles.Forsyth registries->init(); 67*37da2899SCharles.Forsyth browser = load Browser Browser->PATH; 68*37da2899SCharles.Forsyth if (browser == nil) 69*37da2899SCharles.Forsyth badmod(Browser->PATH); 70*37da2899SCharles.Forsyth browser->init(); 71*37da2899SCharles.Forsyth srvbrowse = load Srvbrowse Srvbrowse->PATH; 72*37da2899SCharles.Forsyth if (srvbrowse == nil) 73*37da2899SCharles.Forsyth badmod(Srvbrowse->PATH); 74*37da2899SCharles.Forsyth srvbrowse->init(); 75*37da2899SCharles.Forsyth announce = load Announce Announce->PATH; 76*37da2899SCharles.Forsyth if (announce == nil) 77*37da2899SCharles.Forsyth badmod(Announce->PATH); 78*37da2899SCharles.Forsyth announce->init(); 79*37da2899SCharles.Forsyth reader = load PathReader "$self"; 80*37da2899SCharles.Forsyth if (reader == nil) 81*37da2899SCharles.Forsyth badmod("PathReader"); 82*37da2899SCharles.Forsyth} 83*37da2899SCharles.Forsyth 84*37da2899SCharles.Forsythinit(ctxt : ref Draw->Context, nil: list of string) 85*37da2899SCharles.Forsyth{ 86*37da2899SCharles.Forsyth realinit(); 87*37da2899SCharles.Forsyth spawn start(ctxt, 1); 88*37da2899SCharles.Forsyth} 89*37da2899SCharles.Forsyth 90*37da2899SCharles.Forsythstart(ctxt: ref Draw->Context, standalone: int) 91*37da2899SCharles.Forsyth{ 92*37da2899SCharles.Forsyth sys->pctl(sys->FORKNS | sys->NEWPGRP, nil); 93*37da2899SCharles.Forsyth if (ctxt == nil) 94*37da2899SCharles.Forsyth ctxt = tkclient->makedrawcontext(); 95*37da2899SCharles.Forsyth 96*37da2899SCharles.Forsyth if (standalone) 97*37da2899SCharles.Forsyth sys->create("/tmp/query", sys->OREAD, sys->DMDIR | 8r777); 98*37da2899SCharles.Forsyth root := "/"; 99*37da2899SCharles.Forsyth (top, titlebar) := tkclient->toplevel(ctxt,"","Query", tkclient->Appl); 100*37da2899SCharles.Forsyth butchan := chan of string; 101*37da2899SCharles.Forsyth tk->namechan(top, butchan, "butchan"); 102*37da2899SCharles.Forsyth browsechan := chan of string; 103*37da2899SCharles.Forsyth tk->namechan(top, browsechan, "browsechan"); 104*37da2899SCharles.Forsyth br := Browse.new(top, "browsechan", "services/", "Services", 1, reader); 105*37da2899SCharles.Forsyth br.addopened(File ("services/", nil), 1); 106*37da2899SCharles.Forsyth srvbrowse->refreshservices(srvfilter); 107*37da2899SCharles.Forsyth br.refresh(); 108*37da2899SCharles.Forsyth 109*37da2899SCharles.Forsyth for (ik := 0; ik < len mainscreen; ik++) 110*37da2899SCharles.Forsyth tkcmd(top,mainscreen[ik]); 111*37da2899SCharles.Forsyth 112*37da2899SCharles.Forsyth tkcmd(top, "pack .f -fill both -expand 1; pack propagate . 0"); 113*37da2899SCharles.Forsyth released := 1; 114*37da2899SCharles.Forsyth title := ""; 115*37da2899SCharles.Forsyth resize(top, 400,400); 116*37da2899SCharles.Forsyth tkclient->onscreen(top, nil); 117*37da2899SCharles.Forsyth tkclient->startinput(top, "kbd"::"ptr"::nil); 118*37da2899SCharles.Forsyth tkpath: string; 119*37da2899SCharles.Forsyth main: for (;;) { 120*37da2899SCharles.Forsyth alt { 121*37da2899SCharles.Forsyth s := <-top.ctxt.kbd => 122*37da2899SCharles.Forsyth tk->keyboard(top, s); 123*37da2899SCharles.Forsyth s := <-top.ctxt.ptr => 124*37da2899SCharles.Forsyth tk->pointer(top, *s); 125*37da2899SCharles.Forsyth inp := <-browsechan => 126*37da2899SCharles.Forsyth (nil, lst) := sys->tokenize(inp, " \n\t"); 127*37da2899SCharles.Forsyth if (len lst > 1) 128*37da2899SCharles.Forsyth tkpath = hd tl lst; 129*37da2899SCharles.Forsyth selected := br.getselected(0); 130*37da2899SCharles.Forsyth br.defaultaction(lst, nil); 131*37da2899SCharles.Forsyth if (!File.eq(selected, br.getselected(0))) 132*37da2899SCharles.Forsyth actionbutton(top, br.selected[0].file.path, br.selected[0].tkpath); 133*37da2899SCharles.Forsyth tkcmd(top, "update"); 134*37da2899SCharles.Forsyth inp := <-butchan => 135*37da2899SCharles.Forsyth # sys->print("inp: %s\n",inp); 136*37da2899SCharles.Forsyth (nil, lst) := sys->tokenize(inp, " \n\t"); 137*37da2899SCharles.Forsyth if (len lst > 1) 138*37da2899SCharles.Forsyth tkpath = hd tl lst; 139*37da2899SCharles.Forsyth case hd lst { 140*37da2899SCharles.Forsyth "search" => 141*37da2899SCharles.Forsyth if (tl lst == nil) 142*37da2899SCharles.Forsyth spawn srvbrowse->searchwin(ctxt, butchan, nil); 143*37da2899SCharles.Forsyth else { 144*37da2899SCharles.Forsyth if (hd tl lst == "select") { 145*37da2899SCharles.Forsyth file := hd tl tl lst; 146*37da2899SCharles.Forsyth for (tmp := tl tl tl lst; tl tmp != nil; tmp = tl tmp) 147*37da2899SCharles.Forsyth file += " "+hd tmp; 148*37da2899SCharles.Forsyth qid := hd tmp; 149*37da2899SCharles.Forsyth br.gotoselectfile(File (file, qid)); 150*37da2899SCharles.Forsyth actionbutton(top, br.selected[0].file.path, br.selected[0].tkpath); 151*37da2899SCharles.Forsyth } 152*37da2899SCharles.Forsyth else if (hd tl lst == "search") { 153*37da2899SCharles.Forsyth srvbrowse->refreshservices(srvfilter); 154*37da2899SCharles.Forsyth br.refresh(); 155*37da2899SCharles.Forsyth } 156*37da2899SCharles.Forsyth } 157*37da2899SCharles.Forsyth "refresh" => 158*37da2899SCharles.Forsyth # ! check to see if anything is mounted first 159*37da2899SCharles.Forsyth srvbrowse->refreshservices(srvfilter); 160*37da2899SCharles.Forsyth br.refresh(); 161*37da2899SCharles.Forsyth "mount" => 162*37da2899SCharles.Forsyth file := *br.getpath(tkpath); 163*37da2899SCharles.Forsyth (nsrv, lsrv) := sys->tokenize(file.path, "/"); 164*37da2899SCharles.Forsyth if (nsrv == 3) 165*37da2899SCharles.Forsyth spawn mountsrv(ctxt, file, getcoords(top)); 166*37da2899SCharles.Forsyth } 167*37da2899SCharles.Forsyth tkcmd(top, "update"); 168*37da2899SCharles.Forsyth 169*37da2899SCharles.Forsyth title = <-top.ctxt.ctl or 170*37da2899SCharles.Forsyth title = <-top.wreq or 171*37da2899SCharles.Forsyth title = <-titlebar => 172*37da2899SCharles.Forsyth if (title == "exit") 173*37da2899SCharles.Forsyth break main; 174*37da2899SCharles.Forsyth e := tkclient->wmctl(top, title); 175*37da2899SCharles.Forsyth if (e == nil && title[0] == '!') 176*37da2899SCharles.Forsyth (nil, lst) := sys->tokenize(title, " \t\n"); 177*37da2899SCharles.Forsyth } 178*37da2899SCharles.Forsyth } 179*37da2899SCharles.Forsyth killg(sys->pctl(0,nil)); 180*37da2899SCharles.Forsyth} 181*37da2899SCharles.Forsyth 182*37da2899SCharles.Forsythresize(top: ref Tk->Toplevel, w, h: int) 183*37da2899SCharles.Forsyth{ 184*37da2899SCharles.Forsyth tkcmd(top, ". configure -x 0 -width "+string min(top.screenr.dx(), w)); 185*37da2899SCharles.Forsyth tkcmd(top, ". configure -y 0 -height "+string min(top.screenr.dy(), h)); 186*37da2899SCharles.Forsyth} 187*37da2899SCharles.Forsyth 188*37da2899SCharles.Forsythmin(a, b: int): int 189*37da2899SCharles.Forsyth{ 190*37da2899SCharles.Forsyth if (a < b) 191*37da2899SCharles.Forsyth return a; 192*37da2899SCharles.Forsyth return b; 193*37da2899SCharles.Forsyth} 194*37da2899SCharles.Forsyth 195*37da2899SCharles.Forsythnactionbuttons := 0; 196*37da2899SCharles.Forsythactionbutton(top: ref Tk->Toplevel, path, tkpath: string) 197*37da2899SCharles.Forsyth{ 198*37da2899SCharles.Forsyth for (i := 0; i < nactionbuttons; i++) { 199*37da2899SCharles.Forsyth tkcmd(top, "grid forget .f.ftop.baction"+string i); 200*37da2899SCharles.Forsyth tkcmd(top, "destroy .f.ftop.baction"+string i); 201*37da2899SCharles.Forsyth } 202*37da2899SCharles.Forsyth if (path == nil) { 203*37da2899SCharles.Forsyth nactionbuttons = 0; 204*37da2899SCharles.Forsyth return; 205*37da2899SCharles.Forsyth } 206*37da2899SCharles.Forsyth (n, nil) := sys->tokenize(path, "/"); 207*37da2899SCharles.Forsyth buttons : list of (string, string) = nil; 208*37da2899SCharles.Forsyth if (n == 3) 209*37da2899SCharles.Forsyth buttons = ("Mount", "mount "+tkpath) :: buttons; 210*37da2899SCharles.Forsyth 211*37da2899SCharles.Forsyth nactionbuttons = len buttons; 212*37da2899SCharles.Forsyth for (i = 0; i < nactionbuttons; i++) { 213*37da2899SCharles.Forsyth name := ".f.ftop.baction"+string i+" "; 214*37da2899SCharles.Forsyth (text,cmd) := hd buttons; 215*37da2899SCharles.Forsyth tkcmd(top, "button "+name+"-text {"+text+"} "+ 216*37da2899SCharles.Forsyth "-font /fonts/charon/bold.normal.font "+ 217*37da2899SCharles.Forsyth "-command {send butchan "+cmd+"}"); 218*37da2899SCharles.Forsyth tkcmd(top, "grid "+name+" -row 0 -column "+string (4+i)); 219*37da2899SCharles.Forsyth buttons = tl buttons; 220*37da2899SCharles.Forsyth } 221*37da2899SCharles.Forsyth} 222*37da2899SCharles.Forsyth 223*37da2899SCharles.Forsythkill(pid: int) 224*37da2899SCharles.Forsyth{ 225*37da2899SCharles.Forsyth if ((fd := sys->open("/prog/" + string pid + "/ctl", Sys->OWRITE)) != nil) 226*37da2899SCharles.Forsyth sys->fprint(fd, "kill"); 227*37da2899SCharles.Forsyth} 228*37da2899SCharles.Forsyth 229*37da2899SCharles.Forsythkillg(pid: int) 230*37da2899SCharles.Forsyth{ 231*37da2899SCharles.Forsyth if ((fd := sys->open("/prog/" + string pid + "/ctl", Sys->OWRITE)) != nil) 232*37da2899SCharles.Forsyth sys->fprint(fd, "killgrp"); 233*37da2899SCharles.Forsyth} 234*37da2899SCharles.Forsyth 235*37da2899SCharles.Forsythmainscreen := array[] of { 236*37da2899SCharles.Forsyth "frame .f", 237*37da2899SCharles.Forsyth "frame .f.ftop", 238*37da2899SCharles.Forsyth "variable opt command", 239*37da2899SCharles.Forsyth "button .f.ftop.br -text {Refresh} -command {send butchan refresh} -font /fonts/charon/bold.normal.font", 240*37da2899SCharles.Forsyth "button .f.ftop.bs -text {Search} -command {send butchan search} -font /fonts/charon/bold.normal.font", 241*37da2899SCharles.Forsyth "grid .f.ftop.br .f.ftop.bs -row 0", 242*37da2899SCharles.Forsyth "grid columnconfigure .f.ftop 3 -minsize 30", 243*37da2899SCharles.Forsyth "label .f.l -text { } -height 1 -bg red", 244*37da2899SCharles.Forsyth "grid .f.l -row 1 -column 0 -sticky ew", 245*37da2899SCharles.Forsyth "grid .f.ftop -row 0 -column 0 -pady 2 -sticky w", 246*37da2899SCharles.Forsyth "grid .fbrowse -in .f -row 2 -column 0 -sticky nsew", 247*37da2899SCharles.Forsyth 248*37da2899SCharles.Forsyth "grid columnconfigure .f 0 -weight 1", 249*37da2899SCharles.Forsyth "grid rowconfigure .f 2 -weight 1", 250*37da2899SCharles.Forsyth 251*37da2899SCharles.Forsyth "bind .Wm_t <Button-1> +{focus .Wm_t}", 252*37da2899SCharles.Forsyth "bind .Wm_t.title <Button-1> +{focus .Wm_t}", 253*37da2899SCharles.Forsyth "focus .Wm_t", 254*37da2899SCharles.Forsyth}; 255*37da2899SCharles.Forsyth 256*37da2899SCharles.Forsythreadpath(dir: File): (array of ref sys->Dir, int) 257*37da2899SCharles.Forsyth{ 258*37da2899SCharles.Forsyth return srvbrowse->servicepath2Dir(dir.path, int dir.qid); 259*37da2899SCharles.Forsyth} 260*37da2899SCharles.Forsyth 261*37da2899SCharles.Forsythbadmod(path: string) 262*37da2899SCharles.Forsyth{ 263*37da2899SCharles.Forsyth sys->print("Query: failed to load %s: %r\n",path); 264*37da2899SCharles.Forsyth exit; 265*37da2899SCharles.Forsyth} 266*37da2899SCharles.Forsyth 267*37da2899SCharles.Forsythmountscr := array[] of { 268*37da2899SCharles.Forsyth "frame .f -borderwidth 2 -relief raised", 269*37da2899SCharles.Forsyth "text .f.t -width 200 -height 60 -borderwidth 1 -bg white -font /fonts/charon/plain.normal.font", 270*37da2899SCharles.Forsyth "button .f.b -text {Cancel} -command {send butchan cancel} -width 70 -font /fonts/charon/plain.normal.font", 271*37da2899SCharles.Forsyth "grid .f.t -row 0 -column 0 -padx 10 -pady 10", 272*37da2899SCharles.Forsyth "grid .f.b -row 1 -column 0 -sticky n", 273*37da2899SCharles.Forsyth "grid rowconfigure .f 1 -minsize 30", 274*37da2899SCharles.Forsyth}; 275*37da2899SCharles.Forsyth 276*37da2899SCharles.Forsythmountsrv(ctxt: ref Draw->Context, srvfile: File, coords: draw->Rect) 277*37da2899SCharles.Forsyth{ 278*37da2899SCharles.Forsyth (top, nil) := tkclient->toplevel(ctxt, "", nil, tkclient->Plain); 279*37da2899SCharles.Forsyth ctlchan := chan of string; 280*37da2899SCharles.Forsyth butchan := chan of string; 281*37da2899SCharles.Forsyth tk->namechan(top, butchan, "butchan"); 282*37da2899SCharles.Forsyth tkcmds(top, mountscr); 283*37da2899SCharles.Forsyth tkcmd(top, ". configure "+getcentre(top, coords)+"; pack .f; update"); 284*37da2899SCharles.Forsyth spawn mountit(ctxt, srvfile, ctlchan); 285*37da2899SCharles.Forsyth pid := int <-ctlchan; 286*37da2899SCharles.Forsyth tkclient->onscreen(top, "exact"); 287*37da2899SCharles.Forsyth tkclient->startinput(top, "kbd"::"ptr"::nil); 288*37da2899SCharles.Forsyth for (;;) { 289*37da2899SCharles.Forsyth alt { 290*37da2899SCharles.Forsyth s := <-top.ctxt.kbd => 291*37da2899SCharles.Forsyth tk->keyboard(top, s); 292*37da2899SCharles.Forsyth s := <-top.ctxt.ptr => 293*37da2899SCharles.Forsyth tk->pointer(top, *s); 294*37da2899SCharles.Forsyth e := <- ctlchan => 295*37da2899SCharles.Forsyth if (e[0] == '!') { 296*37da2899SCharles.Forsyth tkcmd(top, ".f.t insert end {"+e[1:]+"}"); 297*37da2899SCharles.Forsyth tkcmd(top, ".f.b configure -text {close}; update"); 298*37da2899SCharles.Forsyth pid = -1; 299*37da2899SCharles.Forsyth } 300*37da2899SCharles.Forsyth else if (e == "ok") 301*37da2899SCharles.Forsyth return; 302*37da2899SCharles.Forsyth else 303*37da2899SCharles.Forsyth tkcmd(top, ".f.t insert end {"+e+"}; update"); 304*37da2899SCharles.Forsyth <- butchan => 305*37da2899SCharles.Forsyth if (pid != -1) 306*37da2899SCharles.Forsyth kill(pid); 307*37da2899SCharles.Forsyth return; 308*37da2899SCharles.Forsyth } 309*37da2899SCharles.Forsyth } 310*37da2899SCharles.Forsyth} 311*37da2899SCharles.Forsyth 312*37da2899SCharles.Forsythmountit(ctxt: ref Draw->Context, srvfile: File, ctlchan: chan of string) 313*37da2899SCharles.Forsyth{ 314*37da2899SCharles.Forsyth ctlchan <-= string sys->pctl(0,nil); 315*37da2899SCharles.Forsyth 316*37da2899SCharles.Forsyth n := 0; 317*37da2899SCharles.Forsyth (nil, lst) := sys->tokenize(srvfile.path, "/"); 318*37da2899SCharles.Forsyth stype := hd tl lst; 319*37da2899SCharles.Forsyth name := hd tl tl lst; 320*37da2899SCharles.Forsyth addr := ""; 321*37da2899SCharles.Forsyth ctlchan <-= "Connecting...\n"; 322*37da2899SCharles.Forsyth lsrv := srvbrowse->servicepath2Service(srvfile.path, srvfile.qid); 323*37da2899SCharles.Forsyth if (len lsrv < 1) { 324*37da2899SCharles.Forsyth ctlchan <-= "!could not find service"; 325*37da2899SCharles.Forsyth return; 326*37da2899SCharles.Forsyth } 327*37da2899SCharles.Forsyth srvc := hd lsrv; 328*37da2899SCharles.Forsyth 329*37da2899SCharles.Forsyth ctlchan <-= "Mounting...\n"; 330*37da2899SCharles.Forsyth 331*37da2899SCharles.Forsyth id := 0; 332*37da2899SCharles.Forsyth dir : string; 333*37da2899SCharles.Forsyth for (;;) { 334*37da2899SCharles.Forsyth dir = "/tmp/query/"+string id; 335*37da2899SCharles.Forsyth (n2, nil) := sys->stat(dir); 336*37da2899SCharles.Forsyth if (n2 == -1) { 337*37da2899SCharles.Forsyth fdtmp := sys->create(dir, sys->OREAD, sys->DMDIR | 8r777); 338*37da2899SCharles.Forsyth if (fdtmp != nil) 339*37da2899SCharles.Forsyth break; 340*37da2899SCharles.Forsyth } 341*37da2899SCharles.Forsyth else { 342*37da2899SCharles.Forsyth (dirs2, nil) := readdir->init(dir, readdir->NAME | readdir->COMPACT); 343*37da2899SCharles.Forsyth if (len dirs2 == 0) 344*37da2899SCharles.Forsyth break; 345*37da2899SCharles.Forsyth } 346*37da2899SCharles.Forsyth id++; 347*37da2899SCharles.Forsyth } 348*37da2899SCharles.Forsyth attached := srvc.attach(nil, nil); 349*37da2899SCharles.Forsyth if (attached == nil) { 350*37da2899SCharles.Forsyth ctlchan <-= sys->sprint("!could not connect: %r"); 351*37da2899SCharles.Forsyth return; 352*37da2899SCharles.Forsyth } 353*37da2899SCharles.Forsyth if (sys->mount(attached.fd, nil, dir, sys->MREPL, nil) != -1) { 354*37da2899SCharles.Forsyth ctlchan <-= "ok"; 355*37da2899SCharles.Forsyth fbrowse := load FBrowse FBrowse->PATH; 356*37da2899SCharles.Forsyth if (fbrowse == nil) 357*37da2899SCharles.Forsyth badmod(FBrowse->PATH); 358*37da2899SCharles.Forsyth fbrowse->init(ctxt, srvfile.path, dir, dir); 359*37da2899SCharles.Forsyth sys->unmount(nil, dir); 360*37da2899SCharles.Forsyth attached = nil; 361*37da2899SCharles.Forsyth } 362*37da2899SCharles.Forsyth else 363*37da2899SCharles.Forsyth ctlchan <-= sys->sprint("!mount failed: %r"); 364*37da2899SCharles.Forsyth} 365*37da2899SCharles.Forsyth 366*37da2899SCharles.Forsythgetcoords(top: ref Tk->Toplevel): draw->Rect 367*37da2899SCharles.Forsyth{ 368*37da2899SCharles.Forsyth h := int tkcmd(top, ". cget -height"); 369*37da2899SCharles.Forsyth w := int tkcmd(top, ". cget -width"); 370*37da2899SCharles.Forsyth x := int tkcmd(top, ". cget -actx"); 371*37da2899SCharles.Forsyth y := int tkcmd(top, ". cget -acty"); 372*37da2899SCharles.Forsyth r := draw->Rect((x,y),(x+w,y+h)); 373*37da2899SCharles.Forsyth return r; 374*37da2899SCharles.Forsyth} 375*37da2899SCharles.Forsyth 376*37da2899SCharles.Forsythgetcentre(top: ref Tk->Toplevel, winr: draw->Rect): string 377*37da2899SCharles.Forsyth{ 378*37da2899SCharles.Forsyth h := int tkcmd(top, ".f cget -height"); 379*37da2899SCharles.Forsyth w := int tkcmd(top, ".f cget -width"); 380*37da2899SCharles.Forsyth midx := winr.min.x + (winr.dx() / 2); 381*37da2899SCharles.Forsyth midy := winr.min.y + (winr.dy() / 2); 382*37da2899SCharles.Forsyth newx := midx - (w/2); 383*37da2899SCharles.Forsyth newy := midy - (h/2); 384*37da2899SCharles.Forsyth return "-x "+string newx+" -y "+string newy; 385*37da2899SCharles.Forsyth} 386*37da2899SCharles.Forsyth 387*37da2899SCharles.Forsythtkcmd(top: ref Tk->Toplevel, cmd: string): string 388*37da2899SCharles.Forsyth{ 389*37da2899SCharles.Forsyth e := tk->cmd(top, cmd); 390*37da2899SCharles.Forsyth if (e != "" && e[0] == '!') 391*37da2899SCharles.Forsyth sys->print("Tk error: '%s': %s\n",cmd,e); 392*37da2899SCharles.Forsyth return e; 393*37da2899SCharles.Forsyth} 394*37da2899SCharles.Forsyth 395*37da2899SCharles.Forsythtkcmds(top: ref Tk->Toplevel, a: array of string) 396*37da2899SCharles.Forsyth{ 397*37da2899SCharles.Forsyth for (j := 0; j < len a; j++) 398*37da2899SCharles.Forsyth tkcmd(top, a[j]); 399*37da2899SCharles.Forsyth} 400