ref: d0ab3a0dd8f6355b3603d0fb04043a9ae867639b
dir: /appl/cmd/wish.b/
implement Test; include "sys.m"; include "draw.m"; draw: Draw; Screen, Display, Image: import draw; include "tk.m"; Test: module { init: fn(ctxt: ref Draw->Context, argv: list of string); }; tk: Tk; sys: Sys; init(nil: ref Draw->Context, argv: list of string) { cmd: string; sys = load Sys Sys->PATH; draw = load Draw Draw->PATH; tk = load Tk Tk->PATH; display := Display.allocate(nil); if(display == nil) { sys->print("can't initialize display: %r\n"); return; } disp := display.image; screen := Screen.allocate(disp, display.rgb(161, 195, 209), 1); if(screen == nil) { sys->print("can't allocate screen: %r\n"); return; } fd := sys->open("/dev/pointer", sys->OREAD); if(fd == nil) { sys->print("open: %s: %r\n", "/dev/pointer"); sys->print("run wm/wish instead\n"); return; } t := tk->toplevel(display, ""); spawn mouse(t, fd); spawn keyboard(t); disp.draw(disp.r, screen.fill, nil, disp.r.min); input := array[8192] of byte; stdin := sys->fildes(0); if(argv != nil) argv = tl argv; while(argv != nil) { exec(t, hd argv); argv = tl argv; } for(;;) { tk->cmd(t, "update"); prompt := '%'; if(cmd != nil) prompt = '>'; sys->print("%c ", prompt); n := sys->read(stdin, input, len input); if(n <= 0) break; if(n == 1) continue; cmd += string input[0:n-1]; if(cmd[len cmd-1] != '\\') { cmd = esc(cmd); s := tk->cmd(t, cmd); if(len s != 0) sys->print("%s\n", s); cmd = nil; continue; } cmd = cmd[0:len cmd-1]; } } esc(s: string): string { c: int; for(i := 0; i < len s; i++) { if(s[i] != '\\') continue; case s[i+1] { 'n'=> c = '\n'; 't'=> c = '\t'; 'b'=> c = '\b'; '\\'=> c = '\\'; * => c = 0; } if(c != 0) { s[i] = c; s = s[0:i+1]+s[i+2:len s]; } } return s; } exec(t: ref Tk->Toplevel, path: string) { fd := sys->open(path, sys->OREAD); if(fd == nil) { sys->print("open: %s: %r\n", path); return; } (ok, d) := sys->fstat(fd); if(ok < 0) { sys->print("fstat: %s: %r\n", path); return; } buf := array[int d.length] of byte; if(sys->read(fd, buf, len buf) < 0) { sys->print("read: %s: %r\n", path); return; } (n, l) := sys->tokenize(string buf, "\n"); buf = nil; n = -1; for(; l != nil; l = tl l) { n++; s := hd l; if(len s == 0 || s[0] == '#') continue; while(s[len s-1] == '\\') { s = s[0:len s-1]; if(tl l != nil) { l = tl l; s = s + hd l; } else break; } s = tk->cmd(t, esc(s)); if(len s != 0 && s[0] == '!') { sys->print("%s:%d %s\n", path, n, s); sys->print("%s:%d %s\n", path, n, hd l); } } } mouse(t: ref Tk->Toplevel, fd: ref Sys->FD) { n := 0; buf := array[100] of byte; for(;;) { n = sys->read(fd, buf, len buf); if(n <= 0) break; if(int buf[0] == 'm' && n >= 1+3*12) { x := int(string buf[ 1:13]); y := int(string buf[12:25]); b := int(string buf[24:37]); tk->pointer(t, Draw->Pointer(b, Draw->Point(x, y), sys->millisec())); } } } keyboard(t: ref Tk->Toplevel) { dfd := sys->open("/dev/keyboard", sys->OREAD); if(dfd == nil) return; b:= array[1] of byte; buf := array[10] of byte; i := 0; for(;;) { n := sys->read(dfd, buf[i:], len buf - i); if(n < 1) break; i += n; while(i >0 && (nutf := sys->utfbytes(buf, i)) > 0){ s := string buf[0:nutf]; tk->keyboard(t, int s[0]); buf[0:] = buf[nutf:i]; i -= nutf; } } }