diff options
Diffstat (limited to 'appl/wm/stopwatch.b')
| -rw-r--r-- | appl/wm/stopwatch.b | 184 |
1 files changed, 184 insertions, 0 deletions
diff --git a/appl/wm/stopwatch.b b/appl/wm/stopwatch.b new file mode 100644 index 00000000..7748bbe0 --- /dev/null +++ b/appl/wm/stopwatch.b @@ -0,0 +1,184 @@ +implement WmStopWatch; + +include "sys.m"; + sys: Sys; + +include "draw.m"; + draw: Draw; + +include "tk.m"; + tk: Tk; + +include "tkclient.m"; + tkclient: Tkclient; + +include "daytime.m"; + daytime: Daytime; + + +WmStopWatch: module +{ + init: fn(ctxt: ref Draw->Context, argv: list of string); +}; + +t: ref Tk->Toplevel; +cmd: chan of string; + +tpid: int; + +hr, +min, +sec: int; + +sw_cfg := array[] of { + "frame .f", + "button .f.b1 -text Start -command {send cmd start}", + "button .f.b2 -text Stop -command {send cmd stop}", + "button .f.b3 -text Reset -command {send cmd reset}", + "pack .f.b1 .f.b2 .f.b3 -side left -fill x -expand 1", + + "frame .ft", + "label .ft.d -label {0:00:00}", + "pack .ft.d -expand 1", + + "frame .fs1", + "button .fs1.s -text Time1 -command {send cmd s1}", + "label .fs1.l -label {0:00:00}", + "pack .fs1.s .fs1.l -side left -expand 1", + + "frame .fs2", + "button .fs2.s -text Time2 -command {send cmd s2}", + "label .fs2.l -label {0:00:00}", + "pack .fs2.s .fs2.l -side left -expand 1", + + "frame .fs3", + "button .fs3.s -text Time3 -command {send cmd s3}", + "label .fs3.l -label {0:00:00}", + "pack .fs3.s .fs3.l -side left -expand 1", + + "pack .Wm_t -fill x", + "pack .f .ft .fs1 .fs2 .fs3", + "pack propagate . 0", + "update", +}; + +init(ctxt: ref Draw->Context, nil: list of string) +{ + sys = load Sys Sys->PATH; + if (ctxt == nil) { + sys->fprint(sys->fildes(2), "stopwatch: no window context\n"); + raise "fail:bad context"; + } + draw = load Draw Draw->PATH; + tk = load Tk Tk->PATH; + tkclient= load Tkclient Tkclient->PATH; + daytime = load Daytime Daytime->PATH; + + if(draw==nil || tk==nil || tkclient==nil || daytime==nil){ + sys->fprint(sys->fildes(2), "stopwatch: couldn't load modules\n"); + return; + } + + tkclient->init(); + + menubut := chan of string; + (t, menubut) = tkclient->toplevel(ctxt, "-borderwidth 2 -relief raised", "StopWatch", Tkclient->Appl); + + hr = 0; + min = 0; + sec = 0; + + cmd = chan of string; + tk->namechan(t, cmd, "cmd"); + for (c:=0; c<len sw_cfg; c++) + tk->cmd(t, sw_cfg[c]); + tkclient->onscreen(t, nil); + tkclient->startinput(t, "kbd"::"ptr"::nil); + tpid = 0; + + # keep the timerloop in a separate thread, + # so that wm events don't hold up the ticker + # i.e., titlebar click&hold would otherwise + # 'pause' the timer since the tick would not + # be processed. + + pid := chan of int; + spawn timerloop(pid); + looppid := <- pid; + + 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 := <-menubut => + if(menu == "exit") { + if(tpid) + kill(tpid); + kill(looppid); + return; + } + tkclient->wmctl(t, menu); + } +} + +timerloop(pid: chan of int) +{ + pid <- = sys->pctl(0, nil); + + tick := chan of int; + s: string; + + for(;;) alt { + c := <-cmd => + if(c == "stop"){ + if(tpid != 0){ + kill(tpid); + tpid = 0; + } + } else if(c == "reset"){ + hr = min = sec = 0; + s = sys->sprint("%d:%2.2d:%2.2d", hr, min, sec); + tk->cmd(t, ".ft.d configure -label {"+s+"};update"); + } else if(c == "start"){ + if(tpid == 0){ + spawn timer(tick); + tpid = <- tick; + } + } else if(c == "s1" || c == "s2" || c == "s3"){ + s = sys->sprint("%d:%2.2d:%2.2d", hr, min, sec); + tk->cmd(t, ".f"+c+".l configure -label {"+s+"};update"); + } + <-tick => + sec++; + if(sec>=60){ + sec = 0; + min++; + if(min>=60){ + min = 0; + hr++; + } + } + s = sys->sprint("%d:%2.2d:%2.2d", hr, min, sec); + tk->cmd(t, ".ft.d configure -label {"+s+"};update"); + } +} + +timer(c: chan of int) +{ + pid := sys->pctl(0, nil); + for(;;) { + c <-= pid; + sys->sleep(1000); + } +} + +kill(pid: int) +{ + fd := sys->open("#p/"+string pid+"/ctl", Sys->OWRITE); + if(fd != nil) + sys->fprint(fd, "kill"); +} |
