]> git.lizzy.rs Git - plan9front.git/blob - acme/bin/source/adict/_win.c
fill /acme
[plan9front.git] / acme / bin / source / adict / _win.c
1 #include <u.h>
2 #include <libc.h>
3 #include <bio.h>
4 #include <thread.h>
5 #include "win.h"
6
7 void*
8 erealloc(void *p, uint n)
9 {
10         p = realloc(p, n);
11         if(p == nil)
12                 threadprint(2, "realloc failed: %r");
13         return p;
14 }
15
16 void
17 wnew(Win *w)
18 {
19         char buf[12];
20
21         w->ctl = open("/mnt/acme/new/ctl", ORDWR);
22         if(w->ctl<0 || read(w->ctl, buf, 12)!=12)
23                  threadprint (2, "can't open window ctl file: %r");
24         ctlwrite(w, "noscroll\n");
25         w->winid = atoi(buf);
26         w->event = openfile(w, "event");
27         w->addr = -1;   /* will be opened when needed */
28         w->body = nil;
29         w->data = -1;
30 }
31
32 int
33 openfile(Win *w, char *f)
34 {
35         char buf[64];
36         int fd;
37
38         sprint(buf, "/mnt/acme/%d/%s", w->winid, f);
39         fd = open(buf, ORDWR|OCEXEC);
40         if(fd < 0)
41                  threadprint (2,"can't open window %s file: %r", f);
42         return fd;
43 }
44
45 void
46 openbody(Win *w, int mode)
47 {
48         char buf[64];
49
50         sprint(buf, "/mnt/acme/%d/body", w->winid);
51         w->body = Bopen(buf, mode|OCEXEC);
52         if(w->body == nil)
53                  threadprint(2,"can't open window body file: %r");
54 }
55
56 void
57 wwritebody(Win *w, char *s, int n)
58 {
59         if(w->body == nil)
60                 openbody(w, OWRITE);
61         if(Bwrite(w->body, s, n) != n)
62                   threadprint(2,"write error to window: %r");
63         Bflush(w->body);
64 }
65
66 void
67 wreplace(Win *w, char *addr, char *repl, int nrepl)
68 {
69         if(w->addr < 0)
70                 w->addr = openfile(w, "addr");
71         if(w->data < 0)
72                 w->data = openfile(w, "data");
73         if(write(w->addr, addr, strlen(addr)) < 0){
74                 threadprint(2, "mail: warning: badd address %s:%r\n", addr);
75                 return;
76         }
77         if(write(w->data, repl, nrepl) != nrepl)
78                  threadprint(2, "writing data: %r");
79 }
80
81 static int
82 nrunes(char *s, int nb)
83 {
84         int i, n;
85         Rune r;
86
87         n = 0;
88         for(i=0; i<nb; n++)
89                 i += chartorune(&r, s+i);
90         return n;
91 }
92
93 void
94 wread(Win *w, uint q0, uint q1, char *data)
95 {
96         int m, n, nr;
97         char buf[256];
98
99         if(w->addr < 0)
100                 w->addr = openfile(w, "addr");
101         if(w->data < 0)
102                 w->data = openfile(w, "data");
103         m = q0;
104         while(m < q1){
105                 n = sprint(buf, "#%d", m);
106                 if(write(w->addr, buf, n) != n)
107                           threadprint(2,"writing addr: %r");
108                 n = read(w->data, buf, sizeof buf);
109                 if(n <= 0)
110                           threadprint(2,"reading data: %r");
111                 nr = nrunes(buf, n);
112                 while(m+nr >q1){
113                         do; while(n>0 && (buf[--n]&0xC0)==0x80);
114                         --nr;
115                 }
116                 if(n == 0)
117                         break;
118                 memmove(data, buf, n);
119                 data += n;
120                 *data = 0;
121                 m += nr;
122         }
123 }
124
125 void
126 wselect(Win *w, char *addr)
127 {
128         if(w->addr < 0)
129                 w->addr = openfile(w, "addr");
130         if(write(w->addr, addr, strlen(addr)) < 0)
131                   threadprint(2,"writing addr");
132         ctlwrite(w, "dot=addr\n");
133 }
134
135 void
136 wtagwrite(Win *w, char *s, int n)
137 {
138         int fd;
139
140         fd = openfile(w, "tag");
141         if(write(fd, s, n) != n)
142                   threadprint(2,"tag write: %r");
143         close(fd);
144 }
145
146 void
147 ctlwrite(Win *w, char *s)
148 {
149         int n;
150
151         n = strlen(s);
152         if(write(w->ctl, s, n) != n)
153                  threadprint(2,"write error to ctl file: %r");
154 }
155
156 int
157 wdel(Win *w)
158 {
159         if(write(w->ctl, "del\n", 4) != 4)
160                 return False;
161         wdormant(w);
162         close(w->ctl);
163         w->ctl = -1;
164         close(w->event);
165         w->event = -1;
166         return True;
167 }
168
169 void
170 wname(Win *w, char *s)
171 {
172         char buf[128];
173
174         sprint(buf, "name %s\n", s);
175         ctlwrite(w, buf);
176 }
177
178 void
179 wclean(Win *w)
180 {
181         if(w->body)
182                 Bflush(w->body);
183         ctlwrite(w, "clean\n");
184 }
185
186 void
187 wdormant(Win *w)
188 {
189         if(w->addr >= 0){
190                 close(w->addr);
191                 w->addr = -1;
192         }
193         if(w->body != nil){
194                 Bterm(w->body);
195                 w->body = nil;
196         }
197         if(w->data >= 0){
198                 close(w->data);
199                 w->data = -1;
200         }
201 }
202
203 int
204 getec(Win *w)
205 {
206         if(w->nbuf == 0){
207                 w->nbuf = read(w->event, w->buf, sizeof w->buf);
208                 if(w->nbuf <= 0)
209                           threadprint(2,"event read error: %r");
210                 w->bufp = w->buf;
211         }
212         w->nbuf--;
213         return *w->bufp++;
214 }
215
216 int
217 geten(Win *w)
218 {
219         int n, c;
220
221         n = 0;
222         while('0'<=(c=getec(w)) && c<='9')
223                 n = n*10+(c-'0');
224         if(c != ' ')
225                  threadprint(2, "event number syntax");
226         return n;
227 }
228
229 int
230 geter(Win *w, char *buf, int *nb)
231 {
232         Rune r;
233         int n;
234
235         r = getec(w);
236         buf[0] = r;
237         n = 1;
238         if(r < Runeself)
239                 goto Return;
240         while(!fullrune(buf, n))
241                 buf[n++] = getec(w);
242         chartorune(&r, buf);
243     Return:
244         *nb = n;
245         return r;
246 }
247
248
249 void
250 wevent(Win *w, Event *e)
251 {
252         int i, nb;
253
254         e->c1 = getec(w);
255         e->c2 = getec(w);
256         e->q0 = geten(w);
257         e->q1 = geten(w);
258         e->flag = geten(w);
259         e->nr = geten(w);
260         if(e->nr > EVENTSIZE)
261                   threadprint(2, "wevent: event string too long");
262         e->nb = 0;
263         for(i=0; i<e->nr; i++){
264                 e->r[i] = geter(w, e->b+e->nb, &nb);
265                 e->nb += nb;
266         }
267         e->r[e->nr] = 0;
268         e->b[e->nb] = 0;
269         if(getec(w) != '\n')
270                  threadprint(2, "wevent: event syntax 2");
271 }
272
273 void
274 wslave(Win *w, Channel *ce)
275 {
276         Event e;
277
278         while(recv(ce, &e) >= 0)
279                 wevent(w, &e);
280 }
281
282 void
283 wwriteevent(Win *w, Event *e)
284 {
285         threadprint(w->event, "%c%c%d %d\n", e->c1, e->c2, e->q0, e->q1);
286 }
287
288 int
289 wreadall(Win *w, char **sp)
290 {
291         char *s;
292         int m, na, n;
293
294         if(w->body != nil)
295                 Bterm(w->body);
296         openbody(w, OREAD);
297         s = nil;
298         na = 0;
299         n = 0;
300         for(;;){
301                 if(na < n+512){
302                         na += 1024;
303                         s = erealloc(s, na+1);
304                 }
305                 m = Bread(w->body, s+n, na-n);
306                 if(m <= 0)
307                         break;
308                 n += m;
309         }
310         s[n] = 0;
311         Bterm(w->body);
312         w->body = nil;
313         *sp = s;
314         return n;
315 }