1implement Test; 2 3include "sys.m"; 4include "draw.m"; 5draw: Draw; 6Screen, Display, Image: import draw; 7include "tk.m"; 8 9Test: module 10{ 11 init: fn(ctxt: ref Draw->Context, argv: list of string); 12}; 13 14tk: Tk; 15sys: Sys; 16 17init(nil: ref Draw->Context, argv: list of string) 18{ 19 cmd: string; 20 21 sys = load Sys Sys->PATH; 22 draw = load Draw Draw->PATH; 23 tk = load Tk Tk->PATH; 24 25 display := Display.allocate(nil); 26 if(display == nil) { 27 sys->print("can't initialize display: %r\n"); 28 return; 29 } 30 31 disp := display.image; 32 screen := Screen.allocate(disp, display.rgb(161, 195, 209), 1); 33 if(screen == nil) { 34 sys->print("can't allocate screen: %r\n"); 35 return; 36 } 37 fd := sys->open("/dev/pointer", sys->OREAD); 38 if(fd == nil) { 39 sys->print("open: %s: %r\n", "/dev/pointer"); 40 sys->print("run wm/wish instead\n"); 41 return; 42 } 43 44 t := tk->toplevel(display, ""); 45 spawn mouse(t, fd); 46 spawn keyboard(t); 47 disp.draw(disp.r, screen.fill, nil, disp.r.min); 48 49 input := array[8192] of byte; 50 stdin := sys->fildes(0); 51 52 if(argv != nil) 53 argv = tl argv; 54 while(argv != nil) { 55 exec(t, hd argv); 56 argv = tl argv; 57 } 58 59 for(;;) { 60 tk->cmd(t, "update"); 61 62 prompt := '%'; 63 if(cmd != nil) 64 prompt = '>'; 65 sys->print("%c ", prompt); 66 67 n := sys->read(stdin, input, len input); 68 if(n <= 0) 69 break; 70 if(n == 1) 71 continue; 72 cmd += string input[0:n-1]; 73 if(cmd[len cmd-1] != '\\') { 74 cmd = esc(cmd); 75 s := tk->cmd(t, cmd); 76 if(len s != 0) 77 sys->print("%s\n", s); 78 cmd = nil; 79 continue; 80 } 81 cmd = cmd[0:len cmd-1]; 82 } 83} 84 85esc(s: string): string 86{ 87 c: int; 88 89 for(i := 0; i < len s; i++) { 90 if(s[i] != '\\') 91 continue; 92 case s[i+1] { 93 'n'=> c = '\n'; 94 't'=> c = '\t'; 95 'b'=> c = '\b'; 96 '\\'=> c = '\\'; 97 * => c = 0; 98 } 99 if(c != 0) { 100 s[i] = c; 101 s = s[0:i+1]+s[i+2:len s]; 102 } 103 } 104 return s; 105} 106 107exec(t: ref Tk->Toplevel, path: string) 108{ 109 fd := sys->open(path, sys->OREAD); 110 if(fd == nil) { 111 sys->print("open: %s: %r\n", path); 112 return; 113 } 114 (ok, d) := sys->fstat(fd); 115 if(ok < 0) { 116 sys->print("fstat: %s: %r\n", path); 117 return; 118 } 119 buf := array[int d.length] of byte; 120 if(sys->read(fd, buf, len buf) < 0) { 121 sys->print("read: %s: %r\n", path); 122 return; 123 } 124 (n, l) := sys->tokenize(string buf, "\n"); 125 buf = nil; 126 n = -1; 127 for(; l != nil; l = tl l) { 128 n++; 129 s := hd l; 130 if(len s == 0 || s[0] == '#') 131 continue; 132 133 while(s[len s-1] == '\\') { 134 s = s[0:len s-1]; 135 if(tl l != nil) { 136 l = tl l; 137 s = s + hd l; 138 } 139 else 140 break; 141 } 142 143 s = tk->cmd(t, esc(s)); 144 145 if(len s != 0 && s[0] == '!') { 146 sys->print("%s:%d %s\n", path, n, s); 147 sys->print("%s:%d %s\n", path, n, hd l); 148 } 149 } 150} 151 152mouse(t: ref Tk->Toplevel, fd: ref Sys->FD) 153{ 154 n := 0; 155 buf := array[100] of byte; 156 for(;;) { 157 n = sys->read(fd, buf, len buf); 158 if(n <= 0) 159 break; 160 161 if(int buf[0] == 'm' && n >= 1+3*12) { 162 x := int(string buf[ 1:13]); 163 y := int(string buf[12:25]); 164 b := int(string buf[24:37]); 165 tk->pointer(t, Draw->Pointer(b, Draw->Point(x, y), sys->millisec())); 166 } 167 } 168} 169 170keyboard(t: ref Tk->Toplevel) 171{ 172 dfd := sys->open("/dev/keyboard", sys->OREAD); 173 if(dfd == nil) 174 return; 175 176 b:= array[1] of byte; 177 buf := array[10] of byte; 178 i := 0; 179 for(;;) { 180 n := sys->read(dfd, buf[i:], len buf - i); 181 if(n < 1) 182 break; 183 i += n; 184 while(i >0 && (nutf := sys->utfbytes(buf, i)) > 0){ 185 s := string buf[0:nutf]; 186 tk->keyboard(t, int s[0]); 187 buf[0:] = buf[nutf:i]; 188 i -= nutf; 189 } 190 } 191} 192