383 lines · 7.0 KB · C
RawDownload
#include <u.h>#include <libc.h>#include <draw.h>#include <memdraw.h>#include <thread.h>#include <cursor.h>#include <mouse.h>#include <keyboard.h>#include <frame.h>#include <plumb.h>#include <html.h>#include "dat.h"#include "fns.h" voidwininit(Window *w, Window *, Rectangle r){	Rectangle r1, br; 	incref(w);	w->r = r;	w->tag.w = w;	w->url.w = w;	w->page.w = w;	w->status.w = w;	r1 = r;	r1.max.y = r1.min.y + font->height;	textinit(&w->tag, screen, r1, font, tagcols);	w->tag.what = Tag;	r1.min.y = r1.max.y++;	draw(screen, r1, tagcols[BORD], nil, ZP);	br.min = w->tag.scrollr.min;	br.max.x = br.min.x + Dx(button->r);	br.max.y  = br.min.y + Dy(button->r);	draw(screen, br, button, nil, button->r.min);	r1.min.y = r1.max.y;	r1.max.y += font->height;	textinit(&w->url, screen, r1, font, tagcols);	w->url.	w->url.what = Urltag;	r1.min.y = r1.max.y++;	draw(screen, r1, tagcols[BORD], nil, ZP);	r1.min.y = r1.max.y;	r1.max.y = r.max.y - font->height - 1;	w->page.all = r1;	w->page.b = screen;	draw(screen, r1, display->white, nil, ZP);	r1.min.y = r1.max.y++;	draw(screen, r1, tagcols[BORD], nil, ZP);	r1.min.y = r1.max.y;	r1.max.y += font->height;	textinit(&w->status, screen, r1, font, tagcols);	w->status.what = Statustag;} intwinresize(Window *w, Rectangle r, int safe){	Rectangle r1, br; 	w->r = r;	r1 = r;	r1.max.y = r1.min.y + font->height;	if(!safe || !eqrect(w->tag.r, r1)){		textresize(&w->tag, screen, r1);		br.min = w->tag.scrollr.min;		br.max.x = r1.min.x + Dx(button->r);		br.max.y  = r1.min.y + Dy(button->r);		draw(screen, br, button, nil, button->r.min);		r1.min.y = r1.max.y++;		draw(screen, r1, tagcols[BORD], nil, ZP);		r1.min.y = r1.max.y;		r1.max.y += font->height;		textresize(&w->url, screen, r1);		r1.min.y = r1.max.y++;		draw(screen, r1, tagcols[BORD], nil, ZP);	}	r1.min.y = r1.max.y;	r1.max.y = r.max.y - font->height - 1;	w->page.b = screen;	if(!safe || !eqrect(w->page.all, r1)){		if(Dy(r1) <= 0){			w->page.all = ZR;			pagerender(&w->page);			w->r = r;			w->r.max.y = r1.min.y;			return w->r.max.y;		}		draw(screen, r1, display->white, nil, ZP);		w->page.all = r1;		pagerender(&w->page);		r1.min.y = r1.max.y++;		draw(screen, r1, tagcols[BORD], nil, ZP);		r1.min.y = r1.max.y;		r1.max.y = r.max.y;		textresize(&w->status, screen, r1);	}	return w->r.max.y;} voidwinclose1(Window *w){	int i; 	if(decref(w) == 0){		textclose(&w->tag);		textclose(&w->url);		textclose(&w->status);		if(w->history.url){			for(i=0; i<w->history.nurl; i++)				urlfree(w->history.url[i]);			free(w->history.url);		}		free(w);	}} voidwinclose(Window *w){	pageclose(&w->page);	winclose1(w);} voidwinlock(Window *w, int owner){	incref(w);	qlock(w);	w->owner = owner;} voidwinunlock(Window *w){	w->owner = 0;	qunlock(w);	winclose1(w);} voidwinsettag1(Window *w){	int i, j, k, n, bar;	Rune *new, *r;	Image *b;	uint q0, q1;	Rectangle br;	Runestr old; 	memset(&old, 0, sizeof(Runestr));	copyrunestr(&old, &w->tag.rs);	for(i=0; i<w->tag.rs.nr; i++)		if(old.r[i]==' ' || old.r[i]=='\t')			break; 	if(runestreq(old, w->page.title) == FALSE){		textdelete(&w->tag, 0, i);		textinsert(&w->tag, 0, w->page.title.r, w->page.title.nr);		closerunestr(&old);		copyrunestr(&old, &w->tag.rs);	}	new = runemalloc(w->page.title.nr+100);	i = 0;	runemove(new+i, L" Del Snarf", 10);	i += 10;	if(w->history.nurl){		if(w->history.cid > 0){			runemove(new+i, L" Back", 5);			i += 5;		}		if(w->history.cid < w->history.nurl-1){			runemove(new+i, L" Next", 5);			i += 5;		}		if(w->page.loading){			runemove(new+i, L" Stop", 5);			i += 5;		}	}	runemove(new+i, L" Get", 4);	i += 4;	runemove(new+i, L" | ", 3);	i += 3;	runemove(new+i, w->page.title.r, w->page.title.nr);	i += w->page.title.nr;/*	r = runestrchr(old.r, '|');	r = nil;	if(r)		k = r-old.r+1;	else{		k = w->tag.rs.nr;		if(w->page.url){			runemove(new+i, L" Look ", 6);			i += 6;		}	}*/	k = w->tag.rs.nr;	if(runeeq(new, i, old.r, k) == FALSE){		n = k;		if(n > i)			n = i;		for(j=0; j<n; j++)			if(old.r[j] != new[j])				break;		q0 = w->tag.q0;		q1 = w->tag.q1;		textdelete(&w->tag, j, k);		textinsert(&w->tag, j, new+j, i-j);		/* try to preserve user selection */		r = runestrchr(old.r, '|');		if(r){			bar = r-old.r;			if(q0 > bar){				bar = (runestrchr(new, '|')-new)-bar;				w->tag.q0 = q0+bar;				w->tag.q1 = q1+bar;			}		}	}	closerunestr(&old);	free(new);	n = w->tag.rs.nr;	if(w->tag.q0 > n)		w->tag.q0 = n;	if(w->tag.q1 > n)		w->tag.q1 = n;	textsetselect(&w->tag, w->tag.q0, w->tag.q1);	b = button;	br.min = w->tag.scrollr.min;	br.max.x = br.min.x + Dx(b->r);	br.max.y = br.min.y + Dy(b->r);	draw(screen, br, b, nil, b->r.min);}  voidwinsettag(Window *w){	if(w->col && w->col->safe)		winsettag1(w);} voidwinseturl(Window *w){	if(w->page.url && runestreq(w->url.rs, w->page.url->act)==FALSE)		textset(&w->url, w->page.url->act.r, w->page.url->act.nr);} voidwinsetstatus(Window *w, Rune *r){	if(w->col && w->col->safe)		textset(&w->status, r, runestrlen(r));} voidwinaddhist(Window *w, Url *u){	Url **url;	int cid, n, i; 	url = w->history.url;	n = w->history.nurl;	cid = w->history.cid;	if(cid < n-1){		for(i=cid+1; i<n; i++)			urlfree(url[i]);		n = cid+1;	}	w->history.url = erealloc(w->history.url, ++n*sizeof(Url *));	w->history.url[n-1] = u;	w->history.cid = u->id = n-1;	w->history.nurl = n;	incref(u);} voidwingohist(Window *w, int isnext){	Page *p;	int n, id; 	n = w->history.nurl;	p = &w->page;	if(!p->url)		return; 	id = p->url->id; 	if(isnext)		id++;	else		id--; 	if(n==0 || id<0 || id==n)		return; 	incref(w->history.url[id]);	pageload(p, w->history.url[id], FALSE);	w->history.cid = id;} Text *wintext(Window *w, Point xy){	w->inpage = FALSE;	if(ptinrect(xy, w->tag.all))		return &w->tag;	if(ptinrect(xy, w->url.all))		return &w->url;	if(ptinrect(xy, w->status.all))		return &w->status;	if(ptinrect(xy, w->page.all))		w->inpage = TRUE; 	return nil;} Text *wintype(Window *w, Point xy, Rune r){	Text *t; 	t = wintext(w, xy);	if(t && !ptinrect(xy, t->scrollr))		return t;	if(w->inpage)		pagetype(&w->page, r, xy); 	return nil;} Text *winmouse(Window *w, Point xy, int but){	Text *t; 	t = wintext(w, xy);	if(t)		return t;	if(w->inpage)		pagemouse(&w->page, xy, but); 	return nil;} voidwinmousebut(Window *w){	moveto(mousectl, divpt(addpt(w->tag.scrollr.min, w->tag.scrollr.max), 2));} intwinclean(Window *, int){	return TRUE;} voidwindebug(Window *w){	Page *p;	int i; 	p = &w->page;	fprint(2, "title:\t%S\n", p->title.r);	fprint(2, "url:\t%.*S\n",w->url.rs.nr, w->url.rs.r);	fprint(2, "aborting:\t%s\n", istrue(p->aborting));	fprint(2, "changed:\t%s\n", istrue(p->changed));	fprint(2, "loading:\t%s\n", istrue(p->loading));	fprint(2, "status:\t%S\n", p->status);	fprint(2, "HISTORY:\n");	for(i=0; i<w->history.nurl; i++)		fprint(2, "url[%d]: %S\n", i, w->history.url[i]->act.r); 	if(p->kidinfo)		fprint(2, "name: %S\n", p->kidinfo->name);}