137da2899SCharles.Forsyth# Gui implementation for running under wm (tk window manager) 237da2899SCharles.Forsythimplement Gui; 337da2899SCharles.Forsyth 437da2899SCharles.Forsythinclude "common.m"; 537da2899SCharles.Forsythinclude "tk.m"; 637da2899SCharles.Forsythinclude "tkclient.m"; 737da2899SCharles.Forsyth 837da2899SCharles.Forsythinclude "dialog.m"; 937da2899SCharles.Forsyth dialog: Dialog; 1037da2899SCharles.Forsyth 1137da2899SCharles.Forsythsys: Sys; 1237da2899SCharles.Forsyth 1337da2899SCharles.ForsythD: Draw; 1437da2899SCharles.Forsyth Font,Point, Rect, Image, Screen, Display: import D; 1537da2899SCharles.Forsyth 1637da2899SCharles.ForsythCU: CharonUtils; 1737da2899SCharles.Forsyth 1837da2899SCharles.ForsythE: Events; 1937da2899SCharles.Forsyth Event: import E; 2037da2899SCharles.Forsyth 2137da2899SCharles.Forsythtk: Tk; 2237da2899SCharles.Forsyth 2337da2899SCharles.Forsythtkclient: Tkclient; 2437da2899SCharles.Forsyth 2537da2899SCharles.ForsythWINDOW, CTLS, PROG, STATUS, BORDER, EXIT: con 1 << iota; 2637da2899SCharles.ForsythREQD: con ~0; 2737da2899SCharles.Forsyth 2837da2899SCharles.Forsythcfg := array[] of { 2937da2899SCharles.Forsyth (REQD, "entry .ctlf.url -bg white -font /fonts/lucidasans/unicode.7.font -height 16"), 3037da2899SCharles.Forsyth (REQD, "button .ctlf.back -bd 1 -command {send gctl back} -state disabled -text {back} -font /fonts/lucidasans/unicode.7.font"), 3137da2899SCharles.Forsyth (REQD, "button .ctlf.stop -bd 1 -command {send gctl stop} -state disabled -text {stop} -font /fonts/lucidasans/unicode.7.font"), 3237da2899SCharles.Forsyth (REQD, "button .ctlf.fwd -bd 1 -command {send gctl fwd} -state disabled -text {next} -font /fonts/lucidasans/unicode.7.font"), 3337da2899SCharles.Forsyth (REQD, "label .status.status -bd 1 -font /fonts/lucidasans/unicode.6.font -height 14 -anchor w"), 3437da2899SCharles.Forsyth (REQD, "button .ctlf.exit -bd 1 -bitmap exit.bit -command {send wm_title exit}"), 3537da2899SCharles.Forsyth (REQD, "frame .f -bd 0"), 3637da2899SCharles.Forsyth (BORDER, ".f configure -bd 2 -relief sunken"), 3737da2899SCharles.Forsyth (CTLS|EXIT, "frame .ctlf"), 3837da2899SCharles.Forsyth (STATUS, "frame .status -bd 0"), 3937da2899SCharles.Forsyth (STATUS, "frame .statussep -bg black -height 1"), 4037da2899SCharles.Forsyth (STATUS, "button .status.snarf -text snarf -command {send gctl snarfstatus} -font /fonts/charon/plain.small.font"), 4137da2899SCharles.Forsyth 4237da2899SCharles.Forsyth (CTLS, "bind .ctlf.url <Key-\n> {send gctl go}"), 4337da2899SCharles.Forsyth (CTLS, "bind .ctlf.url <Key-\u0003> {send gctl copyurl}"), 4437da2899SCharles.Forsyth (CTLS, "bind .ctlf.url <Key-\u0016> {send gctl pasteurl}"), 4537da2899SCharles.Forsyth 4637da2899SCharles.Forsyth# (PROG, "canvas .prog -bd 0 -height 20"), 4737da2899SCharles.Forsyth# (PROG, "bind .prog <ButtonPress-1> {send gctl b1p %X %Y}"), 4837da2899SCharles.Forsyth (CTLS, "pack .ctlf.back .ctlf.stop .ctlf.fwd -side left -anchor w -fill y"), 4937da2899SCharles.Forsyth (CTLS, "pack .ctlf.url -side left -padx 2 -fill x -expand 1"), 5037da2899SCharles.Forsyth (EXIT, "pack .ctlf.exit -side right -anchor e"), 5137da2899SCharles.Forsyth (CTLS|EXIT, "pack .ctlf -side top -fill x"), 5237da2899SCharles.Forsyth (REQD, "pack .f -side top -fill both -expand 1"), 5337da2899SCharles.Forsyth# (PROG, "pack .prog -side bottom -fill x"), 5437da2899SCharles.Forsyth (STATUS, "pack .status.snarf -side right"), 5537da2899SCharles.Forsyth (STATUS, "pack .status.status -side right -fill x -expand 1"), 5637da2899SCharles.Forsyth (STATUS, "pack .statussep -side top -fill x"), 5737da2899SCharles.Forsyth (STATUS, "pack .status -side bottom -fill x"), 5837da2899SCharles.Forsyth (CTLS|EXIT, "pack propagate .ctlf 0"), 5937da2899SCharles.Forsyth (STATUS, "pack propagate .status 0"), 6037da2899SCharles.Forsyth}; 6137da2899SCharles.Forsyth 6237da2899SCharles.Forsythframebinds := array[] of { 6337da2899SCharles.Forsyth "bind .f <Key> {send gctl k %s}", 6437da2899SCharles.Forsyth "bind .f <FocusOut> {send gctl focusout}", 6537da2899SCharles.Forsyth "bind .f <ButtonPress-1> {grab set .f;send gctl b1p %X %Y}", 6637da2899SCharles.Forsyth "bind .f <Double-ButtonPress-1> {send gctl b1p %X %Y}", 6737da2899SCharles.Forsyth "bind .f <ButtonRelease-1> {grab release .f;send gctl b1r %X %Y}", 6837da2899SCharles.Forsyth "bind .f <Motion-Button-1> {send gctl b1d %X %Y}", 6937da2899SCharles.Forsyth "bind .f <ButtonPress-2> {send gctl b2p %X %Y}", 7037da2899SCharles.Forsyth "bind .f <Double-ButtonPress-2> {send gctl b2p %X %Y}", 7137da2899SCharles.Forsyth "bind .f <ButtonRelease-2> {send gctl b2r %X %Y}", 7237da2899SCharles.Forsyth "bind .f <Motion-Button-2> {send gctl b2d %X %Y}", 7337da2899SCharles.Forsyth "bind .f <ButtonPress-3> {send gctl b3p %X %Y}", 7437da2899SCharles.Forsyth "bind .f <Double-ButtonPress-3> {send gctl b3p %X %Y}", 7537da2899SCharles.Forsyth "bind .f <ButtonRelease-3> {send gctl b3r %X %Y}", 7637da2899SCharles.Forsyth "bind .f <Motion-Button-3> {send gctl b3d %X %Y}", 7737da2899SCharles.Forsyth "bind .f <Motion> {send gctl m %X %Y}", 7837da2899SCharles.Forsyth}; 7937da2899SCharles.Forsyth 8037da2899SCharles.Forsythtktop: ref Tk->Toplevel; 8137da2899SCharles.Forsythmousegrabbed := 0; 8237da2899SCharles.Forsythoffset: Point; 8337da2899SCharles.ForsythZP: con Point(0,0); 8437da2899SCharles.Forsythpopup: ref Popup; 8537da2899SCharles.Forsythpopuptk: ref Tk->Toplevel; 8637da2899SCharles.Forsythgctl: chan of string; 8737da2899SCharles.Forsythdrawctxt: ref Draw->Context; 8837da2899SCharles.Forsyth 8937da2899SCharles.Forsythrealwin: ref Draw->Image; 9037da2899SCharles.Forsythmask: ref Draw->Image; 9137da2899SCharles.Forsyth 9237da2899SCharles.Forsythinit(ctxt: ref Draw->Context, cu: CharonUtils): ref Draw->Context 9337da2899SCharles.Forsyth{ 9437da2899SCharles.Forsyth sys = load Sys Sys->PATH; 9537da2899SCharles.Forsyth D = load Draw Draw->PATH; 9637da2899SCharles.Forsyth CU = cu; 9737da2899SCharles.Forsyth E = cu->E; 9837da2899SCharles.Forsyth tk = load Tk Tk->PATH; 9937da2899SCharles.Forsyth tkclient = load Tkclient Tkclient->PATH; 10037da2899SCharles.Forsyth if(tkclient == nil) 101*54041ca4Sforsyth raise sys->sprint("EXInternal: can't load module Tkclient: %r"); 10237da2899SCharles.Forsyth tkclient->init(); 10337da2899SCharles.Forsyth 10437da2899SCharles.Forsyth wmctl: chan of string; 10537da2899SCharles.Forsyth buttons := parsebuttons((CU->config).buttons); 10637da2899SCharles.Forsyth winopts := parsewinopts((CU->config).framework); 10737da2899SCharles.Forsyth 10837da2899SCharles.Forsyth (tktop, wmctl) = tkclient->toplevel(ctxt, "", (CU->config).wintitle, buttons); 10937da2899SCharles.Forsyth 11037da2899SCharles.Forsyth ctxt = tktop.ctxt.ctxt; 11137da2899SCharles.Forsyth drawctxt = ctxt; 11237da2899SCharles.Forsyth display = ctxt.display; 11337da2899SCharles.Forsyth 11437da2899SCharles.Forsyth gctl = chan of string; 11537da2899SCharles.Forsyth tk->namechan(tktop, gctl, "gctl"); 11637da2899SCharles.Forsyth tk->cmd(tktop, "pack propagate . 0"); 11737da2899SCharles.Forsyth filtertkcmds(tktop, winopts, cfg); 11837da2899SCharles.Forsyth tkcmds(tktop, framebinds); 11937da2899SCharles.Forsyth w := (CU->config).defaultwidth; 12037da2899SCharles.Forsyth h := (CU->config).defaultheight; 12137da2899SCharles.Forsyth tk->cmd(tktop, ". configure -width " + string w + " -height " + string h); 12237da2899SCharles.Forsyth tk->cmd(tktop, "update"); 12337da2899SCharles.Forsyth tkclient->onscreen(tktop, nil); 12437da2899SCharles.Forsyth tkclient->startinput(tktop, "kbd"::"ptr"::nil); 12537da2899SCharles.Forsyth makewins(); 12637da2899SCharles.Forsyth mask = display.opaque; 12737da2899SCharles.Forsyth progress = chan of Progressmsg; 12837da2899SCharles.Forsyth pidc := chan of int; 12937da2899SCharles.Forsyth spawn progmon(pidc); 13037da2899SCharles.Forsyth <- pidc; 13137da2899SCharles.Forsyth spawn evhandle(tktop, wmctl, E->evchan); 13237da2899SCharles.Forsyth return ctxt; 13337da2899SCharles.Forsyth} 13437da2899SCharles.Forsyth 13537da2899SCharles.Forsythparsebuttons(s: string): int 13637da2899SCharles.Forsyth{ 13737da2899SCharles.Forsyth b := 0; 13837da2899SCharles.Forsyth (nil, toks) := sys->tokenize(s, ","); 13937da2899SCharles.Forsyth for (;toks != nil; toks = tl toks) { 14037da2899SCharles.Forsyth case hd toks { 14137da2899SCharles.Forsyth "help" => 14237da2899SCharles.Forsyth b |= Tkclient->Help; 14337da2899SCharles.Forsyth "resize" => 14437da2899SCharles.Forsyth b |= Tkclient->Resize; 14537da2899SCharles.Forsyth "hide" => 14637da2899SCharles.Forsyth b |= Tkclient->Hide; 14737da2899SCharles.Forsyth "plain" => 14837da2899SCharles.Forsyth b = Tkclient->Plain; 14937da2899SCharles.Forsyth } 15037da2899SCharles.Forsyth } 15137da2899SCharles.Forsyth return b | Tkclient->Help; 15237da2899SCharles.Forsyth} 15337da2899SCharles.Forsyth 15437da2899SCharles.Forsythparsewinopts(s: string): int 15537da2899SCharles.Forsyth{ 15637da2899SCharles.Forsyth b := WINDOW; 15737da2899SCharles.Forsyth (nil, toks) := sys->tokenize(s, ","); 15837da2899SCharles.Forsyth for (;toks != nil; toks = tl toks) { 15937da2899SCharles.Forsyth case hd toks { 16037da2899SCharles.Forsyth "status" => 16137da2899SCharles.Forsyth b |= STATUS; 16237da2899SCharles.Forsyth "controls" or "ctls" => 16337da2899SCharles.Forsyth b |= CTLS; 16437da2899SCharles.Forsyth "progress" or "prog" => 16537da2899SCharles.Forsyth b |= PROG; 16637da2899SCharles.Forsyth "border" => 16737da2899SCharles.Forsyth b |= BORDER; 16837da2899SCharles.Forsyth "exit" => 16937da2899SCharles.Forsyth b |= EXIT; 17037da2899SCharles.Forsyth "all" => 17137da2899SCharles.Forsyth # note: "all" doesn't include 'EXIT' ! 17237da2899SCharles.Forsyth b |= WINDOW | STATUS | CTLS | PROG | BORDER; 17337da2899SCharles.Forsyth } 17437da2899SCharles.Forsyth } 17537da2899SCharles.Forsyth return b; 17637da2899SCharles.Forsyth} 17737da2899SCharles.Forsyth 17837da2899SCharles.Forsythfiltertkcmds(top: ref Tk->Toplevel, filter: int, cmds: array of (int, string)) 17937da2899SCharles.Forsyth{ 18037da2899SCharles.Forsyth for (i := 0; i < len cmds; i++) { 18137da2899SCharles.Forsyth (val, cmd) := cmds[i]; 18237da2899SCharles.Forsyth if (val & filter) { 18337da2899SCharles.Forsyth if ((e := tk->cmd(top, cmd)) != nil && e[0] == '!') 18437da2899SCharles.Forsyth sys->print("tk error on '%s': %s\n", cmd, e); 18537da2899SCharles.Forsyth } 18637da2899SCharles.Forsyth } 18737da2899SCharles.Forsyth} 18837da2899SCharles.Forsyth 18937da2899SCharles.Forsythtkcmds(top: ref Tk->Toplevel, cmds: array of string) 19037da2899SCharles.Forsyth{ 19137da2899SCharles.Forsyth for (i := 0; i < len cmds; i++) 19237da2899SCharles.Forsyth if ((e := tk->cmd(top, cmds[i])) != nil && e[0] == '!') 19337da2899SCharles.Forsyth sys->print("tk error on '%s': %s\n", cmds[i], e); 19437da2899SCharles.Forsyth} 19537da2899SCharles.Forsyth 19637da2899SCharles.Forsythclientr(t: ref Tk->Toplevel, wname: string): Rect 19737da2899SCharles.Forsyth{ 19837da2899SCharles.Forsyth bd := int tk->cmd(t, wname + " cget -borderwidth"); 19937da2899SCharles.Forsyth x := bd + int tk->cmd(t, wname + " cget -actx"); 20037da2899SCharles.Forsyth y := bd + int tk->cmd(t, wname + " cget -acty"); 20137da2899SCharles.Forsyth w := int tk->cmd(t, wname + " cget -actwidth"); 20237da2899SCharles.Forsyth h := int tk->cmd(t, wname + " cget -actheight"); 20337da2899SCharles.Forsyth return Rect((x,y),(x+w,y+h)); 20437da2899SCharles.Forsyth} 20537da2899SCharles.Forsyth 20637da2899SCharles.Forsythprogmon(pidc: chan of int) 20737da2899SCharles.Forsyth{ 20837da2899SCharles.Forsyth pidc <-= sys->pctl(0, nil); 20937da2899SCharles.Forsyth for (;;) { 21037da2899SCharles.Forsyth msg := <- progress; 21137da2899SCharles.Forsyth#prprog(msg); 21237da2899SCharles.Forsyth # just handle stop button for now 21337da2899SCharles.Forsyth if (msg.bsid == -1) { 21437da2899SCharles.Forsyth case (msg.state) { 21537da2899SCharles.Forsyth Pstart => stopbutton(1); 21637da2899SCharles.Forsyth * => stopbutton(0); 21737da2899SCharles.Forsyth } 21837da2899SCharles.Forsyth } 21937da2899SCharles.Forsyth } 22037da2899SCharles.Forsyth} 22137da2899SCharles.Forsyth 22237da2899SCharles.Forsythst2s := array [] of { 22337da2899SCharles.Forsyth Punused => "unused", 22437da2899SCharles.Forsyth Pstart => "start", 22537da2899SCharles.Forsyth Pconnected => "connected", 22637da2899SCharles.Forsyth Psslconnected => "sslconnected", 22737da2899SCharles.Forsyth Phavehdr => "havehdr", 22837da2899SCharles.Forsyth Phavedata => "havedata", 22937da2899SCharles.Forsyth Pdone => "done", 23037da2899SCharles.Forsyth Perr => "error", 23137da2899SCharles.Forsyth Paborted => "aborted", 23237da2899SCharles.Forsyth}; 23337da2899SCharles.Forsyth 23437da2899SCharles.Forsythprprog(m:Progressmsg) 23537da2899SCharles.Forsyth{ 23637da2899SCharles.Forsyth sys->print("%d %s %d%% %s\n", m.bsid, st2s[m.state], m.pcnt, m.s); 23737da2899SCharles.Forsyth} 23837da2899SCharles.Forsyth 23937da2899SCharles.Forsyth 24037da2899SCharles.Forsythr2s(r: Rect): string 24137da2899SCharles.Forsyth{ 24237da2899SCharles.Forsyth return sys->sprint("%d %d %d %d", r.min.x, r.min.y, r.max.x, r.max.y); 24337da2899SCharles.Forsyth} 24437da2899SCharles.Forsyth 24537da2899SCharles.Forsythwinpos(t: ref Tk->Toplevel): Point 24637da2899SCharles.Forsyth{ 24737da2899SCharles.Forsyth return (int tk->cmd(t, ". cget -actx"), int tk->cmd(t, ". cget -acty")); 24837da2899SCharles.Forsyth} 24937da2899SCharles.Forsyth 25037da2899SCharles.Forsythevhandle(t: ref Tk->Toplevel, wmctl: chan of string, evchan: chan of ref Event) 25137da2899SCharles.Forsyth{ 25237da2899SCharles.Forsyth for(;;) { 25337da2899SCharles.Forsyth ev: ref Event = nil; 25437da2899SCharles.Forsyth dismisspopup := 1; 25537da2899SCharles.Forsyth alt { 25637da2899SCharles.Forsyth s := <-gctl => 25737da2899SCharles.Forsyth (nil, l) := sys->tokenize(s, " "); 25837da2899SCharles.Forsyth case hd l { 25937da2899SCharles.Forsyth "focusout" => 26037da2899SCharles.Forsyth ev = ref Event.Elostfocus; 26137da2899SCharles.Forsyth "b1p" or "b1r" or "b1d" or 26237da2899SCharles.Forsyth "b2p" or "b2r" or "b2d" or 26337da2899SCharles.Forsyth "b3p" or "b3r" or "b3d" or 26437da2899SCharles.Forsyth "m" => 26537da2899SCharles.Forsyth l = tl l; 26637da2899SCharles.Forsyth pt := Point(int hd l, int hd tl l); 26737da2899SCharles.Forsyth pt = pt.sub(offset); 26837da2899SCharles.Forsyth mtype := s2mtype(s); 26937da2899SCharles.Forsyth dismisspopup = 0; 27037da2899SCharles.Forsyth if(mtype == E->Mlbuttondown) { 27137da2899SCharles.Forsyth tk->cmd(t, "focus .f"); 27237da2899SCharles.Forsyth pu := popup; 27337da2899SCharles.Forsyth if (pu != nil && !pu.r.contains(pt)) 27437da2899SCharles.Forsyth dismisspopup = 1; 27537da2899SCharles.Forsyth pu = nil; 27637da2899SCharles.Forsyth } 27737da2899SCharles.Forsyth ev = ref Event.Emouse(pt, mtype); 27837da2899SCharles.Forsyth "k" => 27937da2899SCharles.Forsyth dismisspopup = 0; 28037da2899SCharles.Forsyth k := int hd tl l; 28137da2899SCharles.Forsyth if(k != 0) 28237da2899SCharles.Forsyth ev = ref Event.Ekey(k); 28337da2899SCharles.Forsyth "back" => 28437da2899SCharles.Forsyth ev = ref Event.Eback; 28537da2899SCharles.Forsyth "stop" => 28637da2899SCharles.Forsyth ev = ref Event.Estop; 28737da2899SCharles.Forsyth "fwd" => 28837da2899SCharles.Forsyth ev = ref Event.Efwd; 28937da2899SCharles.Forsyth "go" => 29037da2899SCharles.Forsyth url := tk->cmd(tktop, ".ctlf.url get"); 29137da2899SCharles.Forsyth if (url != nil) 29237da2899SCharles.Forsyth ev = ref Event.Ego(url, nil, 0, E->EGnormal); 29337da2899SCharles.Forsyth "copyurl" => 29437da2899SCharles.Forsyth url := tk->cmd(tktop, ".ctlf.url get"); 29537da2899SCharles.Forsyth snarfput(url); 29637da2899SCharles.Forsyth "pasteurl" => 29737da2899SCharles.Forsyth url := tk->quote(tkclient->snarfget()); 29837da2899SCharles.Forsyth tk->cmd(tktop, ".ctlf.url delete 0 end"); 29937da2899SCharles.Forsyth tk->cmd(tktop, ".ctlf.url insert end " + url); 30037da2899SCharles.Forsyth tk->cmd(tktop, "update"); 30137da2899SCharles.Forsyth "snarfstatus" => 30237da2899SCharles.Forsyth url := tk->cmd(tktop, ".status.status cget -text"); 30337da2899SCharles.Forsyth tkclient->snarfput(url); 30437da2899SCharles.Forsyth } 30537da2899SCharles.Forsyth s := <-t.ctxt.ctl or 30637da2899SCharles.Forsyth s = <-t.wreq or 30737da2899SCharles.Forsyth s = <-wmctl => 30837da2899SCharles.Forsyth case s { 30937da2899SCharles.Forsyth "exit" => 31037da2899SCharles.Forsyth hidewins(); 31137da2899SCharles.Forsyth ev = ref Event.Equit(0); 31237da2899SCharles.Forsyth "task" => 31337da2899SCharles.Forsyth if (cancelpopup()) 31437da2899SCharles.Forsyth evchan <-= ref Event.Edismisspopup; 31537da2899SCharles.Forsyth tkclient->wmctl(t, s); 31637da2899SCharles.Forsyth if(tktop.image == nil) 31737da2899SCharles.Forsyth realwin = nil; 31837da2899SCharles.Forsyth "help" => 31937da2899SCharles.Forsyth ev = ref Event.Ego((CU->config).helpurl, nil, 0, E->EGnormal); 32037da2899SCharles.Forsyth * => 32137da2899SCharles.Forsyth if (s[0] == '!' && cancelpopup()) 32237da2899SCharles.Forsyth evchan <-= ref Event.Edismisspopup; 32337da2899SCharles.Forsyth oldimg := t.image; 32437da2899SCharles.Forsyth e := tkclient->wmctl(t, s); 32537da2899SCharles.Forsyth if(s[0] == '!' && e == nil){ 32637da2899SCharles.Forsyth if(t.image != oldimg){ 32737da2899SCharles.Forsyth oldimg = nil; 32837da2899SCharles.Forsyth makewins(); 32937da2899SCharles.Forsyth ev = ref Event.Ereshape(mainwin.r); 33037da2899SCharles.Forsyth } 33137da2899SCharles.Forsyth offset = tk->rect(tktop, ".f", 0).min; 33237da2899SCharles.Forsyth } 33337da2899SCharles.Forsyth } 33437da2899SCharles.Forsyth s := <-t.ctxt.kbd => 33537da2899SCharles.Forsyth tk->keyboard(t, s); 33637da2899SCharles.Forsyth s := <-t.ctxt.ptr => 33737da2899SCharles.Forsyth tk->pointer(t, *s); 33837da2899SCharles.Forsyth } 33937da2899SCharles.Forsyth if (dismisspopup) { 34037da2899SCharles.Forsyth if (cancelpopup()) { 34137da2899SCharles.Forsyth evchan <-= ref Event.Edismisspopup; 34237da2899SCharles.Forsyth } 34337da2899SCharles.Forsyth } 34437da2899SCharles.Forsyth if (ev != nil) 34537da2899SCharles.Forsyth evchan <-= ev; 34637da2899SCharles.Forsyth } 34737da2899SCharles.Forsyth} 34837da2899SCharles.Forsyth 34937da2899SCharles.Forsyths2mtype(s: string): int 35037da2899SCharles.Forsyth{ 35137da2899SCharles.Forsyth mtype := E->Mmove; 35237da2899SCharles.Forsyth if(s[0] == 'm') 35337da2899SCharles.Forsyth mtype = E->Mmove; 35437da2899SCharles.Forsyth else { 35537da2899SCharles.Forsyth case s[1] { 35637da2899SCharles.Forsyth '1' => 35737da2899SCharles.Forsyth case s[2] { 35837da2899SCharles.Forsyth 'p' => mtype = E->Mlbuttondown; 35937da2899SCharles.Forsyth 'r' => mtype = E->Mlbuttonup; 36037da2899SCharles.Forsyth 'd' => mtype = E->Mldrag; 36137da2899SCharles.Forsyth } 36237da2899SCharles.Forsyth '2' => 36337da2899SCharles.Forsyth case s[2] { 36437da2899SCharles.Forsyth 'p' => mtype = E->Mmbuttondown; 36537da2899SCharles.Forsyth 'r' => mtype = E->Mmbuttonup; 36637da2899SCharles.Forsyth 'd' => mtype = E->Mmdrag; 36737da2899SCharles.Forsyth } 36837da2899SCharles.Forsyth '3' => 36937da2899SCharles.Forsyth case s[2] { 37037da2899SCharles.Forsyth 'p' => mtype = E->Mrbuttondown; 37137da2899SCharles.Forsyth 'r' => mtype = E->Mrbuttonup; 37237da2899SCharles.Forsyth 'd' => mtype = E->Mrdrag; 37337da2899SCharles.Forsyth } 37437da2899SCharles.Forsyth } 37537da2899SCharles.Forsyth } 37637da2899SCharles.Forsyth return mtype; 37737da2899SCharles.Forsyth} 37837da2899SCharles.Forsyth 37937da2899SCharles.Forsythmakewins() 38037da2899SCharles.Forsyth{ 38137da2899SCharles.Forsyth if(tktop.image == nil) 38237da2899SCharles.Forsyth return; 38337da2899SCharles.Forsyth screen := Screen.allocate(tktop.image, display.transparent, 0); 38437da2899SCharles.Forsyth offset = tk->rect(tktop, ".f", 0).min; 38537da2899SCharles.Forsyth r := tk->rect(tktop, ".f", Tk->Local); 38637da2899SCharles.Forsyth realwin = screen.newwindow(r, D->Refnone, D->White); 38737da2899SCharles.Forsyth realwin.origin(ZP, r.min); 38837da2899SCharles.Forsyth if(realwin == nil) 389*54041ca4Sforsyth raise sys->sprint("EXFatal: can't initialize windows: %r"); 39037da2899SCharles.Forsyth 39137da2899SCharles.Forsyth mainwin = display.newimage(realwin.r, realwin.chans, 0, D->White); 39237da2899SCharles.Forsyth if(mainwin == nil) 393*54041ca4Sforsyth raise sys->sprint("EXFatal: can't initialize windows: %r"); 39437da2899SCharles.Forsyth} 39537da2899SCharles.Forsyth 39637da2899SCharles.Forsythhidewins() 39737da2899SCharles.Forsyth{ 39837da2899SCharles.Forsyth tk->cmd(tktop, ". unmap"); 39937da2899SCharles.Forsyth} 40037da2899SCharles.Forsyth 40137da2899SCharles.Forsythsnarfput(s: string) 40237da2899SCharles.Forsyth{ 40337da2899SCharles.Forsyth tkclient->snarfput(s); 40437da2899SCharles.Forsyth} 40537da2899SCharles.Forsyth 40637da2899SCharles.Forsythsetstatus(s: string) 40737da2899SCharles.Forsyth{ 40837da2899SCharles.Forsyth tk->cmd(tktop, ".status.status configure -text " + tk->quote(s)); 40937da2899SCharles.Forsyth tk->cmd(tktop, "update"); 41037da2899SCharles.Forsyth} 41137da2899SCharles.Forsyth 41237da2899SCharles.Forsythseturl(s: string) 41337da2899SCharles.Forsyth{ 41437da2899SCharles.Forsyth tk->cmd(tktop, ".ctlf.url delete 0 end"); 41537da2899SCharles.Forsyth tk->cmd(tktop, ".ctlf.url insert 0 " + tk->quote(s)); 41637da2899SCharles.Forsyth tk->cmd(tktop, "update"); 41737da2899SCharles.Forsyth} 41837da2899SCharles.Forsyth 41937da2899SCharles.Forsythauth(realm: string): (int, string, string) 42037da2899SCharles.Forsyth{ 42137da2899SCharles.Forsyth user := prompt(realm + " username?", nil).t1; 42237da2899SCharles.Forsyth passwd := prompt("password?", nil).t1; 42337da2899SCharles.Forsyth if(user == nil) 42437da2899SCharles.Forsyth return (0, nil, nil); 42537da2899SCharles.Forsyth return (1, user, passwd); 42637da2899SCharles.Forsyth} 42737da2899SCharles.Forsyth 42837da2899SCharles.Forsythalert(msg: string) 42937da2899SCharles.Forsyth{ 43037da2899SCharles.Forsythsys->print("ALERT:%s\n", msg); 43137da2899SCharles.Forsyth return; 43237da2899SCharles.Forsyth} 43337da2899SCharles.Forsyth 43437da2899SCharles.Forsythconfirm(msg: string): int 43537da2899SCharles.Forsyth{ 43637da2899SCharles.Forsythsys->print("CONFIRM:%s\n", msg); 43737da2899SCharles.Forsyth return -1; 43837da2899SCharles.Forsyth} 43937da2899SCharles.Forsyth 44037da2899SCharles.Forsythprompt(msg, dflt: string): (int, string) 44137da2899SCharles.Forsyth{ 44237da2899SCharles.Forsyth if(dialog == nil){ 44337da2899SCharles.Forsyth dialog = load Dialog Dialog->PATH; 44437da2899SCharles.Forsyth dialog->init(); 44537da2899SCharles.Forsyth } 44637da2899SCharles.Forsyth return (1, dialog->getstring(drawctxt, mainwin, msg)); 44737da2899SCharles.Forsyth # return (-1, ""); 44837da2899SCharles.Forsyth} 44937da2899SCharles.Forsyth 45037da2899SCharles.Forsythstopbutton(enable: int) 45137da2899SCharles.Forsyth{ 45237da2899SCharles.Forsyth state: string; 45337da2899SCharles.Forsyth if (enable) { 45437da2899SCharles.Forsyth tk->cmd(tktop, ".ctlf.stop configure -bg red -activebackground red -activeforeground white"); 45537da2899SCharles.Forsyth state = "normal"; 45637da2899SCharles.Forsyth } else { 45737da2899SCharles.Forsyth tk->cmd(tktop, ".ctlf.stop configure -bg #dddddd"); 45837da2899SCharles.Forsyth state = "disabled"; 45937da2899SCharles.Forsyth } 46037da2899SCharles.Forsyth tk->cmd(tktop, ".ctlf.stop configure -state " + state + ";update"); 46137da2899SCharles.Forsyth} 46237da2899SCharles.Forsyth 46337da2899SCharles.Forsythbackbutton(enable: int) 46437da2899SCharles.Forsyth{ 46537da2899SCharles.Forsyth state: string; 46637da2899SCharles.Forsyth if (enable) { 46737da2899SCharles.Forsyth tk->cmd(tktop, ".ctlf.back configure -bg lime -activebackground lime -activeforeground red"); 46837da2899SCharles.Forsyth state = "normal"; 46937da2899SCharles.Forsyth } else { 47037da2899SCharles.Forsyth tk->cmd(tktop, ".ctlf.back configure -bg #dddddd"); 47137da2899SCharles.Forsyth state = "disabled"; 47237da2899SCharles.Forsyth } 47337da2899SCharles.Forsyth tk->cmd(tktop, ".ctlf.back configure -state " + state + ";update"); 47437da2899SCharles.Forsyth} 47537da2899SCharles.Forsyth 47637da2899SCharles.Forsythfwdbutton(enable: int) 47737da2899SCharles.Forsyth{ 47837da2899SCharles.Forsyth state: string; 47937da2899SCharles.Forsyth if (enable) { 48037da2899SCharles.Forsyth tk->cmd(tktop, ".ctlf.fwd configure -bg lime -activebackground lime -activeforeground red"); 48137da2899SCharles.Forsyth state = "normal"; 48237da2899SCharles.Forsyth } else { 48337da2899SCharles.Forsyth tk->cmd(tktop, ".ctlf.fwd configure -bg #dddddd"); 48437da2899SCharles.Forsyth state = "disabled"; 48537da2899SCharles.Forsyth } 48637da2899SCharles.Forsyth tk->cmd(tktop, ".ctlf.fwd configure -state " + state + ";update"); 48737da2899SCharles.Forsyth} 48837da2899SCharles.Forsyth 48937da2899SCharles.Forsythflush(r: Rect) 49037da2899SCharles.Forsyth{ 49137da2899SCharles.Forsyth if(realwin != nil) { 49237da2899SCharles.Forsyth oclipr := mainwin.clipr; 49337da2899SCharles.Forsyth mainwin.clipr = r; 49437da2899SCharles.Forsyth realwin.draw(r, mainwin, nil, r.min); 49537da2899SCharles.Forsyth mainwin.clipr = oclipr; 49637da2899SCharles.Forsyth } 49737da2899SCharles.Forsyth} 49837da2899SCharles.Forsyth 49937da2899SCharles.Forsythclientfocus() 50037da2899SCharles.Forsyth{ 50137da2899SCharles.Forsyth tk->cmd(tktop, "focus .f"); 50237da2899SCharles.Forsyth tk->cmd(tktop, "update"); 50337da2899SCharles.Forsyth} 50437da2899SCharles.Forsyth 50537da2899SCharles.Forsythexitcharon() 50637da2899SCharles.Forsyth{ 50737da2899SCharles.Forsyth hidewins(); 50837da2899SCharles.Forsyth E->evchan <-= ref Event.Equit(0); 50937da2899SCharles.Forsyth} 51037da2899SCharles.Forsyth 51137da2899SCharles.Forsythgetpopup(r: Rect): ref Popup 51237da2899SCharles.Forsyth{ 51337da2899SCharles.Forsyth return nil; 51437da2899SCharles.Forsyth# cancelpopup(); 51537da2899SCharles.Forsyth## img := screen.newwindow(r, D->White); 51637da2899SCharles.Forsyth# img := display.newimage(r, screen.image.chans, 0, D->White); 51737da2899SCharles.Forsyth# if (img == nil) 51837da2899SCharles.Forsyth# return nil; 51937da2899SCharles.Forsyth# winr := r.addpt(offset); # race for offset 52037da2899SCharles.Forsyth# 52137da2899SCharles.Forsyth# pos := "-x " + string winr.min.x + " -y " + string winr.min.y; 52237da2899SCharles.Forsyth# (top, nil) := tkclient->toplevel(drawctxt, pos, nil, Tkclient->Plain); 52337da2899SCharles.Forsyth# tk->namechan(top, gctl, "gctl"); 52437da2899SCharles.Forsyth# tk->cmd(top, "frame .f -bd 0 -bg white -width " + string r.dx() + " -height " + string r.dy()); 52537da2899SCharles.Forsyth# tkcmds(top, framebinds); 52637da2899SCharles.Forsyth# tk->cmd(top, "pack .f; update"); 52737da2899SCharles.Forsyth# tkclient->onscreen(tktop, "onscreen"); 52837da2899SCharles.Forsyth# tkclient->startinput(tktop, "kbd"::"ptr"::nil); 52937da2899SCharles.Forsyth# win := screen.newwindow(winr, D->Refbackup, D->White); 53037da2899SCharles.Forsyth# if (win == nil) 53137da2899SCharles.Forsyth# return nil; 53237da2899SCharles.Forsyth# win.origin(r.min, winr.min); 53337da2899SCharles.Forsyth# 53437da2899SCharles.Forsyth# popuptk = top; 53537da2899SCharles.Forsyth# popup = ref Popup(r, img, win); 53637da2899SCharles.Forsyth## XXXX need to start a thread to feed mouse/kbd events from popup, 53737da2899SCharles.Forsyth## but we need to know when to tear it down. 53837da2899SCharles.Forsyth# return popup; 53937da2899SCharles.Forsyth} 54037da2899SCharles.Forsyth 54137da2899SCharles.Forsythcancelpopup(): int 54237da2899SCharles.Forsyth{ 54337da2899SCharles.Forsyth popuptk = nil; 54437da2899SCharles.Forsyth pu := popup; 54537da2899SCharles.Forsyth if (pu == nil) 54637da2899SCharles.Forsyth return 0; 54737da2899SCharles.Forsyth pu.image = nil; 54837da2899SCharles.Forsyth pu.window = nil; 54937da2899SCharles.Forsyth pu = nil; 55037da2899SCharles.Forsyth popup = nil; 55137da2899SCharles.Forsyth return 1; 55237da2899SCharles.Forsyth} 55337da2899SCharles.Forsyth 55437da2899SCharles.ForsythPopup.flush(p: self ref Popup, r: Rect) 55537da2899SCharles.Forsyth{ 55637da2899SCharles.Forsyth win := p.window; 55737da2899SCharles.Forsyth img := p.image; 55837da2899SCharles.Forsyth if (win != nil && img != nil) 55937da2899SCharles.Forsyth win.draw(r, img, nil, r.min); 56037da2899SCharles.Forsyth} 561