diff options
Diffstat (limited to 'appl/grid/blurdemo.b')
| -rw-r--r-- | appl/grid/blurdemo.b | 977 |
1 files changed, 977 insertions, 0 deletions
diff --git a/appl/grid/blurdemo.b b/appl/grid/blurdemo.b new file mode 100644 index 00000000..7688cd02 --- /dev/null +++ b/appl/grid/blurdemo.b @@ -0,0 +1,977 @@ +implement Blurdemo; + +include "sys.m"; + sys : Sys; +include "draw.m"; + draw: Draw; + Display, Rect, Image: import draw; +include "tk.m"; + tk: Tk; +include "tkclient.m"; + tkclient: Tkclient; +include "readdir.m"; + readdir: Readdir; +include "sh.m"; +include "registries.m"; + registries: Registries; + Registry, Attributes, Service: import registries; +include "grid/pathreader.m"; + reader: PathReader; +include "grid/browser.m"; + browser: Browser; + Browse, Select, File, Parameter, + DESELECT, SELECT, TOGGLE: import browser; +include "grid/srvbrowse.m"; + srvbrowse: Srvbrowse; +include "grid/announce.m"; + announce: Announce; +include "grid/readjpg.m"; + readjpg: Readjpg; + +srvfilter: list of list of (string, string); +currstep: int; + +currsrv: ref Service; +currattach: ref Registries->Attached; +ctxt: ref Draw->Context; +display: ref Draw->Display; +sysname : string; + +IMAGE: con 0; +MOUNT: con 4; + +imgcache: ref Image; +br: ref Browse; +sel: ref Select; + +Blurdemo : module { + init : fn (context : ref Draw->Context, argv : list of string); + readpath: fn (dir: File): (array of ref sys->Dir, int); +}; + +init(context : ref Draw->Context, argv: list of string) +{ + ctxt = context; + display = ctxt.display; + sys = load Sys Sys->PATH; + if (sys == nil) + badmod(Sys->PATH); + readdir = load Readdir Readdir->PATH; + if (readdir == nil) + badmod(Readdir->PATH); + draw = load Draw Draw->PATH; + if (draw == nil) + badmod(Draw->PATH); + tk = load Tk Tk->PATH; + if (tk == nil) + badmod(Tk->PATH); + tkclient = load Tkclient Tkclient->PATH; + if (tkclient == nil) + badmod(Tkclient->PATH); + tkclient->init(); + registries = load Registries Registries->PATH; + if (registries == nil) + badmod(Registries->PATH); + registries->init(); + browser = load Browser Browser->PATH; + if (browser == nil) + badmod(Browser->PATH); + browser->init(); + srvbrowse = load Srvbrowse Srvbrowse->PATH; + if (srvbrowse == nil) + badmod(Srvbrowse->PATH); + srvbrowse->init(); + announce = load Announce Announce->PATH; + if (announce == nil) + badmod(Announce->PATH); + announce->init(); + reader = load PathReader "$self"; + if (reader == nil) + badmod("PathReader"); + readjpg = load Readjpg Readjpg->PATH; + if (readjpg == nil) + badmod(Readjpg->PATH); + readjpg->init(display); + sys->pctl(sys->FORKNS | sys->NEWPGRP, nil); + if (ctxt == nil) { + sys->print("no draw context found!\n"); + exit; + } + sysname = readfile("/dev/sysname"); + if (sysname == "") + sysname = "Localhost"; + imgcache = nil; + setsrvfilter(); + root := "/"; + currsrv = nil; + + attribs := ("resource", "Cpu Pool") :: nil; + lcpupool := srvbrowse->find(attribs :: nil); + if (lcpupool == nil) { + browser->dialog(ctxt, nil, "ok" :: nil, "Alert","Cannot find a Cpu Pool Resource"); + raise "fail: error cannot find a Cpu Pool resource"; + } + + (top, titlebar) := tkclient->toplevel(ctxt,"","BlurDemo", tkclient->Appl); + butchan := chan of string; + tk->namechan(top, butchan, "butchan"); + browsechan := chan of string; + tk->namechan(top, browsechan, "browsechan"); + selectchan := chan of string; + tk->namechan(top, selectchan, "selectchan"); + br = Browse.new(top, "browsechan", "services/", "Services", 1, reader); + bropened := array[] of { + "services/", + "services/Data source/", + "services/Camera/", + "/n/remote/", + "/" , + }; + for (i := 0; i < len bropened; i++) + br.addopened(File (bropened[i], nil), 1); + + sel = Select.new(top, "selectchan"); + + for (ik := 0; ik < len mainscreen; ik++) + tkcmd(top,mainscreen[ik]); + + currstep = -1; + + sel.addframe("image", "Select a '.bit' image"); + + changestep(top, IMAGE, nil); + + tkcmd(top, "pack .f -fill both -expand 1; pack propagate . 0"); + released := 1; + title := ""; + resize(top, ref Rect ((0,0), (400,400))); + tkclient->onscreen(top, nil); + tkclient->startinput(top, "kbd"::"ptr"::nil); + tkpath: string; + selected := array[2] of File; + if (tl argv != nil) + spawn initimg(butchan, hd tl argv); + + main: for (;;) { + alt { + s := <-top.ctxt.kbd => + tk->keyboard(top, s); + s := <-top.ctxt.ptr => + tk->pointer(top, *s); + inp := <-browsechan => + (nil, lst) := sys->tokenize(inp, " \n\t"); + if (len lst > 1) + tkpath = hd tl lst; + selected[0] = br.getselected(0); + selected[1] = br.getselected(1); + br.defaultaction(lst, nil); + i = -1; + if (!File.eq(selected[0], br.getselected(0))) + i = 0; + if (!File.eq(selected[1], br.getselected(1))) + i = 1; + if (i != -1) { + sel.select(sel.currfname,nil,DESELECT); + actionbutton(top, br.selected[i].file.path, br.selected[i].tkpath); + } + tkcmd(top, "update"); + inp := <-selectchan => + (nil, lst) := sys->tokenize(inp, " \n\t"); + case hd lst { + "but3" => + tkpath = hd tl lst; + x := string (int hd tl tl lst - 5); + y := string (int hd tl tl tl lst - 5); + + path := tkcmd(top, tkpath+" cget -text"); + s := blursrvc.attrs.get("name") + " ("+blursrvc.addr+")"; + tk->cmd(top, "destroy .m2"); + tkcmd(top, "menu .m2 -font /fonts/charon/plain.normal.font"); + tkcmd(top, ".m2 add command -label {"+path+"}"); + tkcmd(top, ".m2 add separator"); + tkcmd(top, ".m2 add command -label {"+s+"}"); + tkcmd(top, ".m2 post "+x+" "+y); + "double1" => + tkpath = hd tl lst; + path := tkcmd(top, tkpath+" cget -text"); + qid := ""; + (n, nil) := sys->tokenize(path, "/"); + if (currstep == IMAGE) { + qid = srvbrowse->getqid(blursrvc); + (res,name) := srvbrowse->getresname(blursrvc); + path = "services/"+res+"/"+name+"/"; + } + else if (currsrv.addr != blursrvc.addr) + break; + else if (blursrvc.addr != "Local Machine") + path = "/n/remote" + path; + tkpath = br.gotoselectfile(File(path,qid)); + if (tkpath != nil) { + sel.select(sel.currfname, nil, DESELECT); + actionbutton(top, path, tkpath); + } + "but1" => + if (currstep == IMAGE) + br.selectfile(0, DESELECT, File (nil, nil), nil); + else + br.selectfile(1, DESELECT, File (nil, nil), nil); + sel.defaultaction(lst); + actionbutton(top, sel.getselected(sel.currfname), hd tl lst); + * => + sel.defaultaction(lst); + } + tkcmd(top, "update"); + inp := <-butchan => + # sys->print("inp: %s\n",inp); + (nil, lst) := sys->tokenize(inp, " \n\t"); + if (len lst > 1) + tkpath = hd tl lst; + case hd lst { + "refresh" => + # ! check to see if anything is mounted first + if (currstep == IMAGE) { + # addlocalservice(); + srvbrowse->refreshservices(srvfilter); + } + br.refresh(); + "back" => + changestep(top, IMAGE, nil); + "run" => + spawn run(ctxt, getcoords(top)); + "preview" => + spawn previewwin(top, butchan, hd tl lst); + "add" => + additem(top, hd tl lst, int hd tl tl lst); + "del" => + sel.delselection("image", hd tl lst); + tkcmd (top, ".f.ftop.bn configure -state disabled"); + blurimage = nil; + blurtkpath = nil; + blursrvc = nil; + actionbutton(top, sel.getselected(sel.currfname), hd tl lst); + "mount" => + file := br.getpath(tkpath); + (nsrv, lsrv) := sys->tokenize(file.path, "/"); + if (currstep != IMAGE) + break; + if (nsrv != 3) + break; + if (hd tl tl lsrv != "Local Filestore") { + ok := mountsrv(file.path, file.qid, getcoords(top)); + if (!ok) + break; + changestep(top, MOUNT, hd tl tl lsrv); + } + else { + srv : Service; + srv.attrs = Attributes.new(("name", sysname) :: nil); + srv.addr = "Local Machine"; + currsrv = ref srv; + changestep(top, MOUNT, hd tl tl lsrv); + } + } + tkcmd(top, "update"); + + title = <-top.ctxt.ctl or + title = <-top.wreq or + title = <-titlebar => + if (title == "exit") + break main; + e := tkclient->wmctl(top, title); + if (e == nil && title[0] == '!') { + (nil, lst) := sys->tokenize(title, " \t\n"); + if (len lst >= 2 && hd lst == "!size" && hd tl lst == ".") + resize(top, nil); + } + } + } + currattach = nil; + killg(sys->pctl(0,nil)); +} + +resize(top: ref Tk->Toplevel, r: ref Draw->Rect) +{ + if (r != nil) { + sw := (*r).dx(); + sh := (*r).dy(); + ww := int tkcmd(top, ". cget -actwidth"); + wh := int tkcmd(top, ". cget -actheight"); + if (ww > sw) + tkcmd(top, ". configure -x 0 -width "+string sw); + if (wh > sh) + tkcmd(top, ". configure -y 0 -height "+string sh); + } + w := int tkcmd(top, ".fselect cget -actwidth"); + h := int tkcmd(top, ".fselect cget -actheight"); + sel.resize(w,h); +} + +nactionbuttons := 0; +actionbutton(top: ref Tk->Toplevel, path, tkpath: string) +{ + for (i := 0; i < nactionbuttons; i++) { + tkcmd(top, "grid forget .f.ftop.baction"+string i); + tkcmd(top, "destroy .f.ftop.baction"+string i); + } + if (path == nil) { + nactionbuttons = 0; + return; + } + buttons : list of (string,string) = nil; + (n, nil) := sys->tokenize(path, "/"); + if (len tkpath > 8 && tkpath[:8] == ".fselect") + buttons = ("Remove", "del "+tkpath) :: buttons; + else { + if (currstep == IMAGE) { + if (n == 3) + buttons = ("Mount", "mount "+tkpath) :: buttons; + } + else { + if (len path > 4) { + if (path[len path - 4:] == ".bit") { + buttons = ("Select", "add "+path+" 0") :: + ("Preview", "preview "+path) :: buttons; + } + else if (path[len path - 4:] == ".jpg") + buttons = ("Select", "add "+path+" 0") :: buttons; + } + } + } + nactionbuttons = len buttons; + for (i = 0; i < nactionbuttons; i++) { + name := ".f.ftop.baction"+string i+" "; + (text,cmd) := hd buttons; + tkcmd(top, "button "+name+"-text {"+text+"} "+ + "-font /fonts/charon/bold.normal.font "+ + "-command {send butchan "+cmd+"}"); + tkcmd(top, "grid "+name+" -row 0 -column "+string (4+i)); + buttons = tl buttons; + } +} + +initimg(butchan: chan of string, imgpath: string) +{ + srv : Service; + srv.attrs = Attributes.new(("name", sysname) :: nil); + srv.addr = "Local Machine"; + currsrv = ref srv; + butchan <-= "add "+imgpath+" 0"; + butchan <-= "back"; +} + +blurimage := ""; +blurtkpath := ""; +blursrvc: ref Service; + +additem(top: ref Tk->Toplevel, path: string, overwrite: int) +{ + if (blurimage != nil) { + if (overwrite || browser->dialog(ctxt, top, "ok" :: "cancel" :: nil, + "Alert","Replace existing image '" + +nopath(blurimage)+"' with '"+nopath(path)+"'?") == 0) { + sel.delselection("image", blurtkpath); + } + else + return; + } + imgpath := path; + if (currsrv.addr != "Local Machine") + path = path[len "/n/remote":]; + blurtkpath = sel.addselection("image", path, nil, 0); + tkcmd(top, "update"); + blurimage = path; + blursrvc = currsrv; + if (overwrite) + spawn getpreview(blurtkpath, nil, imgcache); + else + spawn getpreview(blurtkpath, imgpath, nil); +} + +nopath(file: string): string +{ + return file[len browser->prevpath(file):]; +} + +runscr := array[] of { + "frame .f", + "frame .f.f1", + "label .f.f1.l -text {Select no of CPUs} -font /fonts/charon/plain.normal.font", + "scale .f.f1.s -orient horizontal -height 16 -showvalue 0 -from 1 -to 20 -command {.f.f1.ls configure -text}", + "label .f.f1.ls -text {1} -font /fonts/charon/plain.normal.font -width 30", + "button .f.f1.b -text {Run} -font /fonts/charon/plain.normal.font -command {send butchan go}", + "pack .f.f1.l .f.f1.s .f.f1.ls .f.f1.b -side left", + "frame .f.f2", + "text .f.f2.t -width 250 -height 150 -borderwidth 1 -bg white -font /fonts/charon/plain.normal.font -yscrollcommand { .f.f2.sy set }", + "scrollbar .f.f2.sy -command { .f.f2.t yview }", + "pack .f.f2.sy -side left -fill y", + "pack .f.f2.t -fill both -expand 1", + "bind .Wm_t <Button-1> +{focus .Wm_t}", + "bind .Wm_t.title <Button-1> +{focus .Wm_t}", + "focus .Wm_t", + "pack .f.f1 -side top", + "pack .f.f2 -fill both -expand 1", +}; + +run(ctxt: ref Draw->Context, coords: draw->Rect) +{ + (top, titlectl) := tkclient->toplevel(ctxt, "", nil, tkclient->Resize); + butchan := chan of string; + sync := chan of int; + quit := chan of int; + tk->namechan(top, butchan, "butchan"); + tkcmds(top, runscr); + tkcmd(top, ". configure "+getcentre(top, coords)); + tkcmd(top, "pack .f -fill both -expand 1; pack propagate . 0; focus .; update"); + tkclient->onscreen(top, "exact"); + tkclient->startinput(top, "kbd"::"ptr"::nil); + done := 1; + loop: for (;;) { + alt { + s := <-top.ctxt.kbd => + tk->keyboard(top, s); + s := <-top.ctxt.ptr => + tk->pointer(top, *s); + <-sync => + tkcmd(top, ".f.f1.b configure -state normal; update"); + done = 1; + inp := <-butchan => + (nil, lst) := sys->tokenize(inp, " \n\t"); + case hd lst { + "go" => + tkcmd(top, ".f.f1.b configure -state disabled"); + ncpus := int tkcmd(top, ".f.f1.s get"); + done = 0; + spawn startit(ncpus, butchan, sync, quit); + "output" => + tkcmd(top, ".f.f2.t insert end {"+inp[len "output ":]+"}"); + "error" => + tkcmd(top, ".f.f2.t insert end {Error: "+inp[len "error ":]+"\n}"); + tkcmd(top, ".f.f1.b configure -state normal"); + "fewcpu" => + i := browser->dialog(ctxt, top, "ok" :: "cancel" :: nil, "Alert", + "Only found "+hd tl lst+" cpus available. Continue?"); + quit <-= i; + if (i == 1) + return; + } + tkcmd(top, "update"); + s := <-top.ctxt.ctl or + s = <-top.wreq or + s = <- titlectl => + if (s == "exit") { + if (done) + return; + break loop; + } + else + tkclient->wmctl(top, s); + } + } + top = nil; + for (;;) alt { + <- butchan => + ; + <-sync => + return; + } +} + +startit(ncpus: int, butchan: chan of string, sync, quit: chan of int) +{ + imgattached : ref Registries->Attached; + imgpath := blurimage; + if (blursrvc.addr != "Local Machine") { + imgattached = blursrvc.attach(nil, nil); + if (imgattached == nil) { + butchan <-= "error cannot connect to data source: "+blursrvc.attrs.get("name"); + return; + } + if (sys->mount(imgattached.fd, nil, "/n/local", sys->MREPL, nil) == -1) { + butchan <-= sys->sprint("error img mount failed: %r"); + return; + } + imgpath = "/n/local" + imgpath; + butchan <-= "output Found image namespace\n"; + } + sys->pctl(sys->FORKNS, nil); + attribs := ("resource", "Cpu Pool") :: nil; + lsrv := srvbrowse->find(attribs :: nil); + if (lsrv == nil) { + butchan <-= "error cannot find Cpu Pool resource"; + return; + } + cpupoolsrvc := hd lsrv; + attached := cpupoolsrvc.attach(nil, nil); + if (attached == nil) { + butchan <-= "error cannot connect to Cpu Pool resource"; + return; + } + if (sys->mount(attached.fd, nil, "/n/remote", sys->MREPL, nil) == -1) { + butchan <-= sys->sprint("error Cpu Pool mount failed: %r"); + return; + } + butchan <-= "output Connected to Cpu Pool resource\n"; + if (blurimage[len blurimage - 4:] == ".jpg") { + butchan <-= "output Converting jpg => bit image\n"; + chanin := chan of string; + killchan := chan of int; + spawn jpgprog(butchan, chanin, killchan); + img := readjpg->jpg2img(imgpath, "", chan of string, chanin); + killchan <-= 1; + butchan <-= "output \n"; + if (img == nil) { + butchan <-= "error Error converting jpg"; + return; + } + sys->remove("/n/remote/data/blurimage.bit"); + fd := sys->create("/n/remote/data/blurimage.bit", sys->OWRITE, 8r666); + if (fd == nil || display.writeimage(fd, img) == -1) { + butchan <-= sys->sprint("error Error saving bit: %r"); + return; + } + imgpath = "/n/remote/data/blurimage.bit"; + } + afd := array[ncpus] of ref sys->FD; + ngot := 0; + for (i := 0; i < ncpus; i++) { + afd[ngot] = sys->open("/n/remote/clone", sys->ORDWR); + if (afd[ngot] == nil) + break; + ngot++; + } + if (ngot == 0) { + butchan <-= "error no cpu resources available"; + return; + } + if (ngot < ncpus) { + butchan <-= "fewcpu "+string ngot; + q := <-quit; + if (q) + return; + } + butchan <-= "output Found "+string ngot+" Cpu resource(s)\n"; + sh := load Sh Sh->PATH; + if (sh == nil) + badmod(Sh->PATH); + sys->create("/n/remote/data/blur", sys->OREAD, 8r777 | sys->DMDIR); + done := chan of int; + for (i = 0; i < ngot; i++) + spawn go(afd[i], i, butchan, done); + err := sh->run(ctxt, "/dis/grid/demo/blur.dis" :: "/n/remote/data" :: imgpath :: nil); + if (err != nil) + butchan <-= "error "+err; + finished := 0; + for (;;) { + <-done; + finished++; + if (finished == ngot) + break; + } + sys->unmount(nil, "/n/remote"); + butchan <-= "output Finished\n"; + sync <-= 1; +} + +jpgprog(butchan, chanin: chan of string, killchan: chan of int) +{ + i := 0; + for (;;) alt { + <-killchan => + return; + <-chanin => + i = (i+1) % 2; + if (i) + butchan <-= "output ."; + } +} + +go(fd: ref sys->FD, id: int, butchan: chan of string, done: chan of int) +{ + op := "output Cpu "+string id+": "; + sys->fprint(fd, "/dis/grid/demo/blur.dis /data/"); + buf := array[sys->ATOMICIO] of byte; + sys->seek(fd, big 0, sys->SEEKSTART); + i := sys->read(fd, buf, len buf); + if (i < 1) + sys->print("Error reading dir name: %r\n"); + dir := string buf[:i]; + if (dir[len dir - 1] == '\n') + dir = dir[:len dir -1]; + fdout := sys->open("/n/remote/"+dir+"/data", sys->OREAD); + if (fdout == nil) { + butchan <-= op+"Cannot read from stdout"; + done <-= 1; + return; + } + for (;;) { + i = sys->read(fdout, buf, len buf); + if (i < 1) + break; + s := string buf[:i]; + if (s[len s - 1] != '\n') + s[len s] = '\n'; + butchan <-= op+s; + } + done <-= 1; +} + +kill(pid: int) +{ + if ((fd := sys->open("/prog/" + string pid + "/ctl", Sys->OWRITE)) != nil) + sys->fprint(fd, "kill"); +} + +killg(pid: int) +{ + if ((fd := sys->open("/prog/" + string pid + "/ctl", Sys->OWRITE)) != nil) + sys->fprint(fd, "killgrp"); +} + +mainscreen := array[] of { + "frame .f", + "frame .f.ftop", + "variable opt command", + "button .f.ftop.bp -text {Services} -command {send butchan back} -font /fonts/charon/bold.normal.font -state disabled -state disabled", + "button .f.ftop.bn -text {Run} -command {send butchan run} -font /fonts/charon/bold.normal.font -state disabled", + "button .f.ftop.br -text {Refresh} -command {send butchan refresh} -font /fonts/charon/bold.normal.font", + "grid .f.ftop.br .f.ftop.bp .f.ftop.bn -row 0", + "grid columnconfigure .f.ftop 3 -minsize 30", + "label .f.l -text { } -height 1 -bg red", + "grid .f.l -row 1 -column 0 -sticky ew", + "grid .f.ftop -row 0 -column 0 -pady 2 -sticky w", + "grid .fbrowse -in .f -row 2 -column 0 -sticky nsew", + "grid .fselect -in .f -row 3 -column 0 -sticky nsew", + "grid columnconfigure .f 0 -weight 1", + "grid rowconfigure .f 2 -weight 1", + "grid rowconfigure .f 3 -weight 1", + + "bind .Wm_t <Button-1> +{focus .Wm_t}", + "bind .Wm_t.title <Button-1> +{focus .Wm_t}", + "focus .Wm_t", +}; + +readpath(dir: File): (array of ref sys->Dir, int) +{ + if (currstep == MOUNT) { + (dirs, nil) := readdir->init(dir.path, readdir->NAME | readdir->COMPACT); + dirs2 := array[len dirs] of ref sys->Dir; + num := 0; + for (i := 0; i < len dirs; i++) + if (dirs[i].mode & sys->DMDIR || + (len dirs[i].name > 4 && ( + dirs[i].name[len dirs[i].name - 4:] == ".bit" || + dirs[i].name[len dirs[i].name - 4:] == ".jpg"))) + dirs2[num++] = dirs[i]; + return (dirs2[:num], 0); + } + else + return srvbrowse->servicepath2Dir(dir.path, int dir.qid); + return (nil, 0); +} + +badmod(path: string) +{ + sys->print("Blurdemo: failed to load %s: %r\n",path); + exit; +} + +mountscr := array[] of { + "frame .f -borderwidth 2 -relief raised", + "text .f.t -width 200 -height 60 -borderwidth 1 -bg white -font /fonts/charon/plain.normal.font", + "button .f.b -text {Cancel} -command {send butchan cancel} -width 70 -font /fonts/charon/plain.normal.font", + "grid .f.t -row 0 -column 0 -padx 10 -pady 10", + "grid .f.b -row 1 -column 0 -sticky n", + "grid rowconfigure .f 1 -minsize 30", +}; + +mountsrv(srvpath, qid: string, coords: draw->Rect):int +{ + (top, nil) := tkclient->toplevel(ctxt, "", nil, tkclient->Plain); + ctlchan := chan of string; + butchan := chan of string; + tk->namechan(top, butchan, "butchan"); + tkcmds(top, mountscr); + tkcmd(top, ". configure "+getcentre(top, coords)+"; pack .f; update"); + spawn mountit(srvpath, qid, ctlchan); + pid := int <-ctlchan; + tkclient->onscreen(top, "exact"); + tkclient->startinput(top, "kbd"::"ptr"::nil); + for (;;) { + alt { + s := <-top.ctxt.kbd => + tk->keyboard(top, s); + s := <-top.ctxt.ptr => + tk->pointer(top, *s); + e := <- ctlchan => + if (e[0] == '!') { + tkcmd(top, ".f.t insert end {"+e[1:]+"}"); + tkcmd(top, ".f.b configure -text {close}; update"); + pid = -1; + } + else if (e == "ok") + return 1; + else + tkcmd(top, ".f.t insert end {"+e+"}; update"); + <- butchan => + if (pid != -1) + kill(pid); + return 0; + } + } + return 0; +} + +mountit(srvpath, qid: string, ctlchan: chan of string) +{ + ctlchan <-= string sys->pctl(0,nil); + + n := 0; + (nil, lst) := sys->tokenize(srvpath, "/"); + stype := hd tl lst; + name := hd tl tl lst; + addr := ""; + ctlchan <-= "Connecting...\n"; + lsrv := srvbrowse->servicepath2Service(srvpath, qid); + if (len lsrv < 1) { + ctlchan <-= "!could not find service"; + return; + } + srvc := hd lsrv; + currattach = srvc.attach(nil, nil); + if (currattach == nil) { + ctlchan <-= "!attach failed"; + return; + } + ctlchan <-= "Mounting...\n"; + if (sys->mount(currattach.fd, nil, "/n/remote", sys->MREPL, nil) != -1) { + ctlchan <-= "ok"; + currsrv = srvc; + } + else + ctlchan <-= "!mount failed"; +} + +getcoords(top: ref Tk->Toplevel): draw->Rect +{ + h := int tkcmd(top, ". cget -height"); + w := int tkcmd(top, ". cget -width"); + x := int tkcmd(top, ". cget -actx"); + y := int tkcmd(top, ". cget -acty"); + r := draw->Rect((x,y),(x+w,y+h)); + return r; +} + +getcentre(top: ref Tk->Toplevel, winr: draw->Rect): string +{ + h := int tkcmd(top, ".f cget -height"); + w := int tkcmd(top, ".f cget -width"); + midx := winr.min.x + (winr.dx() / 2); + midy := winr.min.y + (winr.dy() / 2); + newx := midx - (w/2); + newy := midy - (h/2); + return "-x "+string newx+" -y "+string newy; +} + +changestep(top: ref Tk->Toplevel, step: int, label: string) +{ + root, rlabel: string; + if (step == MOUNT) { + tkcmd (top, ".f.ftop.bp configure -state normal"); + br.changeview(2); + rlabel = label; + if (currsrv.addr == "Local Machine") + root = "/"; + else + root = "/n/remote/"; + } + else if (step == IMAGE) { + br.changeview(1); + if (currsrv != nil) { + sys->unmount(nil, "/n/remote"); + currattach = nil; + currsrv = nil; + } + srvbrowse->refreshservices(srvfilter); + root = "services/"; + rlabel = "Image Services"; + sel.showframe("image"); + tkcmd (top, ".f.ftop.bp configure -state disabled"); + # addlocalservice(); + sel.select("image", nil, DESELECT); + } + currstep = step; + br.selectfile(1, DESELECT, File (nil, nil), nil); + br.selectfile(0, DESELECT,File (nil, nil), nil); + actionbutton(top, nil, nil); + + br.newroot(root, rlabel); + if (currstep == MOUNT) + br.selectfile(0, SELECT, File (root, nil), ".fbrowse.fl.f0.l"); + tkcmd(top, "update"); +} + +addlocalservice() +{ + lsrv : Service; + attrs := ("resource", "Data source") :: + ("name", "Local Filestore") :: + ("type", "styx") :: nil; + lsrv.attrs = Attributes.new(attrs); + lsrv.addr = "@your local filestore"; + srvbrowse->addservice(ref lsrv); +} + +tkcmd(top: ref Tk->Toplevel, cmd: string): string +{ + e := tk->cmd(top, cmd); + if (e != "" && e[0] == '!') + sys->print("Tk error: '%s': %s\n",cmd,e); + return e; +} + +tkcmds(top: ref Tk->Toplevel, a: array of string) +{ + for (j := 0; j < len a; j++) + tkcmd(top, a[j]); +} + +readfile(f: string): string +{ + fd := sys->open(f, sys->OREAD); + if(fd == nil) + return nil; + + buf := array[8192] of byte; + n := sys->read(fd, buf, len buf); + if(n < 0) + return nil; + + return string buf[:n]; +} + +setsrvfilter() +{ + imagefilter := ("proto", "styx") :: ("auth", "none") :: ("Image resource", "1") :: nil; + srvfilter = imagefilter :: nil; +} + +getpreview(tkpath, imgpath: string, img: ref Image) +{ + if (imgpath != nil && imgpath[len imgpath - 4:] == ".jpg") { + tkcmd (sel.top, ".f.ftop.bn configure -state normal"); + return; + } + if (img == nil) { + img = display.open(imgpath); + if (img == nil) { + browser->dialog(ctxt, sel.top, "ok" :: nil, "Alert", + sys->sprint("Invalid '.bit' image: %r")); + sel.delselection("image", blurtkpath); + blurimage = nil; + blursrvc = nil; + return; + } + } + previmg := preview(img, 100); + tk->cmd(sel.top, "destroy .preview"); + tkcmd(sel.top, "image create bitmap .preview"); + tk->putimage(sel.top, ".preview", previmg, nil); + tkcmd(sel.top, sys->sprint("%s configure -image .preview -width %d -height %d", + tkpath, previmg.r.dx(), previmg.r.dy())); + tkcmd(sel.top, "grid forget "+tkpath+"; grid "+tkpath+" -row 1 "+ + "-column 0 -columnspan 3 -pady 5 -sticky ew;"); + sel.setscrollr(sel.currfname); + tkcmd (sel.top, ".f.ftop.bn configure -state normal"); + tkcmd(sel.top, "update;"); +} + +preview(img: ref Image, maxsize: int): ref Image +{ + mx := max(img.r.dx(), img.r.dy()); + if (mx <= maxsize) { + imgcache = img; + return img; + } + prevr := Rect ((0,0), (img.r.dx()*maxsize/mx, img.r.dy()*maxsize/mx)); + tmpimg := display.newimage(img.r, Draw->RGB24, 0, Draw->White); + previmg := display.newimage(prevr, Draw->RGB24, 0, Draw->White); + tmpimg.draw(img.r, img, nil, (0,0)); + + getr := Rect ((0,0), (img.r.dx() / prevr.dx(), img.r.dy() / prevr.dy())); + + nopixels := getr.dx() * getr.dy(); + getrgb := array[nopixels * 3] of byte; + newrgb := array[3] of byte; + for (y := 0; y < prevr.dy(); y++) { + for (x := 0; x < prevr.dx(); x++) { + tmpimg.readpixels(getr.addpt((x*getr.dx(), y*getr.dy())), getrgb); + tmprgb := array[] of { 0, 0, 0 }; + for (i := 0; i < len getrgb; i++) + tmprgb[i%3] += int getrgb[i]; + for (i = 0; i < 3; i++) + newrgb[i] = byte (tmprgb[i] / nopixels); + previmg.writepixels(((x,y),(x+1,y+1)), newrgb); + } + } + imgcache = previmg; + return previmg; +} + +max(a,b: int): int +{ + if (a > b) + return a; + return b; +} + +previewscr := array[] of { + "frame .f", + "panel .f.p -borderwidth 2 -relief raised", + "button .f.bs -text Select -font /fonts/charon/plain.normal.font -command {send prevchan select} -state disabled", + "button .f.bc -text Close -font /fonts/charon/plain.normal.font -command {send prevchan close} -state disabled", + "pack .f", + "grid .f.p -row 0 -column 0 -columnspan 2 -padx 5 -pady 5", + "grid .f.bs .f.bc -row 1 -padx 5 -pady 5", + "update", +}; + +previewwin(oldtop: ref Tk->Toplevel, chanout: chan of string, path: string) +{ + (top, titlectl) := tkclient->toplevel(ctxt, "", "Loading...", 0); + prevchan := chan of string; + tk->namechan(top, prevchan, "prevchan"); + tkclient->onscreen(top, "exact"); + + img := display.open(path); + if (img == nil) { + browser->dialog(ctxt, oldtop, "ok" :: nil, "Alert", "Invalid '.bit' image"); + return; + } + + previmg := preview(img, 100); + tkcmds(top, previewscr); + tk->putimage(top, ".f.p", previmg, nil); + tkcmd(top, ".Wm_t.title configure -text Preview"); + tkcmd(top, ".f.p dirty; update"); + browser->setcentre(oldtop, top); + tkcmd(top, ".f.bs configure -state normal; .f.bc configure -state normal"); + tkclient->startinput(top, "kbd"::"ptr"::nil); + + main: for(;;) alt { + s := <-top.ctxt.kbd => + tk->keyboard(top, s); + s := <-top.ctxt.ptr => + tk->pointer(top, *s); + s := <- prevchan => + if (s == "select") + chanout <-= "add "+path+" 1"; + break main; + s := <-top.ctxt.ctl or + s = <-top.wreq or + s = <- titlectl => + if (s == "exit") + break main; + else + tkclient->wmctl(top, s); + } +} |
