1 #include <u.h> 2 #include <libc.h> 3 #include <bio.h> 4 #include <thread.h> 5 #include "dat.h" 6 7 Window* 8 newwindow(void) 9 { 10 char buf[12]; 11 Window *w; 12 13 w = emalloc(sizeof(Window)); 14 w->ctl = open("/mnt/wsys/new/ctl", ORDWR|OCEXEC); 15 if(w->ctl<0 || read(w->ctl, buf, 12)!=12) 16 error("can't open window ctl file: %r"); 17 ctlprint(w->ctl, "noscroll\n"); 18 w->id = atoi(buf); 19 w->event = winopenfile(w, "event"); 20 w->addr = winopenfile(w, "addr"); 21 w->body = winopenfile(w, "body"); 22 w->data = winopenfile(w, "data"); 23 w->cevent = chancreate(sizeof(Event*), 0); 24 return w; 25 } 26 27 void 28 winsetdump(Window *w, char *dir, char *cmd) 29 { 30 if(dir != nil) 31 ctlprint(w->ctl, "dumpdir %s\n", dir); 32 if(cmd != nil) 33 ctlprint(w->ctl, "dump %s\n", cmd); 34 } 35 36 void 37 wineventproc(void *v) 38 { 39 Window *w; 40 int i; 41 42 w = v; 43 for(i=0; ; i++){ 44 if(i >= NEVENT) 45 i = 0; 46 wingetevent(w, &w->e[i]); 47 sendp(w->cevent, &w->e[i]); 48 } 49 } 50 51 int 52 winopenfile(Window *w, char *f) 53 { 54 char buf[64]; 55 int fd; 56 57 sprint(buf, "/mnt/wsys/%d/%s", w->id, f); 58 fd = open(buf, ORDWR|OCEXEC); 59 if(fd < 0) 60 error("can't open window file %s: %r", f); 61 return fd; 62 } 63 64 void 65 wintagwrite(Window *w, char *s, int n) 66 { 67 int fd; 68 69 fd = winopenfile(w, "tag"); 70 if(write(fd, s, n) != n) 71 error("tag write: %r"); 72 close(fd); 73 } 74 75 void 76 winname(Window *w, char *s) 77 { 78 ctlprint(w->ctl, "name %s\n", s); 79 } 80 81 int 82 wingetec(Window *w) 83 { 84 if(w->nbuf == 0){ 85 w->nbuf = read(w->event, w->buf, sizeof w->buf); 86 if(w->nbuf <= 0){ 87 /* probably because window has exited, and only called by wineventproc, so just shut down */ 88 threadexits(nil); 89 } 90 w->bufp = w->buf; 91 } 92 w->nbuf--; 93 return *w->bufp++; 94 } 95 96 int 97 wingeten(Window *w) 98 { 99 int n, c; 100 101 n = 0; 102 while('0'<=(c=wingetec(w)) && c<='9') 103 n = n*10+(c-'0'); 104 if(c != ' ') 105 error("event number syntax"); 106 return n; 107 } 108 109 int 110 wingeter(Window *w, char *buf, int *nb) 111 { 112 Rune r; 113 int n; 114 115 r = wingetec(w); 116 buf[0] = r; 117 n = 1; 118 if(r >= Runeself) { 119 while(!fullrune(buf, n)) 120 buf[n++] = wingetec(w); 121 chartorune(&r, buf); 122 } 123 *nb = n; 124 return r; 125 } 126 127 void 128 wingetevent(Window *w, Event *e) 129 { 130 int i, nb; 131 132 e->c1 = wingetec(w); 133 e->c2 = wingetec(w); 134 e->q0 = wingeten(w); 135 e->q1 = wingeten(w); 136 e->flag = wingeten(w); 137 e->nr = wingeten(w); 138 if(e->nr > EVENTSIZE) 139 error("event string too long"); 140 e->nb = 0; 141 for(i=0; i<e->nr; i++){ 142 e->r[i] = wingeter(w, e->b+e->nb, &nb); 143 e->nb += nb; 144 } 145 e->r[e->nr] = 0; 146 e->b[e->nb] = 0; 147 if(wingetec(w) != '\n') 148 error("event syntax error"); 149 } 150 151 void 152 winwriteevent(Window *w, Event *e) 153 { 154 fprint(w->event, "%c%c%d %d\n", e->c1, e->c2, e->q0, e->q1); 155 } 156 157 static int 158 nrunes(char *s, int nb) 159 { 160 int i, n; 161 Rune r; 162 163 n = 0; 164 for(i=0; i<nb; n++) 165 i += chartorune(&r, s+i); 166 return n; 167 } 168 169 int 170 winread(Window *w, uint q0, uint q1, char *data) 171 { 172 int m, n, nr, nb; 173 char buf[256]; 174 175 if(w->addr < 0) 176 w->addr = winopenfile(w, "addr"); 177 if(w->data < 0) 178 w->data = winopenfile(w, "data"); 179 m = q0; 180 nb = 0; 181 while(m < q1){ 182 n = sprint(buf, "#%d", m); 183 if(write(w->addr, buf, n) != n) 184 error("error writing addr: %r"); 185 n = read(w->data, buf, sizeof buf); 186 if(n < 0) 187 error("reading data: %r"); 188 nr = nrunes(buf, n); 189 while(m+nr >q1){ 190 do; while(n>0 && (buf[--n]&0xC0)==0x80); 191 --nr; 192 } 193 if(n == 0) 194 break; 195 memmove(data, buf, n); 196 nb += n; 197 data += n; 198 *data = 0; 199 m += nr; 200 } 201 return nb; 202 } 203 204 void 205 windormant(Window *w) 206 { 207 if(w->addr >= 0){ 208 close(w->addr); 209 w->addr = -1; 210 } 211 if(w->body >= 0){ 212 close(w->body); 213 w->body = -1; 214 } 215 if(w->data >= 0){ 216 close(w->data); 217 w->data = -1; 218 } 219 } 220 221 int 222 windel(Window *w, int sure) 223 { 224 if(sure) 225 write(w->ctl, "delete\n", 7); 226 else if(write(w->ctl, "del\n", 4) != 4) 227 return 0; 228 /* event proc will die due to read error from event file */ 229 windormant(w); 230 close(w->ctl); 231 w->ctl = -1; 232 close(w->event); 233 w->event = -1; 234 return 1; 235 } 236 237 void 238 winclean(Window *w) 239 { 240 ctlprint(w->ctl, "clean\n"); 241 } 242 243 int 244 winsetaddr(Window *w, char *addr, int errok) 245 { 246 if(w->addr < 0) 247 w->addr = winopenfile(w, "addr"); 248 if(write(w->addr, addr, strlen(addr)) < 0){ 249 if(!errok) 250 error("error writing addr(%s): %r", addr); 251 return 0; 252 } 253 return 1; 254 } 255 256 int 257 winselect(Window *w, char *addr, int errok) 258 { 259 if(winsetaddr(w, addr, errok)){ 260 ctlprint(w->ctl, "dot=addr\n"); 261 return 1; 262 } 263 return 0; 264 } 265