1 #include <u.h>
2 #include <libc.h>
3 #include <draw.h>
4 #include <memdraw.h>
5 #include <thread.h>
6 #include <cursor.h>
7 #include <mouse.h>
8 #include <keyboard.h>
9 #include <frame.h>
10 #include <plumb.h>
11 #include <html.h>
12 #include "dat.h"
13 #include "fns.h"
14
15 void
wininit(Window * w,Window *,Rectangle r)16 wininit(Window *w, Window *, Rectangle r)
17 {
18 Rectangle r1, br;
19
20 incref(w);
21 w->r = r;
22 w->tag.w = w;
23 w->url.w = w;
24 w->page.w = w;
25 w->status.w = w;
26 r1 = r;
27 r1.max.y = r1.min.y + font->height;
28 textinit(&w->tag, screen, r1, font, tagcols);
29 w->tag.what = Tag;
30 r1.min.y = r1.max.y++;
31 draw(screen, r1, tagcols[BORD], nil, ZP);
32 br.min = w->tag.scrollr.min;
33 br.max.x = br.min.x + Dx(button->r);
34 br.max.y = br.min.y + Dy(button->r);
35 draw(screen, br, button, nil, button->r.min);
36 r1.min.y = r1.max.y;
37 r1.max.y += font->height;
38 textinit(&w->url, screen, r1, font, tagcols);
39 w->url.
40 w->url.what = Urltag;
41 r1.min.y = r1.max.y++;
42 draw(screen, r1, tagcols[BORD], nil, ZP);
43 r1.min.y = r1.max.y;
44 r1.max.y = r.max.y - font->height - 1;
45 w->page.all = r1;
46 w->page.b = screen;
47 draw(screen, r1, display->white, nil, ZP);
48 r1.min.y = r1.max.y++;
49 draw(screen, r1, tagcols[BORD], nil, ZP);
50 r1.min.y = r1.max.y;
51 r1.max.y += font->height;
52 textinit(&w->status, screen, r1, font, tagcols);
53 w->status.what = Statustag;
54 }
55
56 int
winresize(Window * w,Rectangle r,int safe)57 winresize(Window *w, Rectangle r, int safe)
58 {
59 Rectangle r1, br;
60
61 w->r = r;
62 r1 = r;
63 r1.max.y = r1.min.y + font->height;
64 if(!safe || !eqrect(w->tag.r, r1)){
65 textresize(&w->tag, screen, r1);
66 br.min = w->tag.scrollr.min;
67 br.max.x = r1.min.x + Dx(button->r);
68 br.max.y = r1.min.y + Dy(button->r);
69 draw(screen, br, button, nil, button->r.min);
70 r1.min.y = r1.max.y++;
71 draw(screen, r1, tagcols[BORD], nil, ZP);
72 r1.min.y = r1.max.y;
73 r1.max.y += font->height;
74 textresize(&w->url, screen, r1);
75 r1.min.y = r1.max.y++;
76 draw(screen, r1, tagcols[BORD], nil, ZP);
77 }
78 r1.min.y = r1.max.y;
79 r1.max.y = r.max.y - font->height - 1;
80 w->page.b = screen;
81 if(!safe || !eqrect(w->page.all, r1)){
82 if(Dy(r1) <= 0){
83 w->page.all = ZR;
84 pagerender(&w->page);
85 w->r = r;
86 w->r.max.y = r1.min.y;
87 return w->r.max.y;
88 }
89 draw(screen, r1, display->white, nil, ZP);
90 w->page.all = r1;
91 pagerender(&w->page);
92 r1.min.y = r1.max.y++;
93 draw(screen, r1, tagcols[BORD], nil, ZP);
94 r1.min.y = r1.max.y;
95 r1.max.y = r.max.y;
96 textresize(&w->status, screen, r1);
97 }
98 return w->r.max.y;
99 }
100
101 void
winclose1(Window * w)102 winclose1(Window *w)
103 {
104 int i;
105
106 if(decref(w) == 0){
107 textclose(&w->tag);
108 textclose(&w->url);
109 textclose(&w->status);
110 if(w->history.url){
111 for(i=0; i<w->history.nurl; i++)
112 urlfree(w->history.url[i]);
113 free(w->history.url);
114 }
115 free(w);
116 }
117 }
118
119 void
winclose(Window * w)120 winclose(Window *w)
121 {
122 pageclose(&w->page);
123 winclose1(w);
124 }
125
126 void
winlock(Window * w,int owner)127 winlock(Window *w, int owner)
128 {
129 incref(w);
130 qlock(w);
131 w->owner = owner;
132 }
133
134 void
winunlock(Window * w)135 winunlock(Window *w)
136 {
137 w->owner = 0;
138 qunlock(w);
139 winclose1(w);
140 }
141
142 void
winsettag1(Window * w)143 winsettag1(Window *w)
144 {
145 int i, j, k, n, bar;
146 Rune *new, *r;
147 Image *b;
148 uint q0, q1;
149 Rectangle br;
150 Runestr old;
151
152 memset(&old, 0, sizeof(Runestr));
153 copyrunestr(&old, &w->tag.rs);
154 for(i=0; i<w->tag.rs.nr; i++)
155 if(old.r[i]==' ' || old.r[i]=='\t')
156 break;
157
158 if(runestreq(old, w->page.title) == FALSE){
159 textdelete(&w->tag, 0, i);
160 textinsert(&w->tag, 0, w->page.title.r, w->page.title.nr);
161 closerunestr(&old);
162 copyrunestr(&old, &w->tag.rs);
163 }
164 new = runemalloc(w->page.title.nr+100);
165 i = 0;
166 runemove(new+i, L" Del Snarf", 10);
167 i += 10;
168 if(w->history.nurl){
169 if(w->history.cid > 0){
170 runemove(new+i, L" Back", 5);
171 i += 5;
172 }
173 if(w->history.cid < w->history.nurl-1){
174 runemove(new+i, L" Next", 5);
175 i += 5;
176 }
177 if(w->page.loading){
178 runemove(new+i, L" Stop", 5);
179 i += 5;
180 }
181 }
182 runemove(new+i, L" Get", 4);
183 i += 4;
184 runemove(new+i, L" | ", 3);
185 i += 3;
186 runemove(new+i, w->page.title.r, w->page.title.nr);
187 i += w->page.title.nr;
188 /*
189 r = runestrchr(old.r, '|');
190 r = nil;
191 if(r)
192 k = r-old.r+1;
193 else{
194 k = w->tag.rs.nr;
195 if(w->page.url){
196 runemove(new+i, L" Look ", 6);
197 i += 6;
198 }
199 }
200 */
201 k = w->tag.rs.nr;
202 if(runeeq(new, i, old.r, k) == FALSE){
203 n = k;
204 if(n > i)
205 n = i;
206 for(j=0; j<n; j++)
207 if(old.r[j] != new[j])
208 break;
209 q0 = w->tag.q0;
210 q1 = w->tag.q1;
211 textdelete(&w->tag, j, k);
212 textinsert(&w->tag, j, new+j, i-j);
213 /* try to preserve user selection */
214 r = runestrchr(old.r, '|');
215 if(r){
216 bar = r-old.r;
217 if(q0 > bar){
218 bar = (runestrchr(new, '|')-new)-bar;
219 w->tag.q0 = q0+bar;
220 w->tag.q1 = q1+bar;
221 }
222 }
223 }
224 closerunestr(&old);
225 free(new);
226 n = w->tag.rs.nr;
227 if(w->tag.q0 > n)
228 w->tag.q0 = n;
229 if(w->tag.q1 > n)
230 w->tag.q1 = n;
231 textsetselect(&w->tag, w->tag.q0, w->tag.q1);
232 b = button;
233 br.min = w->tag.scrollr.min;
234 br.max.x = br.min.x + Dx(b->r);
235 br.max.y = br.min.y + Dy(b->r);
236 draw(screen, br, b, nil, b->r.min);
237 }
238
239
240 void
winsettag(Window * w)241 winsettag(Window *w)
242 {
243 if(w->col && w->col->safe)
244 winsettag1(w);
245 }
246
247 void
winseturl(Window * w)248 winseturl(Window *w)
249 {
250 if(w->page.url && runestreq(w->url.rs, w->page.url->act)==FALSE)
251 textset(&w->url, w->page.url->act.r, w->page.url->act.nr);
252 }
253
254 void
winsetstatus(Window * w,Rune * r)255 winsetstatus(Window *w, Rune *r)
256 {
257 if(w->col && w->col->safe)
258 textset(&w->status, r, runestrlen(r));
259 }
260
261 void
winaddhist(Window * w,Url * u)262 winaddhist(Window *w, Url *u)
263 {
264 Url **url;
265 int cid, n, i;
266
267 url = w->history.url;
268 n = w->history.nurl;
269 cid = w->history.cid;
270 if(cid < n-1){
271 for(i=cid+1; i<n; i++)
272 urlfree(url[i]);
273 n = cid+1;
274 }
275 w->history.url = erealloc(w->history.url, ++n*sizeof(Url *));
276 w->history.url[n-1] = u;
277 w->history.cid = u->id = n-1;
278 w->history.nurl = n;
279 incref(u);
280 }
281
282 void
wingohist(Window * w,int isnext)283 wingohist(Window *w, int isnext)
284 {
285 Page *p;
286 int n, id;
287
288 n = w->history.nurl;
289 p = &w->page;
290 if(!p->url)
291 return;
292
293 id = p->url->id;
294
295 if(isnext)
296 id++;
297 else
298 id--;
299
300 if(n==0 || id<0 || id==n)
301 return;
302
303 incref(w->history.url[id]);
304 pageload(p, w->history.url[id], FALSE);
305 w->history.cid = id;
306 }
307
308 Text *
wintext(Window * w,Point xy)309 wintext(Window *w, Point xy)
310 {
311 w->inpage = FALSE;
312 if(ptinrect(xy, w->tag.all))
313 return &w->tag;
314 if(ptinrect(xy, w->url.all))
315 return &w->url;
316 if(ptinrect(xy, w->status.all))
317 return &w->status;
318 if(ptinrect(xy, w->page.all))
319 w->inpage = TRUE;
320
321 return nil;
322 }
323
324 Text *
wintype(Window * w,Point xy,Rune r)325 wintype(Window *w, Point xy, Rune r)
326 {
327 Text *t;
328
329 t = wintext(w, xy);
330 if(t && !ptinrect(xy, t->scrollr))
331 return t;
332 if(w->inpage)
333 pagetype(&w->page, r, xy);
334
335 return nil;
336 }
337
338 Text *
winmouse(Window * w,Point xy,int but)339 winmouse(Window *w, Point xy, int but)
340 {
341 Text *t;
342
343 t = wintext(w, xy);
344 if(t)
345 return t;
346 if(w->inpage)
347 pagemouse(&w->page, xy, but);
348
349 return nil;
350 }
351
352 void
winmousebut(Window * w)353 winmousebut(Window *w)
354 {
355 moveto(mousectl, divpt(addpt(w->tag.scrollr.min, w->tag.scrollr.max), 2));
356 }
357
358 int
winclean(Window *,int)359 winclean(Window *, int)
360 {
361 return TRUE;
362 }
363
364 void
windebug(Window * w)365 windebug(Window *w)
366 {
367 Page *p;
368 int i;
369
370 p = &w->page;
371 fprint(2, "title:\t%S\n", p->title.r);
372 fprint(2, "url:\t%.*S\n",w->url.rs.nr, w->url.rs.r);
373 fprint(2, "aborting:\t%s\n", istrue(p->aborting));
374 fprint(2, "changed:\t%s\n", istrue(p->changed));
375 fprint(2, "loading:\t%s\n", istrue(p->loading));
376 fprint(2, "status:\t%S\n", p->status);
377 fprint(2, "HISTORY:\n");
378 for(i=0; i<w->history.nurl; i++)
379 fprint(2, "url[%d]: %S\n", i, w->history.url[i]->act.r);
380
381 if(p->kidinfo)
382 fprint(2, "name: %S\n", p->kidinfo->name);
383 }
384