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
15 b3994ec5 2003-12-11 devnull static Point prevmouse;
16 b3994ec5 2003-12-11 devnull static Window *mousew;
17 be22ae2d 2004-03-26 devnull
18 be22ae2d 2004-03-26 devnull Range
19 be22ae2d 2004-03-26 devnull range(int q0, int q1)
20 be22ae2d 2004-03-26 devnull {
21 be22ae2d 2004-03-26 devnull Range r;
22 be22ae2d 2004-03-26 devnull
23 be22ae2d 2004-03-26 devnull r.q0 = q0;
24 be22ae2d 2004-03-26 devnull r.q1 = q1;
25 be22ae2d 2004-03-26 devnull return r;
26 be22ae2d 2004-03-26 devnull }
27 b3994ec5 2003-12-11 devnull
28 8ad51794 2004-03-25 devnull Runestr
29 8ad51794 2004-03-25 devnull runestr(Rune *r, uint n)
30 8ad51794 2004-03-25 devnull {
31 8ad51794 2004-03-25 devnull Runestr rs;
32 8ad51794 2004-03-25 devnull
33 8ad51794 2004-03-25 devnull rs.r = r;
34 8ad51794 2004-03-25 devnull rs.nr = n;
35 8ad51794 2004-03-25 devnull return rs;
36 8ad51794 2004-03-25 devnull }
37 8ad51794 2004-03-25 devnull
38 b3994ec5 2003-12-11 devnull void
39 b3994ec5 2003-12-11 devnull cvttorunes(char *p, int n, Rune *r, int *nb, int *nr, int *nulls)
40 b3994ec5 2003-12-11 devnull {
41 b3994ec5 2003-12-11 devnull uchar *q;
42 b3994ec5 2003-12-11 devnull Rune *s;
43 b3994ec5 2003-12-11 devnull int j, w;
44 b3994ec5 2003-12-11 devnull
45 b3994ec5 2003-12-11 devnull /*
46 b3994ec5 2003-12-11 devnull * Always guaranteed that n bytes may be interpreted
47 b3994ec5 2003-12-11 devnull * without worrying about partial runes. This may mean
48 b3994ec5 2003-12-11 devnull * reading up to UTFmax-1 more bytes than n; the caller
49 b3994ec5 2003-12-11 devnull * knows this. If n is a firm limit, the caller should
50 b3994ec5 2003-12-11 devnull * set p[n] = 0.
51 b3994ec5 2003-12-11 devnull */
52 b3994ec5 2003-12-11 devnull q = (uchar*)p;
53 b3994ec5 2003-12-11 devnull s = r;
54 b3994ec5 2003-12-11 devnull for(j=0; j<n; j+=w){
55 b3994ec5 2003-12-11 devnull if(*q < Runeself){
56 b3994ec5 2003-12-11 devnull w = 1;
57 b3994ec5 2003-12-11 devnull *s = *q++;
58 b3994ec5 2003-12-11 devnull }else{
59 b3994ec5 2003-12-11 devnull w = chartorune(s, (char*)q);
60 b3994ec5 2003-12-11 devnull q += w;
61 b3994ec5 2003-12-11 devnull }
62 b3994ec5 2003-12-11 devnull if(*s)
63 b3994ec5 2003-12-11 devnull s++;
64 b3994ec5 2003-12-11 devnull else if(nulls)
65 b3994ec5 2003-12-11 devnull *nulls = TRUE;
66 b3994ec5 2003-12-11 devnull }
67 b3994ec5 2003-12-11 devnull *nb = (char*)q-p;
68 b3994ec5 2003-12-11 devnull *nr = s-r;
69 b3994ec5 2003-12-11 devnull }
70 b3994ec5 2003-12-11 devnull
71 b3994ec5 2003-12-11 devnull void
72 b3994ec5 2003-12-11 devnull error(char *s)
73 b3994ec5 2003-12-11 devnull {
74 b3994ec5 2003-12-11 devnull fprint(2, "acme: %s: %r\n", s);
75 37c7bc13 2005-07-13 devnull threadexitsall(nil);
76 b3994ec5 2003-12-11 devnull }
77 b3994ec5 2003-12-11 devnull
78 b3994ec5 2003-12-11 devnull Window*
79 b3994ec5 2003-12-11 devnull errorwin1(Rune *dir, int ndir, Rune **incl, int nincl)
80 b3994ec5 2003-12-11 devnull {
81 b3994ec5 2003-12-11 devnull Window *w;
82 b3994ec5 2003-12-11 devnull Rune *r;
83 b3994ec5 2003-12-11 devnull int i, n;
84 b3994ec5 2003-12-11 devnull static Rune Lpluserrors[] = { '+', 'E', 'r', 'r', 'o', 'r', 's', 0 };
85 b3994ec5 2003-12-11 devnull
86 5a8e63b2 2004-02-29 devnull r = runemalloc(ndir+8);
87 6d7fdb24 2004-12-27 devnull if((n = ndir) != 0){
88 b3994ec5 2003-12-11 devnull runemove(r, dir, ndir);
89 5a8e63b2 2004-02-29 devnull r[n++] = L'/';
90 5a8e63b2 2004-02-29 devnull }
91 b3994ec5 2003-12-11 devnull runemove(r+n, Lpluserrors, 7);
92 b3994ec5 2003-12-11 devnull n += 7;
93 b3994ec5 2003-12-11 devnull w = lookfile(r, n);
94 b3994ec5 2003-12-11 devnull if(w == nil){
95 b3994ec5 2003-12-11 devnull if(row.ncol == 0)
96 b3994ec5 2003-12-11 devnull if(rowadd(&row, nil, -1) == nil)
97 b3994ec5 2003-12-11 devnull error("can't create column to make error window");
98 b3994ec5 2003-12-11 devnull w = coladd(row.col[row.ncol-1], nil, nil, -1);
99 b3994ec5 2003-12-11 devnull w->filemenu = FALSE;
100 b3994ec5 2003-12-11 devnull winsetname(w, r, n);
101 4a3fb872 2014-04-30 rsc xfidlog(w, "new");
102 b3994ec5 2003-12-11 devnull }
103 b3994ec5 2003-12-11 devnull free(r);
104 b3994ec5 2003-12-11 devnull for(i=nincl; --i>=0; ){
105 b3994ec5 2003-12-11 devnull n = runestrlen(incl[i]);
106 b3994ec5 2003-12-11 devnull r = runemalloc(n);
107 b3994ec5 2003-12-11 devnull runemove(r, incl[i], n);
108 b3994ec5 2003-12-11 devnull winaddincl(w, r, n);
109 b3994ec5 2003-12-11 devnull }
110 5a8e63b2 2004-02-29 devnull w->autoindent = globalautoindent;
111 b3994ec5 2003-12-11 devnull return w;
112 b3994ec5 2003-12-11 devnull }
113 b3994ec5 2003-12-11 devnull
114 b3994ec5 2003-12-11 devnull /* make new window, if necessary; return with it locked */
115 b3994ec5 2003-12-11 devnull Window*
116 5a8e63b2 2004-02-29 devnull errorwin(Mntdir *md, int owner)
117 b3994ec5 2003-12-11 devnull {
118 b3994ec5 2003-12-11 devnull Window *w;
119 b3994ec5 2003-12-11 devnull
120 b3994ec5 2003-12-11 devnull for(;;){
121 b3994ec5 2003-12-11 devnull if(md == nil)
122 b3994ec5 2003-12-11 devnull w = errorwin1(nil, 0, nil, 0);
123 b3994ec5 2003-12-11 devnull else
124 b3994ec5 2003-12-11 devnull w = errorwin1(md->dir, md->ndir, md->incl, md->nincl);
125 5a8e63b2 2004-02-29 devnull winlock(w, owner);
126 b3994ec5 2003-12-11 devnull if(w->col != nil)
127 b3994ec5 2003-12-11 devnull break;
128 b3994ec5 2003-12-11 devnull /* window was deleted too fast */
129 5a8e63b2 2004-02-29 devnull winunlock(w);
130 b3994ec5 2003-12-11 devnull }
131 b3994ec5 2003-12-11 devnull return w;
132 b3994ec5 2003-12-11 devnull }
133 b3994ec5 2003-12-11 devnull
134 9d01e221 2005-01-30 devnull /*
135 9d01e221 2005-01-30 devnull * Incoming window should be locked.
136 9d01e221 2005-01-30 devnull * It will be unlocked and returned window
137 9d01e221 2005-01-30 devnull * will be locked in its place.
138 9d01e221 2005-01-30 devnull */
139 9d01e221 2005-01-30 devnull Window*
140 9d01e221 2005-01-30 devnull errorwinforwin(Window *w)
141 9d01e221 2005-01-30 devnull {
142 9d01e221 2005-01-30 devnull int i, n, nincl, owner;
143 9d01e221 2005-01-30 devnull Rune **incl;
144 9d01e221 2005-01-30 devnull Runestr dir;
145 9d01e221 2005-01-30 devnull Text *t;
146 9d01e221 2005-01-30 devnull
147 9d01e221 2005-01-30 devnull t = &w->body;
148 9d01e221 2005-01-30 devnull dir = dirname(t, nil, 0);
149 9d01e221 2005-01-30 devnull if(dir.nr==1 && dir.r[0]=='.'){ /* sigh */
150 9d01e221 2005-01-30 devnull free(dir.r);
151 9d01e221 2005-01-30 devnull dir.r = nil;
152 9d01e221 2005-01-30 devnull dir.nr = 0;
153 9d01e221 2005-01-30 devnull }
154 9d01e221 2005-01-30 devnull incl = nil;
155 9d01e221 2005-01-30 devnull nincl = w->nincl;
156 9d01e221 2005-01-30 devnull if(nincl > 0){
157 9d01e221 2005-01-30 devnull incl = emalloc(nincl*sizeof(Rune*));
158 9d01e221 2005-01-30 devnull for(i=0; i<nincl; i++){
159 9d01e221 2005-01-30 devnull n = runestrlen(w->incl[i]);
160 9d01e221 2005-01-30 devnull incl[i] = runemalloc(n+1);
161 9d01e221 2005-01-30 devnull runemove(incl[i], w->incl[i], n);
162 9d01e221 2005-01-30 devnull }
163 9d01e221 2005-01-30 devnull }
164 9d01e221 2005-01-30 devnull owner = w->owner;
165 9d01e221 2005-01-30 devnull winunlock(w);
166 9d01e221 2005-01-30 devnull for(;;){
167 9d01e221 2005-01-30 devnull w = errorwin1(dir.r, dir.nr, incl, nincl);
168 9d01e221 2005-01-30 devnull winlock(w, owner);
169 9d01e221 2005-01-30 devnull if(w->col != nil)
170 9d01e221 2005-01-30 devnull break;
171 9d01e221 2005-01-30 devnull /* window deleted too fast */
172 9d01e221 2005-01-30 devnull winunlock(w);
173 9d01e221 2005-01-30 devnull }
174 9d01e221 2005-01-30 devnull return w;
175 9d01e221 2005-01-30 devnull }
176 9d01e221 2005-01-30 devnull
177 5a8e63b2 2004-02-29 devnull typedef struct Warning Warning;
178 5a8e63b2 2004-02-29 devnull
179 5a8e63b2 2004-02-29 devnull struct Warning{
180 5a8e63b2 2004-02-29 devnull Mntdir *md;
181 5a8e63b2 2004-02-29 devnull Buffer buf;
182 5a8e63b2 2004-02-29 devnull Warning *next;
183 5a8e63b2 2004-02-29 devnull };
184 5a8e63b2 2004-02-29 devnull
185 5a8e63b2 2004-02-29 devnull static Warning *warnings;
186 5a8e63b2 2004-02-29 devnull
187 5a8e63b2 2004-02-29 devnull static
188 5a8e63b2 2004-02-29 devnull void
189 5a8e63b2 2004-02-29 devnull addwarningtext(Mntdir *md, Rune *r, int nr)
190 b3994ec5 2003-12-11 devnull {
191 5a8e63b2 2004-02-29 devnull Warning *warn;
192 5a8e63b2 2004-02-29 devnull
193 5a8e63b2 2004-02-29 devnull for(warn = warnings; warn; warn=warn->next){
194 5a8e63b2 2004-02-29 devnull if(warn->md == md){
195 5a8e63b2 2004-02-29 devnull bufinsert(&warn->buf, warn->buf.nc, r, nr);
196 5a8e63b2 2004-02-29 devnull return;
197 5a8e63b2 2004-02-29 devnull }
198 5a8e63b2 2004-02-29 devnull }
199 5a8e63b2 2004-02-29 devnull warn = emalloc(sizeof(Warning));
200 5a8e63b2 2004-02-29 devnull warn->next = warnings;
201 8ad51794 2004-03-25 devnull warn->md = md;
202 8ad51794 2004-03-25 devnull if(md)
203 8ad51794 2004-03-25 devnull fsysincid(md);
204 5a8e63b2 2004-02-29 devnull warnings = warn;
205 5a8e63b2 2004-02-29 devnull bufinsert(&warn->buf, 0, r, nr);
206 8ad51794 2004-03-25 devnull nbsendp(cwarn, 0);
207 5a8e63b2 2004-02-29 devnull }
208 5a8e63b2 2004-02-29 devnull
209 8ad51794 2004-03-25 devnull /* called while row is locked */
210 5a8e63b2 2004-02-29 devnull void
211 8ad51794 2004-03-25 devnull flushwarnings(void)
212 5a8e63b2 2004-02-29 devnull {
213 5a8e63b2 2004-02-29 devnull Warning *warn, *next;
214 b3994ec5 2003-12-11 devnull Window *w;
215 b3994ec5 2003-12-11 devnull Text *t;
216 5a8e63b2 2004-02-29 devnull int owner, nr, q0, n;
217 5a8e63b2 2004-02-29 devnull Rune *r;
218 b3994ec5 2003-12-11 devnull
219 5a8e63b2 2004-02-29 devnull for(warn=warnings; warn; warn=next) {
220 5a8e63b2 2004-02-29 devnull w = errorwin(warn->md, 'E');
221 5a8e63b2 2004-02-29 devnull t = &w->body;
222 5a8e63b2 2004-02-29 devnull owner = w->owner;
223 5a8e63b2 2004-02-29 devnull if(owner == 0)
224 5a8e63b2 2004-02-29 devnull w->owner = 'E';
225 5a8e63b2 2004-02-29 devnull wincommit(w, t);
226 5a8e63b2 2004-02-29 devnull /*
227 5a8e63b2 2004-02-29 devnull * Most commands don't generate much output. For instance,
228 5a8e63b2 2004-02-29 devnull * Edit ,>cat goes through /dev/cons and is already in blocks
229 5a8e63b2 2004-02-29 devnull * because of the i/o system, but a few can. Edit ,p will
230 5a8e63b2 2004-02-29 devnull * put the entire result into a single hunk. So it's worth doing
231 5a8e63b2 2004-02-29 devnull * this in blocks (and putting the text in a buffer in the first
232 5a8e63b2 2004-02-29 devnull * place), to avoid a big memory footprint.
233 5a8e63b2 2004-02-29 devnull */
234 5a8e63b2 2004-02-29 devnull r = fbufalloc();
235 5a8e63b2 2004-02-29 devnull q0 = t->file->b.nc;
236 5a8e63b2 2004-02-29 devnull for(n = 0; n < warn->buf.nc; n += nr){
237 5a8e63b2 2004-02-29 devnull nr = warn->buf.nc - n;
238 5a8e63b2 2004-02-29 devnull if(nr > RBUFSIZE)
239 5a8e63b2 2004-02-29 devnull nr = RBUFSIZE;
240 5a8e63b2 2004-02-29 devnull bufread(&warn->buf, n, r, nr);
241 5a8e63b2 2004-02-29 devnull textbsinsert(t, t->file->b.nc, r, nr, TRUE, &nr);
242 5a8e63b2 2004-02-29 devnull }
243 5a8e63b2 2004-02-29 devnull textshow(t, q0, t->file->b.nc, 1);
244 5a8e63b2 2004-02-29 devnull free(r);
245 5a8e63b2 2004-02-29 devnull winsettag(t->w);
246 5a8e63b2 2004-02-29 devnull textscrdraw(t);
247 5a8e63b2 2004-02-29 devnull w->owner = owner;
248 5a8e63b2 2004-02-29 devnull w->dirty = FALSE;
249 b3994ec5 2003-12-11 devnull winunlock(w);
250 5a8e63b2 2004-02-29 devnull bufclose(&warn->buf);
251 5a8e63b2 2004-02-29 devnull next = warn->next;
252 8ad51794 2004-03-25 devnull if(warn->md)
253 8ad51794 2004-03-25 devnull fsysdelid(warn->md);
254 5a8e63b2 2004-02-29 devnull free(warn);
255 5a8e63b2 2004-02-29 devnull }
256 5a8e63b2 2004-02-29 devnull warnings = nil;
257 b3994ec5 2003-12-11 devnull }
258 b3994ec5 2003-12-11 devnull
259 b3994ec5 2003-12-11 devnull void
260 b3994ec5 2003-12-11 devnull warning(Mntdir *md, char *s, ...)
261 b3994ec5 2003-12-11 devnull {
262 b3994ec5 2003-12-11 devnull Rune *r;
263 b3994ec5 2003-12-11 devnull va_list arg;
264 b3994ec5 2003-12-11 devnull
265 b3994ec5 2003-12-11 devnull va_start(arg, s);
266 b3994ec5 2003-12-11 devnull r = runevsmprint(s, arg);
267 b3994ec5 2003-12-11 devnull va_end(arg);
268 5a8e63b2 2004-02-29 devnull if(r == nil)
269 5a8e63b2 2004-02-29 devnull error("runevsmprint failed");
270 5a8e63b2 2004-02-29 devnull addwarningtext(md, r, runestrlen(r));
271 acecbb16 2007-08-22 rsc free(r);
272 b3994ec5 2003-12-11 devnull }
273 b3994ec5 2003-12-11 devnull
274 b3994ec5 2003-12-11 devnull int
275 b3994ec5 2003-12-11 devnull runeeq(Rune *s1, uint n1, Rune *s2, uint n2)
276 b3994ec5 2003-12-11 devnull {
277 b3994ec5 2003-12-11 devnull if(n1 != n2)
278 b3994ec5 2003-12-11 devnull return FALSE;
279 b3994ec5 2003-12-11 devnull return memcmp(s1, s2, n1*sizeof(Rune)) == 0;
280 b3994ec5 2003-12-11 devnull }
281 b3994ec5 2003-12-11 devnull
282 b3994ec5 2003-12-11 devnull uint
283 b3994ec5 2003-12-11 devnull min(uint a, uint b)
284 b3994ec5 2003-12-11 devnull {
285 b3994ec5 2003-12-11 devnull if(a < b)
286 b3994ec5 2003-12-11 devnull return a;
287 b3994ec5 2003-12-11 devnull return b;
288 b3994ec5 2003-12-11 devnull }
289 b3994ec5 2003-12-11 devnull
290 b3994ec5 2003-12-11 devnull uint
291 b3994ec5 2003-12-11 devnull max(uint a, uint b)
292 b3994ec5 2003-12-11 devnull {
293 b3994ec5 2003-12-11 devnull if(a > b)
294 b3994ec5 2003-12-11 devnull return a;
295 b3994ec5 2003-12-11 devnull return b;
296 b3994ec5 2003-12-11 devnull }
297 b3994ec5 2003-12-11 devnull
298 b3994ec5 2003-12-11 devnull char*
299 b3994ec5 2003-12-11 devnull runetobyte(Rune *r, int n)
300 b3994ec5 2003-12-11 devnull {
301 b3994ec5 2003-12-11 devnull char *s;
302 b3994ec5 2003-12-11 devnull
303 b3994ec5 2003-12-11 devnull if(r == nil)
304 b3994ec5 2003-12-11 devnull return nil;
305 b3994ec5 2003-12-11 devnull s = emalloc(n*UTFmax+1);
306 b3994ec5 2003-12-11 devnull setmalloctag(s, getcallerpc(&r));
307 b3994ec5 2003-12-11 devnull snprint(s, n*UTFmax+1, "%.*S", n, r);
308 b3994ec5 2003-12-11 devnull return s;
309 b3994ec5 2003-12-11 devnull }
310 b3994ec5 2003-12-11 devnull
311 b3994ec5 2003-12-11 devnull Rune*
312 b3994ec5 2003-12-11 devnull bytetorune(char *s, int *ip)
313 b3994ec5 2003-12-11 devnull {
314 b3994ec5 2003-12-11 devnull Rune *r;
315 b3994ec5 2003-12-11 devnull int nb, nr;
316 b3994ec5 2003-12-11 devnull
317 b3994ec5 2003-12-11 devnull nb = strlen(s);
318 b3994ec5 2003-12-11 devnull r = runemalloc(nb+1);
319 b3994ec5 2003-12-11 devnull cvttorunes(s, nb, r, &nb, &nr, nil);
320 b3994ec5 2003-12-11 devnull r[nr] = '\0';
321 b3994ec5 2003-12-11 devnull *ip = nr;
322 b3994ec5 2003-12-11 devnull return r;
323 b3994ec5 2003-12-11 devnull }
324 b3994ec5 2003-12-11 devnull
325 b3994ec5 2003-12-11 devnull int
326 b3994ec5 2003-12-11 devnull isalnum(Rune c)
327 b3994ec5 2003-12-11 devnull {
328 b3994ec5 2003-12-11 devnull /*
329 b3994ec5 2003-12-11 devnull * Hard to get absolutely right. Use what we know about ASCII
330 b3994ec5 2003-12-11 devnull * and assume anything above the Latin control characters is
331 b3994ec5 2003-12-11 devnull * potentially an alphanumeric.
332 b3994ec5 2003-12-11 devnull */
333 b3994ec5 2003-12-11 devnull if(c <= ' ')
334 b3994ec5 2003-12-11 devnull return FALSE;
335 b3994ec5 2003-12-11 devnull if(0x7F<=c && c<=0xA0)
336 b3994ec5 2003-12-11 devnull return FALSE;
337 b3994ec5 2003-12-11 devnull if(utfrune("!\"#$%&'()*+,-./:;<=>?@[\\]^`{|}~", c))
338 b3994ec5 2003-12-11 devnull return FALSE;
339 b3994ec5 2003-12-11 devnull return TRUE;
340 b3994ec5 2003-12-11 devnull }
341 b3994ec5 2003-12-11 devnull
342 b3994ec5 2003-12-11 devnull int
343 b3994ec5 2003-12-11 devnull rgetc(void *v, uint n)
344 b3994ec5 2003-12-11 devnull {
345 b3994ec5 2003-12-11 devnull return ((Rune*)v)[n];
346 b3994ec5 2003-12-11 devnull }
347 b3994ec5 2003-12-11 devnull
348 b3994ec5 2003-12-11 devnull int
349 b3994ec5 2003-12-11 devnull tgetc(void *a, uint n)
350 b3994ec5 2003-12-11 devnull {
351 b3994ec5 2003-12-11 devnull Text *t;
352 b3994ec5 2003-12-11 devnull
353 b3994ec5 2003-12-11 devnull t = a;
354 b3994ec5 2003-12-11 devnull if(n >= t->file->b.nc)
355 b3994ec5 2003-12-11 devnull return 0;
356 b3994ec5 2003-12-11 devnull return textreadc(t, n);
357 b3994ec5 2003-12-11 devnull }
358 b3994ec5 2003-12-11 devnull
359 b3994ec5 2003-12-11 devnull Rune*
360 b3994ec5 2003-12-11 devnull skipbl(Rune *r, int n, int *np)
361 b3994ec5 2003-12-11 devnull {
362 15680d56 2004-03-05 devnull while(n>0 && (*r==' ' || *r=='\t' || *r=='\n')){
363 b3994ec5 2003-12-11 devnull --n;
364 b3994ec5 2003-12-11 devnull r++;
365 b3994ec5 2003-12-11 devnull }
366 b3994ec5 2003-12-11 devnull *np = n;
367 b3994ec5 2003-12-11 devnull return r;
368 b3994ec5 2003-12-11 devnull }
369 b3994ec5 2003-12-11 devnull
370 b3994ec5 2003-12-11 devnull Rune*
371 b3994ec5 2003-12-11 devnull findbl(Rune *r, int n, int *np)
372 b3994ec5 2003-12-11 devnull {
373 0d0df317 2004-03-05 devnull while(n>0 && *r!=' ' && *r!='\t' && *r!='\n'){
374 b3994ec5 2003-12-11 devnull --n;
375 b3994ec5 2003-12-11 devnull r++;
376 b3994ec5 2003-12-11 devnull }
377 b3994ec5 2003-12-11 devnull *np = n;
378 b3994ec5 2003-12-11 devnull return r;
379 b3994ec5 2003-12-11 devnull }
380 b3994ec5 2003-12-11 devnull
381 b3994ec5 2003-12-11 devnull void
382 b3994ec5 2003-12-11 devnull savemouse(Window *w)
383 b3994ec5 2003-12-11 devnull {
384 b3994ec5 2003-12-11 devnull prevmouse = mouse->xy;
385 b3994ec5 2003-12-11 devnull mousew = w;
386 b3994ec5 2003-12-11 devnull }
387 b3994ec5 2003-12-11 devnull
388 37f8ed24 2012-09-24 rsc int
389 b3994ec5 2003-12-11 devnull restoremouse(Window *w)
390 b3994ec5 2003-12-11 devnull {
391 37f8ed24 2012-09-24 rsc int did;
392 37f8ed24 2012-09-24 rsc
393 37f8ed24 2012-09-24 rsc did = 0;
394 37f8ed24 2012-09-24 rsc if(mousew!=nil && mousew==w) {
395 b3994ec5 2003-12-11 devnull moveto(mousectl, prevmouse);
396 37f8ed24 2012-09-24 rsc did = 1;
397 37f8ed24 2012-09-24 rsc }
398 b3994ec5 2003-12-11 devnull mousew = nil;
399 37f8ed24 2012-09-24 rsc return did;
400 b3994ec5 2003-12-11 devnull }
401 b3994ec5 2003-12-11 devnull
402 b3994ec5 2003-12-11 devnull void
403 b3994ec5 2003-12-11 devnull clearmouse()
404 b3994ec5 2003-12-11 devnull {
405 b3994ec5 2003-12-11 devnull mousew = nil;
406 b3994ec5 2003-12-11 devnull }
407 b3994ec5 2003-12-11 devnull
408 b3994ec5 2003-12-11 devnull char*
409 b3994ec5 2003-12-11 devnull estrdup(char *s)
410 b3994ec5 2003-12-11 devnull {
411 b3994ec5 2003-12-11 devnull char *t;
412 b3994ec5 2003-12-11 devnull
413 b3994ec5 2003-12-11 devnull t = strdup(s);
414 b3994ec5 2003-12-11 devnull if(t == nil)
415 b3994ec5 2003-12-11 devnull error("strdup failed");
416 b3994ec5 2003-12-11 devnull setmalloctag(t, getcallerpc(&s));
417 b3994ec5 2003-12-11 devnull return t;
418 b3994ec5 2003-12-11 devnull }
419 b3994ec5 2003-12-11 devnull
420 b3994ec5 2003-12-11 devnull void*
421 b3994ec5 2003-12-11 devnull emalloc(uint n)
422 b3994ec5 2003-12-11 devnull {
423 b3994ec5 2003-12-11 devnull void *p;
424 b3994ec5 2003-12-11 devnull
425 b3994ec5 2003-12-11 devnull p = malloc(n);
426 734a96bd 2008-03-07 rsc if(p == nil)
427 b3994ec5 2003-12-11 devnull error("malloc failed");
428 b3994ec5 2003-12-11 devnull setmalloctag(p, getcallerpc(&n));
429 b3994ec5 2003-12-11 devnull memset(p, 0, n);
430 b3994ec5 2003-12-11 devnull return p;
431 b3994ec5 2003-12-11 devnull }
432 b3994ec5 2003-12-11 devnull
433 b3994ec5 2003-12-11 devnull void*
434 b3994ec5 2003-12-11 devnull erealloc(void *p, uint n)
435 b3994ec5 2003-12-11 devnull {
436 b3994ec5 2003-12-11 devnull p = realloc(p, n);
437 734a96bd 2008-03-07 rsc if(p == nil)
438 b3994ec5 2003-12-11 devnull error("realloc failed");
439 b3994ec5 2003-12-11 devnull setmalloctag(p, getcallerpc(&n));
440 b3994ec5 2003-12-11 devnull return p;
441 b3994ec5 2003-12-11 devnull }
442 b3994ec5 2003-12-11 devnull
443 b3994ec5 2003-12-11 devnull /*
444 b3994ec5 2003-12-11 devnull * Heuristic city.
445 b3994ec5 2003-12-11 devnull */
446 b3994ec5 2003-12-11 devnull Window*
447 b3994ec5 2003-12-11 devnull makenewwindow(Text *t)
448 b3994ec5 2003-12-11 devnull {
449 b3994ec5 2003-12-11 devnull Column *c;
450 b3994ec5 2003-12-11 devnull Window *w, *bigw, *emptyw;
451 b3994ec5 2003-12-11 devnull Text *emptyb;
452 b3994ec5 2003-12-11 devnull int i, y, el;
453 b3994ec5 2003-12-11 devnull
454 b3994ec5 2003-12-11 devnull if(activecol)
455 b3994ec5 2003-12-11 devnull c = activecol;
456 b3994ec5 2003-12-11 devnull else if(seltext && seltext->col)
457 b3994ec5 2003-12-11 devnull c = seltext->col;
458 b3994ec5 2003-12-11 devnull else if(t && t->col)
459 b3994ec5 2003-12-11 devnull c = t->col;
460 b3994ec5 2003-12-11 devnull else{
461 b3994ec5 2003-12-11 devnull if(row.ncol==0 && rowadd(&row, nil, -1)==nil)
462 b3994ec5 2003-12-11 devnull error("can't make column");
463 b3994ec5 2003-12-11 devnull c = row.col[row.ncol-1];
464 b3994ec5 2003-12-11 devnull }
465 b3994ec5 2003-12-11 devnull activecol = c;
466 b3994ec5 2003-12-11 devnull if(t==nil || t->w==nil || c->nw==0)
467 b3994ec5 2003-12-11 devnull return coladd(c, nil, nil, -1);
468 b3994ec5 2003-12-11 devnull
469 b3994ec5 2003-12-11 devnull /* find biggest window and biggest blank spot */
470 b3994ec5 2003-12-11 devnull emptyw = c->w[0];
471 b3994ec5 2003-12-11 devnull bigw = emptyw;
472 b3994ec5 2003-12-11 devnull for(i=1; i<c->nw; i++){
473 b3994ec5 2003-12-11 devnull w = c->w[i];
474 b3994ec5 2003-12-11 devnull /* use >= to choose one near bottom of screen */
475 b3994ec5 2003-12-11 devnull if(w->body.fr.maxlines >= bigw->body.fr.maxlines)
476 b3994ec5 2003-12-11 devnull bigw = w;
477 b3994ec5 2003-12-11 devnull if(w->body.fr.maxlines-w->body.fr.nlines >= emptyw->body.fr.maxlines-emptyw->body.fr.nlines)
478 b3994ec5 2003-12-11 devnull emptyw = w;
479 b3994ec5 2003-12-11 devnull }
480 b3994ec5 2003-12-11 devnull emptyb = &emptyw->body;
481 b3994ec5 2003-12-11 devnull el = emptyb->fr.maxlines-emptyb->fr.nlines;
482 b3994ec5 2003-12-11 devnull /* if empty space is big, use it */
483 b3994ec5 2003-12-11 devnull if(el>15 || (el>3 && el>(bigw->body.fr.maxlines-1)/2))
484 b3994ec5 2003-12-11 devnull y = emptyb->fr.r.min.y+emptyb->fr.nlines*font->height;
485 b3994ec5 2003-12-11 devnull else{
486 b3994ec5 2003-12-11 devnull /* if this window is in column and isn't much smaller, split it */
487 b3994ec5 2003-12-11 devnull if(t->col==c && Dy(t->w->r)>2*Dy(bigw->r)/3)
488 b3994ec5 2003-12-11 devnull bigw = t->w;
489 b3994ec5 2003-12-11 devnull y = (bigw->r.min.y + bigw->r.max.y)/2;
490 b3994ec5 2003-12-11 devnull }
491 b3994ec5 2003-12-11 devnull w = coladd(c, nil, nil, y);
492 b3994ec5 2003-12-11 devnull if(w->body.fr.maxlines < 2)
493 b3994ec5 2003-12-11 devnull colgrow(w->col, w, 1);
494 b3994ec5 2003-12-11 devnull return w;
495 b3994ec5 2003-12-11 devnull }