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