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. 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 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 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 120 winclose(Window *w) 121 { 122 pageclose(&w->page); 123 winclose1(w); 124 } 125 126 void 127 winlock(Window *w, int owner) 128 { 129 incref(w); 130 qlock(w); 131 w->owner = owner; 132 } 133 134 void 135 winunlock(Window *w) 136 { 137 w->owner = 0; 138 qunlock(w); 139 winclose1(w); 140 } 141 142 void 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 241 winsettag(Window *w) 242 { 243 if(w->col && w->col->safe) 244 winsettag1(w); 245 } 246 247 void 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 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 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 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 * 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 * 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 * 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 353 winmousebut(Window *w) 354 { 355 moveto(mousectl, divpt(addpt(w->tag.scrollr.min, w->tag.scrollr.max), 2)); 356 } 357 358 int 359 winclean(Window *, int) 360 { 361 return TRUE; 362 } 363 364 void 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