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