Blame


1 e830a908 2005-11-06 devnull #include <u.h>
2 e830a908 2005-11-06 devnull #include <libc.h>
3 e830a908 2005-11-06 devnull #include <draw.h>
4 e830a908 2005-11-06 devnull #include <thread.h>
5 e830a908 2005-11-06 devnull #include <cursor.h>
6 e830a908 2005-11-06 devnull #include <mouse.h>
7 e830a908 2005-11-06 devnull #include <keyboard.h>
8 e830a908 2005-11-06 devnull #include <frame.h>
9 e830a908 2005-11-06 devnull #include <fcall.h>
10 0c7f940a 2005-11-07 devnull #include <9pclient.h>
11 e830a908 2005-11-06 devnull #include <plumb.h>
12 e830a908 2005-11-06 devnull #include <complete.h>
13 e830a908 2005-11-06 devnull #include "dat.h"
14 e830a908 2005-11-06 devnull #include "fns.h"
15 e830a908 2005-11-06 devnull
16 e830a908 2005-11-06 devnull #define MOVEIT if(0)
17 e830a908 2005-11-06 devnull
18 e830a908 2005-11-06 devnull enum
19 e830a908 2005-11-06 devnull {
20 210d461c 2011-10-12 rsc HiWater = 64000000, /* max size of history */
21 e830a908 2005-11-06 devnull LoWater = 400000, /* min size of history after max'ed */
22 cbeb0b26 2006-04-01 devnull MinWater = 20000 /* room to leave available when reallocating */
23 e830a908 2005-11-06 devnull };
24 e830a908 2005-11-06 devnull
25 e830a908 2005-11-06 devnull static int topped;
26 e830a908 2005-11-06 devnull static int id;
27 e830a908 2005-11-06 devnull
28 e830a908 2005-11-06 devnull static Image *cols[NCOL];
29 e830a908 2005-11-06 devnull static Image *grey;
30 e830a908 2005-11-06 devnull static Image *darkgrey;
31 e830a908 2005-11-06 devnull static Cursor *lastcursor;
32 e830a908 2005-11-06 devnull static Image *titlecol;
33 e830a908 2005-11-06 devnull static Image *lighttitlecol;
34 e830a908 2005-11-06 devnull static Image *holdcol;
35 e830a908 2005-11-06 devnull static Image *lightholdcol;
36 e830a908 2005-11-06 devnull static Image *paleholdcol;
37 e830a908 2005-11-06 devnull
38 a8a0a642 2012-11-26 rsc static int
39 a8a0a642 2012-11-26 rsc wscale(Window *w, int n)
40 a8a0a642 2012-11-26 rsc {
41 a8a0a642 2012-11-26 rsc if(w == nil || w->i == nil)
42 a8a0a642 2012-11-26 rsc return n;
43 a8a0a642 2012-11-26 rsc return scalesize(w->i->display, n);
44 a8a0a642 2012-11-26 rsc }
45 a8a0a642 2012-11-26 rsc
46 e830a908 2005-11-06 devnull Window*
47 210d461c 2011-10-12 rsc wmk(Image *i, Mousectl *mc, Channel *ck, Channel *cctl, int scrolling)
48 e830a908 2005-11-06 devnull {
49 e830a908 2005-11-06 devnull Window *w;
50 e830a908 2005-11-06 devnull Rectangle r;
51 e830a908 2005-11-06 devnull
52 e830a908 2005-11-06 devnull if(cols[0] == nil){
53 e830a908 2005-11-06 devnull /* greys are multiples of 0x11111100+0xFF, 14* being palest */
54 e830a908 2005-11-06 devnull grey = allocimage(display, Rect(0,0,1,1), CMAP8, 1, 0xEEEEEEFF);
55 e830a908 2005-11-06 devnull darkgrey = allocimage(display, Rect(0,0,1,1), CMAP8, 1, 0x666666FF);
56 e830a908 2005-11-06 devnull cols[BACK] = display->white;
57 e830a908 2005-11-06 devnull cols[HIGH] = allocimage(display, Rect(0,0,1,1), CMAP8, 1, 0xCCCCCCFF);
58 e830a908 2005-11-06 devnull cols[BORD] = allocimage(display, Rect(0,0,1,1), CMAP8, 1, 0x999999FF);
59 e830a908 2005-11-06 devnull cols[TEXT] = display->black;
60 e830a908 2005-11-06 devnull cols[HTEXT] = display->black;
61 e830a908 2005-11-06 devnull titlecol = allocimage(display, Rect(0,0,1,1), CMAP8, 1, DGreygreen);
62 e830a908 2005-11-06 devnull lighttitlecol = allocimage(display, Rect(0,0,1,1), CMAP8, 1, DPalegreygreen);
63 e830a908 2005-11-06 devnull holdcol = allocimage(display, Rect(0,0,1,1), CMAP8, 1, DMedblue);
64 e830a908 2005-11-06 devnull lightholdcol = allocimage(display, Rect(0,0,1,1), CMAP8, 1, DGreyblue);
65 e830a908 2005-11-06 devnull paleholdcol = allocimage(display, Rect(0,0,1,1), CMAP8, 1, DPalegreyblue);
66 e830a908 2005-11-06 devnull }
67 e830a908 2005-11-06 devnull w = emalloc(sizeof(Window));
68 e830a908 2005-11-06 devnull w->screenr = i->r;
69 a8a0a642 2012-11-26 rsc r = insetrect(i->r, wscale(w, Selborder)+wscale(w, 1));
70 e830a908 2005-11-06 devnull w->i = i;
71 e830a908 2005-11-06 devnull w->mc = *mc;
72 e830a908 2005-11-06 devnull w->ck = ck;
73 e830a908 2005-11-06 devnull w->cctl = cctl;
74 e830a908 2005-11-06 devnull w->cursorp = nil;
75 e830a908 2005-11-06 devnull w->conswrite = chancreate(sizeof(Conswritemesg), 0);
76 e830a908 2005-11-06 devnull w->consread = chancreate(sizeof(Consreadmesg), 0);
77 e830a908 2005-11-06 devnull w->mouseread = chancreate(sizeof(Mousereadmesg), 0);
78 e830a908 2005-11-06 devnull w->wctlread = chancreate(sizeof(Consreadmesg), 0);
79 e830a908 2005-11-06 devnull w->scrollr = r;
80 a8a0a642 2012-11-26 rsc w->scrollr.max.x = r.min.x+wscale(w, Scrollwid);
81 e830a908 2005-11-06 devnull w->lastsr = ZR;
82 a8a0a642 2012-11-26 rsc r.min.x += wscale(w, Scrollwid)+wscale(w, Scrollgap);
83 e830a908 2005-11-06 devnull frinit(&w->f, r, font, i, cols);
84 e830a908 2005-11-06 devnull w->f.maxtab = maxtab*stringwidth(font, "0");
85 e830a908 2005-11-06 devnull w->topped = ++topped;
86 e830a908 2005-11-06 devnull w->id = ++id;
87 e830a908 2005-11-06 devnull w->notefd = -1;
88 210d461c 2011-10-12 rsc w->scrolling = scrolling;
89 e830a908 2005-11-06 devnull w->dir = estrdup(startdir);
90 e830a908 2005-11-06 devnull w->label = estrdup("<unnamed>");
91 a8a0a642 2012-11-26 rsc r = insetrect(w->i->r, wscale(w, Selborder));
92 e830a908 2005-11-06 devnull draw(w->i, r, cols[BACK], nil, w->f.entire.min);
93 a8a0a642 2012-11-26 rsc wborder(w, wscale(w, Selborder));
94 e830a908 2005-11-06 devnull wscrdraw(w);
95 e830a908 2005-11-06 devnull incref(&w->ref); /* ref will be removed after mounting; avoids delete before ready to be deleted */
96 e830a908 2005-11-06 devnull return w;
97 e830a908 2005-11-06 devnull }
98 e830a908 2005-11-06 devnull
99 e830a908 2005-11-06 devnull void
100 e830a908 2005-11-06 devnull wsetname(Window *w)
101 e830a908 2005-11-06 devnull {
102 e830a908 2005-11-06 devnull int i, n;
103 e830a908 2005-11-06 devnull char err[ERRMAX];
104 fa325e9b 2020-01-10 cross
105 e830a908 2005-11-06 devnull n = sprint(w->name, "window.%d.%d", w->id, w->namecount++);
106 e830a908 2005-11-06 devnull for(i='A'; i<='Z'; i++){
107 e830a908 2005-11-06 devnull if(nameimage(w->i, w->name, 1) > 0)
108 e830a908 2005-11-06 devnull return;
109 e830a908 2005-11-06 devnull errstr(err, sizeof err);
110 e830a908 2005-11-06 devnull if(strcmp(err, "image name in use") != 0)
111 e830a908 2005-11-06 devnull break;
112 e830a908 2005-11-06 devnull w->name[n] = i;
113 e830a908 2005-11-06 devnull w->name[n+1] = 0;
114 e830a908 2005-11-06 devnull }
115 e830a908 2005-11-06 devnull w->name[0] = 0;
116 e830a908 2005-11-06 devnull fprint(2, "rio: setname failed: %s\n", err);
117 e830a908 2005-11-06 devnull }
118 e830a908 2005-11-06 devnull
119 e830a908 2005-11-06 devnull void
120 e830a908 2005-11-06 devnull wresize(Window *w, Image *i, int move)
121 e830a908 2005-11-06 devnull {
122 e830a908 2005-11-06 devnull Rectangle r, or;
123 e830a908 2005-11-06 devnull
124 e830a908 2005-11-06 devnull or = w->i->r;
125 e830a908 2005-11-06 devnull if(move || (Dx(or)==Dx(i->r) && Dy(or)==Dy(i->r)))
126 e830a908 2005-11-06 devnull draw(i, i->r, w->i, nil, w->i->r.min);
127 e830a908 2005-11-06 devnull if(w->i != i){
128 e830a908 2005-11-06 devnull fprint(2, "res %p %p\n", w->i, i);
129 e830a908 2005-11-06 devnull freeimage(w->i);
130 e830a908 2005-11-06 devnull w->i = i;
131 e830a908 2005-11-06 devnull }
132 cbeb0b26 2006-04-01 devnull /* wsetname(w); */
133 cbeb0b26 2006-04-01 devnull /*XXX w->mc.image = i; */
134 a8a0a642 2012-11-26 rsc r = insetrect(i->r, wscale(w, Selborder)+wscale(w, 1));
135 a8a0a642 2012-11-26 rsc w->scrollr = r;
136 a8a0a642 2012-11-26 rsc w->scrollr.max.x = r.min.x+wscale(w, Scrollwid);
137 e830a908 2005-11-06 devnull w->lastsr = ZR;
138 a8a0a642 2012-11-26 rsc r.min.x += wscale(w, Scrollwid)+wscale(w, Scrollgap);
139 e830a908 2005-11-06 devnull if(move)
140 e830a908 2005-11-06 devnull frsetrects(&w->f, r, w->i);
141 e830a908 2005-11-06 devnull else{
142 e830a908 2005-11-06 devnull frclear(&w->f, FALSE);
143 e830a908 2005-11-06 devnull frinit(&w->f, r, w->f.font, w->i, cols);
144 e830a908 2005-11-06 devnull wsetcols(w);
145 e830a908 2005-11-06 devnull w->f.maxtab = maxtab*stringwidth(w->f.font, "0");
146 a8a0a642 2012-11-26 rsc r = insetrect(w->i->r, wscale(w, Selborder));
147 e830a908 2005-11-06 devnull draw(w->i, r, cols[BACK], nil, w->f.entire.min);
148 e830a908 2005-11-06 devnull wfill(w);
149 e830a908 2005-11-06 devnull wsetselect(w, w->q0, w->q1);
150 e830a908 2005-11-06 devnull wscrdraw(w);
151 e830a908 2005-11-06 devnull }
152 a8a0a642 2012-11-26 rsc wborder(w, wscale(w, Selborder));
153 e830a908 2005-11-06 devnull w->topped = ++topped;
154 e830a908 2005-11-06 devnull w->resized = TRUE;
155 e830a908 2005-11-06 devnull w->mouse.counter++;
156 e830a908 2005-11-06 devnull }
157 e830a908 2005-11-06 devnull
158 e830a908 2005-11-06 devnull void
159 e830a908 2005-11-06 devnull wrefresh(Window *w, Rectangle r)
160 e830a908 2005-11-06 devnull {
161 e830a908 2005-11-06 devnull /* USED(r); */
162 e830a908 2005-11-06 devnull
163 e830a908 2005-11-06 devnull /* BUG: rectangle is ignored */
164 e830a908 2005-11-06 devnull if(w == input)
165 a8a0a642 2012-11-26 rsc wborder(w, wscale(w, Selborder));
166 e830a908 2005-11-06 devnull else
167 a8a0a642 2012-11-26 rsc wborder(w, wscale(w, Unselborder));
168 e830a908 2005-11-06 devnull if(w->mouseopen)
169 e830a908 2005-11-06 devnull return;
170 e830a908 2005-11-06 devnull draw(w->i, insetrect(w->i->r, Borderwidth), w->f.cols[BACK], nil, w->i->r.min);
171 e830a908 2005-11-06 devnull w->f.ticked = 0;
172 e830a908 2005-11-06 devnull if(w->f.p0 > 0)
173 e830a908 2005-11-06 devnull frdrawsel(&w->f, frptofchar(&w->f, 0), 0, w->f.p0, 0);
174 e830a908 2005-11-06 devnull if(w->f.p1 < w->f.nchars)
175 e830a908 2005-11-06 devnull frdrawsel(&w->f, frptofchar(&w->f, w->f.p1), w->f.p1, w->f.nchars, 0);
176 e830a908 2005-11-06 devnull frdrawsel(&w->f, frptofchar(&w->f, w->f.p0), w->f.p0, w->f.p1, 1);
177 e830a908 2005-11-06 devnull w->lastsr = ZR;
178 e830a908 2005-11-06 devnull wscrdraw(w);
179 e830a908 2005-11-06 devnull }
180 e830a908 2005-11-06 devnull
181 e830a908 2005-11-06 devnull int
182 e830a908 2005-11-06 devnull wclose(Window *w)
183 e830a908 2005-11-06 devnull {
184 e830a908 2005-11-06 devnull int i;
185 e830a908 2005-11-06 devnull
186 e830a908 2005-11-06 devnull i = decref(&w->ref);
187 e830a908 2005-11-06 devnull if(i > 0)
188 e830a908 2005-11-06 devnull return 0;
189 e830a908 2005-11-06 devnull if(i < 0)
190 e830a908 2005-11-06 devnull error("negative ref count");
191 e830a908 2005-11-06 devnull if(!w->deleted)
192 e830a908 2005-11-06 devnull wclosewin(w);
193 e830a908 2005-11-06 devnull wsendctlmesg(w, Exited, ZR, nil);
194 e830a908 2005-11-06 devnull return 1;
195 e830a908 2005-11-06 devnull }
196 e830a908 2005-11-06 devnull
197 e830a908 2005-11-06 devnull
198 e830a908 2005-11-06 devnull void
199 e830a908 2005-11-06 devnull winctl(void *arg)
200 e830a908 2005-11-06 devnull {
201 f535642f 2005-11-10 devnull Rune *rp, *bp, *up, *kbdr;
202 e830a908 2005-11-06 devnull uint qh;
203 ba31ab30 2011-04-27 rsc int nr, nb, c, wid, i, npart, initial, lastb, scrolling;
204 0cadb430 2009-09-11 russcox char *s, *t, part[UTFmax];
205 e830a908 2005-11-06 devnull Window *w;
206 e830a908 2005-11-06 devnull Mousestate *mp, m;
207 e830a908 2005-11-06 devnull enum { WKey, WMouse, WMouseread, WCtl, WCwrite, WCread, WWread, NWALT };
208 e830a908 2005-11-06 devnull Alt alts[NWALT+1];
209 e830a908 2005-11-06 devnull Mousereadmesg mrm;
210 e830a908 2005-11-06 devnull Conswritemesg cwm;
211 e830a908 2005-11-06 devnull Consreadmesg crm;
212 e830a908 2005-11-06 devnull Consreadmesg cwrm;
213 e830a908 2005-11-06 devnull Stringpair pair;
214 e830a908 2005-11-06 devnull Wctlmesg wcm;
215 e830a908 2005-11-06 devnull char buf[4*12+1];
216 e830a908 2005-11-06 devnull
217 e830a908 2005-11-06 devnull w = arg;
218 e830a908 2005-11-06 devnull snprint(buf, sizeof buf, "winctl-id%d", w->id);
219 e830a908 2005-11-06 devnull threadsetname(buf);
220 e830a908 2005-11-06 devnull
221 e830a908 2005-11-06 devnull mrm.cm = chancreate(sizeof(Mouse), 0);
222 e830a908 2005-11-06 devnull cwm.cw = chancreate(sizeof(Stringpair), 0);
223 e830a908 2005-11-06 devnull crm.c1 = chancreate(sizeof(Stringpair), 0);
224 e830a908 2005-11-06 devnull crm.c2 = chancreate(sizeof(Stringpair), 0);
225 e830a908 2005-11-06 devnull cwrm.c1 = chancreate(sizeof(Stringpair), 0);
226 e830a908 2005-11-06 devnull cwrm.c2 = chancreate(sizeof(Stringpair), 0);
227 e830a908 2005-11-06 devnull
228 fa325e9b 2020-01-10 cross
229 e830a908 2005-11-06 devnull alts[WKey].c = w->ck;
230 e830a908 2005-11-06 devnull alts[WKey].v = &kbdr;
231 e830a908 2005-11-06 devnull alts[WKey].op = CHANRCV;
232 e830a908 2005-11-06 devnull alts[WMouse].c = w->mc.c;
233 e830a908 2005-11-06 devnull alts[WMouse].v = &w->mc.m;
234 e830a908 2005-11-06 devnull alts[WMouse].op = CHANRCV;
235 e830a908 2005-11-06 devnull alts[WMouseread].c = w->mouseread;
236 e830a908 2005-11-06 devnull alts[WMouseread].v = &mrm;
237 e830a908 2005-11-06 devnull alts[WMouseread].op = CHANSND;
238 e830a908 2005-11-06 devnull alts[WCtl].c = w->cctl;
239 e830a908 2005-11-06 devnull alts[WCtl].v = &wcm;
240 e830a908 2005-11-06 devnull alts[WCtl].op = CHANRCV;
241 e830a908 2005-11-06 devnull alts[WCwrite].c = w->conswrite;
242 e830a908 2005-11-06 devnull alts[WCwrite].v = &cwm;
243 e830a908 2005-11-06 devnull alts[WCwrite].op = CHANSND;
244 e830a908 2005-11-06 devnull alts[WCread].c = w->consread;
245 e830a908 2005-11-06 devnull alts[WCread].v = &crm;
246 e830a908 2005-11-06 devnull alts[WCread].op = CHANSND;
247 e830a908 2005-11-06 devnull alts[WWread].c = w->wctlread;
248 e830a908 2005-11-06 devnull alts[WWread].v = &cwrm;
249 e830a908 2005-11-06 devnull alts[WWread].op = CHANSND;
250 e830a908 2005-11-06 devnull alts[NWALT].op = CHANEND;
251 e830a908 2005-11-06 devnull
252 e830a908 2005-11-06 devnull npart = 0;
253 e830a908 2005-11-06 devnull lastb = -1;
254 e830a908 2005-11-06 devnull for(;;){
255 e830a908 2005-11-06 devnull if(w->mouseopen && w->mouse.counter != w->mouse.lastcounter)
256 e830a908 2005-11-06 devnull alts[WMouseread].op = CHANSND;
257 e830a908 2005-11-06 devnull else
258 e830a908 2005-11-06 devnull alts[WMouseread].op = CHANNOP;
259 210d461c 2011-10-12 rsc // if(!w->scrolling && !w->mouseopen && w->qh>w->org+w->f.nchars)
260 210d461c 2011-10-12 rsc // alts[WCwrite].op = CHANNOP;
261 210d461c 2011-10-12 rsc // else
262 ba31ab30 2011-04-27 rsc alts[WCwrite].op = CHANSND;
263 e830a908 2005-11-06 devnull if(w->deleted || !w->wctlready)
264 e830a908 2005-11-06 devnull alts[WWread].op = CHANNOP;
265 e830a908 2005-11-06 devnull else
266 e830a908 2005-11-06 devnull alts[WWread].op = CHANSND;
267 e830a908 2005-11-06 devnull /* this code depends on NL and EOT fitting in a single byte */
268 e830a908 2005-11-06 devnull /* kind of expensive for each loop; worth precomputing? */
269 e830a908 2005-11-06 devnull if(w->holding)
270 e830a908 2005-11-06 devnull alts[WCread].op = CHANNOP;
271 e830a908 2005-11-06 devnull else if(npart || (w->rawing && w->nraw>0))
272 e830a908 2005-11-06 devnull alts[WCread].op = CHANSND;
273 e830a908 2005-11-06 devnull else{
274 e830a908 2005-11-06 devnull alts[WCread].op = CHANNOP;
275 e830a908 2005-11-06 devnull for(i=w->qh; i<w->nr; i++){
276 e830a908 2005-11-06 devnull c = w->r[i];
277 e830a908 2005-11-06 devnull if(c=='\n' || c=='\004'){
278 e830a908 2005-11-06 devnull alts[WCread].op = CHANSND;
279 e830a908 2005-11-06 devnull break;
280 e830a908 2005-11-06 devnull }
281 e830a908 2005-11-06 devnull }
282 e830a908 2005-11-06 devnull }
283 e830a908 2005-11-06 devnull switch(alt(alts)){
284 e830a908 2005-11-06 devnull case WKey:
285 e830a908 2005-11-06 devnull for(i=0; kbdr[i]!=L'\0'; i++)
286 e830a908 2005-11-06 devnull wkeyctl(w, kbdr[i]);
287 cbeb0b26 2006-04-01 devnull /* wkeyctl(w, r); */
288 cbeb0b26 2006-04-01 devnull /* while(nbrecv(w->ck, &r)) */
289 cbeb0b26 2006-04-01 devnull /* wkeyctl(w, r); */
290 e830a908 2005-11-06 devnull break;
291 e830a908 2005-11-06 devnull case WMouse:
292 e830a908 2005-11-06 devnull if(w->mouseopen) {
293 e830a908 2005-11-06 devnull w->mouse.counter++;
294 e830a908 2005-11-06 devnull
295 e830a908 2005-11-06 devnull /* queue click events */
296 e830a908 2005-11-06 devnull if(!w->mouse.qfull && lastb != w->mc.m.buttons) { /* add to ring */
297 e830a908 2005-11-06 devnull mp = &w->mouse.queue[w->mouse.wi];
298 e830a908 2005-11-06 devnull if(++w->mouse.wi == nelem(w->mouse.queue))
299 e830a908 2005-11-06 devnull w->mouse.wi = 0;
300 e830a908 2005-11-06 devnull if(w->mouse.wi == w->mouse.ri)
301 e830a908 2005-11-06 devnull w->mouse.qfull = TRUE;
302 e830a908 2005-11-06 devnull mp->m = w->mc.m;
303 e830a908 2005-11-06 devnull mp->counter = w->mouse.counter;
304 e830a908 2005-11-06 devnull lastb = w->mc.m.buttons;
305 e830a908 2005-11-06 devnull }
306 e830a908 2005-11-06 devnull } else
307 e830a908 2005-11-06 devnull wmousectl(w);
308 e830a908 2005-11-06 devnull break;
309 e830a908 2005-11-06 devnull case WMouseread:
310 e830a908 2005-11-06 devnull /* send a queued event or, if the queue is empty, the current state */
311 e830a908 2005-11-06 devnull /* if the queue has filled, we discard all the events it contained. */
312 e830a908 2005-11-06 devnull /* the intent is to discard frantic clicking by the user during long latencies. */
313 e830a908 2005-11-06 devnull w->mouse.qfull = FALSE;
314 e830a908 2005-11-06 devnull if(w->mouse.wi != w->mouse.ri) {
315 e830a908 2005-11-06 devnull m = w->mouse.queue[w->mouse.ri];
316 e830a908 2005-11-06 devnull if(++w->mouse.ri == nelem(w->mouse.queue))
317 e830a908 2005-11-06 devnull w->mouse.ri = 0;
318 cbeb0b26 2006-04-01 devnull } else {
319 cbeb0b26 2006-04-01 devnull m.m = w->mc.m;
320 cbeb0b26 2006-04-01 devnull m.counter = w->mouse.counter;
321 cbeb0b26 2006-04-01 devnull }
322 e830a908 2005-11-06 devnull w->mouse.lastcounter = m.counter;
323 e830a908 2005-11-06 devnull send(mrm.cm, &m.m);
324 e830a908 2005-11-06 devnull continue;
325 e830a908 2005-11-06 devnull case WCtl:
326 e830a908 2005-11-06 devnull if(wctlmesg(w, wcm.type, wcm.r, wcm.image) == Exited){
327 e830a908 2005-11-06 devnull chanfree(crm.c1);
328 e830a908 2005-11-06 devnull chanfree(crm.c2);
329 e830a908 2005-11-06 devnull chanfree(mrm.cm);
330 e830a908 2005-11-06 devnull chanfree(cwm.cw);
331 e830a908 2005-11-06 devnull chanfree(cwrm.c1);
332 e830a908 2005-11-06 devnull chanfree(cwrm.c2);
333 e830a908 2005-11-06 devnull threadexits(nil);
334 e830a908 2005-11-06 devnull }
335 e830a908 2005-11-06 devnull continue;
336 e830a908 2005-11-06 devnull case WCwrite:
337 e830a908 2005-11-06 devnull recv(cwm.cw, &pair);
338 e830a908 2005-11-06 devnull rp = pair.s;
339 e830a908 2005-11-06 devnull nr = pair.ns;
340 c21d0ab4 2005-11-11 devnull bp = rp;
341 c21d0ab4 2005-11-11 devnull up = rp;
342 f535642f 2005-11-10 devnull initial = 0;
343 f535642f 2005-11-10 devnull for(i=0; i<nr; i++){
344 f535642f 2005-11-10 devnull switch(*bp){
345 f535642f 2005-11-10 devnull case 0:
346 f535642f 2005-11-10 devnull break;
347 f535642f 2005-11-10 devnull case '\b':
348 f535642f 2005-11-10 devnull if(up == rp)
349 f535642f 2005-11-10 devnull initial++;
350 f535642f 2005-11-10 devnull else
351 f535642f 2005-11-10 devnull --up;
352 f535642f 2005-11-10 devnull break;
353 f535642f 2005-11-10 devnull case '\r':
354 f535642f 2005-11-10 devnull while(i<nr-1 && *(bp+1) == '\r'){
355 f535642f 2005-11-10 devnull bp++;
356 f535642f 2005-11-10 devnull i++;
357 e830a908 2005-11-06 devnull }
358 f535642f 2005-11-10 devnull if(i<nr-1 && *(bp+1) != '\n'){
359 f535642f 2005-11-10 devnull while(up > rp && *(up-1) != '\n')
360 f535642f 2005-11-10 devnull up--;
361 f535642f 2005-11-10 devnull if(up == rp)
362 540eaf98 2005-11-26 devnull initial = wbswidth(w, '\r');
363 f535642f 2005-11-10 devnull }else if(i == nr-1)
364 0d2dfbc8 2015-11-10 rsc *up++ = '\n';
365 e830a908 2005-11-06 devnull break;
366 f535642f 2005-11-10 devnull default:
367 f535642f 2005-11-10 devnull *up++ = *bp;
368 f535642f 2005-11-10 devnull break;
369 e830a908 2005-11-06 devnull }
370 f535642f 2005-11-10 devnull bp++;
371 f535642f 2005-11-10 devnull }
372 f535642f 2005-11-10 devnull if(initial){
373 f535642f 2005-11-10 devnull if(initial > w->qh)
374 f535642f 2005-11-10 devnull initial = w->qh;
375 f535642f 2005-11-10 devnull qh = w->qh - initial;
376 f535642f 2005-11-10 devnull wdelete(w, qh, qh+initial);
377 f535642f 2005-11-10 devnull w->qh = qh;
378 f535642f 2005-11-10 devnull }
379 c21d0ab4 2005-11-11 devnull nr = up - rp;
380 210d461c 2011-10-12 rsc scrolling = w->scrolling && w->org <= w->qh && w->qh <= w->org + w->f.nchars;
381 e830a908 2005-11-06 devnull w->qh = winsert(w, rp, nr, w->qh)+nr;
382 ba31ab30 2011-04-27 rsc if(scrolling)
383 e830a908 2005-11-06 devnull wshow(w, w->qh);
384 e830a908 2005-11-06 devnull wsetselect(w, w->q0, w->q1);
385 e830a908 2005-11-06 devnull wscrdraw(w);
386 e830a908 2005-11-06 devnull free(rp);
387 e830a908 2005-11-06 devnull break;
388 e830a908 2005-11-06 devnull case WCread:
389 e830a908 2005-11-06 devnull recv(crm.c1, &pair);
390 e830a908 2005-11-06 devnull t = pair.s;
391 e830a908 2005-11-06 devnull nb = pair.ns;
392 e830a908 2005-11-06 devnull i = npart;
393 e830a908 2005-11-06 devnull npart = 0;
394 e830a908 2005-11-06 devnull if(i)
395 e830a908 2005-11-06 devnull memmove(t, part, i);
396 e830a908 2005-11-06 devnull while(i<nb && (w->qh<w->nr || w->nraw>0)){
397 e830a908 2005-11-06 devnull if(w->qh == w->nr){
398 e830a908 2005-11-06 devnull wid = runetochar(t+i, &w->raw[0]);
399 e830a908 2005-11-06 devnull w->nraw--;
400 e830a908 2005-11-06 devnull runemove(w->raw, w->raw+1, w->nraw);
401 e830a908 2005-11-06 devnull }else
402 e830a908 2005-11-06 devnull wid = runetochar(t+i, &w->r[w->qh++]);
403 e830a908 2005-11-06 devnull c = t[i]; /* knows break characters fit in a byte */
404 e830a908 2005-11-06 devnull i += wid;
405 e830a908 2005-11-06 devnull if(!w->rawing && (c == '\n' || c=='\004')){
406 cbeb0b26 2006-04-01 devnull /* if(c == '\004') */
407 cbeb0b26 2006-04-01 devnull /* i--; */
408 e830a908 2005-11-06 devnull break;
409 e830a908 2005-11-06 devnull }
410 e830a908 2005-11-06 devnull }
411 cbeb0b26 2006-04-01 devnull /* if(i==nb && w->qh<w->nr && w->r[w->qh]=='\004') */
412 cbeb0b26 2006-04-01 devnull /* w->qh++; */
413 e830a908 2005-11-06 devnull if(i > nb){
414 e830a908 2005-11-06 devnull npart = i-nb;
415 e830a908 2005-11-06 devnull memmove(part, t+nb, npart);
416 e830a908 2005-11-06 devnull i = nb;
417 e830a908 2005-11-06 devnull }
418 e830a908 2005-11-06 devnull pair.s = t;
419 e830a908 2005-11-06 devnull pair.ns = i;
420 e830a908 2005-11-06 devnull send(crm.c2, &pair);
421 e830a908 2005-11-06 devnull continue;
422 e830a908 2005-11-06 devnull case WWread:
423 e830a908 2005-11-06 devnull w->wctlready = 0;
424 e830a908 2005-11-06 devnull recv(cwrm.c1, &pair);
425 e830a908 2005-11-06 devnull if(w->deleted || w->i==nil)
426 e830a908 2005-11-06 devnull pair.ns = sprint(pair.s, "");
427 e830a908 2005-11-06 devnull else{
428 e830a908 2005-11-06 devnull s = "visible";
429 e830a908 2005-11-06 devnull for(i=0; i<nhidden; i++)
430 e830a908 2005-11-06 devnull if(hidden[i] == w){
431 e830a908 2005-11-06 devnull s = "hidden";
432 e830a908 2005-11-06 devnull break;
433 e830a908 2005-11-06 devnull }
434 e830a908 2005-11-06 devnull t = "notcurrent";
435 e830a908 2005-11-06 devnull if(w == input)
436 e830a908 2005-11-06 devnull t = "current";
437 e830a908 2005-11-06 devnull pair.ns = snprint(pair.s, pair.ns, "%11d %11d %11d %11d %s %s ",
438 e830a908 2005-11-06 devnull w->i->r.min.x, w->i->r.min.y, w->i->r.max.x, w->i->r.max.y, t, s);
439 e830a908 2005-11-06 devnull }
440 e830a908 2005-11-06 devnull send(cwrm.c2, &pair);
441 e830a908 2005-11-06 devnull continue;
442 e830a908 2005-11-06 devnull }
443 e830a908 2005-11-06 devnull if(!w->deleted)
444 e830a908 2005-11-06 devnull flushimage(display, 1);
445 e830a908 2005-11-06 devnull }
446 e830a908 2005-11-06 devnull }
447 e830a908 2005-11-06 devnull
448 e830a908 2005-11-06 devnull void
449 e830a908 2005-11-06 devnull waddraw(Window *w, Rune *r, int nr)
450 e830a908 2005-11-06 devnull {
451 e830a908 2005-11-06 devnull w->raw = runerealloc(w->raw, w->nraw+nr);
452 e830a908 2005-11-06 devnull runemove(w->raw+w->nraw, r, nr);
453 e830a908 2005-11-06 devnull w->nraw += nr;
454 e830a908 2005-11-06 devnull }
455 e830a908 2005-11-06 devnull
456 e830a908 2005-11-06 devnull /*
457 e830a908 2005-11-06 devnull * Need to do this in a separate proc because if process we're interrupting
458 e830a908 2005-11-06 devnull * is dying and trying to print tombstone, kernel is blocked holding p->debug lock.
459 e830a908 2005-11-06 devnull */
460 e830a908 2005-11-06 devnull void
461 e830a908 2005-11-06 devnull interruptproc(void *v)
462 e830a908 2005-11-06 devnull {
463 e830a908 2005-11-06 devnull int *notefd;
464 e830a908 2005-11-06 devnull
465 e830a908 2005-11-06 devnull notefd = v;
466 e830a908 2005-11-06 devnull write(*notefd, "interrupt", 9);
467 e830a908 2005-11-06 devnull free(notefd);
468 e830a908 2005-11-06 devnull }
469 e830a908 2005-11-06 devnull
470 e830a908 2005-11-06 devnull int
471 e830a908 2005-11-06 devnull windfilewidth(Window *w, uint q0, int oneelement)
472 e830a908 2005-11-06 devnull {
473 e830a908 2005-11-06 devnull uint q;
474 e830a908 2005-11-06 devnull Rune r;
475 e830a908 2005-11-06 devnull
476 e830a908 2005-11-06 devnull q = q0;
477 e830a908 2005-11-06 devnull while(q > 0){
478 e830a908 2005-11-06 devnull r = w->r[q-1];
479 e830a908 2005-11-06 devnull if(r<=' ')
480 e830a908 2005-11-06 devnull break;
481 e830a908 2005-11-06 devnull if(oneelement && r=='/')
482 e830a908 2005-11-06 devnull break;
483 e830a908 2005-11-06 devnull --q;
484 e830a908 2005-11-06 devnull }
485 e830a908 2005-11-06 devnull return q0-q;
486 e830a908 2005-11-06 devnull }
487 e830a908 2005-11-06 devnull
488 e830a908 2005-11-06 devnull void
489 e830a908 2005-11-06 devnull showcandidates(Window *w, Completion *c)
490 e830a908 2005-11-06 devnull {
491 e830a908 2005-11-06 devnull int i;
492 e830a908 2005-11-06 devnull Fmt f;
493 e830a908 2005-11-06 devnull Rune *rp;
494 e830a908 2005-11-06 devnull uint nr, qline, q0;
495 e830a908 2005-11-06 devnull char *s;
496 e830a908 2005-11-06 devnull
497 e830a908 2005-11-06 devnull runefmtstrinit(&f);
498 e830a908 2005-11-06 devnull if (c->nmatch == 0)
499 e830a908 2005-11-06 devnull s = "[no matches in ";
500 e830a908 2005-11-06 devnull else
501 e830a908 2005-11-06 devnull s = "[";
502 e830a908 2005-11-06 devnull if(c->nfile > 32)
503 e830a908 2005-11-06 devnull fmtprint(&f, "%s%d files]\n", s, c->nfile);
504 e830a908 2005-11-06 devnull else{
505 e830a908 2005-11-06 devnull fmtprint(&f, "%s", s);
506 e830a908 2005-11-06 devnull for(i=0; i<c->nfile; i++){
507 e830a908 2005-11-06 devnull if(i > 0)
508 e830a908 2005-11-06 devnull fmtprint(&f, " ");
509 e830a908 2005-11-06 devnull fmtprint(&f, "%s", c->filename[i]);
510 e830a908 2005-11-06 devnull }
511 e830a908 2005-11-06 devnull fmtprint(&f, "]\n");
512 e830a908 2005-11-06 devnull }
513 e830a908 2005-11-06 devnull /* place text at beginning of line before host point */
514 e830a908 2005-11-06 devnull qline = w->qh;
515 e830a908 2005-11-06 devnull while(qline>0 && w->r[qline-1] != '\n')
516 e830a908 2005-11-06 devnull qline--;
517 e830a908 2005-11-06 devnull
518 e830a908 2005-11-06 devnull rp = runefmtstrflush(&f);
519 e830a908 2005-11-06 devnull nr = runestrlen(rp);
520 e830a908 2005-11-06 devnull
521 e830a908 2005-11-06 devnull q0 = w->q0;
522 e830a908 2005-11-06 devnull q0 += winsert(w, rp, runestrlen(rp), qline) - qline;
523 e830a908 2005-11-06 devnull free(rp);
524 e830a908 2005-11-06 devnull wsetselect(w, q0+nr, q0+nr);
525 e830a908 2005-11-06 devnull }
526 e830a908 2005-11-06 devnull
527 e830a908 2005-11-06 devnull Rune*
528 e830a908 2005-11-06 devnull namecomplete(Window *w)
529 e830a908 2005-11-06 devnull {
530 e830a908 2005-11-06 devnull int nstr, npath;
531 e830a908 2005-11-06 devnull Rune *rp, *path, *str;
532 e830a908 2005-11-06 devnull Completion *c;
533 e830a908 2005-11-06 devnull char *s, *dir, *root;
534 e830a908 2005-11-06 devnull
535 e830a908 2005-11-06 devnull /* control-f: filename completion; works back to white space or / */
536 e830a908 2005-11-06 devnull if(w->q0<w->nr && w->r[w->q0]>' ') /* must be at end of word */
537 e830a908 2005-11-06 devnull return nil;
538 e830a908 2005-11-06 devnull nstr = windfilewidth(w, w->q0, TRUE);
539 e830a908 2005-11-06 devnull str = runemalloc(nstr);
540 e830a908 2005-11-06 devnull runemove(str, w->r+(w->q0-nstr), nstr);
541 e830a908 2005-11-06 devnull npath = windfilewidth(w, w->q0-nstr, FALSE);
542 e830a908 2005-11-06 devnull path = runemalloc(npath);
543 e830a908 2005-11-06 devnull runemove(path, w->r+(w->q0-nstr-npath), npath);
544 e830a908 2005-11-06 devnull rp = nil;
545 e830a908 2005-11-06 devnull
546 e830a908 2005-11-06 devnull /* is path rooted? if not, we need to make it relative to window path */
547 e830a908 2005-11-06 devnull if(npath>0 && path[0]=='/'){
548 e830a908 2005-11-06 devnull dir = malloc(UTFmax*npath+1);
549 e830a908 2005-11-06 devnull sprint(dir, "%.*S", npath, path);
550 e830a908 2005-11-06 devnull }else{
551 e830a908 2005-11-06 devnull if(strcmp(w->dir, "") == 0)
552 e830a908 2005-11-06 devnull root = ".";
553 e830a908 2005-11-06 devnull else
554 e830a908 2005-11-06 devnull root = w->dir;
555 e830a908 2005-11-06 devnull dir = malloc(strlen(root)+1+UTFmax*npath+1);
556 e830a908 2005-11-06 devnull sprint(dir, "%s/%.*S", root, npath, path);
557 e830a908 2005-11-06 devnull }
558 e830a908 2005-11-06 devnull dir = cleanname(dir);
559 e830a908 2005-11-06 devnull
560 e830a908 2005-11-06 devnull s = smprint("%.*S", nstr, str);
561 e830a908 2005-11-06 devnull c = complete(dir, s);
562 e830a908 2005-11-06 devnull free(s);
563 e830a908 2005-11-06 devnull if(c == nil)
564 e830a908 2005-11-06 devnull goto Return;
565 e830a908 2005-11-06 devnull
566 e830a908 2005-11-06 devnull if(!c->advance)
567 e830a908 2005-11-06 devnull showcandidates(w, c);
568 e830a908 2005-11-06 devnull
569 e830a908 2005-11-06 devnull if(c->advance)
570 e830a908 2005-11-06 devnull rp = runesmprint("%s", c->string);
571 e830a908 2005-11-06 devnull
572 e830a908 2005-11-06 devnull Return:
573 e830a908 2005-11-06 devnull freecompletion(c);
574 e830a908 2005-11-06 devnull free(dir);
575 e830a908 2005-11-06 devnull free(path);
576 e830a908 2005-11-06 devnull free(str);
577 e830a908 2005-11-06 devnull return rp;
578 e830a908 2005-11-06 devnull }
579 e830a908 2005-11-06 devnull
580 e830a908 2005-11-06 devnull void
581 e830a908 2005-11-06 devnull wkeyctl(Window *w, Rune r)
582 e830a908 2005-11-06 devnull {
583 e830a908 2005-11-06 devnull uint q0 ,q1;
584 e830a908 2005-11-06 devnull int n, nb, nr;
585 e830a908 2005-11-06 devnull Rune *rp;
586 e830a908 2005-11-06 devnull
587 e830a908 2005-11-06 devnull if(r == 0)
588 e830a908 2005-11-06 devnull return;
589 e830a908 2005-11-06 devnull if(w->deleted)
590 e830a908 2005-11-06 devnull return;
591 e830a908 2005-11-06 devnull w->rawing = rawon();
592 e830a908 2005-11-06 devnull /* navigation keys work only when mouse is not open */
593 e830a908 2005-11-06 devnull if(!w->mouseopen)
594 e830a908 2005-11-06 devnull switch(r){
595 e830a908 2005-11-06 devnull case Kdown:
596 e830a908 2005-11-06 devnull n = w->f.maxlines/3;
597 e830a908 2005-11-06 devnull goto case_Down;
598 e830a908 2005-11-06 devnull case Kscrollonedown:
599 e830a908 2005-11-06 devnull n = mousescrollsize(w->f.maxlines);
600 e830a908 2005-11-06 devnull if(n <= 0)
601 e830a908 2005-11-06 devnull n = 1;
602 e830a908 2005-11-06 devnull goto case_Down;
603 e830a908 2005-11-06 devnull case Kpgdown:
604 e830a908 2005-11-06 devnull n = 2*w->f.maxlines/3;
605 e830a908 2005-11-06 devnull case_Down:
606 e830a908 2005-11-06 devnull q0 = w->org+frcharofpt(&w->f, Pt(w->f.r.min.x, w->f.r.min.y+n*w->f.font->height));
607 e830a908 2005-11-06 devnull wsetorigin(w, q0, TRUE);
608 e830a908 2005-11-06 devnull return;
609 e830a908 2005-11-06 devnull case Kup:
610 e830a908 2005-11-06 devnull n = w->f.maxlines/3;
611 e830a908 2005-11-06 devnull goto case_Up;
612 e830a908 2005-11-06 devnull case Kscrolloneup:
613 e830a908 2005-11-06 devnull n = mousescrollsize(w->f.maxlines);
614 e830a908 2005-11-06 devnull if(n <= 0)
615 e830a908 2005-11-06 devnull n = 1;
616 e830a908 2005-11-06 devnull goto case_Up;
617 e830a908 2005-11-06 devnull case Kpgup:
618 e830a908 2005-11-06 devnull n = 2*w->f.maxlines/3;
619 e830a908 2005-11-06 devnull case_Up:
620 e830a908 2005-11-06 devnull q0 = wbacknl(w, w->org, n);
621 e830a908 2005-11-06 devnull wsetorigin(w, q0, TRUE);
622 e830a908 2005-11-06 devnull return;
623 e830a908 2005-11-06 devnull case Kleft:
624 e830a908 2005-11-06 devnull if(w->q0 > 0){
625 e830a908 2005-11-06 devnull q0 = w->q0-1;
626 e830a908 2005-11-06 devnull wsetselect(w, q0, q0);
627 e830a908 2005-11-06 devnull wshow(w, q0);
628 e830a908 2005-11-06 devnull }
629 e830a908 2005-11-06 devnull return;
630 e830a908 2005-11-06 devnull case Kright:
631 e830a908 2005-11-06 devnull if(w->q1 < w->nr){
632 e830a908 2005-11-06 devnull q1 = w->q1+1;
633 e830a908 2005-11-06 devnull wsetselect(w, q1, q1);
634 e830a908 2005-11-06 devnull wshow(w, q1);
635 e830a908 2005-11-06 devnull }
636 e830a908 2005-11-06 devnull return;
637 e830a908 2005-11-06 devnull case Khome:
638 65a5e5fe 2011-08-02 rsc if(w->org > w->iq1) {
639 65a5e5fe 2011-08-02 rsc q0 = wbacknl(w, w->iq1, 1);
640 65a5e5fe 2011-08-02 rsc wsetorigin(w, q0, TRUE);
641 65a5e5fe 2011-08-02 rsc } else
642 65a5e5fe 2011-08-02 rsc wshow(w, 0);
643 e830a908 2005-11-06 devnull return;
644 e830a908 2005-11-06 devnull case Kend:
645 65a5e5fe 2011-08-02 rsc if(w->iq1 > w->org+w->f.nchars) {
646 65a5e5fe 2011-08-02 rsc q0 = wbacknl(w, w->iq1, 1);
647 65a5e5fe 2011-08-02 rsc wsetorigin(w, q0, TRUE);
648 65a5e5fe 2011-08-02 rsc } else
649 65a5e5fe 2011-08-02 rsc wshow(w, w->nr);
650 e830a908 2005-11-06 devnull return;
651 e830a908 2005-11-06 devnull case 0x01: /* ^A: beginning of line */
652 e830a908 2005-11-06 devnull if(w->q0==0 || w->q0==w->qh || w->r[w->q0-1]=='\n')
653 e830a908 2005-11-06 devnull return;
654 e830a908 2005-11-06 devnull nb = wbswidth(w, 0x15 /* ^U */);
655 e830a908 2005-11-06 devnull wsetselect(w, w->q0-nb, w->q0-nb);
656 e830a908 2005-11-06 devnull wshow(w, w->q0);
657 e830a908 2005-11-06 devnull return;
658 e830a908 2005-11-06 devnull case 0x05: /* ^E: end of line */
659 e830a908 2005-11-06 devnull q0 = w->q0;
660 e830a908 2005-11-06 devnull while(q0 < w->nr && w->r[q0]!='\n')
661 e830a908 2005-11-06 devnull q0++;
662 e830a908 2005-11-06 devnull wsetselect(w, q0, q0);
663 e830a908 2005-11-06 devnull wshow(w, w->q0);
664 e830a908 2005-11-06 devnull return;
665 e830a908 2005-11-06 devnull }
666 e830a908 2005-11-06 devnull /*
667 e830a908 2005-11-06 devnull * This if used to be below the if(w->rawing ...),
668 e830a908 2005-11-06 devnull * but let's try putting it here. This will allow ESC-processing
669 e830a908 2005-11-06 devnull * to toggle hold mode even in remote SSH connections.
670 e830a908 2005-11-06 devnull * The drawback is that vi-style processing gets harder.
671 e830a908 2005-11-06 devnull * If you find yourself in some weird readline mode, good
672 e830a908 2005-11-06 devnull * luck getting out without ESC. Let's see who complains.
673 e830a908 2005-11-06 devnull */
674 e830a908 2005-11-06 devnull if(r==0x1B || (w->holding && r==0x7F)){ /* toggle hold */
675 e830a908 2005-11-06 devnull if(w->holding)
676 e830a908 2005-11-06 devnull --w->holding;
677 e830a908 2005-11-06 devnull else
678 e830a908 2005-11-06 devnull w->holding++;
679 e830a908 2005-11-06 devnull wrepaint(w);
680 e830a908 2005-11-06 devnull if(r == 0x1B)
681 e830a908 2005-11-06 devnull return;
682 e830a908 2005-11-06 devnull }
683 e830a908 2005-11-06 devnull if(!w->holding && w->rawing && (w->q0==w->nr || w->mouseopen)){
684 e830a908 2005-11-06 devnull waddraw(w, &r, 1);
685 7b08cf33 2010-04-13 rsc return;
686 7b08cf33 2010-04-13 rsc }
687 7b08cf33 2010-04-13 rsc if(r == Kcmd+'x'){
688 7b08cf33 2010-04-13 rsc wsnarf(w);
689 7b08cf33 2010-04-13 rsc wcut(w);
690 7b08cf33 2010-04-13 rsc wscrdraw(w);
691 7b08cf33 2010-04-13 rsc return;
692 7b08cf33 2010-04-13 rsc }
693 7b08cf33 2010-04-13 rsc if(r == Kcmd+'c'){
694 7b08cf33 2010-04-13 rsc wsnarf(w);
695 e830a908 2005-11-06 devnull return;
696 e830a908 2005-11-06 devnull }
697 7b08cf33 2010-04-13 rsc if(r == Kcmd+'v'){
698 7b08cf33 2010-04-13 rsc riogetsnarf();
699 7b08cf33 2010-04-13 rsc wpaste(w);
700 7b08cf33 2010-04-13 rsc wscrdraw(w);
701 7b08cf33 2010-04-13 rsc return;
702 7b08cf33 2010-04-13 rsc }
703 e830a908 2005-11-06 devnull if(r != 0x7F){
704 e830a908 2005-11-06 devnull wsnarf(w);
705 e830a908 2005-11-06 devnull wcut(w);
706 e830a908 2005-11-06 devnull }
707 e830a908 2005-11-06 devnull switch(r){
708 be7485e1 2017-01-09 rsc case 0x03: /* maybe send interrupt */
709 be7485e1 2017-01-09 rsc /* since ^C is so commonly used as interrupt, special case it */
710 be7485e1 2017-01-09 rsc if (intrc() != 0x03)
711 be7485e1 2017-01-09 rsc break;
712 be7485e1 2017-01-09 rsc /* fall through */
713 e830a908 2005-11-06 devnull case 0x7F: /* send interrupt */
714 e830a908 2005-11-06 devnull w->qh = w->nr;
715 e830a908 2005-11-06 devnull wshow(w, w->qh);
716 10ab06a7 2005-11-06 devnull winterrupt(w);
717 65a5e5fe 2011-08-02 rsc w->iq1 = w->q0;
718 e830a908 2005-11-06 devnull return;
719 e830a908 2005-11-06 devnull case 0x06: /* ^F: file name completion */
720 e830a908 2005-11-06 devnull case Kins: /* Insert: file name completion */
721 e830a908 2005-11-06 devnull rp = namecomplete(w);
722 e830a908 2005-11-06 devnull if(rp == nil)
723 e830a908 2005-11-06 devnull return;
724 e830a908 2005-11-06 devnull nr = runestrlen(rp);
725 e830a908 2005-11-06 devnull q0 = w->q0;
726 e830a908 2005-11-06 devnull q0 = winsert(w, rp, nr, q0);
727 e830a908 2005-11-06 devnull wshow(w, q0+nr);
728 65a5e5fe 2011-08-02 rsc w->iq1 = w->q0;
729 e830a908 2005-11-06 devnull free(rp);
730 e830a908 2005-11-06 devnull return;
731 e830a908 2005-11-06 devnull case 0x08: /* ^H: erase character */
732 e830a908 2005-11-06 devnull case 0x15: /* ^U: erase line */
733 e830a908 2005-11-06 devnull case 0x17: /* ^W: erase word */
734 e830a908 2005-11-06 devnull if(w->q0==0 || w->q0==w->qh)
735 e830a908 2005-11-06 devnull return;
736 e830a908 2005-11-06 devnull nb = wbswidth(w, r);
737 e830a908 2005-11-06 devnull q1 = w->q0;
738 e830a908 2005-11-06 devnull q0 = q1-nb;
739 e830a908 2005-11-06 devnull if(q0 < w->org){
740 e830a908 2005-11-06 devnull q0 = w->org;
741 e830a908 2005-11-06 devnull nb = q1-q0;
742 e830a908 2005-11-06 devnull }
743 e830a908 2005-11-06 devnull if(nb > 0){
744 e830a908 2005-11-06 devnull wdelete(w, q0, q0+nb);
745 e830a908 2005-11-06 devnull wsetselect(w, q0, q0);
746 e830a908 2005-11-06 devnull }
747 65a5e5fe 2011-08-02 rsc w->iq1 = w->q0;
748 e830a908 2005-11-06 devnull return;
749 e830a908 2005-11-06 devnull }
750 e830a908 2005-11-06 devnull /* otherwise ordinary character; just insert */
751 e830a908 2005-11-06 devnull q0 = w->q0;
752 e830a908 2005-11-06 devnull q0 = winsert(w, &r, 1, q0);
753 e830a908 2005-11-06 devnull wshow(w, q0+1);
754 65a5e5fe 2011-08-02 rsc w->iq1 = w->q0;
755 e830a908 2005-11-06 devnull }
756 e830a908 2005-11-06 devnull
757 e830a908 2005-11-06 devnull void
758 e830a908 2005-11-06 devnull wsetcols(Window *w)
759 e830a908 2005-11-06 devnull {
760 e830a908 2005-11-06 devnull if(w->holding)
761 e830a908 2005-11-06 devnull if(w == input)
762 e830a908 2005-11-06 devnull w->f.cols[TEXT] = w->f.cols[HTEXT] = holdcol;
763 e830a908 2005-11-06 devnull else
764 e830a908 2005-11-06 devnull w->f.cols[TEXT] = w->f.cols[HTEXT] = lightholdcol;
765 e830a908 2005-11-06 devnull else
766 e830a908 2005-11-06 devnull if(w == input)
767 e830a908 2005-11-06 devnull w->f.cols[TEXT] = w->f.cols[HTEXT] = display->black;
768 e830a908 2005-11-06 devnull else
769 e830a908 2005-11-06 devnull w->f.cols[TEXT] = w->f.cols[HTEXT] = darkgrey;
770 e830a908 2005-11-06 devnull }
771 e830a908 2005-11-06 devnull
772 e830a908 2005-11-06 devnull void
773 e830a908 2005-11-06 devnull wrepaint(Window *w)
774 e830a908 2005-11-06 devnull {
775 e830a908 2005-11-06 devnull wsetcols(w);
776 dcf4d596 2006-03-30 devnull if(!w->mouseopen){
777 482299b8 2008-07-21 rsc frredraw(&w->f);
778 dcf4d596 2006-03-30 devnull }
779 e830a908 2005-11-06 devnull if(w == input){
780 a8a0a642 2012-11-26 rsc wborder(w, wscale(w, Selborder));
781 e830a908 2005-11-06 devnull wsetcursor(w, 0);
782 e830a908 2005-11-06 devnull }else
783 a8a0a642 2012-11-26 rsc wborder(w, wscale(w, Unselborder));
784 e830a908 2005-11-06 devnull }
785 e830a908 2005-11-06 devnull
786 e830a908 2005-11-06 devnull int
787 e830a908 2005-11-06 devnull wbswidth(Window *w, Rune c)
788 e830a908 2005-11-06 devnull {
789 e830a908 2005-11-06 devnull uint q, eq, stop;
790 e830a908 2005-11-06 devnull Rune r;
791 e830a908 2005-11-06 devnull int skipping;
792 e830a908 2005-11-06 devnull
793 e830a908 2005-11-06 devnull /* there is known to be at least one character to erase */
794 e830a908 2005-11-06 devnull if(c == 0x08) /* ^H: erase character */
795 e830a908 2005-11-06 devnull return 1;
796 e830a908 2005-11-06 devnull q = w->q0;
797 e830a908 2005-11-06 devnull stop = 0;
798 e830a908 2005-11-06 devnull if(q > w->qh)
799 e830a908 2005-11-06 devnull stop = w->qh;
800 e830a908 2005-11-06 devnull skipping = TRUE;
801 e830a908 2005-11-06 devnull while(q > stop){
802 e830a908 2005-11-06 devnull r = w->r[q-1];
803 e830a908 2005-11-06 devnull if(r == '\n'){ /* eat at most one more character */
804 540eaf98 2005-11-26 devnull if(q == w->q0 && c != '\r') /* eat the newline */
805 e830a908 2005-11-06 devnull --q;
806 fa325e9b 2020-01-10 cross break;
807 e830a908 2005-11-06 devnull }
808 e830a908 2005-11-06 devnull if(c == 0x17){
809 e830a908 2005-11-06 devnull eq = isalnum(r);
810 e830a908 2005-11-06 devnull if(eq && skipping) /* found one; stop skipping */
811 e830a908 2005-11-06 devnull skipping = FALSE;
812 e830a908 2005-11-06 devnull else if(!eq && !skipping)
813 e830a908 2005-11-06 devnull break;
814 e830a908 2005-11-06 devnull }
815 e830a908 2005-11-06 devnull --q;
816 e830a908 2005-11-06 devnull }
817 e830a908 2005-11-06 devnull return w->q0-q;
818 e830a908 2005-11-06 devnull }
819 e830a908 2005-11-06 devnull
820 e830a908 2005-11-06 devnull void
821 e830a908 2005-11-06 devnull wsnarf(Window *w)
822 e830a908 2005-11-06 devnull {
823 e830a908 2005-11-06 devnull if(w->q1 == w->q0)
824 e830a908 2005-11-06 devnull return;
825 e830a908 2005-11-06 devnull nsnarf = w->q1-w->q0;
826 e830a908 2005-11-06 devnull snarf = runerealloc(snarf, nsnarf);
827 e830a908 2005-11-06 devnull snarfversion++; /* maybe modified by parent */
828 e830a908 2005-11-06 devnull runemove(snarf, w->r+w->q0, nsnarf);
829 3fd51250 2005-11-07 devnull rioputsnarf();
830 e830a908 2005-11-06 devnull }
831 e830a908 2005-11-06 devnull
832 e830a908 2005-11-06 devnull void
833 e830a908 2005-11-06 devnull wcut(Window *w)
834 e830a908 2005-11-06 devnull {
835 e830a908 2005-11-06 devnull if(w->q1 == w->q0)
836 e830a908 2005-11-06 devnull return;
837 e830a908 2005-11-06 devnull wdelete(w, w->q0, w->q1);
838 e830a908 2005-11-06 devnull wsetselect(w, w->q0, w->q0);
839 e830a908 2005-11-06 devnull }
840 e830a908 2005-11-06 devnull
841 e830a908 2005-11-06 devnull void
842 e830a908 2005-11-06 devnull wpaste(Window *w)
843 e830a908 2005-11-06 devnull {
844 e830a908 2005-11-06 devnull uint q0;
845 e830a908 2005-11-06 devnull
846 e830a908 2005-11-06 devnull if(nsnarf == 0)
847 e830a908 2005-11-06 devnull return;
848 e830a908 2005-11-06 devnull wcut(w);
849 e830a908 2005-11-06 devnull q0 = w->q0;
850 e58459c7 2005-12-29 devnull if(w->rawing && !w->holding && q0==w->nr){
851 e830a908 2005-11-06 devnull waddraw(w, snarf, nsnarf);
852 e830a908 2005-11-06 devnull wsetselect(w, q0, q0);
853 e830a908 2005-11-06 devnull }else{
854 e830a908 2005-11-06 devnull q0 = winsert(w, snarf, nsnarf, w->q0);
855 e830a908 2005-11-06 devnull wsetselect(w, q0, q0+nsnarf);
856 e830a908 2005-11-06 devnull }
857 e830a908 2005-11-06 devnull }
858 e830a908 2005-11-06 devnull
859 e830a908 2005-11-06 devnull void
860 e830a908 2005-11-06 devnull wplumb(Window *w)
861 e830a908 2005-11-06 devnull {
862 e830a908 2005-11-06 devnull Plumbmsg *m;
863 0c7f940a 2005-11-07 devnull static CFid *fd;
864 e830a908 2005-11-06 devnull char buf[32];
865 e830a908 2005-11-06 devnull uint p0, p1;
866 e830a908 2005-11-06 devnull Cursor *c;
867 e830a908 2005-11-06 devnull
868 0c7f940a 2005-11-07 devnull if(fd == nil)
869 0c7f940a 2005-11-07 devnull fd = plumbopenfid("send", OWRITE);
870 0c7f940a 2005-11-07 devnull if(fd == nil)
871 e830a908 2005-11-06 devnull return;
872 e830a908 2005-11-06 devnull m = emalloc(sizeof(Plumbmsg));
873 e830a908 2005-11-06 devnull m->src = estrdup("rio");
874 e830a908 2005-11-06 devnull m->dst = nil;
875 e830a908 2005-11-06 devnull m->wdir = estrdup(w->dir);
876 e830a908 2005-11-06 devnull m->type = estrdup("text");
877 e830a908 2005-11-06 devnull p0 = w->q0;
878 e830a908 2005-11-06 devnull p1 = w->q1;
879 e830a908 2005-11-06 devnull if(w->q1 > w->q0)
880 e830a908 2005-11-06 devnull m->attr = nil;
881 e830a908 2005-11-06 devnull else{
882 e830a908 2005-11-06 devnull while(p0>0 && w->r[p0-1]!=' ' && w->r[p0-1]!='\t' && w->r[p0-1]!='\n')
883 e830a908 2005-11-06 devnull p0--;
884 e830a908 2005-11-06 devnull while(p1<w->nr && w->r[p1]!=' ' && w->r[p1]!='\t' && w->r[p1]!='\n')
885 e830a908 2005-11-06 devnull p1++;
886 e830a908 2005-11-06 devnull sprint(buf, "click=%d", w->q0-p0);
887 e830a908 2005-11-06 devnull m->attr = plumbunpackattr(buf);
888 e830a908 2005-11-06 devnull }
889 e830a908 2005-11-06 devnull if(p1-p0 > messagesize-1024){
890 e830a908 2005-11-06 devnull plumbfree(m);
891 e830a908 2005-11-06 devnull return; /* too large for 9P */
892 e830a908 2005-11-06 devnull }
893 e830a908 2005-11-06 devnull m->data = runetobyte(w->r+p0, p1-p0, &m->ndata);
894 0c7f940a 2005-11-07 devnull if(plumbsendtofid(fd, m) < 0){
895 e830a908 2005-11-06 devnull c = lastcursor;
896 e830a908 2005-11-06 devnull riosetcursor(&query, 1);
897 e830a908 2005-11-06 devnull sleep(300);
898 e830a908 2005-11-06 devnull riosetcursor(c, 1);
899 e830a908 2005-11-06 devnull }
900 e830a908 2005-11-06 devnull plumbfree(m);
901 e830a908 2005-11-06 devnull }
902 e830a908 2005-11-06 devnull
903 e830a908 2005-11-06 devnull int
904 e830a908 2005-11-06 devnull winborder(Window *w, Point xy)
905 e830a908 2005-11-06 devnull {
906 a8a0a642 2012-11-26 rsc return ptinrect(xy, w->screenr) && !ptinrect(xy, insetrect(w->screenr, wscale(w, Selborder)));
907 e830a908 2005-11-06 devnull }
908 e830a908 2005-11-06 devnull
909 e830a908 2005-11-06 devnull void
910 a4e59b37 2020-01-07 crossd wlook(Window *w)
911 a4e59b37 2020-01-07 crossd {
912 a4e59b37 2020-01-07 crossd int i, n, e;
913 a4e59b37 2020-01-07 crossd
914 a4e59b37 2020-01-07 crossd i = w->q1;
915 a4e59b37 2020-01-07 crossd n = i - w->q0;
916 a4e59b37 2020-01-07 crossd e = w->nr - n;
917 a4e59b37 2020-01-07 crossd if(n <= 0 || e < n)
918 a4e59b37 2020-01-07 crossd return;
919 a4e59b37 2020-01-07 crossd
920 a4e59b37 2020-01-07 crossd if(i > e)
921 a4e59b37 2020-01-07 crossd i = 0;
922 a4e59b37 2020-01-07 crossd
923 a4e59b37 2020-01-07 crossd while(runestrncmp(w->r+w->q0, w->r+i, n) != 0){
924 a4e59b37 2020-01-07 crossd if(i < e)
925 a4e59b37 2020-01-07 crossd i++;
926 a4e59b37 2020-01-07 crossd else
927 a4e59b37 2020-01-07 crossd i = 0;
928 a4e59b37 2020-01-07 crossd }
929 a4e59b37 2020-01-07 crossd
930 a4e59b37 2020-01-07 crossd wsetselect(w, i, i+n);
931 a4e59b37 2020-01-07 crossd wshow(w, i);
932 a4e59b37 2020-01-07 crossd }
933 a4e59b37 2020-01-07 crossd
934 a4e59b37 2020-01-07 crossd void
935 e830a908 2005-11-06 devnull wmousectl(Window *w)
936 e830a908 2005-11-06 devnull {
937 e830a908 2005-11-06 devnull int but;
938 e830a908 2005-11-06 devnull
939 e830a908 2005-11-06 devnull if(w->mc.m.buttons == 1)
940 e830a908 2005-11-06 devnull but = 1;
941 e830a908 2005-11-06 devnull else if(w->mc.m.buttons == 2)
942 e830a908 2005-11-06 devnull but = 2;
943 e830a908 2005-11-06 devnull else if(w->mc.m.buttons == 4)
944 e830a908 2005-11-06 devnull but = 3;
945 e830a908 2005-11-06 devnull else{
946 e830a908 2005-11-06 devnull if(w->mc.m.buttons == 8)
947 e830a908 2005-11-06 devnull wkeyctl(w, Kscrolloneup);
948 e830a908 2005-11-06 devnull if(w->mc.m.buttons == 16)
949 e830a908 2005-11-06 devnull wkeyctl(w, Kscrollonedown);
950 e830a908 2005-11-06 devnull return;
951 e830a908 2005-11-06 devnull }
952 e830a908 2005-11-06 devnull
953 e830a908 2005-11-06 devnull incref(&w->ref); /* hold up window while we track */
954 e830a908 2005-11-06 devnull if(w->deleted)
955 e830a908 2005-11-06 devnull goto Return;
956 e830a908 2005-11-06 devnull if(ptinrect(w->mc.m.xy, w->scrollr)){
957 e830a908 2005-11-06 devnull if(but)
958 e830a908 2005-11-06 devnull wscroll(w, but);
959 e830a908 2005-11-06 devnull goto Return;
960 e830a908 2005-11-06 devnull }
961 e830a908 2005-11-06 devnull if(but == 1)
962 e830a908 2005-11-06 devnull wselect(w);
963 e830a908 2005-11-06 devnull /* else all is handled by main process */
964 e830a908 2005-11-06 devnull Return:
965 e830a908 2005-11-06 devnull wclose(w);
966 e830a908 2005-11-06 devnull }
967 e830a908 2005-11-06 devnull
968 e830a908 2005-11-06 devnull void
969 e830a908 2005-11-06 devnull wdelete(Window *w, uint q0, uint q1)
970 e830a908 2005-11-06 devnull {
971 e830a908 2005-11-06 devnull uint n, p0, p1;
972 e830a908 2005-11-06 devnull
973 e830a908 2005-11-06 devnull n = q1-q0;
974 e830a908 2005-11-06 devnull if(n == 0)
975 e830a908 2005-11-06 devnull return;
976 e830a908 2005-11-06 devnull runemove(w->r+q0, w->r+q1, w->nr-q1);
977 e830a908 2005-11-06 devnull w->nr -= n;
978 65a5e5fe 2011-08-02 rsc if(q0 < w->iq1)
979 65a5e5fe 2011-08-02 rsc w->iq1 -= min(n, w->iq1-q0);
980 e830a908 2005-11-06 devnull if(q0 < w->q0)
981 e830a908 2005-11-06 devnull w->q0 -= min(n, w->q0-q0);
982 e830a908 2005-11-06 devnull if(q0 < w->q1)
983 e830a908 2005-11-06 devnull w->q1 -= min(n, w->q1-q0);
984 e830a908 2005-11-06 devnull if(q1 < w->qh)
985 e830a908 2005-11-06 devnull w->qh -= n;
986 e830a908 2005-11-06 devnull else if(q0 < w->qh)
987 e830a908 2005-11-06 devnull w->qh = q0;
988 e830a908 2005-11-06 devnull if(q1 <= w->org)
989 e830a908 2005-11-06 devnull w->org -= n;
990 e830a908 2005-11-06 devnull else if(q0 < w->org+w->f.nchars){
991 e830a908 2005-11-06 devnull p1 = q1 - w->org;
992 e830a908 2005-11-06 devnull if(p1 > w->f.nchars)
993 e830a908 2005-11-06 devnull p1 = w->f.nchars;
994 e830a908 2005-11-06 devnull if(q0 < w->org){
995 e830a908 2005-11-06 devnull w->org = q0;
996 e830a908 2005-11-06 devnull p0 = 0;
997 e830a908 2005-11-06 devnull }else
998 e830a908 2005-11-06 devnull p0 = q0 - w->org;
999 e830a908 2005-11-06 devnull frdelete(&w->f, p0, p1);
1000 e830a908 2005-11-06 devnull wfill(w);
1001 e830a908 2005-11-06 devnull }
1002 e830a908 2005-11-06 devnull }
1003 e830a908 2005-11-06 devnull
1004 e830a908 2005-11-06 devnull
1005 e830a908 2005-11-06 devnull static Window *clickwin;
1006 e830a908 2005-11-06 devnull static uint clickmsec;
1007 e830a908 2005-11-06 devnull static Window *selectwin;
1008 e830a908 2005-11-06 devnull static uint selectq;
1009 e830a908 2005-11-06 devnull
1010 e830a908 2005-11-06 devnull /*
1011 e830a908 2005-11-06 devnull * called from frame library
1012 e830a908 2005-11-06 devnull */
1013 e830a908 2005-11-06 devnull void
1014 e830a908 2005-11-06 devnull framescroll(Frame *f, int dl)
1015 e830a908 2005-11-06 devnull {
1016 e830a908 2005-11-06 devnull if(f != &selectwin->f)
1017 e830a908 2005-11-06 devnull error("frameselect not right frame");
1018 e830a908 2005-11-06 devnull wframescroll(selectwin, dl);
1019 e830a908 2005-11-06 devnull }
1020 e830a908 2005-11-06 devnull
1021 e830a908 2005-11-06 devnull void
1022 e830a908 2005-11-06 devnull wframescroll(Window *w, int dl)
1023 e830a908 2005-11-06 devnull {
1024 e830a908 2005-11-06 devnull uint q0;
1025 e830a908 2005-11-06 devnull
1026 e830a908 2005-11-06 devnull if(dl == 0){
1027 e830a908 2005-11-06 devnull wscrsleep(w, 100);
1028 e830a908 2005-11-06 devnull return;
1029 e830a908 2005-11-06 devnull }
1030 e830a908 2005-11-06 devnull if(dl < 0){
1031 e830a908 2005-11-06 devnull q0 = wbacknl(w, w->org, -dl);
1032 e830a908 2005-11-06 devnull if(selectq > w->org+w->f.p0)
1033 e830a908 2005-11-06 devnull wsetselect(w, w->org+w->f.p0, selectq);
1034 e830a908 2005-11-06 devnull else
1035 e830a908 2005-11-06 devnull wsetselect(w, selectq, w->org+w->f.p0);
1036 e830a908 2005-11-06 devnull }else{
1037 e830a908 2005-11-06 devnull if(w->org+w->f.nchars == w->nr)
1038 e830a908 2005-11-06 devnull return;
1039 e830a908 2005-11-06 devnull q0 = w->org+frcharofpt(&w->f, Pt(w->f.r.min.x, w->f.r.min.y+dl*w->f.font->height));
1040 e830a908 2005-11-06 devnull if(selectq >= w->org+w->f.p1)
1041 e830a908 2005-11-06 devnull wsetselect(w, w->org+w->f.p1, selectq);
1042 e830a908 2005-11-06 devnull else
1043 e830a908 2005-11-06 devnull wsetselect(w, selectq, w->org+w->f.p1);
1044 e830a908 2005-11-06 devnull }
1045 e830a908 2005-11-06 devnull wsetorigin(w, q0, TRUE);
1046 e830a908 2005-11-06 devnull }
1047 e830a908 2005-11-06 devnull
1048 e830a908 2005-11-06 devnull void
1049 e830a908 2005-11-06 devnull wselect(Window *w)
1050 e830a908 2005-11-06 devnull {
1051 e830a908 2005-11-06 devnull uint q0, q1;
1052 e830a908 2005-11-06 devnull int b, x, y, first;
1053 e830a908 2005-11-06 devnull
1054 e830a908 2005-11-06 devnull first = 1;
1055 e830a908 2005-11-06 devnull selectwin = w;
1056 e830a908 2005-11-06 devnull /*
1057 e830a908 2005-11-06 devnull * Double-click immediately if it might make sense.
1058 e830a908 2005-11-06 devnull */
1059 e830a908 2005-11-06 devnull b = w->mc.m.buttons;
1060 e830a908 2005-11-06 devnull q0 = w->q0;
1061 e830a908 2005-11-06 devnull q1 = w->q1;
1062 e830a908 2005-11-06 devnull selectq = w->org+frcharofpt(&w->f, w->mc.m.xy);
1063 e830a908 2005-11-06 devnull if(clickwin==w && w->mc.m.msec-clickmsec<500)
1064 e830a908 2005-11-06 devnull if(q0==q1 && selectq==w->q0){
1065 e830a908 2005-11-06 devnull wdoubleclick(w, &q0, &q1);
1066 e830a908 2005-11-06 devnull wsetselect(w, q0, q1);
1067 e830a908 2005-11-06 devnull flushimage(display, 1);
1068 e830a908 2005-11-06 devnull x = w->mc.m.xy.x;
1069 e830a908 2005-11-06 devnull y = w->mc.m.xy.y;
1070 e830a908 2005-11-06 devnull /* stay here until something interesting happens */
1071 e830a908 2005-11-06 devnull do
1072 e830a908 2005-11-06 devnull readmouse(&w->mc);
1073 e830a908 2005-11-06 devnull while(w->mc.m.buttons==b && abs(w->mc.m.xy.x-x)<3 && abs(w->mc.m.xy.y-y)<3);
1074 e830a908 2005-11-06 devnull w->mc.m.xy.x = x; /* in case we're calling frselect */
1075 e830a908 2005-11-06 devnull w->mc.m.xy.y = y;
1076 e830a908 2005-11-06 devnull q0 = w->q0; /* may have changed */
1077 e830a908 2005-11-06 devnull q1 = w->q1;
1078 e830a908 2005-11-06 devnull selectq = q0;
1079 e830a908 2005-11-06 devnull }
1080 e830a908 2005-11-06 devnull if(w->mc.m.buttons == b){
1081 e830a908 2005-11-06 devnull w->f.scroll = framescroll;
1082 e830a908 2005-11-06 devnull frselect(&w->f, &w->mc);
1083 e830a908 2005-11-06 devnull /* horrible botch: while asleep, may have lost selection altogether */
1084 e830a908 2005-11-06 devnull if(selectq > w->nr)
1085 e830a908 2005-11-06 devnull selectq = w->org + w->f.p0;
1086 e830a908 2005-11-06 devnull w->f.scroll = nil;
1087 e830a908 2005-11-06 devnull if(selectq < w->org)
1088 e830a908 2005-11-06 devnull q0 = selectq;
1089 e830a908 2005-11-06 devnull else
1090 e830a908 2005-11-06 devnull q0 = w->org + w->f.p0;
1091 e830a908 2005-11-06 devnull if(selectq > w->org+w->f.nchars)
1092 e830a908 2005-11-06 devnull q1 = selectq;
1093 e830a908 2005-11-06 devnull else
1094 e830a908 2005-11-06 devnull q1 = w->org+w->f.p1;
1095 e830a908 2005-11-06 devnull }
1096 e830a908 2005-11-06 devnull if(q0 == q1){
1097 e830a908 2005-11-06 devnull if(q0==w->q0 && clickwin==w && w->mc.m.msec-clickmsec<500){
1098 e830a908 2005-11-06 devnull wdoubleclick(w, &q0, &q1);
1099 e830a908 2005-11-06 devnull clickwin = nil;
1100 e830a908 2005-11-06 devnull }else{
1101 e830a908 2005-11-06 devnull clickwin = w;
1102 e830a908 2005-11-06 devnull clickmsec = w->mc.m.msec;
1103 e830a908 2005-11-06 devnull }
1104 e830a908 2005-11-06 devnull }else
1105 e830a908 2005-11-06 devnull clickwin = nil;
1106 e830a908 2005-11-06 devnull wsetselect(w, q0, q1);
1107 e830a908 2005-11-06 devnull flushimage(display, 1);
1108 e830a908 2005-11-06 devnull while(w->mc.m.buttons){
1109 e830a908 2005-11-06 devnull w->mc.m.msec = 0;
1110 e830a908 2005-11-06 devnull b = w->mc.m.buttons;
1111 e830a908 2005-11-06 devnull if(b & 6){
1112 e830a908 2005-11-06 devnull if(b & 2){
1113 e830a908 2005-11-06 devnull wsnarf(w);
1114 e830a908 2005-11-06 devnull wcut(w);
1115 e830a908 2005-11-06 devnull }else{
1116 e830a908 2005-11-06 devnull if(first){
1117 e830a908 2005-11-06 devnull first = 0;
1118 3fd51250 2005-11-07 devnull riogetsnarf();
1119 e830a908 2005-11-06 devnull }
1120 e830a908 2005-11-06 devnull wpaste(w);
1121 e830a908 2005-11-06 devnull }
1122 e830a908 2005-11-06 devnull }
1123 e830a908 2005-11-06 devnull wscrdraw(w);
1124 e830a908 2005-11-06 devnull flushimage(display, 1);
1125 e830a908 2005-11-06 devnull while(w->mc.m.buttons == b)
1126 e830a908 2005-11-06 devnull readmouse(&w->mc);
1127 e830a908 2005-11-06 devnull clickwin = nil;
1128 e830a908 2005-11-06 devnull }
1129 e830a908 2005-11-06 devnull }
1130 e830a908 2005-11-06 devnull
1131 e830a908 2005-11-06 devnull void
1132 e830a908 2005-11-06 devnull wsendctlmesg(Window *w, int type, Rectangle r, Image *image)
1133 e830a908 2005-11-06 devnull {
1134 e830a908 2005-11-06 devnull Wctlmesg wcm;
1135 e830a908 2005-11-06 devnull
1136 e830a908 2005-11-06 devnull wcm.type = type;
1137 e830a908 2005-11-06 devnull wcm.r = r;
1138 e830a908 2005-11-06 devnull wcm.image = image;
1139 e830a908 2005-11-06 devnull send(w->cctl, &wcm);
1140 e830a908 2005-11-06 devnull }
1141 e830a908 2005-11-06 devnull
1142 e830a908 2005-11-06 devnull int
1143 e830a908 2005-11-06 devnull wctlmesg(Window *w, int m, Rectangle r, Image *i)
1144 e830a908 2005-11-06 devnull {
1145 e830a908 2005-11-06 devnull char buf[64];
1146 e830a908 2005-11-06 devnull
1147 e830a908 2005-11-06 devnull switch(m){
1148 e830a908 2005-11-06 devnull default:
1149 e830a908 2005-11-06 devnull error("unknown control message");
1150 e830a908 2005-11-06 devnull break;
1151 e830a908 2005-11-06 devnull case Wakeup:
1152 e830a908 2005-11-06 devnull break;
1153 e830a908 2005-11-06 devnull case Moved:
1154 e830a908 2005-11-06 devnull case Reshaped:
1155 e830a908 2005-11-06 devnull if(w->deleted){
1156 e830a908 2005-11-06 devnull freeimage(i);
1157 e830a908 2005-11-06 devnull break;
1158 e830a908 2005-11-06 devnull }
1159 e830a908 2005-11-06 devnull w->screenr = r;
1160 e830a908 2005-11-06 devnull strcpy(buf, w->name);
1161 e830a908 2005-11-06 devnull wresize(w, i, m==Moved);
1162 e830a908 2005-11-06 devnull w->wctlready = 1;
1163 e830a908 2005-11-06 devnull if(Dx(r) > 0){
1164 e830a908 2005-11-06 devnull if(w != input)
1165 e830a908 2005-11-06 devnull wcurrent(w);
1166 e830a908 2005-11-06 devnull }else if(w == input)
1167 e830a908 2005-11-06 devnull wcurrent(nil);
1168 e830a908 2005-11-06 devnull flushimage(display, 1);
1169 e830a908 2005-11-06 devnull break;
1170 e830a908 2005-11-06 devnull case Refresh:
1171 e830a908 2005-11-06 devnull if(w->deleted || Dx(w->screenr)<=0 || !rectclip(&r, w->i->r))
1172 e830a908 2005-11-06 devnull break;
1173 e830a908 2005-11-06 devnull if(!w->mouseopen)
1174 e830a908 2005-11-06 devnull wrefresh(w, r);
1175 e830a908 2005-11-06 devnull flushimage(display, 1);
1176 e830a908 2005-11-06 devnull break;
1177 e830a908 2005-11-06 devnull case Movemouse:
1178 e830a908 2005-11-06 devnull if(sweeping || !ptinrect(r.min, w->i->r))
1179 e830a908 2005-11-06 devnull break;
1180 e830a908 2005-11-06 devnull wmovemouse(w, r.min);
1181 e830a908 2005-11-06 devnull case Rawon:
1182 e830a908 2005-11-06 devnull break;
1183 e830a908 2005-11-06 devnull case Rawoff:
1184 e830a908 2005-11-06 devnull if(w->deleted)
1185 e830a908 2005-11-06 devnull break;
1186 e830a908 2005-11-06 devnull while(w->nraw > 0){
1187 e830a908 2005-11-06 devnull wkeyctl(w, w->raw[0]);
1188 e830a908 2005-11-06 devnull --w->nraw;
1189 e830a908 2005-11-06 devnull runemove(w->raw, w->raw+1, w->nraw);
1190 e830a908 2005-11-06 devnull }
1191 e830a908 2005-11-06 devnull break;
1192 e830a908 2005-11-06 devnull case Holdon:
1193 e830a908 2005-11-06 devnull case Holdoff:
1194 e830a908 2005-11-06 devnull if(w->deleted)
1195 e830a908 2005-11-06 devnull break;
1196 e830a908 2005-11-06 devnull wrepaint(w);
1197 e830a908 2005-11-06 devnull flushimage(display, 1);
1198 e830a908 2005-11-06 devnull break;
1199 e830a908 2005-11-06 devnull case Deleted:
1200 e830a908 2005-11-06 devnull if(w->deleted)
1201 e830a908 2005-11-06 devnull break;
1202 e830a908 2005-11-06 devnull write(w->notefd, "hangup", 6);
1203 e830a908 2005-11-06 devnull wclosewin(w);
1204 e830a908 2005-11-06 devnull break;
1205 e830a908 2005-11-06 devnull case Exited:
1206 e830a908 2005-11-06 devnull frclear(&w->f, TRUE);
1207 e830a908 2005-11-06 devnull close(w->notefd);
1208 e830a908 2005-11-06 devnull chanfree(w->mc.c);
1209 e830a908 2005-11-06 devnull chanfree(w->ck);
1210 e830a908 2005-11-06 devnull chanfree(w->cctl);
1211 e830a908 2005-11-06 devnull chanfree(w->conswrite);
1212 e830a908 2005-11-06 devnull chanfree(w->consread);
1213 e830a908 2005-11-06 devnull chanfree(w->mouseread);
1214 e830a908 2005-11-06 devnull chanfree(w->wctlread);
1215 e830a908 2005-11-06 devnull free(w->raw);
1216 e830a908 2005-11-06 devnull free(w->r);
1217 e830a908 2005-11-06 devnull free(w->dir);
1218 e830a908 2005-11-06 devnull free(w->label);
1219 e830a908 2005-11-06 devnull free(w);
1220 e830a908 2005-11-06 devnull break;
1221 e830a908 2005-11-06 devnull }
1222 e830a908 2005-11-06 devnull return m;
1223 e830a908 2005-11-06 devnull }
1224 e830a908 2005-11-06 devnull
1225 e830a908 2005-11-06 devnull /*
1226 e830a908 2005-11-06 devnull * Convert back to physical coordinates
1227 e830a908 2005-11-06 devnull */
1228 e830a908 2005-11-06 devnull void
1229 e830a908 2005-11-06 devnull wmovemouse(Window *w, Point p)
1230 e830a908 2005-11-06 devnull {
1231 e830a908 2005-11-06 devnull p.x += w->screenr.min.x-w->i->r.min.x;
1232 e830a908 2005-11-06 devnull p.y += w->screenr.min.y-w->i->r.min.y;
1233 e830a908 2005-11-06 devnull moveto(mousectl, p);
1234 e830a908 2005-11-06 devnull }
1235 e830a908 2005-11-06 devnull
1236 e830a908 2005-11-06 devnull void
1237 e830a908 2005-11-06 devnull wcurrent(Window *w)
1238 e830a908 2005-11-06 devnull {
1239 e830a908 2005-11-06 devnull Window *oi;
1240 e830a908 2005-11-06 devnull
1241 e830a908 2005-11-06 devnull if(wkeyboard!=nil && w==wkeyboard)
1242 e830a908 2005-11-06 devnull return;
1243 e830a908 2005-11-06 devnull oi = input;
1244 e830a908 2005-11-06 devnull input = w;
1245 e830a908 2005-11-06 devnull if(oi!=w && oi!=nil)
1246 e830a908 2005-11-06 devnull wrepaint(oi);
1247 e830a908 2005-11-06 devnull if(w !=nil){
1248 e830a908 2005-11-06 devnull wrepaint(w);
1249 e830a908 2005-11-06 devnull wsetcursor(w, 0);
1250 e830a908 2005-11-06 devnull }
1251 e830a908 2005-11-06 devnull if(w != oi){
1252 e830a908 2005-11-06 devnull if(oi){
1253 e830a908 2005-11-06 devnull oi->wctlready = 1;
1254 e830a908 2005-11-06 devnull wsendctlmesg(oi, Wakeup, ZR, nil);
1255 e830a908 2005-11-06 devnull }
1256 e830a908 2005-11-06 devnull if(w){
1257 e830a908 2005-11-06 devnull w->wctlready = 1;
1258 e830a908 2005-11-06 devnull wsendctlmesg(w, Wakeup, ZR, nil);
1259 e830a908 2005-11-06 devnull }
1260 e830a908 2005-11-06 devnull }
1261 e830a908 2005-11-06 devnull }
1262 e830a908 2005-11-06 devnull
1263 e830a908 2005-11-06 devnull void
1264 e830a908 2005-11-06 devnull wsetcursor(Window *w, int force)
1265 e830a908 2005-11-06 devnull {
1266 e830a908 2005-11-06 devnull Cursor *p;
1267 e830a908 2005-11-06 devnull
1268 e830a908 2005-11-06 devnull if(w==nil || /*w!=input || */ w->i==nil || Dx(w->screenr)<=0)
1269 e830a908 2005-11-06 devnull p = nil;
1270 e830a908 2005-11-06 devnull else if(wpointto(mouse->xy) == w){
1271 e830a908 2005-11-06 devnull p = w->cursorp;
1272 e830a908 2005-11-06 devnull if(p==nil && w->holding)
1273 e830a908 2005-11-06 devnull p = &whitearrow;
1274 e830a908 2005-11-06 devnull }else
1275 e830a908 2005-11-06 devnull p = nil;
1276 e830a908 2005-11-06 devnull if(!menuing)
1277 e830a908 2005-11-06 devnull riosetcursor(p, force && !menuing);
1278 e830a908 2005-11-06 devnull }
1279 e830a908 2005-11-06 devnull
1280 e830a908 2005-11-06 devnull void
1281 e830a908 2005-11-06 devnull riosetcursor(Cursor *p, int force)
1282 e830a908 2005-11-06 devnull {
1283 e830a908 2005-11-06 devnull if(!force && p==lastcursor)
1284 e830a908 2005-11-06 devnull return;
1285 e830a908 2005-11-06 devnull setcursor(mousectl, p);
1286 e830a908 2005-11-06 devnull lastcursor = p;
1287 e830a908 2005-11-06 devnull }
1288 e830a908 2005-11-06 devnull
1289 e830a908 2005-11-06 devnull Window*
1290 e830a908 2005-11-06 devnull wtop(Point pt)
1291 e830a908 2005-11-06 devnull {
1292 e830a908 2005-11-06 devnull Window *w;
1293 e830a908 2005-11-06 devnull
1294 e830a908 2005-11-06 devnull w = wpointto(pt);
1295 e830a908 2005-11-06 devnull if(w){
1296 e830a908 2005-11-06 devnull if(w->topped == topped)
1297 e830a908 2005-11-06 devnull return nil;
1298 e830a908 2005-11-06 devnull topwindow(w->i);
1299 e830a908 2005-11-06 devnull wcurrent(w);
1300 e830a908 2005-11-06 devnull flushimage(display, 1);
1301 e830a908 2005-11-06 devnull w->topped = ++topped;
1302 e830a908 2005-11-06 devnull }
1303 e830a908 2005-11-06 devnull return w;
1304 e830a908 2005-11-06 devnull }
1305 e830a908 2005-11-06 devnull
1306 e830a908 2005-11-06 devnull void
1307 e830a908 2005-11-06 devnull wtopme(Window *w)
1308 e830a908 2005-11-06 devnull {
1309 e830a908 2005-11-06 devnull if(w!=nil && w->i!=nil && !w->deleted && w->topped!=topped){
1310 e830a908 2005-11-06 devnull topwindow(w->i);
1311 e830a908 2005-11-06 devnull flushimage(display, 1);
1312 e830a908 2005-11-06 devnull w->topped = ++ topped;
1313 e830a908 2005-11-06 devnull }
1314 e830a908 2005-11-06 devnull }
1315 e830a908 2005-11-06 devnull
1316 e830a908 2005-11-06 devnull void
1317 e830a908 2005-11-06 devnull wbottomme(Window *w)
1318 e830a908 2005-11-06 devnull {
1319 e830a908 2005-11-06 devnull if(w!=nil && w->i!=nil && !w->deleted){
1320 e830a908 2005-11-06 devnull bottomwindow(w->i);
1321 e830a908 2005-11-06 devnull flushimage(display, 1);
1322 e830a908 2005-11-06 devnull w->topped = 0;
1323 e830a908 2005-11-06 devnull }
1324 e830a908 2005-11-06 devnull }
1325 e830a908 2005-11-06 devnull
1326 e830a908 2005-11-06 devnull Window*
1327 e830a908 2005-11-06 devnull wlookid(int id)
1328 e830a908 2005-11-06 devnull {
1329 e830a908 2005-11-06 devnull int i;
1330 e830a908 2005-11-06 devnull
1331 e830a908 2005-11-06 devnull for(i=0; i<nwindow; i++)
1332 e830a908 2005-11-06 devnull if(window[i]->id == id)
1333 e830a908 2005-11-06 devnull return window[i];
1334 e830a908 2005-11-06 devnull return nil;
1335 e830a908 2005-11-06 devnull }
1336 e830a908 2005-11-06 devnull
1337 e830a908 2005-11-06 devnull void
1338 e830a908 2005-11-06 devnull wclosewin(Window *w)
1339 e830a908 2005-11-06 devnull {
1340 e830a908 2005-11-06 devnull Rectangle r;
1341 e830a908 2005-11-06 devnull int i;
1342 e830a908 2005-11-06 devnull
1343 e830a908 2005-11-06 devnull w->deleted = TRUE;
1344 e830a908 2005-11-06 devnull if(w == input){
1345 e830a908 2005-11-06 devnull input = nil;
1346 e830a908 2005-11-06 devnull wsetcursor(w, 0);
1347 e830a908 2005-11-06 devnull }
1348 e830a908 2005-11-06 devnull if(w == wkeyboard)
1349 e830a908 2005-11-06 devnull wkeyboard = nil;
1350 e830a908 2005-11-06 devnull for(i=0; i<nhidden; i++)
1351 e830a908 2005-11-06 devnull if(hidden[i] == w){
1352 e830a908 2005-11-06 devnull --nhidden;
1353 e830a908 2005-11-06 devnull memmove(hidden+i, hidden+i+1, (nhidden-i)*sizeof(hidden[0]));
1354 e830a908 2005-11-06 devnull break;
1355 e830a908 2005-11-06 devnull }
1356 e830a908 2005-11-06 devnull for(i=0; i<nwindow; i++)
1357 e830a908 2005-11-06 devnull if(window[i] == w){
1358 e830a908 2005-11-06 devnull --nwindow;
1359 e830a908 2005-11-06 devnull memmove(window+i, window+i+1, (nwindow-i)*sizeof(Window*));
1360 e830a908 2005-11-06 devnull w->deleted = TRUE;
1361 e830a908 2005-11-06 devnull r = w->i->r;
1362 e830a908 2005-11-06 devnull /* move it off-screen to hide it, in case client is slow in letting it go */
1363 e830a908 2005-11-06 devnull MOVEIT originwindow(w->i, r.min, view->r.max);
1364 e830a908 2005-11-06 devnull freeimage(w->i);
1365 e830a908 2005-11-06 devnull w->i = nil;
1366 e830a908 2005-11-06 devnull return;
1367 e830a908 2005-11-06 devnull }
1368 e830a908 2005-11-06 devnull error("unknown window in closewin");
1369 e830a908 2005-11-06 devnull }
1370 e830a908 2005-11-06 devnull
1371 e830a908 2005-11-06 devnull void
1372 e830a908 2005-11-06 devnull wsetpid(Window *w, int pid, int dolabel)
1373 e830a908 2005-11-06 devnull {
1374 e830a908 2005-11-06 devnull char buf[128];
1375 e830a908 2005-11-06 devnull
1376 e830a908 2005-11-06 devnull w->pid = pid;
1377 e830a908 2005-11-06 devnull if(dolabel){
1378 e830a908 2005-11-06 devnull sprint(buf, "rc %d", pid);
1379 e830a908 2005-11-06 devnull free(w->label);
1380 e830a908 2005-11-06 devnull w->label = estrdup(buf);
1381 10ab06a7 2005-11-06 devnull drawsetlabel(w->label);
1382 e830a908 2005-11-06 devnull }
1383 e830a908 2005-11-06 devnull }
1384 e830a908 2005-11-06 devnull
1385 fa325e9b 2020-01-10 cross static Rune left1[] = {
1386 96e0eb83 2006-04-01 devnull '{', '[', '(', '<', 0xAB,
1387 fa325e9b 2020-01-10 cross 0x207d, 0x2329, 0x27e6, 0x27e8, 0x27ea,
1388 fa325e9b 2020-01-10 cross 0xfe59, 0xfe5b, 0xfe5d, 0xff08, 0xff3b, 0xff5b,
1389 96e0eb83 2006-04-01 devnull 0
1390 96e0eb83 2006-04-01 devnull };
1391 96e0eb83 2006-04-01 devnull static Rune right1[] = {
1392 96e0eb83 2006-04-01 devnull '}', ']', ')', '>', 0xBB,
1393 fa325e9b 2020-01-10 cross 0x207e, 0x232a, 0x27e7, 0x27e9, 0x27eb,
1394 96e0eb83 2006-04-01 devnull 0xfe5a, 0xfe5c, 0xfe5e, 0xff09, 0xff3d, 0xff5d,
1395 96e0eb83 2006-04-01 devnull 0
1396 96e0eb83 2006-04-01 devnull };
1397 e830a908 2005-11-06 devnull static Rune left2[] = { '\n', 0 };
1398 e830a908 2005-11-06 devnull static Rune left3[] = { '\'', '"', '`', 0 };
1399 e830a908 2005-11-06 devnull
1400 e830a908 2005-11-06 devnull Rune *left[] = {
1401 e830a908 2005-11-06 devnull left1,
1402 e830a908 2005-11-06 devnull left2,
1403 e830a908 2005-11-06 devnull left3,
1404 e830a908 2005-11-06 devnull nil
1405 e830a908 2005-11-06 devnull };
1406 e830a908 2005-11-06 devnull Rune *right[] = {
1407 e830a908 2005-11-06 devnull right1,
1408 e830a908 2005-11-06 devnull left2,
1409 e830a908 2005-11-06 devnull left3,
1410 e830a908 2005-11-06 devnull nil
1411 e830a908 2005-11-06 devnull };
1412 e830a908 2005-11-06 devnull
1413 e830a908 2005-11-06 devnull void
1414 e830a908 2005-11-06 devnull wdoubleclick(Window *w, uint *q0, uint *q1)
1415 e830a908 2005-11-06 devnull {
1416 e830a908 2005-11-06 devnull int c, i;
1417 e830a908 2005-11-06 devnull Rune *r, *l, *p;
1418 e830a908 2005-11-06 devnull uint q;
1419 e830a908 2005-11-06 devnull
1420 e830a908 2005-11-06 devnull for(i=0; left[i]!=nil; i++){
1421 e830a908 2005-11-06 devnull q = *q0;
1422 e830a908 2005-11-06 devnull l = left[i];
1423 e830a908 2005-11-06 devnull r = right[i];
1424 e830a908 2005-11-06 devnull /* try matching character to left, looking right */
1425 e830a908 2005-11-06 devnull if(q == 0)
1426 e830a908 2005-11-06 devnull c = '\n';
1427 e830a908 2005-11-06 devnull else
1428 e830a908 2005-11-06 devnull c = w->r[q-1];
1429 e830a908 2005-11-06 devnull p = strrune(l, c);
1430 e830a908 2005-11-06 devnull if(p != nil){
1431 e830a908 2005-11-06 devnull if(wclickmatch(w, c, r[p-l], 1, &q))
1432 e830a908 2005-11-06 devnull *q1 = q-(c!='\n');
1433 e830a908 2005-11-06 devnull return;
1434 e830a908 2005-11-06 devnull }
1435 e830a908 2005-11-06 devnull /* try matching character to right, looking left */
1436 e830a908 2005-11-06 devnull if(q == w->nr)
1437 e830a908 2005-11-06 devnull c = '\n';
1438 e830a908 2005-11-06 devnull else
1439 e830a908 2005-11-06 devnull c = w->r[q];
1440 e830a908 2005-11-06 devnull p = strrune(r, c);
1441 e830a908 2005-11-06 devnull if(p != nil){
1442 e830a908 2005-11-06 devnull if(wclickmatch(w, c, l[p-r], -1, &q)){
1443 e830a908 2005-11-06 devnull *q1 = *q0+(*q0<w->nr && c=='\n');
1444 e830a908 2005-11-06 devnull *q0 = q;
1445 e830a908 2005-11-06 devnull if(c!='\n' || q!=0 || w->r[0]=='\n')
1446 e830a908 2005-11-06 devnull (*q0)++;
1447 e830a908 2005-11-06 devnull }
1448 e830a908 2005-11-06 devnull return;
1449 e830a908 2005-11-06 devnull }
1450 e830a908 2005-11-06 devnull }
1451 e830a908 2005-11-06 devnull /* try filling out word to right */
1452 e830a908 2005-11-06 devnull while(*q1<w->nr && isalnum(w->r[*q1]))
1453 e830a908 2005-11-06 devnull (*q1)++;
1454 e830a908 2005-11-06 devnull /* try filling out word to left */
1455 e830a908 2005-11-06 devnull while(*q0>0 && isalnum(w->r[*q0-1]))
1456 e830a908 2005-11-06 devnull (*q0)--;
1457 e830a908 2005-11-06 devnull }
1458 e830a908 2005-11-06 devnull
1459 e830a908 2005-11-06 devnull int
1460 e830a908 2005-11-06 devnull wclickmatch(Window *w, int cl, int cr, int dir, uint *q)
1461 e830a908 2005-11-06 devnull {
1462 e830a908 2005-11-06 devnull Rune c;
1463 e830a908 2005-11-06 devnull int nest;
1464 e830a908 2005-11-06 devnull
1465 e830a908 2005-11-06 devnull nest = 1;
1466 e830a908 2005-11-06 devnull for(;;){
1467 e830a908 2005-11-06 devnull if(dir > 0){
1468 e830a908 2005-11-06 devnull if(*q == w->nr)
1469 e830a908 2005-11-06 devnull break;
1470 e830a908 2005-11-06 devnull c = w->r[*q];
1471 e830a908 2005-11-06 devnull (*q)++;
1472 e830a908 2005-11-06 devnull }else{
1473 e830a908 2005-11-06 devnull if(*q == 0)
1474 e830a908 2005-11-06 devnull break;
1475 e830a908 2005-11-06 devnull (*q)--;
1476 e830a908 2005-11-06 devnull c = w->r[*q];
1477 e830a908 2005-11-06 devnull }
1478 e830a908 2005-11-06 devnull if(c == cr){
1479 e830a908 2005-11-06 devnull if(--nest==0)
1480 e830a908 2005-11-06 devnull return 1;
1481 e830a908 2005-11-06 devnull }else if(c == cl)
1482 e830a908 2005-11-06 devnull nest++;
1483 e830a908 2005-11-06 devnull }
1484 e830a908 2005-11-06 devnull return cl=='\n' && nest==1;
1485 e830a908 2005-11-06 devnull }
1486 e830a908 2005-11-06 devnull
1487 e830a908 2005-11-06 devnull
1488 e830a908 2005-11-06 devnull uint
1489 e830a908 2005-11-06 devnull wbacknl(Window *w, uint p, uint n)
1490 e830a908 2005-11-06 devnull {
1491 e830a908 2005-11-06 devnull int i, j;
1492 e830a908 2005-11-06 devnull
1493 e830a908 2005-11-06 devnull /* look for start of this line if n==0 */
1494 e830a908 2005-11-06 devnull if(n==0 && p>0 && w->r[p-1]!='\n')
1495 e830a908 2005-11-06 devnull n = 1;
1496 e830a908 2005-11-06 devnull i = n;
1497 e830a908 2005-11-06 devnull while(i-->0 && p>0){
1498 e830a908 2005-11-06 devnull --p; /* it's at a newline now; back over it */
1499 e830a908 2005-11-06 devnull if(p == 0)
1500 e830a908 2005-11-06 devnull break;
1501 e830a908 2005-11-06 devnull /* at 128 chars, call it a line anyway */
1502 e830a908 2005-11-06 devnull for(j=128; --j>0 && p>0; p--)
1503 e830a908 2005-11-06 devnull if(w->r[p-1]=='\n')
1504 e830a908 2005-11-06 devnull break;
1505 e830a908 2005-11-06 devnull }
1506 e830a908 2005-11-06 devnull return p;
1507 e830a908 2005-11-06 devnull }
1508 e830a908 2005-11-06 devnull
1509 e830a908 2005-11-06 devnull void
1510 e830a908 2005-11-06 devnull wshow(Window *w, uint q0)
1511 e830a908 2005-11-06 devnull {
1512 e830a908 2005-11-06 devnull int qe;
1513 e830a908 2005-11-06 devnull int nl;
1514 e830a908 2005-11-06 devnull uint q;
1515 e830a908 2005-11-06 devnull
1516 e830a908 2005-11-06 devnull qe = w->org+w->f.nchars;
1517 e830a908 2005-11-06 devnull if(w->org<=q0 && (q0<qe || (q0==qe && qe==w->nr)))
1518 e830a908 2005-11-06 devnull wscrdraw(w);
1519 e830a908 2005-11-06 devnull else{
1520 e830a908 2005-11-06 devnull nl = 4*w->f.maxlines/5;
1521 e830a908 2005-11-06 devnull q = wbacknl(w, q0, nl);
1522 e830a908 2005-11-06 devnull /* avoid going backwards if trying to go forwards - long lines! */
1523 e830a908 2005-11-06 devnull if(!(q0>w->org && q<w->org))
1524 e830a908 2005-11-06 devnull wsetorigin(w, q, TRUE);
1525 e830a908 2005-11-06 devnull while(q0 > w->org+w->f.nchars)
1526 e830a908 2005-11-06 devnull wsetorigin(w, w->org+1, FALSE);
1527 e830a908 2005-11-06 devnull }
1528 e830a908 2005-11-06 devnull }
1529 e830a908 2005-11-06 devnull
1530 e830a908 2005-11-06 devnull void
1531 e830a908 2005-11-06 devnull wsetorigin(Window *w, uint org, int exact)
1532 e830a908 2005-11-06 devnull {
1533 e830a908 2005-11-06 devnull int i, a, fixup;
1534 e830a908 2005-11-06 devnull Rune *r;
1535 e830a908 2005-11-06 devnull uint n;
1536 e830a908 2005-11-06 devnull
1537 e830a908 2005-11-06 devnull if(org>0 && !exact){
1538 e830a908 2005-11-06 devnull /* org is an estimate of the char posn; find a newline */
1539 e830a908 2005-11-06 devnull /* don't try harder than 256 chars */
1540 e830a908 2005-11-06 devnull for(i=0; i<256 && org<w->nr; i++){
1541 e830a908 2005-11-06 devnull if(w->r[org] == '\n'){
1542 e830a908 2005-11-06 devnull org++;
1543 e830a908 2005-11-06 devnull break;
1544 e830a908 2005-11-06 devnull }
1545 e830a908 2005-11-06 devnull org++;
1546 e830a908 2005-11-06 devnull }
1547 e830a908 2005-11-06 devnull }
1548 e830a908 2005-11-06 devnull a = org-w->org;
1549 e830a908 2005-11-06 devnull fixup = 0;
1550 e830a908 2005-11-06 devnull if(a>=0 && a<w->f.nchars){
1551 e830a908 2005-11-06 devnull frdelete(&w->f, 0, a);
1552 e830a908 2005-11-06 devnull fixup = 1; /* frdelete can leave end of last line in wrong selection mode; it doesn't know what follows */
1553 e830a908 2005-11-06 devnull }else if(a<0 && -a<w->f.nchars){
1554 e830a908 2005-11-06 devnull n = w->org - org;
1555 e830a908 2005-11-06 devnull r = runemalloc(n);
1556 e830a908 2005-11-06 devnull runemove(r, w->r+org, n);
1557 e830a908 2005-11-06 devnull frinsert(&w->f, r, r+n, 0);
1558 e830a908 2005-11-06 devnull free(r);
1559 e830a908 2005-11-06 devnull }else
1560 e830a908 2005-11-06 devnull frdelete(&w->f, 0, w->f.nchars);
1561 e830a908 2005-11-06 devnull w->org = org;
1562 e830a908 2005-11-06 devnull wfill(w);
1563 e830a908 2005-11-06 devnull wscrdraw(w);
1564 e830a908 2005-11-06 devnull wsetselect(w, w->q0, w->q1);
1565 e830a908 2005-11-06 devnull if(fixup && w->f.p1 > w->f.p0)
1566 e830a908 2005-11-06 devnull frdrawsel(&w->f, frptofchar(&w->f, w->f.p1-1), w->f.p1-1, w->f.p1, 1);
1567 e830a908 2005-11-06 devnull }
1568 e830a908 2005-11-06 devnull
1569 e830a908 2005-11-06 devnull void
1570 e830a908 2005-11-06 devnull wsetselect(Window *w, uint q0, uint q1)
1571 e830a908 2005-11-06 devnull {
1572 e830a908 2005-11-06 devnull int p0, p1;
1573 e830a908 2005-11-06 devnull
1574 e830a908 2005-11-06 devnull /* w->f.p0 and w->f.p1 are always right; w->q0 and w->q1 may be off */
1575 e830a908 2005-11-06 devnull w->q0 = q0;
1576 e830a908 2005-11-06 devnull w->q1 = q1;
1577 e830a908 2005-11-06 devnull /* compute desired p0,p1 from q0,q1 */
1578 e830a908 2005-11-06 devnull p0 = q0-w->org;
1579 e830a908 2005-11-06 devnull p1 = q1-w->org;
1580 e830a908 2005-11-06 devnull if(p0 < 0)
1581 e830a908 2005-11-06 devnull p0 = 0;
1582 e830a908 2005-11-06 devnull if(p1 < 0)
1583 e830a908 2005-11-06 devnull p1 = 0;
1584 e830a908 2005-11-06 devnull if(p0 > w->f.nchars)
1585 e830a908 2005-11-06 devnull p0 = w->f.nchars;
1586 e830a908 2005-11-06 devnull if(p1 > w->f.nchars)
1587 e830a908 2005-11-06 devnull p1 = w->f.nchars;
1588 e830a908 2005-11-06 devnull if(p0==w->f.p0 && p1==w->f.p1)
1589 e830a908 2005-11-06 devnull return;
1590 e830a908 2005-11-06 devnull /* screen disagrees with desired selection */
1591 e830a908 2005-11-06 devnull if(w->f.p1<=p0 || p1<=w->f.p0 || p0==p1 || w->f.p1==w->f.p0){
1592 e830a908 2005-11-06 devnull /* no overlap or too easy to bother trying */
1593 e830a908 2005-11-06 devnull frdrawsel(&w->f, frptofchar(&w->f, w->f.p0), w->f.p0, w->f.p1, 0);
1594 e830a908 2005-11-06 devnull frdrawsel(&w->f, frptofchar(&w->f, p0), p0, p1, 1);
1595 e830a908 2005-11-06 devnull goto Return;
1596 e830a908 2005-11-06 devnull }
1597 e830a908 2005-11-06 devnull /* overlap; avoid unnecessary painting */
1598 e830a908 2005-11-06 devnull if(p0 < w->f.p0){
1599 e830a908 2005-11-06 devnull /* extend selection backwards */
1600 e830a908 2005-11-06 devnull frdrawsel(&w->f, frptofchar(&w->f, p0), p0, w->f.p0, 1);
1601 e830a908 2005-11-06 devnull }else if(p0 > w->f.p0){
1602 e830a908 2005-11-06 devnull /* trim first part of selection */
1603 e830a908 2005-11-06 devnull frdrawsel(&w->f, frptofchar(&w->f, w->f.p0), w->f.p0, p0, 0);
1604 e830a908 2005-11-06 devnull }
1605 e830a908 2005-11-06 devnull if(p1 > w->f.p1){
1606 e830a908 2005-11-06 devnull /* extend selection forwards */
1607 e830a908 2005-11-06 devnull frdrawsel(&w->f, frptofchar(&w->f, w->f.p1), w->f.p1, p1, 1);
1608 e830a908 2005-11-06 devnull }else if(p1 < w->f.p1){
1609 e830a908 2005-11-06 devnull /* trim last part of selection */
1610 e830a908 2005-11-06 devnull frdrawsel(&w->f, frptofchar(&w->f, p1), p1, w->f.p1, 0);
1611 e830a908 2005-11-06 devnull }
1612 e830a908 2005-11-06 devnull
1613 e830a908 2005-11-06 devnull Return:
1614 e830a908 2005-11-06 devnull w->f.p0 = p0;
1615 e830a908 2005-11-06 devnull w->f.p1 = p1;
1616 e830a908 2005-11-06 devnull }
1617 e830a908 2005-11-06 devnull
1618 e830a908 2005-11-06 devnull uint
1619 e830a908 2005-11-06 devnull winsert(Window *w, Rune *r, int n, uint q0)
1620 e830a908 2005-11-06 devnull {
1621 e830a908 2005-11-06 devnull uint m;
1622 e830a908 2005-11-06 devnull
1623 e830a908 2005-11-06 devnull if(n == 0)
1624 e830a908 2005-11-06 devnull return q0;
1625 e830a908 2005-11-06 devnull if(w->nr+n>HiWater && q0>=w->org && q0>=w->qh){
1626 e830a908 2005-11-06 devnull m = min(HiWater-LoWater, min(w->org, w->qh));
1627 e830a908 2005-11-06 devnull w->org -= m;
1628 e830a908 2005-11-06 devnull w->qh -= m;
1629 e830a908 2005-11-06 devnull if(w->q0 > m)
1630 e830a908 2005-11-06 devnull w->q0 -= m;
1631 e830a908 2005-11-06 devnull else
1632 e830a908 2005-11-06 devnull w->q0 = 0;
1633 e830a908 2005-11-06 devnull if(w->q1 > m)
1634 e830a908 2005-11-06 devnull w->q1 -= m;
1635 e830a908 2005-11-06 devnull else
1636 e830a908 2005-11-06 devnull w->q1 = 0;
1637 e830a908 2005-11-06 devnull w->nr -= m;
1638 e830a908 2005-11-06 devnull runemove(w->r, w->r+m, w->nr);
1639 e830a908 2005-11-06 devnull q0 -= m;
1640 e830a908 2005-11-06 devnull }
1641 e830a908 2005-11-06 devnull if(w->nr+n > w->maxr){
1642 e830a908 2005-11-06 devnull /*
1643 e830a908 2005-11-06 devnull * Minimize realloc breakage:
1644 e830a908 2005-11-06 devnull * Allocate at least MinWater
1645 e830a908 2005-11-06 devnull * Double allocation size each time
1646 e830a908 2005-11-06 devnull * But don't go much above HiWater
1647 e830a908 2005-11-06 devnull */
1648 e830a908 2005-11-06 devnull m = max(min(2*(w->nr+n), HiWater), w->nr+n)+MinWater;
1649 e830a908 2005-11-06 devnull if(m > HiWater)
1650 e830a908 2005-11-06 devnull m = max(HiWater+MinWater, w->nr+n);
1651 e830a908 2005-11-06 devnull if(m > w->maxr){
1652 e830a908 2005-11-06 devnull w->r = runerealloc(w->r, m);
1653 e830a908 2005-11-06 devnull w->maxr = m;
1654 e830a908 2005-11-06 devnull }
1655 e830a908 2005-11-06 devnull }
1656 e830a908 2005-11-06 devnull runemove(w->r+q0+n, w->r+q0, w->nr-q0);
1657 e830a908 2005-11-06 devnull runemove(w->r+q0, r, n);
1658 e830a908 2005-11-06 devnull w->nr += n;
1659 e830a908 2005-11-06 devnull /* if output touches, advance selection, not qh; works best for keyboard and output */
1660 e830a908 2005-11-06 devnull if(q0 <= w->q1)
1661 e830a908 2005-11-06 devnull w->q1 += n;
1662 e830a908 2005-11-06 devnull if(q0 <= w->q0)
1663 e830a908 2005-11-06 devnull w->q0 += n;
1664 e830a908 2005-11-06 devnull if(q0 < w->qh)
1665 e830a908 2005-11-06 devnull w->qh += n;
1666 65a5e5fe 2011-08-02 rsc if(q0 < w->iq1)
1667 65a5e5fe 2011-08-02 rsc w->iq1 += n;
1668 53000799 2011-09-12 rsc if(q0 < w->org)
1669 53000799 2011-09-12 rsc w->org += n;
1670 e830a908 2005-11-06 devnull else if(q0 <= w->org+w->f.nchars)
1671 e830a908 2005-11-06 devnull frinsert(&w->f, r, r+n, q0-w->org);
1672 e830a908 2005-11-06 devnull return q0;
1673 e830a908 2005-11-06 devnull }
1674 e830a908 2005-11-06 devnull
1675 e830a908 2005-11-06 devnull void
1676 e830a908 2005-11-06 devnull wfill(Window *w)
1677 e830a908 2005-11-06 devnull {
1678 e830a908 2005-11-06 devnull Rune *rp;
1679 e830a908 2005-11-06 devnull int i, n, m, nl;
1680 e830a908 2005-11-06 devnull
1681 e830a908 2005-11-06 devnull if(w->f.lastlinefull)
1682 e830a908 2005-11-06 devnull return;
1683 e830a908 2005-11-06 devnull rp = malloc(messagesize);
1684 e830a908 2005-11-06 devnull do{
1685 e830a908 2005-11-06 devnull n = w->nr-(w->org+w->f.nchars);
1686 e830a908 2005-11-06 devnull if(n == 0)
1687 e830a908 2005-11-06 devnull break;
1688 e830a908 2005-11-06 devnull if(n > 2000) /* educated guess at reasonable amount */
1689 e830a908 2005-11-06 devnull n = 2000;
1690 e830a908 2005-11-06 devnull runemove(rp, w->r+(w->org+w->f.nchars), n);
1691 e830a908 2005-11-06 devnull /*
1692 e830a908 2005-11-06 devnull * it's expensive to frinsert more than we need, so
1693 e830a908 2005-11-06 devnull * count newlines.
1694 e830a908 2005-11-06 devnull */
1695 e830a908 2005-11-06 devnull nl = w->f.maxlines-w->f.nlines;
1696 e830a908 2005-11-06 devnull m = 0;
1697 e830a908 2005-11-06 devnull for(i=0; i<n; ){
1698 e830a908 2005-11-06 devnull if(rp[i++] == '\n'){
1699 e830a908 2005-11-06 devnull m++;
1700 e830a908 2005-11-06 devnull if(m >= nl)
1701 e830a908 2005-11-06 devnull break;
1702 e830a908 2005-11-06 devnull }
1703 e830a908 2005-11-06 devnull }
1704 e830a908 2005-11-06 devnull frinsert(&w->f, rp, rp+i, w->f.nchars);
1705 e830a908 2005-11-06 devnull }while(w->f.lastlinefull == FALSE);
1706 e830a908 2005-11-06 devnull free(rp);
1707 e830a908 2005-11-06 devnull }
1708 e830a908 2005-11-06 devnull
1709 e830a908 2005-11-06 devnull char*
1710 e830a908 2005-11-06 devnull wcontents(Window *w, int *ip)
1711 e830a908 2005-11-06 devnull {
1712 e830a908 2005-11-06 devnull return runetobyte(w->r, w->nr, ip);
1713 e830a908 2005-11-06 devnull }