summaryrefslogtreecommitdiff
path: root/appl/wm/logwindow.b
diff options
context:
space:
mode:
authorCharles.Forsyth <devnull@localhost>2006-12-22 17:07:39 +0000
committerCharles.Forsyth <devnull@localhost>2006-12-22 17:07:39 +0000
commit37da2899f40661e3e9631e497da8dc59b971cbd0 (patch)
treecbc6d4680e347d906f5fa7fca73214418741df72 /appl/wm/logwindow.b
parent54bc8ff236ac10b3eaa928fd6bcfc0cdb2ba46ae (diff)
20060303a
Diffstat (limited to 'appl/wm/logwindow.b')
-rw-r--r--appl/wm/logwindow.b187
1 files changed, 187 insertions, 0 deletions
diff --git a/appl/wm/logwindow.b b/appl/wm/logwindow.b
new file mode 100644
index 00000000..4d0326b4
--- /dev/null
+++ b/appl/wm/logwindow.b
@@ -0,0 +1,187 @@
+implement Logwindow;
+
+#
+# Copyright © 1999 Vita Nuova Limited. All rights reserved.
+#
+
+include "sys.m";
+ sys: Sys;
+ stderr: ref Sys->FD;
+include "draw.m";
+ draw: Draw;
+include "tk.m";
+ tk: Tk;
+ cmd: import tk;
+include "tkclient.m";
+ tkclient: Tkclient;
+include "arg.m";
+
+Logwindow: module {
+ init: fn(ctxt: ref Draw->Context, argv: list of string);
+};
+
+cfg := array[] of {
+ "frame .bf",
+ "checkbutton .bf.scroll -text Scroll -variable scroll -command {send cmd scroll}",
+ ".bf.scroll select",
+ "checkbutton .bf.popup -text {Pop up} -variable popup -command {send cmd popup}",
+ ".bf.popup select",
+ "pack .bf.scroll .bf.popup -side left",
+ "frame .t",
+ "scrollbar .t.scroll -command {.t.t yview}",
+ "text .t.t -height 7c -yscrollcommand {.t.scroll set}",
+ "pack .t.scroll -side left -fill y",
+ "pack .t.t -fill both -expand 1",
+ "pack .Wm_t -fill x",
+ "pack .bf -anchor w",
+ "pack .t -fill both -expand 1",
+ "pack propagate . 0",
+};
+
+eflag := 0;
+
+badmodule(p: string)
+{
+ sys->fprint(stderr, "logwindow: cannot load %s: %r\n", p);
+ raise "fail:bad module";
+}
+
+init(ctxt: ref Draw->Context, argv: list of string)
+{
+ sys = load Sys Sys->PATH;
+ stderr = sys->fildes(2);
+
+ tkclient = load Tkclient Tkclient->PATH;
+ if (tkclient == nil)
+ badmodule(Tkclient->PATH);
+ tkclient->init();
+
+ tk = load Tk Tk->PATH;
+ if (tk == nil)
+ badmodule(Tk->PATH);
+
+ arg := load Arg Arg->PATH;
+ if (arg == nil)
+ badmodule(Arg->PATH);
+
+ if (ctxt == nil) {
+ sys->fprint(stderr, "logwindow: nil Draw->Context\n");
+ raise "fail:no draw context";
+ }
+ gflag := 0;
+ title := "Log Window";
+ arg->init(argv);
+ while ((opt := arg->opt()) != 0) {
+ case opt {
+ 'e' =>
+ eflag = 1;
+ 'g' =>
+ gflag = 1;
+ * =>
+ sys->fprint(stderr, "usage: logwindow [-ge] [title]\n");
+ raise "fail:usage";
+ }
+ }
+ argv = arg->argv();
+ if (argv != nil)
+ title = hd argv;
+
+ if (!gflag)
+ sys->pctl(Sys->NEWPGRP, nil);
+
+ (top, wmchan) := tkclient->toplevel(ctxt, "", title, Tkclient->Hide|Tkclient->Resize);
+ if (top == nil) {
+ sys->fprint(stderr, "logwindow: couldn't make window\n");
+ raise "fail: no window";
+ }
+ cmd(top, ". unmap");
+
+ for (c:=0; c<len cfg; c++)
+ tk->cmd(top, cfg[c]);
+ if ((err := tk->cmd(top, "variable lasterror")) != nil) {
+ sys->fprint(stderr, "logwindow: tk error: %s\n", err);
+ raise "fail: tk error";
+ }
+
+ logwin(sys->fildes(0), top, wmchan);
+}
+
+scrolling := 1;
+popup := 1;
+
+logwin(fd: ref Sys->FD, top: ref Tk->Toplevel, wmchan: chan of string)
+{
+ cmd := chan of string;
+ tk->namechan(top, cmd, "cmd");
+ raised := 0;
+ ichan := chan of int;
+ spawn inputmon(fd, top, ichan);
+ tkclient->onscreen(top, nil);
+ tkclient->startinput(top, "kbd"::"ptr"::nil);
+ tkclient->wmctl(top, "task");
+ for (;;) alt {
+ s := <-top.ctxt.kbd =>
+ tk->keyboard(top, s);
+ s := <-top.ctxt.ptr =>
+ tk->pointer(top, *s);
+ s := <-top.ctxt.ctl or
+ s = <-top.wreq or
+ s = <-wmchan =>
+ case s {
+ "task" =>
+ raised = 0;
+ "untask" =>
+ raised = 1;
+ }
+ tkclient->wmctl(top, s);
+ e := <-ichan =>
+ if (e == 0 && eflag) {
+ tkclient->wmctl(top, "exit");
+ exit;
+ }
+ if (!raised && popup)
+ tkclient->wmctl(top, "untask");
+ msg := <-cmd =>
+ case msg {
+ "scroll" =>
+ scrolling = int tk->cmd(top, "variable scroll");
+ "popup" =>
+ popup = int tk->cmd(top, "variable popup");
+ }
+ }
+}
+
+inputmon(fd: ref Sys->FD, top: ref Tk->Toplevel, ichan: chan of int)
+{
+ buf := array[Sys->ATOMICIO] of byte;
+ t := 0;
+ while ((n := sys->read(fd, buf[t:], len buf-t)) > 0) {
+ t += n;
+ cl := 0;
+ for (i := t - 1; i >= 0; i--) {
+ (nil, cl, nil) = sys->byte2char(buf, i);
+ if (cl > 0)
+ break;
+ }
+ if (cl == 0)
+ continue;
+ logmsg(top, ichan, string buf[0:i+cl]);
+ buf[0:] = buf[i+cl:t];
+ t -= i + cl;
+ }
+ if (n < 0)
+ logmsg(top, ichan, sys->sprint("Input error: %r\n"));
+ else
+ logmsg(top, ichan, "Got EOF\n");
+ if (eflag)
+ ichan <-= 0;
+}
+
+logmsg(top: ref Tk->Toplevel, ichan: chan of int, m: string)
+{
+ tk->cmd(top, ".t.t insert end '"+m);
+ if (scrolling)
+ tk->cmd(top, ".t.t see end");
+ tk->cmd(top, "update");
+ ichan <-= 1;
+}