Blame


1 b3994ec5 2003-12-11 devnull #include <u.h>
2 b3994ec5 2003-12-11 devnull #include <libc.h>
3 b3994ec5 2003-12-11 devnull #include <draw.h>
4 b3994ec5 2003-12-11 devnull #include <thread.h>
5 b3994ec5 2003-12-11 devnull #include <cursor.h>
6 b3994ec5 2003-12-11 devnull #include <mouse.h>
7 b3994ec5 2003-12-11 devnull #include <keyboard.h>
8 b3994ec5 2003-12-11 devnull #include <frame.h>
9 b3994ec5 2003-12-11 devnull #include <fcall.h>
10 b3994ec5 2003-12-11 devnull #include <plumb.h>
11 b3994ec5 2003-12-11 devnull #include "dat.h"
12 b3994ec5 2003-12-11 devnull #include "fns.h"
13 b3994ec5 2003-12-11 devnull /* for generating syms in mkfile only: */
14 b3994ec5 2003-12-11 devnull #include <bio.h>
15 b3994ec5 2003-12-11 devnull #include "edit.h"
16 b3994ec5 2003-12-11 devnull
17 b3994ec5 2003-12-11 devnull void mousethread(void*);
18 b3994ec5 2003-12-11 devnull void keyboardthread(void*);
19 b3994ec5 2003-12-11 devnull void waitthread(void*);
20 b3994ec5 2003-12-11 devnull void xfidallocthread(void*);
21 b3994ec5 2003-12-11 devnull void newwindowthread(void*);
22 b3994ec5 2003-12-11 devnull void plumbproc(void*);
23 b3994ec5 2003-12-11 devnull
24 b3994ec5 2003-12-11 devnull Reffont **fontcache;
25 b3994ec5 2003-12-11 devnull int nfontcache;
26 b3994ec5 2003-12-11 devnull char wdir[512] = ".";
27 b3994ec5 2003-12-11 devnull Reffont *reffonts[2];
28 b3994ec5 2003-12-11 devnull int snarffd = -1;
29 b3994ec5 2003-12-11 devnull int mainpid;
30 b3994ec5 2003-12-11 devnull
31 b3994ec5 2003-12-11 devnull enum{
32 b3994ec5 2003-12-11 devnull NSnarf = 1000 /* less than 1024, I/O buffer size */
33 b3994ec5 2003-12-11 devnull };
34 b3994ec5 2003-12-11 devnull Rune snarfrune[NSnarf+1];
35 b3994ec5 2003-12-11 devnull
36 b3994ec5 2003-12-11 devnull char *fontnames[2] =
37 b3994ec5 2003-12-11 devnull {
38 b3994ec5 2003-12-11 devnull "/lib/font/bit/lucidasans/euro.8.font",
39 b3994ec5 2003-12-11 devnull "/lib/font/bit/lucm/unicode.9.font",
40 b3994ec5 2003-12-11 devnull };
41 b3994ec5 2003-12-11 devnull
42 b3994ec5 2003-12-11 devnull Command *command;
43 b3994ec5 2003-12-11 devnull
44 b3994ec5 2003-12-11 devnull void acmeerrorinit(void);
45 b3994ec5 2003-12-11 devnull void readfile(Column*, char*);
46 4da83e7c 2004-03-05 devnull static int shutdown(void*, char*);
47 b3994ec5 2003-12-11 devnull
48 b3994ec5 2003-12-11 devnull void
49 b3994ec5 2003-12-11 devnull derror(Display *d, char *errorstr)
50 b3994ec5 2003-12-11 devnull {
51 b3994ec5 2003-12-11 devnull USED(d);
52 b3994ec5 2003-12-11 devnull error(errorstr);
53 b3994ec5 2003-12-11 devnull }
54 b3994ec5 2003-12-11 devnull
55 b3994ec5 2003-12-11 devnull void
56 b3994ec5 2003-12-11 devnull threadmain(int argc, char *argv[])
57 b3994ec5 2003-12-11 devnull {
58 b3994ec5 2003-12-11 devnull int i;
59 b3994ec5 2003-12-11 devnull char *p, *loadfile;
60 b3994ec5 2003-12-11 devnull Column *c;
61 b3994ec5 2003-12-11 devnull int ncol;
62 b3994ec5 2003-12-11 devnull Display *d;
63 b3994ec5 2003-12-11 devnull
64 b3994ec5 2003-12-11 devnull rfork(RFENVG|RFNAMEG);
65 b3994ec5 2003-12-11 devnull
66 b3994ec5 2003-12-11 devnull ncol = -1;
67 b3994ec5 2003-12-11 devnull
68 b3994ec5 2003-12-11 devnull loadfile = nil;
69 b3994ec5 2003-12-11 devnull ARGBEGIN{
70 5a8e63b2 2004-02-29 devnull case 'a':
71 5a8e63b2 2004-02-29 devnull globalautoindent = TRUE;
72 5a8e63b2 2004-02-29 devnull break;
73 b3994ec5 2003-12-11 devnull case 'b':
74 b3994ec5 2003-12-11 devnull bartflag = TRUE;
75 b3994ec5 2003-12-11 devnull break;
76 b3994ec5 2003-12-11 devnull case 'c':
77 b3994ec5 2003-12-11 devnull p = ARGF();
78 b3994ec5 2003-12-11 devnull if(p == nil)
79 b3994ec5 2003-12-11 devnull goto Usage;
80 b3994ec5 2003-12-11 devnull ncol = atoi(p);
81 b3994ec5 2003-12-11 devnull if(ncol <= 0)
82 b3994ec5 2003-12-11 devnull goto Usage;
83 b3994ec5 2003-12-11 devnull break;
84 b3994ec5 2003-12-11 devnull case 'f':
85 b3994ec5 2003-12-11 devnull fontnames[0] = ARGF();
86 b3994ec5 2003-12-11 devnull if(fontnames[0] == nil)
87 b3994ec5 2003-12-11 devnull goto Usage;
88 b3994ec5 2003-12-11 devnull break;
89 b3994ec5 2003-12-11 devnull case 'F':
90 b3994ec5 2003-12-11 devnull fontnames[1] = ARGF();
91 b3994ec5 2003-12-11 devnull if(fontnames[1] == nil)
92 b3994ec5 2003-12-11 devnull goto Usage;
93 b3994ec5 2003-12-11 devnull break;
94 b3994ec5 2003-12-11 devnull case 'l':
95 b3994ec5 2003-12-11 devnull loadfile = ARGF();
96 b3994ec5 2003-12-11 devnull if(loadfile == nil)
97 b3994ec5 2003-12-11 devnull goto Usage;
98 b3994ec5 2003-12-11 devnull break;
99 b3994ec5 2003-12-11 devnull default:
100 b3994ec5 2003-12-11 devnull Usage:
101 5a8e63b2 2004-02-29 devnull fprint(2, "usage: acme -a -c ncol -f fontname -F fixedwidthfontname -l loadfile\n");
102 b3994ec5 2003-12-11 devnull exits("usage");
103 b3994ec5 2003-12-11 devnull }ARGEND
104 b3994ec5 2003-12-11 devnull
105 b3994ec5 2003-12-11 devnull cputype = getenv("cputype");
106 b3994ec5 2003-12-11 devnull objtype = getenv("objtype");
107 b3994ec5 2003-12-11 devnull home = getenv("home");
108 b3994ec5 2003-12-11 devnull p = getenv("tabstop");
109 b3994ec5 2003-12-11 devnull if(p != nil){
110 b3994ec5 2003-12-11 devnull maxtab = strtoul(p, nil, 0);
111 b3994ec5 2003-12-11 devnull free(p);
112 b3994ec5 2003-12-11 devnull }
113 b3994ec5 2003-12-11 devnull if(maxtab == 0)
114 b3994ec5 2003-12-11 devnull maxtab = 4;
115 b3994ec5 2003-12-11 devnull if(loadfile)
116 b3994ec5 2003-12-11 devnull rowloadfonts(loadfile);
117 b3994ec5 2003-12-11 devnull putenv("font", fontnames[0]);
118 b3994ec5 2003-12-11 devnull snarffd = open("/dev/snarf", OREAD|OCEXEC);
119 b3994ec5 2003-12-11 devnull /*
120 b3994ec5 2003-12-11 devnull if(cputype){
121 b3994ec5 2003-12-11 devnull sprint(buf, "/acme/bin/%s", cputype);
122 b3994ec5 2003-12-11 devnull bind(buf, "/bin", MBEFORE);
123 b3994ec5 2003-12-11 devnull }
124 b3994ec5 2003-12-11 devnull bind("/acme/bin", "/bin", MBEFORE);
125 b3994ec5 2003-12-11 devnull */
126 b3994ec5 2003-12-11 devnull getwd(wdir, sizeof wdir);
127 b3994ec5 2003-12-11 devnull
128 b3994ec5 2003-12-11 devnull /*
129 b3994ec5 2003-12-11 devnull if(geninitdraw(nil, derror, fontnames[0], "acme", nil, Refnone) < 0){
130 b3994ec5 2003-12-11 devnull fprint(2, "acme: can't open display: %r\n");
131 b3994ec5 2003-12-11 devnull exits("geninitdraw");
132 b3994ec5 2003-12-11 devnull }
133 b3994ec5 2003-12-11 devnull */
134 b3994ec5 2003-12-11 devnull if(initdraw(derror, fontnames[0], "acme") < 0){
135 b3994ec5 2003-12-11 devnull fprint(2, "acme: can't open display: %r\n");
136 b3994ec5 2003-12-11 devnull exits("initdraw");
137 b3994ec5 2003-12-11 devnull }
138 b3994ec5 2003-12-11 devnull
139 b3994ec5 2003-12-11 devnull d = display;
140 b3994ec5 2003-12-11 devnull font = d->defaultfont;
141 c1973705 2004-02-09 devnull //assert(font);
142 b3994ec5 2003-12-11 devnull
143 b3994ec5 2003-12-11 devnull reffont.f = font;
144 b3994ec5 2003-12-11 devnull reffonts[0] = &reffont;
145 b3994ec5 2003-12-11 devnull incref(&reffont.ref); /* one to hold up 'font' variable */
146 b3994ec5 2003-12-11 devnull incref(&reffont.ref); /* one to hold up reffonts[0] */
147 b3994ec5 2003-12-11 devnull fontcache = emalloc(sizeof(Reffont*));
148 b3994ec5 2003-12-11 devnull nfontcache = 1;
149 b3994ec5 2003-12-11 devnull fontcache[0] = &reffont;
150 b3994ec5 2003-12-11 devnull
151 b3994ec5 2003-12-11 devnull iconinit();
152 b3994ec5 2003-12-11 devnull timerinit();
153 b3994ec5 2003-12-11 devnull rxinit();
154 b3994ec5 2003-12-11 devnull
155 b3994ec5 2003-12-11 devnull cwait = threadwaitchan();
156 b3994ec5 2003-12-11 devnull ccommand = chancreate(sizeof(Command**), 0);
157 b3994ec5 2003-12-11 devnull ckill = chancreate(sizeof(Rune*), 0);
158 b3994ec5 2003-12-11 devnull cxfidalloc = chancreate(sizeof(Xfid*), 0);
159 b3994ec5 2003-12-11 devnull cxfidfree = chancreate(sizeof(Xfid*), 0);
160 b3994ec5 2003-12-11 devnull cnewwindow = chancreate(sizeof(Channel*), 0);
161 b3994ec5 2003-12-11 devnull cerr = chancreate(sizeof(char*), 0);
162 b3994ec5 2003-12-11 devnull cedit = chancreate(sizeof(int), 0);
163 b3994ec5 2003-12-11 devnull cexit = chancreate(sizeof(int), 0);
164 8ad51794 2004-03-25 devnull cwarn = chancreate(sizeof(void*), 1);
165 8ad51794 2004-03-25 devnull if(cwait==nil || ccommand==nil || ckill==nil || cxfidalloc==nil || cxfidfree==nil || cerr==nil || cexit==nil || cwarn==nil){
166 b3994ec5 2003-12-11 devnull fprint(2, "acme: can't create initial channels: %r\n");
167 b3994ec5 2003-12-11 devnull exits("channels");
168 b3994ec5 2003-12-11 devnull }
169 b3994ec5 2003-12-11 devnull
170 b3994ec5 2003-12-11 devnull mousectl = initmouse(nil, screen);
171 b3994ec5 2003-12-11 devnull if(mousectl == nil){
172 b3994ec5 2003-12-11 devnull fprint(2, "acme: can't initialize mouse: %r\n");
173 b3994ec5 2003-12-11 devnull exits("mouse");
174 b3994ec5 2003-12-11 devnull }
175 b3994ec5 2003-12-11 devnull mouse = &mousectl->m;
176 b3994ec5 2003-12-11 devnull keyboardctl = initkeyboard(nil);
177 b3994ec5 2003-12-11 devnull if(keyboardctl == nil){
178 b3994ec5 2003-12-11 devnull fprint(2, "acme: can't initialize keyboard: %r\n");
179 b3994ec5 2003-12-11 devnull exits("keyboard");
180 b3994ec5 2003-12-11 devnull }
181 b3994ec5 2003-12-11 devnull mainpid = getpid();
182 2277c5d7 2004-03-21 devnull startplumbing();
183 2277c5d7 2004-03-21 devnull /*
184 b3994ec5 2003-12-11 devnull plumbeditfd = plumbopen("edit", OREAD|OCEXEC);
185 b3994ec5 2003-12-11 devnull if(plumbeditfd < 0)
186 b3994ec5 2003-12-11 devnull fprint(2, "acme: can't initialize plumber: %r\n");
187 b3994ec5 2003-12-11 devnull else{
188 b3994ec5 2003-12-11 devnull cplumb = chancreate(sizeof(Plumbmsg*), 0);
189 5a8e63b2 2004-02-29 devnull threadcreate(plumbproc, nil, STACK);
190 b3994ec5 2003-12-11 devnull }
191 b3994ec5 2003-12-11 devnull plumbsendfd = plumbopen("send", OWRITE|OCEXEC);
192 2277c5d7 2004-03-21 devnull */
193 b3994ec5 2003-12-11 devnull
194 b3994ec5 2003-12-11 devnull fsysinit();
195 b3994ec5 2003-12-11 devnull
196 b3994ec5 2003-12-11 devnull #define WPERCOL 8
197 b3994ec5 2003-12-11 devnull disk = diskinit();
198 b3994ec5 2003-12-11 devnull if(loadfile)
199 b3994ec5 2003-12-11 devnull rowload(&row, loadfile, TRUE);
200 b3994ec5 2003-12-11 devnull else{
201 b3994ec5 2003-12-11 devnull rowinit(&row, screen->clipr);
202 b3994ec5 2003-12-11 devnull if(ncol < 0){
203 b3994ec5 2003-12-11 devnull if(argc == 0)
204 b3994ec5 2003-12-11 devnull ncol = 2;
205 b3994ec5 2003-12-11 devnull else{
206 b3994ec5 2003-12-11 devnull ncol = (argc+(WPERCOL-1))/WPERCOL;
207 b3994ec5 2003-12-11 devnull if(ncol < 2)
208 b3994ec5 2003-12-11 devnull ncol = 2;
209 b3994ec5 2003-12-11 devnull }
210 b3994ec5 2003-12-11 devnull }
211 b3994ec5 2003-12-11 devnull if(ncol == 0)
212 b3994ec5 2003-12-11 devnull ncol = 2;
213 b3994ec5 2003-12-11 devnull for(i=0; i<ncol; i++){
214 b3994ec5 2003-12-11 devnull c = rowadd(&row, nil, -1);
215 b3994ec5 2003-12-11 devnull if(c==nil && i==0)
216 b3994ec5 2003-12-11 devnull error("initializing columns");
217 b3994ec5 2003-12-11 devnull }
218 b3994ec5 2003-12-11 devnull c = row.col[row.ncol-1];
219 b3994ec5 2003-12-11 devnull if(argc == 0)
220 b3994ec5 2003-12-11 devnull readfile(c, wdir);
221 b3994ec5 2003-12-11 devnull else
222 b3994ec5 2003-12-11 devnull for(i=0; i<argc; i++){
223 b3994ec5 2003-12-11 devnull p = utfrrune(argv[i], '/');
224 b3994ec5 2003-12-11 devnull if((p!=nil && strcmp(p, "/guide")==0) || i/WPERCOL>=row.ncol)
225 b3994ec5 2003-12-11 devnull readfile(c, argv[i]);
226 b3994ec5 2003-12-11 devnull else
227 b3994ec5 2003-12-11 devnull readfile(row.col[i/WPERCOL], argv[i]);
228 b3994ec5 2003-12-11 devnull }
229 b3994ec5 2003-12-11 devnull }
230 b3994ec5 2003-12-11 devnull flushimage(display, 1);
231 b3994ec5 2003-12-11 devnull
232 b3994ec5 2003-12-11 devnull acmeerrorinit();
233 b3994ec5 2003-12-11 devnull threadcreate(keyboardthread, nil, STACK);
234 b3994ec5 2003-12-11 devnull threadcreate(mousethread, nil, STACK);
235 b3994ec5 2003-12-11 devnull threadcreate(waitthread, nil, STACK);
236 b3994ec5 2003-12-11 devnull threadcreate(xfidallocthread, nil, STACK);
237 b3994ec5 2003-12-11 devnull threadcreate(newwindowthread, nil, STACK);
238 b3994ec5 2003-12-11 devnull
239 b3994ec5 2003-12-11 devnull threadnotify(shutdown, 1);
240 b3994ec5 2003-12-11 devnull recvul(cexit);
241 b3994ec5 2003-12-11 devnull killprocs();
242 b3994ec5 2003-12-11 devnull threadexitsall(nil);
243 b3994ec5 2003-12-11 devnull }
244 b3994ec5 2003-12-11 devnull
245 b3994ec5 2003-12-11 devnull void
246 b3994ec5 2003-12-11 devnull readfile(Column *c, char *s)
247 b3994ec5 2003-12-11 devnull {
248 b3994ec5 2003-12-11 devnull Window *w;
249 b3994ec5 2003-12-11 devnull Rune rb[256];
250 b3994ec5 2003-12-11 devnull int nb, nr;
251 b3994ec5 2003-12-11 devnull Runestr rs;
252 b3994ec5 2003-12-11 devnull
253 b3994ec5 2003-12-11 devnull w = coladd(c, nil, nil, -1);
254 b3994ec5 2003-12-11 devnull cvttorunes(s, strlen(s), rb, &nb, &nr, nil);
255 8ad51794 2004-03-25 devnull rs = cleanrname(runestr(rb, nr));
256 b3994ec5 2003-12-11 devnull winsetname(w, rs.r, rs.nr);
257 b3994ec5 2003-12-11 devnull textload(&w->body, 0, s, 1);
258 b3994ec5 2003-12-11 devnull w->body.file->mod = FALSE;
259 b3994ec5 2003-12-11 devnull w->dirty = FALSE;
260 b3994ec5 2003-12-11 devnull winsettag(w);
261 b3994ec5 2003-12-11 devnull textscrdraw(&w->body);
262 b3994ec5 2003-12-11 devnull textsetselect(&w->tag, w->tag.file->b.nc, w->tag.file->b.nc);
263 b3994ec5 2003-12-11 devnull }
264 b3994ec5 2003-12-11 devnull
265 b3994ec5 2003-12-11 devnull char *oknotes[] ={
266 b3994ec5 2003-12-11 devnull "delete",
267 b3994ec5 2003-12-11 devnull "hangup",
268 b3994ec5 2003-12-11 devnull "kill",
269 b3994ec5 2003-12-11 devnull "exit",
270 b3994ec5 2003-12-11 devnull nil
271 b3994ec5 2003-12-11 devnull };
272 b3994ec5 2003-12-11 devnull
273 b3994ec5 2003-12-11 devnull int dumping;
274 b3994ec5 2003-12-11 devnull
275 4da83e7c 2004-03-05 devnull static int
276 b3994ec5 2003-12-11 devnull shutdown(void *v, char *msg)
277 b3994ec5 2003-12-11 devnull {
278 b3994ec5 2003-12-11 devnull int i;
279 b3994ec5 2003-12-11 devnull
280 b3994ec5 2003-12-11 devnull if(strcmp(msg, "sys: write on closed pipe") == 0)
281 b3994ec5 2003-12-11 devnull return 1;
282 b3994ec5 2003-12-11 devnull
283 b3994ec5 2003-12-11 devnull USED(v);
284 b3994ec5 2003-12-11 devnull killprocs();
285 b3994ec5 2003-12-11 devnull if(!dumping && strcmp(msg, "kill")!=0 && strcmp(msg, "exit")!=0 && getpid()==mainpid){
286 b3994ec5 2003-12-11 devnull dumping = TRUE;
287 b3994ec5 2003-12-11 devnull rowdump(&row, nil);
288 b3994ec5 2003-12-11 devnull }
289 b3994ec5 2003-12-11 devnull for(i=0; oknotes[i]; i++)
290 b3994ec5 2003-12-11 devnull if(strncmp(oknotes[i], msg, strlen(oknotes[i])) == 0)
291 b3994ec5 2003-12-11 devnull threadexitsall(msg);
292 b3994ec5 2003-12-11 devnull print("acme: %s\n", msg);
293 b3994ec5 2003-12-11 devnull abort();
294 b3994ec5 2003-12-11 devnull return 0;
295 b3994ec5 2003-12-11 devnull }
296 b3994ec5 2003-12-11 devnull
297 b3994ec5 2003-12-11 devnull void
298 b3994ec5 2003-12-11 devnull killprocs(void)
299 b3994ec5 2003-12-11 devnull {
300 b3994ec5 2003-12-11 devnull Command *c;
301 b3994ec5 2003-12-11 devnull
302 b3994ec5 2003-12-11 devnull fsysclose();
303 b3994ec5 2003-12-11 devnull // if(display)
304 b3994ec5 2003-12-11 devnull // flushimage(display, 1);
305 b3994ec5 2003-12-11 devnull
306 b3994ec5 2003-12-11 devnull for(c=command; c; c=c->next)
307 b3994ec5 2003-12-11 devnull postnote(PNGROUP, c->pid, "hangup");
308 b3994ec5 2003-12-11 devnull }
309 b3994ec5 2003-12-11 devnull
310 b3994ec5 2003-12-11 devnull static int errorfd;
311 b3994ec5 2003-12-11 devnull int erroutfd;
312 b3994ec5 2003-12-11 devnull
313 b3994ec5 2003-12-11 devnull void
314 b3994ec5 2003-12-11 devnull acmeerrorproc(void *v)
315 b3994ec5 2003-12-11 devnull {
316 b3994ec5 2003-12-11 devnull char *buf;
317 b3994ec5 2003-12-11 devnull int n;
318 b3994ec5 2003-12-11 devnull
319 b3994ec5 2003-12-11 devnull USED(v);
320 b3994ec5 2003-12-11 devnull threadsetname("acmeerrorproc");
321 b3994ec5 2003-12-11 devnull buf = emalloc(8192+1);
322 5a8e63b2 2004-02-29 devnull while((n=threadread(errorfd, buf, 8192)) >= 0){
323 b3994ec5 2003-12-11 devnull buf[n] = '\0';
324 b3994ec5 2003-12-11 devnull sendp(cerr, estrdup(buf));
325 b3994ec5 2003-12-11 devnull }
326 b3994ec5 2003-12-11 devnull }
327 b3994ec5 2003-12-11 devnull
328 b3994ec5 2003-12-11 devnull void
329 b3994ec5 2003-12-11 devnull acmeerrorinit(void)
330 b3994ec5 2003-12-11 devnull {
331 5a8e63b2 2004-02-29 devnull int pfd[2];
332 b3994ec5 2003-12-11 devnull
333 b3994ec5 2003-12-11 devnull if(pipe(pfd) < 0)
334 b3994ec5 2003-12-11 devnull error("can't create pipe");
335 b3994ec5 2003-12-11 devnull #if 0
336 b3994ec5 2003-12-11 devnull sprint(acmeerrorfile, "/srv/acme.%s.%d", getuser(), mainpid);
337 b3994ec5 2003-12-11 devnull fd = create(acmeerrorfile, OWRITE, 0666);
338 b3994ec5 2003-12-11 devnull if(fd < 0){
339 b3994ec5 2003-12-11 devnull remove(acmeerrorfile);
340 b3994ec5 2003-12-11 devnull fd = create(acmeerrorfile, OWRITE, 0666);
341 b3994ec5 2003-12-11 devnull if(fd < 0)
342 b3994ec5 2003-12-11 devnull error("can't create acmeerror file");
343 b3994ec5 2003-12-11 devnull }
344 b3994ec5 2003-12-11 devnull sprint(buf, "%d", pfd[0]);
345 b3994ec5 2003-12-11 devnull write(fd, buf, strlen(buf));
346 b3994ec5 2003-12-11 devnull close(fd);
347 b3994ec5 2003-12-11 devnull /* reopen pfd[1] close on exec */
348 b3994ec5 2003-12-11 devnull sprint(buf, "/fd/%d", pfd[1]);
349 b3994ec5 2003-12-11 devnull errorfd = open(buf, OREAD|OCEXEC);
350 b3994ec5 2003-12-11 devnull #endif
351 b3994ec5 2003-12-11 devnull fcntl(pfd[0], F_SETFD, FD_CLOEXEC);
352 b3994ec5 2003-12-11 devnull fcntl(pfd[1], F_SETFD, FD_CLOEXEC);
353 b3994ec5 2003-12-11 devnull erroutfd = pfd[0];
354 b3994ec5 2003-12-11 devnull errorfd = pfd[1];
355 b3994ec5 2003-12-11 devnull if(errorfd < 0)
356 b3994ec5 2003-12-11 devnull error("can't re-open acmeerror file");
357 5a8e63b2 2004-02-29 devnull threadcreate(acmeerrorproc, nil, STACK);
358 b3994ec5 2003-12-11 devnull }
359 b3994ec5 2003-12-11 devnull
360 2277c5d7 2004-03-21 devnull /*
361 b3994ec5 2003-12-11 devnull void
362 b3994ec5 2003-12-11 devnull plumbproc(void *v)
363 b3994ec5 2003-12-11 devnull {
364 b3994ec5 2003-12-11 devnull Plumbmsg *m;
365 b3994ec5 2003-12-11 devnull
366 b3994ec5 2003-12-11 devnull USED(v);
367 b3994ec5 2003-12-11 devnull threadsetname("plumbproc");
368 b3994ec5 2003-12-11 devnull for(;;){
369 5a8e63b2 2004-02-29 devnull m = threadplumbrecv(plumbeditfd);
370 b3994ec5 2003-12-11 devnull if(m == nil)
371 b3994ec5 2003-12-11 devnull threadexits(nil);
372 b3994ec5 2003-12-11 devnull sendp(cplumb, m);
373 b3994ec5 2003-12-11 devnull }
374 b3994ec5 2003-12-11 devnull }
375 2277c5d7 2004-03-21 devnull */
376 b3994ec5 2003-12-11 devnull
377 b3994ec5 2003-12-11 devnull void
378 b3994ec5 2003-12-11 devnull keyboardthread(void *v)
379 b3994ec5 2003-12-11 devnull {
380 b3994ec5 2003-12-11 devnull Rune r;
381 b3994ec5 2003-12-11 devnull Timer *timer;
382 b3994ec5 2003-12-11 devnull Text *t;
383 b3994ec5 2003-12-11 devnull enum { KTimer, KKey, NKALT };
384 b3994ec5 2003-12-11 devnull static Alt alts[NKALT+1];
385 b3994ec5 2003-12-11 devnull
386 b3994ec5 2003-12-11 devnull USED(v);
387 b3994ec5 2003-12-11 devnull alts[KTimer].c = nil;
388 b3994ec5 2003-12-11 devnull alts[KTimer].v = nil;
389 b3994ec5 2003-12-11 devnull alts[KTimer].op = CHANNOP;
390 b3994ec5 2003-12-11 devnull alts[KKey].c = keyboardctl->c;
391 b3994ec5 2003-12-11 devnull alts[KKey].v = &r;
392 b3994ec5 2003-12-11 devnull alts[KKey].op = CHANRCV;
393 b3994ec5 2003-12-11 devnull alts[NKALT].op = CHANEND;
394 b3994ec5 2003-12-11 devnull
395 b3994ec5 2003-12-11 devnull timer = nil;
396 b3994ec5 2003-12-11 devnull typetext = nil;
397 b3994ec5 2003-12-11 devnull threadsetname("keyboardthread");
398 b3994ec5 2003-12-11 devnull for(;;){
399 b3994ec5 2003-12-11 devnull switch(alt(alts)){
400 b3994ec5 2003-12-11 devnull case KTimer:
401 b3994ec5 2003-12-11 devnull timerstop(timer);
402 b3994ec5 2003-12-11 devnull t = typetext;
403 b3994ec5 2003-12-11 devnull if(t!=nil && t->what==Tag){
404 b3994ec5 2003-12-11 devnull winlock(t->w, 'K');
405 b3994ec5 2003-12-11 devnull wincommit(t->w, t);
406 b3994ec5 2003-12-11 devnull winunlock(t->w);
407 b3994ec5 2003-12-11 devnull flushimage(display, 1);
408 b3994ec5 2003-12-11 devnull }
409 b3994ec5 2003-12-11 devnull alts[KTimer].c = nil;
410 b3994ec5 2003-12-11 devnull alts[KTimer].op = CHANNOP;
411 b3994ec5 2003-12-11 devnull break;
412 b3994ec5 2003-12-11 devnull case KKey:
413 b3994ec5 2003-12-11 devnull casekeyboard:
414 b3994ec5 2003-12-11 devnull typetext = rowtype(&row, r, mouse->xy);
415 b3994ec5 2003-12-11 devnull t = typetext;
416 b3994ec5 2003-12-11 devnull if(t!=nil && t->col!=nil && !(r==Kdown || r==Kleft || r==Kright)) /* scrolling doesn't change activecol */
417 b3994ec5 2003-12-11 devnull activecol = t->col;
418 b3994ec5 2003-12-11 devnull if(t!=nil && t->w!=nil)
419 b3994ec5 2003-12-11 devnull t->w->body.file->curtext = &t->w->body;
420 b3994ec5 2003-12-11 devnull if(timer != nil)
421 b3994ec5 2003-12-11 devnull timercancel(timer);
422 b3994ec5 2003-12-11 devnull if(t!=nil && t->what==Tag) {
423 b3994ec5 2003-12-11 devnull timer = timerstart(500);
424 b3994ec5 2003-12-11 devnull alts[KTimer].c = timer->c;
425 b3994ec5 2003-12-11 devnull alts[KTimer].op = CHANRCV;
426 b3994ec5 2003-12-11 devnull }else{
427 b3994ec5 2003-12-11 devnull timer = nil;
428 b3994ec5 2003-12-11 devnull alts[KTimer].c = nil;
429 b3994ec5 2003-12-11 devnull alts[KTimer].op = CHANNOP;
430 b3994ec5 2003-12-11 devnull }
431 b3994ec5 2003-12-11 devnull if(nbrecv(keyboardctl->c, &r) > 0)
432 b3994ec5 2003-12-11 devnull goto casekeyboard;
433 b3994ec5 2003-12-11 devnull flushimage(display, 1);
434 b3994ec5 2003-12-11 devnull break;
435 b3994ec5 2003-12-11 devnull }
436 b3994ec5 2003-12-11 devnull }
437 b3994ec5 2003-12-11 devnull }
438 b3994ec5 2003-12-11 devnull
439 b3994ec5 2003-12-11 devnull void
440 b3994ec5 2003-12-11 devnull mousethread(void *v)
441 b3994ec5 2003-12-11 devnull {
442 b3994ec5 2003-12-11 devnull Text *t, *argt;
443 b3994ec5 2003-12-11 devnull int but;
444 b3994ec5 2003-12-11 devnull uint q0, q1;
445 b3994ec5 2003-12-11 devnull Window *w;
446 b3994ec5 2003-12-11 devnull Plumbmsg *pm;
447 b3994ec5 2003-12-11 devnull Mouse m;
448 b3994ec5 2003-12-11 devnull char *act;
449 8ad51794 2004-03-25 devnull enum { MResize, MMouse, MPlumb, MWarnings, NMALT };
450 b3994ec5 2003-12-11 devnull static Alt alts[NMALT+1];
451 b3994ec5 2003-12-11 devnull
452 b3994ec5 2003-12-11 devnull USED(v);
453 b3994ec5 2003-12-11 devnull threadsetname("mousethread");
454 b3994ec5 2003-12-11 devnull alts[MResize].c = mousectl->resizec;
455 b3994ec5 2003-12-11 devnull alts[MResize].v = nil;
456 b3994ec5 2003-12-11 devnull alts[MResize].op = CHANRCV;
457 b3994ec5 2003-12-11 devnull alts[MMouse].c = mousectl->c;
458 b3994ec5 2003-12-11 devnull alts[MMouse].v = &mousectl->m;
459 b3994ec5 2003-12-11 devnull alts[MMouse].op = CHANRCV;
460 b3994ec5 2003-12-11 devnull alts[MPlumb].c = cplumb;
461 b3994ec5 2003-12-11 devnull alts[MPlumb].v = &pm;
462 b3994ec5 2003-12-11 devnull alts[MPlumb].op = CHANRCV;
463 8ad51794 2004-03-25 devnull alts[MWarnings].c = cwarn;
464 8ad51794 2004-03-25 devnull alts[MWarnings].v = nil;
465 8ad51794 2004-03-25 devnull alts[MWarnings].op = CHANRCV;
466 b3994ec5 2003-12-11 devnull if(cplumb == nil)
467 b3994ec5 2003-12-11 devnull alts[MPlumb].op = CHANNOP;
468 b3994ec5 2003-12-11 devnull alts[NMALT].op = CHANEND;
469 b3994ec5 2003-12-11 devnull
470 b3994ec5 2003-12-11 devnull for(;;){
471 8ad51794 2004-03-25 devnull qlock(&row.lk);
472 8ad51794 2004-03-25 devnull flushwarnings();
473 8ad51794 2004-03-25 devnull qunlock(&row.lk);
474 8ad51794 2004-03-25 devnull flushimage(display, 1);
475 b3994ec5 2003-12-11 devnull switch(alt(alts)){
476 b3994ec5 2003-12-11 devnull case MResize:
477 b3994ec5 2003-12-11 devnull if(getwindow(display, Refnone) < 0)
478 b3994ec5 2003-12-11 devnull error("attach to window");
479 b3994ec5 2003-12-11 devnull draw(screen, screen->r, display->white, nil, ZP);
480 b3994ec5 2003-12-11 devnull scrlresize();
481 b3994ec5 2003-12-11 devnull rowresize(&row, screen->clipr);
482 b3994ec5 2003-12-11 devnull break;
483 b3994ec5 2003-12-11 devnull case MPlumb:
484 b3994ec5 2003-12-11 devnull if(strcmp(pm->type, "text") == 0){
485 b3994ec5 2003-12-11 devnull act = plumblookup(pm->attr, "action");
486 b3994ec5 2003-12-11 devnull if(act==nil || strcmp(act, "showfile")==0)
487 b3994ec5 2003-12-11 devnull plumblook(pm);
488 b3994ec5 2003-12-11 devnull else if(strcmp(act, "showdata")==0)
489 b3994ec5 2003-12-11 devnull plumbshow(pm);
490 b3994ec5 2003-12-11 devnull }
491 8ad51794 2004-03-25 devnull plumbfree(pm);
492 b3994ec5 2003-12-11 devnull break;
493 8ad51794 2004-03-25 devnull case MWarnings:
494 8ad51794 2004-03-25 devnull break;
495 b3994ec5 2003-12-11 devnull case MMouse:
496 b3994ec5 2003-12-11 devnull /*
497 b3994ec5 2003-12-11 devnull * Make a copy so decisions are consistent; mousectl changes
498 b3994ec5 2003-12-11 devnull * underfoot. Can't just receive into m because this introduces
499 b3994ec5 2003-12-11 devnull * another race; see /sys/src/libdraw/mouse.c.
500 b3994ec5 2003-12-11 devnull */
501 b3994ec5 2003-12-11 devnull m = mousectl->m;
502 b3994ec5 2003-12-11 devnull qlock(&row.lk);
503 b3994ec5 2003-12-11 devnull t = rowwhich(&row, m.xy);
504 b3994ec5 2003-12-11 devnull if(t!=mousetext && mousetext!=nil && mousetext->w!=nil){
505 b3994ec5 2003-12-11 devnull winlock(mousetext->w, 'M');
506 b3994ec5 2003-12-11 devnull mousetext->eq0 = ~0;
507 b3994ec5 2003-12-11 devnull wincommit(mousetext->w, mousetext);
508 b3994ec5 2003-12-11 devnull winunlock(mousetext->w);
509 b3994ec5 2003-12-11 devnull }
510 b3994ec5 2003-12-11 devnull mousetext = t;
511 b3994ec5 2003-12-11 devnull if(t == nil)
512 b3994ec5 2003-12-11 devnull goto Continue;
513 b3994ec5 2003-12-11 devnull w = t->w;
514 b3994ec5 2003-12-11 devnull if(t==nil || m.buttons==0)
515 b3994ec5 2003-12-11 devnull goto Continue;
516 b3994ec5 2003-12-11 devnull but = 0;
517 b3994ec5 2003-12-11 devnull if(m.buttons == 1)
518 b3994ec5 2003-12-11 devnull but = 1;
519 b3994ec5 2003-12-11 devnull else if(m.buttons == 2)
520 b3994ec5 2003-12-11 devnull but = 2;
521 b3994ec5 2003-12-11 devnull else if(m.buttons == 4)
522 b3994ec5 2003-12-11 devnull but = 3;
523 b3994ec5 2003-12-11 devnull barttext = t;
524 b3994ec5 2003-12-11 devnull if(t->what==Body && ptinrect(m.xy, t->scrollr)){
525 b3994ec5 2003-12-11 devnull if(but){
526 b3994ec5 2003-12-11 devnull winlock(w, 'M');
527 b3994ec5 2003-12-11 devnull t->eq0 = ~0;
528 b3994ec5 2003-12-11 devnull textscroll(t, but);
529 b3994ec5 2003-12-11 devnull winunlock(w);
530 b3994ec5 2003-12-11 devnull }
531 b3994ec5 2003-12-11 devnull goto Continue;
532 b3994ec5 2003-12-11 devnull }
533 b3994ec5 2003-12-11 devnull if(ptinrect(m.xy, t->scrollr)){
534 b3994ec5 2003-12-11 devnull if(but){
535 b3994ec5 2003-12-11 devnull if(t->what == Columntag)
536 b3994ec5 2003-12-11 devnull rowdragcol(&row, t->col, but);
537 b3994ec5 2003-12-11 devnull else if(t->what == Tag){
538 b3994ec5 2003-12-11 devnull coldragwin(t->col, t->w, but);
539 b3994ec5 2003-12-11 devnull if(t->w)
540 b3994ec5 2003-12-11 devnull barttext = &t->w->body;
541 b3994ec5 2003-12-11 devnull }
542 b3994ec5 2003-12-11 devnull if(t->col)
543 b3994ec5 2003-12-11 devnull activecol = t->col;
544 b3994ec5 2003-12-11 devnull }
545 b3994ec5 2003-12-11 devnull goto Continue;
546 b3994ec5 2003-12-11 devnull }
547 b3994ec5 2003-12-11 devnull if(m.buttons){
548 b3994ec5 2003-12-11 devnull if(w)
549 b3994ec5 2003-12-11 devnull winlock(w, 'M');
550 b3994ec5 2003-12-11 devnull t->eq0 = ~0;
551 b3994ec5 2003-12-11 devnull if(w)
552 b3994ec5 2003-12-11 devnull wincommit(w, t);
553 b3994ec5 2003-12-11 devnull else
554 b3994ec5 2003-12-11 devnull textcommit(t, TRUE);
555 b3994ec5 2003-12-11 devnull if(m.buttons & 1){
556 b3994ec5 2003-12-11 devnull textselect(t);
557 b3994ec5 2003-12-11 devnull if(w)
558 b3994ec5 2003-12-11 devnull winsettag(w);
559 b3994ec5 2003-12-11 devnull argtext = t;
560 b3994ec5 2003-12-11 devnull seltext = t;
561 b3994ec5 2003-12-11 devnull if(t->col)
562 b3994ec5 2003-12-11 devnull activecol = t->col; /* button 1 only */
563 b3994ec5 2003-12-11 devnull if(t->w!=nil && t==&t->w->body)
564 b3994ec5 2003-12-11 devnull activewin = t->w;
565 b3994ec5 2003-12-11 devnull }else if(m.buttons & 2){
566 b3994ec5 2003-12-11 devnull if(textselect2(t, &q0, &q1, &argt))
567 b3994ec5 2003-12-11 devnull execute(t, q0, q1, FALSE, argt);
568 b3994ec5 2003-12-11 devnull }else if(m.buttons & 4){
569 b3994ec5 2003-12-11 devnull if(textselect3(t, &q0, &q1))
570 b3994ec5 2003-12-11 devnull look3(t, q0, q1, FALSE);
571 b3994ec5 2003-12-11 devnull }
572 b3994ec5 2003-12-11 devnull if(w)
573 b3994ec5 2003-12-11 devnull winunlock(w);
574 b3994ec5 2003-12-11 devnull goto Continue;
575 b3994ec5 2003-12-11 devnull }
576 b3994ec5 2003-12-11 devnull Continue:
577 b3994ec5 2003-12-11 devnull qunlock(&row.lk);
578 b3994ec5 2003-12-11 devnull break;
579 b3994ec5 2003-12-11 devnull }
580 b3994ec5 2003-12-11 devnull }
581 b3994ec5 2003-12-11 devnull }
582 b3994ec5 2003-12-11 devnull
583 b3994ec5 2003-12-11 devnull /*
584 b3994ec5 2003-12-11 devnull * There is a race between process exiting and our finding out it was ever created.
585 b3994ec5 2003-12-11 devnull * This structure keeps a list of processes that have exited we haven't heard of.
586 b3994ec5 2003-12-11 devnull */
587 b3994ec5 2003-12-11 devnull typedef struct Pid Pid;
588 b3994ec5 2003-12-11 devnull struct Pid
589 b3994ec5 2003-12-11 devnull {
590 b3994ec5 2003-12-11 devnull int pid;
591 b3994ec5 2003-12-11 devnull char msg[ERRMAX];
592 b3994ec5 2003-12-11 devnull Pid *next;
593 b3994ec5 2003-12-11 devnull };
594 b3994ec5 2003-12-11 devnull
595 b3994ec5 2003-12-11 devnull void
596 b3994ec5 2003-12-11 devnull waitthread(void *v)
597 b3994ec5 2003-12-11 devnull {
598 b3994ec5 2003-12-11 devnull Waitmsg *w;
599 b3994ec5 2003-12-11 devnull Command *c, *lc;
600 b3994ec5 2003-12-11 devnull uint pid;
601 b3994ec5 2003-12-11 devnull int found, ncmd;
602 b3994ec5 2003-12-11 devnull Rune *cmd;
603 b3994ec5 2003-12-11 devnull char *err;
604 b3994ec5 2003-12-11 devnull Text *t;
605 b3994ec5 2003-12-11 devnull Pid *pids, *p, *lastp;
606 b3994ec5 2003-12-11 devnull enum { WErr, WKill, WWait, WCmd, NWALT };
607 b3994ec5 2003-12-11 devnull Alt alts[NWALT+1];
608 b3994ec5 2003-12-11 devnull
609 b3994ec5 2003-12-11 devnull USED(v);
610 b3994ec5 2003-12-11 devnull threadsetname("waitthread");
611 b3994ec5 2003-12-11 devnull pids = nil;
612 b3994ec5 2003-12-11 devnull alts[WErr].c = cerr;
613 b3994ec5 2003-12-11 devnull alts[WErr].v = &err;
614 b3994ec5 2003-12-11 devnull alts[WErr].op = CHANRCV;
615 b3994ec5 2003-12-11 devnull alts[WKill].c = ckill;
616 b3994ec5 2003-12-11 devnull alts[WKill].v = &cmd;
617 b3994ec5 2003-12-11 devnull alts[WKill].op = CHANRCV;
618 b3994ec5 2003-12-11 devnull alts[WWait].c = cwait;
619 b3994ec5 2003-12-11 devnull alts[WWait].v = &w;
620 b3994ec5 2003-12-11 devnull alts[WWait].op = CHANRCV;
621 b3994ec5 2003-12-11 devnull alts[WCmd].c = ccommand;
622 b3994ec5 2003-12-11 devnull alts[WCmd].v = &c;
623 b3994ec5 2003-12-11 devnull alts[WCmd].op = CHANRCV;
624 b3994ec5 2003-12-11 devnull alts[NWALT].op = CHANEND;
625 b3994ec5 2003-12-11 devnull
626 b3994ec5 2003-12-11 devnull command = nil;
627 b3994ec5 2003-12-11 devnull for(;;){
628 b3994ec5 2003-12-11 devnull switch(alt(alts)){
629 b3994ec5 2003-12-11 devnull case WErr:
630 b3994ec5 2003-12-11 devnull qlock(&row.lk);
631 b3994ec5 2003-12-11 devnull warning(nil, "%s", err);
632 b3994ec5 2003-12-11 devnull free(err);
633 b3994ec5 2003-12-11 devnull flushimage(display, 1);
634 b3994ec5 2003-12-11 devnull qunlock(&row.lk);
635 b3994ec5 2003-12-11 devnull break;
636 b3994ec5 2003-12-11 devnull case WKill:
637 b3994ec5 2003-12-11 devnull found = FALSE;
638 b3994ec5 2003-12-11 devnull ncmd = runestrlen(cmd);
639 b3994ec5 2003-12-11 devnull for(c=command; c; c=c->next){
640 b3994ec5 2003-12-11 devnull /* -1 for blank */
641 b3994ec5 2003-12-11 devnull if(runeeq(c->name, c->nname-1, cmd, ncmd) == TRUE){
642 b3994ec5 2003-12-11 devnull if(postnote(PNGROUP, c->pid, "kill") < 0)
643 b3994ec5 2003-12-11 devnull warning(nil, "kill %S: %r\n", cmd);
644 b3994ec5 2003-12-11 devnull found = TRUE;
645 b3994ec5 2003-12-11 devnull }
646 b3994ec5 2003-12-11 devnull }
647 b3994ec5 2003-12-11 devnull if(!found)
648 b3994ec5 2003-12-11 devnull warning(nil, "Kill: no process %S\n", cmd);
649 b3994ec5 2003-12-11 devnull free(cmd);
650 b3994ec5 2003-12-11 devnull break;
651 b3994ec5 2003-12-11 devnull case WWait:
652 b3994ec5 2003-12-11 devnull pid = w->pid;
653 b3994ec5 2003-12-11 devnull lc = nil;
654 b3994ec5 2003-12-11 devnull for(c=command; c; c=c->next){
655 b3994ec5 2003-12-11 devnull if(c->pid == pid){
656 b3994ec5 2003-12-11 devnull if(lc)
657 b3994ec5 2003-12-11 devnull lc->next = c->next;
658 b3994ec5 2003-12-11 devnull else
659 b3994ec5 2003-12-11 devnull command = c->next;
660 b3994ec5 2003-12-11 devnull break;
661 b3994ec5 2003-12-11 devnull }
662 b3994ec5 2003-12-11 devnull lc = c;
663 b3994ec5 2003-12-11 devnull }
664 b3994ec5 2003-12-11 devnull qlock(&row.lk);
665 b3994ec5 2003-12-11 devnull t = &row.tag;
666 b3994ec5 2003-12-11 devnull textcommit(t, TRUE);
667 b3994ec5 2003-12-11 devnull if(c == nil){
668 b3994ec5 2003-12-11 devnull /* helper processes use this exit status */
669 b3994ec5 2003-12-11 devnull if(strncmp(w->msg, "libthread", 9) != 0){
670 b3994ec5 2003-12-11 devnull p = emalloc(sizeof(Pid));
671 b3994ec5 2003-12-11 devnull p->pid = pid;
672 b3994ec5 2003-12-11 devnull strncpy(p->msg, w->msg, sizeof(p->msg));
673 b3994ec5 2003-12-11 devnull p->next = pids;
674 b3994ec5 2003-12-11 devnull pids = p;
675 b3994ec5 2003-12-11 devnull }
676 b3994ec5 2003-12-11 devnull }else{
677 b3994ec5 2003-12-11 devnull if(search(t, c->name, c->nname)){
678 b3994ec5 2003-12-11 devnull textdelete(t, t->q0, t->q1, TRUE);
679 b3994ec5 2003-12-11 devnull textsetselect(t, 0, 0);
680 b3994ec5 2003-12-11 devnull }
681 b3994ec5 2003-12-11 devnull if(w->msg[0])
682 2277c5d7 2004-03-21 devnull warning(c->md, "%S: %s\n", c->name, w->msg);
683 b3994ec5 2003-12-11 devnull flushimage(display, 1);
684 b3994ec5 2003-12-11 devnull }
685 b3994ec5 2003-12-11 devnull qunlock(&row.lk);
686 b3994ec5 2003-12-11 devnull free(w);
687 b3994ec5 2003-12-11 devnull Freecmd:
688 b3994ec5 2003-12-11 devnull if(c){
689 b3994ec5 2003-12-11 devnull if(c->iseditcmd)
690 b3994ec5 2003-12-11 devnull sendul(cedit, 0);
691 b3994ec5 2003-12-11 devnull free(c->text);
692 b3994ec5 2003-12-11 devnull free(c->name);
693 b3994ec5 2003-12-11 devnull fsysdelid(c->md);
694 b3994ec5 2003-12-11 devnull free(c);
695 b3994ec5 2003-12-11 devnull }
696 b3994ec5 2003-12-11 devnull break;
697 b3994ec5 2003-12-11 devnull case WCmd:
698 b3994ec5 2003-12-11 devnull /* has this command already exited? */
699 b3994ec5 2003-12-11 devnull lastp = nil;
700 b3994ec5 2003-12-11 devnull for(p=pids; p!=nil; p=p->next){
701 b3994ec5 2003-12-11 devnull if(p->pid == c->pid){
702 b3994ec5 2003-12-11 devnull if(p->msg[0])
703 b3994ec5 2003-12-11 devnull warning(c->md, "%s\n", p->msg);
704 b3994ec5 2003-12-11 devnull if(lastp == nil)
705 b3994ec5 2003-12-11 devnull pids = p->next;
706 b3994ec5 2003-12-11 devnull else
707 b3994ec5 2003-12-11 devnull lastp->next = p->next;
708 b3994ec5 2003-12-11 devnull free(p);
709 b3994ec5 2003-12-11 devnull goto Freecmd;
710 b3994ec5 2003-12-11 devnull }
711 b3994ec5 2003-12-11 devnull lastp = p;
712 b3994ec5 2003-12-11 devnull }
713 b3994ec5 2003-12-11 devnull c->next = command;
714 b3994ec5 2003-12-11 devnull command = c;
715 b3994ec5 2003-12-11 devnull qlock(&row.lk);
716 b3994ec5 2003-12-11 devnull t = &row.tag;
717 b3994ec5 2003-12-11 devnull textcommit(t, TRUE);
718 b3994ec5 2003-12-11 devnull textinsert(t, 0, c->name, c->nname, TRUE);
719 b3994ec5 2003-12-11 devnull textsetselect(t, 0, 0);
720 b3994ec5 2003-12-11 devnull flushimage(display, 1);
721 b3994ec5 2003-12-11 devnull qunlock(&row.lk);
722 b3994ec5 2003-12-11 devnull break;
723 b3994ec5 2003-12-11 devnull }
724 b3994ec5 2003-12-11 devnull }
725 b3994ec5 2003-12-11 devnull }
726 b3994ec5 2003-12-11 devnull
727 b3994ec5 2003-12-11 devnull void
728 b3994ec5 2003-12-11 devnull xfidallocthread(void *v)
729 b3994ec5 2003-12-11 devnull {
730 b3994ec5 2003-12-11 devnull Xfid *xfree, *x;
731 b3994ec5 2003-12-11 devnull enum { Alloc, Free, N };
732 b3994ec5 2003-12-11 devnull static Alt alts[N+1];
733 b3994ec5 2003-12-11 devnull
734 b3994ec5 2003-12-11 devnull USED(v);
735 b3994ec5 2003-12-11 devnull threadsetname("xfidallocthread");
736 b3994ec5 2003-12-11 devnull alts[Alloc].c = cxfidalloc;
737 b3994ec5 2003-12-11 devnull alts[Alloc].v = nil;
738 b3994ec5 2003-12-11 devnull alts[Alloc].op = CHANRCV;
739 b3994ec5 2003-12-11 devnull alts[Free].c = cxfidfree;
740 b3994ec5 2003-12-11 devnull alts[Free].v = &x;
741 b3994ec5 2003-12-11 devnull alts[Free].op = CHANRCV;
742 b3994ec5 2003-12-11 devnull alts[N].op = CHANEND;
743 b3994ec5 2003-12-11 devnull
744 b3994ec5 2003-12-11 devnull xfree = nil;
745 b3994ec5 2003-12-11 devnull for(;;){
746 b3994ec5 2003-12-11 devnull switch(alt(alts)){
747 b3994ec5 2003-12-11 devnull case Alloc:
748 b3994ec5 2003-12-11 devnull x = xfree;
749 b3994ec5 2003-12-11 devnull if(x)
750 b3994ec5 2003-12-11 devnull xfree = x->next;
751 b3994ec5 2003-12-11 devnull else{
752 b3994ec5 2003-12-11 devnull x = emalloc(sizeof(Xfid));
753 b3994ec5 2003-12-11 devnull x->c = chancreate(sizeof(void(*)(Xfid*)), 0);
754 b3994ec5 2003-12-11 devnull x->arg = x;
755 b3994ec5 2003-12-11 devnull threadcreate(xfidctl, x->arg, STACK);
756 b3994ec5 2003-12-11 devnull }
757 b3994ec5 2003-12-11 devnull sendp(cxfidalloc, x);
758 b3994ec5 2003-12-11 devnull break;
759 b3994ec5 2003-12-11 devnull case Free:
760 b3994ec5 2003-12-11 devnull x->next = xfree;
761 b3994ec5 2003-12-11 devnull xfree = x;
762 b3994ec5 2003-12-11 devnull break;
763 b3994ec5 2003-12-11 devnull }
764 b3994ec5 2003-12-11 devnull }
765 b3994ec5 2003-12-11 devnull }
766 b3994ec5 2003-12-11 devnull
767 b3994ec5 2003-12-11 devnull /* this thread, in the main proc, allows fsysproc to get a window made without doing graphics */
768 b3994ec5 2003-12-11 devnull void
769 b3994ec5 2003-12-11 devnull newwindowthread(void *v)
770 b3994ec5 2003-12-11 devnull {
771 b3994ec5 2003-12-11 devnull Window *w;
772 b3994ec5 2003-12-11 devnull
773 b3994ec5 2003-12-11 devnull USED(v);
774 b3994ec5 2003-12-11 devnull threadsetname("newwindowthread");
775 b3994ec5 2003-12-11 devnull
776 b3994ec5 2003-12-11 devnull for(;;){
777 b3994ec5 2003-12-11 devnull /* only fsysproc is talking to us, so synchronization is trivial */
778 b3994ec5 2003-12-11 devnull recvp(cnewwindow);
779 b3994ec5 2003-12-11 devnull w = makenewwindow(nil);
780 b3994ec5 2003-12-11 devnull winsettag(w);
781 b3994ec5 2003-12-11 devnull sendp(cnewwindow, w);
782 b3994ec5 2003-12-11 devnull }
783 b3994ec5 2003-12-11 devnull }
784 b3994ec5 2003-12-11 devnull
785 b3994ec5 2003-12-11 devnull Reffont*
786 b3994ec5 2003-12-11 devnull rfget(int fix, int save, int setfont, char *name)
787 b3994ec5 2003-12-11 devnull {
788 b3994ec5 2003-12-11 devnull Reffont *r;
789 b3994ec5 2003-12-11 devnull Font *f;
790 b3994ec5 2003-12-11 devnull int i;
791 b3994ec5 2003-12-11 devnull
792 b3994ec5 2003-12-11 devnull r = nil;
793 b3994ec5 2003-12-11 devnull if(name == nil){
794 b3994ec5 2003-12-11 devnull name = fontnames[fix];
795 b3994ec5 2003-12-11 devnull r = reffonts[fix];
796 b3994ec5 2003-12-11 devnull }
797 b3994ec5 2003-12-11 devnull if(r == nil){
798 b3994ec5 2003-12-11 devnull for(i=0; i<nfontcache; i++)
799 b3994ec5 2003-12-11 devnull if(strcmp(name, fontcache[i]->f->name) == 0){
800 b3994ec5 2003-12-11 devnull r = fontcache[i];
801 b3994ec5 2003-12-11 devnull goto Found;
802 b3994ec5 2003-12-11 devnull }
803 b3994ec5 2003-12-11 devnull f = openfont(display, name);
804 b3994ec5 2003-12-11 devnull if(f == nil){
805 c1973705 2004-02-09 devnull fprint(2, "can't open font file %s: %r\n", name);
806 b3994ec5 2003-12-11 devnull warning(nil, "can't open font file %s: %r\n", name);
807 b3994ec5 2003-12-11 devnull return nil;
808 b3994ec5 2003-12-11 devnull }
809 b3994ec5 2003-12-11 devnull r = emalloc(sizeof(Reffont));
810 b3994ec5 2003-12-11 devnull r->f = f;
811 b3994ec5 2003-12-11 devnull fontcache = realloc(fontcache, (nfontcache+1)*sizeof(Reffont*));
812 b3994ec5 2003-12-11 devnull fontcache[nfontcache++] = r;
813 b3994ec5 2003-12-11 devnull }
814 b3994ec5 2003-12-11 devnull Found:
815 b3994ec5 2003-12-11 devnull if(save){
816 b3994ec5 2003-12-11 devnull incref(&r->ref);
817 b3994ec5 2003-12-11 devnull if(reffonts[fix])
818 b3994ec5 2003-12-11 devnull rfclose(reffonts[fix]);
819 b3994ec5 2003-12-11 devnull reffonts[fix] = r;
820 b3994ec5 2003-12-11 devnull free(fontnames[fix]);
821 b3994ec5 2003-12-11 devnull fontnames[fix] = name;
822 b3994ec5 2003-12-11 devnull }
823 b3994ec5 2003-12-11 devnull if(setfont){
824 b3994ec5 2003-12-11 devnull reffont.f = r->f;
825 b3994ec5 2003-12-11 devnull incref(&r->ref);
826 b3994ec5 2003-12-11 devnull rfclose(reffonts[0]);
827 b3994ec5 2003-12-11 devnull font = r->f;
828 b3994ec5 2003-12-11 devnull reffonts[0] = r;
829 b3994ec5 2003-12-11 devnull incref(&r->ref);
830 b3994ec5 2003-12-11 devnull iconinit();
831 b3994ec5 2003-12-11 devnull }
832 b3994ec5 2003-12-11 devnull incref(&r->ref);
833 b3994ec5 2003-12-11 devnull return r;
834 b3994ec5 2003-12-11 devnull }
835 b3994ec5 2003-12-11 devnull
836 b3994ec5 2003-12-11 devnull void
837 b3994ec5 2003-12-11 devnull rfclose(Reffont *r)
838 b3994ec5 2003-12-11 devnull {
839 b3994ec5 2003-12-11 devnull int i;
840 b3994ec5 2003-12-11 devnull
841 b3994ec5 2003-12-11 devnull if(decref(&r->ref) == 0){
842 b3994ec5 2003-12-11 devnull for(i=0; i<nfontcache; i++)
843 b3994ec5 2003-12-11 devnull if(r == fontcache[i])
844 b3994ec5 2003-12-11 devnull break;
845 b3994ec5 2003-12-11 devnull if(i >= nfontcache)
846 b3994ec5 2003-12-11 devnull warning(nil, "internal error: can't find font in cache\n");
847 b3994ec5 2003-12-11 devnull else{
848 b3994ec5 2003-12-11 devnull nfontcache--;
849 b3994ec5 2003-12-11 devnull memmove(fontcache+i, fontcache+i+1, (nfontcache-i)*sizeof(Reffont*));
850 b3994ec5 2003-12-11 devnull }
851 b3994ec5 2003-12-11 devnull freefont(r->f);
852 b3994ec5 2003-12-11 devnull free(r);
853 b3994ec5 2003-12-11 devnull }
854 b3994ec5 2003-12-11 devnull }
855 b3994ec5 2003-12-11 devnull
856 b3994ec5 2003-12-11 devnull Cursor boxcursor = {
857 b3994ec5 2003-12-11 devnull {-7, -7},
858 b3994ec5 2003-12-11 devnull {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
859 b3994ec5 2003-12-11 devnull 0xFF, 0xFF, 0xF8, 0x1F, 0xF8, 0x1F, 0xF8, 0x1F,
860 b3994ec5 2003-12-11 devnull 0xF8, 0x1F, 0xF8, 0x1F, 0xF8, 0x1F, 0xFF, 0xFF,
861 b3994ec5 2003-12-11 devnull 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},
862 b3994ec5 2003-12-11 devnull {0x00, 0x00, 0x7F, 0xFE, 0x7F, 0xFE, 0x7F, 0xFE,
863 b3994ec5 2003-12-11 devnull 0x70, 0x0E, 0x70, 0x0E, 0x70, 0x0E, 0x70, 0x0E,
864 b3994ec5 2003-12-11 devnull 0x70, 0x0E, 0x70, 0x0E, 0x70, 0x0E, 0x70, 0x0E,
865 b3994ec5 2003-12-11 devnull 0x7F, 0xFE, 0x7F, 0xFE, 0x7F, 0xFE, 0x00, 0x00}
866 b3994ec5 2003-12-11 devnull };
867 b3994ec5 2003-12-11 devnull
868 b3994ec5 2003-12-11 devnull void
869 b3994ec5 2003-12-11 devnull iconinit(void)
870 b3994ec5 2003-12-11 devnull {
871 b3994ec5 2003-12-11 devnull Rectangle r;
872 b3994ec5 2003-12-11 devnull Image *tmp;
873 b3994ec5 2003-12-11 devnull
874 b3994ec5 2003-12-11 devnull /* Blue */
875 b3994ec5 2003-12-11 devnull tagcols[BACK] = allocimagemix(display, DPalebluegreen, DWhite);
876 b3994ec5 2003-12-11 devnull tagcols[HIGH] = allocimage(display, Rect(0,0,1,1), screen->chan, 1, DPalegreygreen);
877 b3994ec5 2003-12-11 devnull tagcols[BORD] = allocimage(display, Rect(0,0,1,1), screen->chan, 1, DPurpleblue);
878 b3994ec5 2003-12-11 devnull tagcols[TEXT] = display->black;
879 b3994ec5 2003-12-11 devnull tagcols[HTEXT] = display->black;
880 b3994ec5 2003-12-11 devnull
881 b3994ec5 2003-12-11 devnull /* Yellow */
882 b3994ec5 2003-12-11 devnull textcols[BACK] = allocimagemix(display, DPaleyellow, DWhite);
883 b3994ec5 2003-12-11 devnull textcols[HIGH] = allocimage(display, Rect(0,0,1,1), screen->chan, 1, DDarkyellow);
884 b3994ec5 2003-12-11 devnull textcols[BORD] = allocimage(display, Rect(0,0,1,1), screen->chan, 1, DYellowgreen);
885 b3994ec5 2003-12-11 devnull textcols[TEXT] = display->black;
886 b3994ec5 2003-12-11 devnull textcols[HTEXT] = display->black;
887 b3994ec5 2003-12-11 devnull
888 b3994ec5 2003-12-11 devnull if(button){
889 b3994ec5 2003-12-11 devnull freeimage(button);
890 b3994ec5 2003-12-11 devnull freeimage(modbutton);
891 b3994ec5 2003-12-11 devnull freeimage(colbutton);
892 b3994ec5 2003-12-11 devnull }
893 b3994ec5 2003-12-11 devnull
894 b3994ec5 2003-12-11 devnull r = Rect(0, 0, Scrollwid+2, font->height+1);
895 b3994ec5 2003-12-11 devnull button = allocimage(display, r, screen->chan, 0, DNofill);
896 b3994ec5 2003-12-11 devnull draw(button, r, tagcols[BACK], nil, r.min);
897 b3994ec5 2003-12-11 devnull r.max.x -= 2;
898 b3994ec5 2003-12-11 devnull border(button, r, 2, tagcols[BORD], ZP);
899 b3994ec5 2003-12-11 devnull
900 b3994ec5 2003-12-11 devnull r = button->r;
901 b3994ec5 2003-12-11 devnull modbutton = allocimage(display, r, screen->chan, 0, DNofill);
902 b3994ec5 2003-12-11 devnull draw(modbutton, r, tagcols[BACK], nil, r.min);
903 b3994ec5 2003-12-11 devnull r.max.x -= 2;
904 b3994ec5 2003-12-11 devnull border(modbutton, r, 2, tagcols[BORD], ZP);
905 b3994ec5 2003-12-11 devnull r = insetrect(r, 2);
906 b3994ec5 2003-12-11 devnull tmp = allocimage(display, Rect(0,0,1,1), screen->chan, 1, DMedblue);
907 b3994ec5 2003-12-11 devnull draw(modbutton, r, tmp, nil, ZP);
908 b3994ec5 2003-12-11 devnull freeimage(tmp);
909 b3994ec5 2003-12-11 devnull
910 b3994ec5 2003-12-11 devnull r = button->r;
911 b3994ec5 2003-12-11 devnull colbutton = allocimage(display, r, screen->chan, 0, DPurpleblue);
912 b3994ec5 2003-12-11 devnull
913 b3994ec5 2003-12-11 devnull but2col = allocimage(display, r, screen->chan, 1, 0xAA0000FF);
914 b3994ec5 2003-12-11 devnull but3col = allocimage(display, r, screen->chan, 1, 0x006600FF);
915 b3994ec5 2003-12-11 devnull }
916 b3994ec5 2003-12-11 devnull
917 b3994ec5 2003-12-11 devnull /*
918 b3994ec5 2003-12-11 devnull * /dev/snarf updates when the file is closed, so we must open our own
919 b3994ec5 2003-12-11 devnull * fd here rather than use snarffd
920 b3994ec5 2003-12-11 devnull */
921 b3994ec5 2003-12-11 devnull
922 b3994ec5 2003-12-11 devnull /* rio truncates larges snarf buffers, so this avoids using the
923 b3994ec5 2003-12-11 devnull * service if the string is huge */
924 b3994ec5 2003-12-11 devnull
925 b3994ec5 2003-12-11 devnull #define MAXSNARF 100*1024
926 b3994ec5 2003-12-11 devnull
927 b3994ec5 2003-12-11 devnull void
928 b3994ec5 2003-12-11 devnull acmeputsnarf(void)
929 b3994ec5 2003-12-11 devnull {
930 5a8e63b2 2004-02-29 devnull int i, n;
931 5a8e63b2 2004-02-29 devnull Fmt f;
932 5a8e63b2 2004-02-29 devnull char *s;
933 b3994ec5 2003-12-11 devnull
934 5a8e63b2 2004-02-29 devnull if(snarfbuf.nc==0)
935 b3994ec5 2003-12-11 devnull return;
936 b3994ec5 2003-12-11 devnull if(snarfbuf.nc > MAXSNARF)
937 b3994ec5 2003-12-11 devnull return;
938 5a8e63b2 2004-02-29 devnull
939 5a8e63b2 2004-02-29 devnull fmtstrinit(&f);
940 b3994ec5 2003-12-11 devnull for(i=0; i<snarfbuf.nc; i+=n){
941 b3994ec5 2003-12-11 devnull n = snarfbuf.nc-i;
942 b3994ec5 2003-12-11 devnull if(n >= NSnarf)
943 b3994ec5 2003-12-11 devnull n = NSnarf;
944 b3994ec5 2003-12-11 devnull bufread(&snarfbuf, i, snarfrune, n);
945 5a8e63b2 2004-02-29 devnull if(fmtprint(&f, "%.*S", n, snarfrune) < 0)
946 b3994ec5 2003-12-11 devnull break;
947 b3994ec5 2003-12-11 devnull }
948 5a8e63b2 2004-02-29 devnull s = fmtstrflush(&f);
949 5a8e63b2 2004-02-29 devnull if(s && s[0])
950 5a8e63b2 2004-02-29 devnull putsnarf(s);
951 5a8e63b2 2004-02-29 devnull free(s);
952 b3994ec5 2003-12-11 devnull }
953 b3994ec5 2003-12-11 devnull
954 b3994ec5 2003-12-11 devnull void
955 5a8e63b2 2004-02-29 devnull acmegetsnarf(void)
956 b3994ec5 2003-12-11 devnull {
957 5a8e63b2 2004-02-29 devnull char *s;
958 5a8e63b2 2004-02-29 devnull int nb, nr, nulls, len;
959 5a8e63b2 2004-02-29 devnull Rune *r;
960 b3994ec5 2003-12-11 devnull
961 5a8e63b2 2004-02-29 devnull s = getsnarf();
962 5a8e63b2 2004-02-29 devnull if(s == nil || s[0]==0){
963 5a8e63b2 2004-02-29 devnull free(s);
964 b3994ec5 2003-12-11 devnull return;
965 5a8e63b2 2004-02-29 devnull }
966 5a8e63b2 2004-02-29 devnull
967 5a8e63b2 2004-02-29 devnull len = strlen(s);
968 5a8e63b2 2004-02-29 devnull r = runemalloc(len+1);
969 5a8e63b2 2004-02-29 devnull cvttorunes(s, len, r, &nb, &nr, &nulls);
970 b3994ec5 2003-12-11 devnull bufreset(&snarfbuf);
971 5a8e63b2 2004-02-29 devnull bufinsert(&snarfbuf, 0, r, nr);
972 5a8e63b2 2004-02-29 devnull free(r);
973 5a8e63b2 2004-02-29 devnull free(s);
974 b3994ec5 2003-12-11 devnull }