Пример #1
0
// Look for string s in token source.
// If found, return 1, with buffer at next char after s,
// else return 0 (caller should back up).
static int
findstr(TokenSource* ts, Rune* s)
{
	int	c0;
	int	n;
	int	nexti;
	int	i;
	int	c;

	c0 = s[0];
	n = runestrlen(s);
	while(1) {
		c = getchar(ts);
		if(c < 0)
			break;
		if(c == c0) {
			if(n == 1)
				return 1;
			nexti = ts->i;
			for(i = 1; i < n; i++) {
				c = getchar(ts);
				if(c < 0)
					goto mainloop_done;
				if(c != s[i])
					break;
			}
			if(i == n)
				return 1;
			backup(ts, nexti);
		}
	}
mainloop_done:
	return 0;
}
Пример #2
0
void
renderrunes(Bytes *b, Rune *r)
{
	int i, n;

	n = runestrlen(r);
	for(i=0; i<n; i++){
		switch(r[i]){
		case '\n':
			if(inword)
				emitword(b, r+wordi, i-wordi);
			col = 0;
			if(b->n == 0)
				break;	/* don't start with blank lines */
			if(b->n<2 || b->b[b->n-1]!='\n' || b->b[b->n-2]!='\n')
				growbytes(b, "\n", 1);
			break;
		case ' ':
			if(inword)
				emitword(b, r+wordi, i-wordi);
			break;
		default:
			if(!inword)
				wordi = i;
			inword = 1;
			break;
		}
	}
	if(inword)
		emitword(b, r+wordi, i-wordi);
}
Пример #3
0
static
void
loadchilds(Page *p, Kidinfo *k)
{
	Runestr rs;
	Kidinfo *t;
	Page *c;

	addrefresh(p, "loading frames...");
	p->kidinfo = k;
	for(t=k->kidinfos; t!=nil; t=t->next){
		c = emalloc(sizeof(Page));
		addchild(p, c);
		if(t->isframeset){
			c->url = urldup(p->url);
			loadchilds(c, t);
		}else{
			c->kidinfo = t;
			/* this check shouldn't be necessary, but... */
			if(t->src){
				rs.r = urlcombine(p->url->act.r, t->src);
				rs.nr = runestrlen(rs.r);
				pageload1(c, urlalloc(&rs, nil, HGet), FALSE);
				closerunestr(&rs);
			}
		}
	}
}
Пример #4
0
Window*
errorwin1(Rune *dir, int ndir, Rune **incl, int nincl)
{
	Window *w;
	Rune *r;
	int i, n;

	r = runemalloc(ndir+8);
	if(n = ndir){	/* assign = */
		runemove(r, dir, ndir);
		r[n++] = L'/';
	}
	runemove(r+n, L"+Errors", 7);
	n += 7;
	w = lookfile(r, n);
	if(w == nil){
		if(row.ncol == 0)
			if(rowadd(&row, nil, -1) == nil)
				error("can't create column to make error window");
		w = coladd(row.col[row.ncol-1], nil, nil, -1);
		w->filemenu = FALSE;
		winsetname(w, r, n);
	}
	free(r);
	for(i=nincl; --i>=0; ){
		n = runestrlen(incl[i]);
		r = runemalloc(n);
		runemove(r, incl[i], n);
		winaddincl(w, r, n);
	}
	w->autoindent = globalautoindent;
	return w;
}
Пример #5
0
char*
fullurl(URLwin *u, Rune *rhref)
{
	char *base, *href, *hrefbase;
	char *result;

	if(rhref == nil)
		return estrdup("NULL URL");
	href = runetobyte(rhref, runestrlen(rhref));
	hrefbase = baseurl(href);
	result = nil;
	if(hrefbase==nil && (base = baseurl(u->url))!=nil){
		result = estrdup(base);
		if(base[strlen(base)-1]!='/' && (href==nil || href[0]!='/'))
			result = eappend(result, "/", "");
		free(base);
	}
	if(href){
		if(result)
			result = eappend(result, "", href);
		else
			result = estrdup(href);
	}
	free(hrefbase);
	if(result == nil)
		return estrdup("***unknown***");
	return result;
}
Пример #6
0
void
flushdi(void)
{
	int n;
	Rune *p;
	
	if(ndi == 0 || difmtinit == 0)
		return;
	fmtrune(&difmt, Uunformatted);
	p = runefmtstrflush(&difmt);
	memset(&difmt, 0, sizeof difmt);
	difmtinit = 0;
	if(p == nil)
		warn("out of memory in diversion %C%S", dot, di[ndi-1]);
	else{
		n = runestrlen(p);
		if(n > 0 && p[n-1] != '\n'){
			p = runerealloc(p, n+2);
			p[n] = '\n';
			p[n+1] = 0;
		}
	}
	as(di[ndi-1], p);
	free(p);
}
Пример #7
0
static int
inclass(char c, Rune* cl)
{
    int n, ans, negate, i;

    n = runestrlen(cl);
    if(n == 0)
        return 0;
    ans = 0;
    negate = 0;
    if(cl[0] == '^') {
        negate = 1;
        cl++;
        n--;
    }
    for(i=0; i<n; i++) {
        if(cl[i]=='-' && i>0 && i<n-1) {
            if(c>=cl[i - 1] && c<=cl[i+1]) {
                ans = 1;
                break;
            }
            i++;
        }
        else if(c == cl[i]) {
            ans = 1;
            break;
        }
    }
    if(negate)
        ans = !ans;
    return ans;
}
Пример #8
0
static
Cimage *
loadimg(Rune *src, int x , int y)
{
	Channel *sync;
	Cimage *ci;
	Runestr rs;
	Exec *e;
	char *filter;
	int fd, p[2], q[2];

	ci = emalloc(sizeof(Cimage));
	rs. r = src;
	rs.nr = runestrlen(rs.r);
	ci->url = urlalloc(&rs, nil, HGet);
	fd = urlopen(ci->url);
	if(fd < 0){
    Err1:
		return ci;
	}
	filter = getfilter(ci->url->ctype.r, x, y);
	if(filter == nil){
		werrstr("%S unsupported: %S", ci->url->ctype.r, ci->url->act.r);
    Err2:
		close(fd);
		goto Err1;
	}

	if(pipe(p)<0 || pipe(q)<0)
		error("can't create pipe");
	close(p[0]);
	p[0] = fd;
	sync = chancreate(sizeof(ulong), 0);
	if(sync == nil)
		error("can't create channel");
	e = emalloc(sizeof(Exec));
	e->p[0] = p[0];
	e->p[1] = p[1];
	e->q[0] = q[0];
	e->q[1] = q[1];
	e->cmd = filter;
	e->sync = sync;
	proccreate(execproc, e, STACK);
	recvul(sync);
	chanfree(sync);
	close(p[0]);
	close(p[1]);
	close(q[1]);

	ci->mi = readmemimage(q[0]);
	close(q[0]);
	if(ci->mi == nil){
		werrstr("can't read image");
		goto Err2;
	}
	free(filter);
	return ci;
}
Пример #9
0
int
plumbgetc(void *a, uint n)
{
	Rune *r;

	r = a;
	if(n>runestrlen(r))
		return 0;
	return r[n];
}
Пример #10
0
Rune*
runestrdup(Rune *s) 
{  
	Rune *ns;

	ns = malloc(sizeof(Rune)*(runestrlen(s) + 1));
	if(ns == 0)
		return 0;
	setmalloctag(ns, getcallerpc(&s));
	return runestrcpy(ns, s);
}
Пример #11
0
Rune*
runestrdup(Rune *s) 
{  
	Rune *ns;

	ns = malloc(sizeof(Rune)*(runestrlen(s) + 1));
	if(ns == 0)
		return 0;

	return runestrcpy(ns, s);
}
Пример #12
0
void
_inputstring(Rune *s, void (*push)(Istack*))
{
	Istack *is;
	
	is = emalloc(sizeof *is);
	is->s = erunestrdup(s);
	is->p = is->s;
	is->ep = is->p+runestrlen(is->p);
	push(is);
}
Пример #13
0
void
addhttp(Url *u)
{
	Rune *s;
	if(validurl(u->src.r))
		return;
	s = u->src.r;
	u->src.r = runesmprint("http://%S", u->src.r);
	free(s);
	u->src.nr = runestrlen(u->src.r);
}
Пример #14
0
// tired of typing http://, tired of going to google first.
void
justgoogleit(Url *u)
{
	Rune *s;
	
	s = ucvt(u->src.r+2);
	free(u->src.r);
	u->src.r = runesmprint("http://www.google.com/search?hl=en&ie=UTF-8&q=%S", s);
	free(s);
	u->src.nr = runestrlen(u->src.r);
}
Пример #15
0
void
urlcanon(Rune *name){
	Rune *s, *t;
	Rune **comp, **p, **q;
	int rooted;

	name = runestrchr(name, L'/')+2;
	rooted=name[0]==L'/';
	/*
	 * Break the name into a list of components
	 */
	comp=emalloc(runestrlen(name)*sizeof(char *));
	p=comp;
	*p++=name;
	for(s=name;;s++){
		if(*s==L'/'){
			*p++=s+1;
			*s='\0';
		}
		else if(*s=='\0')
			break;
	}
	*p=0;
	/*
	 * go through the component list, deleting components that are empty (except
	 * the last component) or ., and any .. and its non-.. predecessor.
	 */
	p=q=comp;
	while(*p){
		if(runestrcmp(*p, L"")==0 && p[1]!=0
		|| runestrcmp(*p, L".")==0)
			p++;
		else if(runestrcmp(*p, L"..")==0 && q!=comp && runestrcmp(q[-1], L"..")!=0){
			--q;
			p++;
		}
		else
			*q++=*p++;
	}
	*q=0;
	/*
	 * rebuild the path name
	 */
	s=name;
	if(rooted) *s++='/';
	for(p=comp;*p;p++){
		t=*p;
		while(*t) *s++=*t++;
		if(p[1]!=0) *s++='/';
	}
	*s='\0';
	free(comp);
}
Пример #16
0
void
warning(Mntdir *md, char *s, ...)
{
	Rune *r;
	va_list arg;

	va_start(arg, s);
	r = runevsmprint(s, arg);
	va_end(arg);
	if(r == nil)
		error("runevsmprint failed");
	addwarningtext(md, r, runestrlen(r));
	free(r);
}
Пример #17
0
Файл: t11.c Проект: aahud/harvey
int
e_w(void)
{
	Rune *a;
	Rune buf[40];
	
	a = getqarg();
	runesnprint(buf, sizeof buf, "%ld", runestrlen(a));
	pushinputstring(buf);
	nr(L("st"), 0);
	nr(L("sb"), 0);
	nr(L("ct"), 0);
	return 0;
}
Пример #18
0
void
_appleputsnarf(char *s)
{
	CFDataRef cfdata;
	PasteboardSyncFlags flags;

/*	fprint(2, "appleputsnarf\n"); */

	if(strlen(s) >= SnarfSize)
		return;
	qlock(&clip.lk);
	strcpy(clip.buf, s);
	runesnprint(clip.rbuf, nelem(clip.rbuf), "%s", s);
	if(clip.apple == nil){
		if(PasteboardCreate(kPasteboardClipboard, &clip.apple) != noErr){
			fprint(2, "apple pasteboard create failed\n");
			qunlock(&clip.lk);
			return;
		}
	}
	if(PasteboardClear(clip.apple) != noErr){
		fprint(2, "apple pasteboard clear failed\n");
		qunlock(&clip.lk);
		return;
	}
	flags = PasteboardSynchronize(clip.apple);
	if((flags&kPasteboardModified) || !(flags&kPasteboardClientIsOwner)){
		fprint(2, "apple pasteboard cannot assert ownership\n");
		qunlock(&clip.lk);
		return;
	}
	cfdata = CFDataCreate(kCFAllocatorDefault, 
		(uchar*)clip.rbuf, runestrlen(clip.rbuf)*2);
	if(cfdata == nil){
		fprint(2, "apple pasteboard cfdatacreate failed\n");
		qunlock(&clip.lk);
		return;
	}
	if(PasteboardPutItemFlavor(clip.apple, (PasteboardItemID)1,
		CFSTR("public.utf16-plain-text"), cfdata, 0) != noErr){
		fprint(2, "apple pasteboard putitem failed\n");
		CFRelease(cfdata);
		qunlock(&clip.lk);
		return;
	}
	/* CFRelease(cfdata); ??? */
	qunlock(&clip.lk);
}
Пример #19
0
int
e_w(void)
{
	Rune *a;
	Rune buf[40];
	static Rune zero;

	a = getqarg();
	if(a == nil){
		warn("no arg for \\w");
		a = &zero;
	}
	runesnprint(buf, sizeof buf, "%ld", runestrlen(a));
	pushinputstring(buf);
	nr(L("st"), 0);
	nr(L("sb"), 0);
	nr(L("ct"), 0);
	return 0;
}
Пример #20
0
void
columnate(void)
{
	int i, j;
	int words_per_line;
	int nlines;
	int col;
	int endcol;


	scanwords();
	if(nwords==0)
		return;
	maxwidth = nexttab(maxwidth+mintab-1);
	words_per_line = linewidth/maxwidth;
	if(words_per_line <= 0)
		words_per_line = 1;
	nlines=(nwords+words_per_line-1)/words_per_line;
	for(i = 0; i < nlines; i++){
		col = endcol = 0;
		for(j = i; j < nwords; j += nlines){
			endcol += maxwidth;
			Bprint(&bout, "%S", word[j]);
			col += wordsize(word[j], runestrlen(word[j]));
			if(j+nlines < nwords){
				if(tabflag) {
					while(col < endcol){
						Bputc(&bout, '\t');
						col = nexttab(col);
					}
				}else{
					while(col < endcol){
						Bputc(&bout, ' ');
						col++;
					}
				}
			}
		}
		Bputc(&bout, '\n');
	}
}
Пример #21
0
Runestr
includefile(Rune *dir, Rune *file, int nfile)
{
	int m, n;
	char *a;
	Rune *r;
	static Rune Lslash[] = { '/', 0 };

	m = runestrlen(dir);
	a = emalloc((m+1+nfile)*UTFmax+1);
	sprint(a, "%S/%.*S", dir, nfile, file);
	n = access(a, 0);
	free(a);
	if(n < 0)
		return runestr(nil, 0);
	r = runemalloc(m+1+nfile);
	runemove(r, dir, m);
	runemove(r+m, Lslash, 1);
	runemove(r+m+1, file, nfile);
	free(file);
	return cleanrname(runestr(r, m+1+nfile));
}
Пример #22
0
/* define macro - .de, .am, .ig */
void
r_de(int argc, Rune **argv)
{
	Rune *end, *p;
	Fmt fmt;
	int ignore, len;

	delreq(argv[1]);
	delraw(argv[1]);
	ignore = runestrcmp(argv[0], L("ig")) == 0;
	if(!ignore)
		runefmtstrinit(&fmt);
	end = L("..");
	if(argc >= 3)
		end = argv[2];
	if(runestrcmp(argv[0], L("am")) == 0 && (p=getds(argv[1])) != nil)
		fmtrunestrcpy(&fmt, p);
	len = runestrlen(end);
	while((p = readline(CopyMode)) != nil){
		if(runestrncmp(p, end, len) == 0 
		&& (p[len]==' ' || p[len]==0 || p[len]=='\t'
			|| (p[len]=='\\' && p[len+1]=='}'))){
			free(p);
			goto done;
		}
		if(!ignore)
			fmtprint(&fmt, "%S\n", p);
		free(p);
	}
	warn("eof in %C%S %S - looking for %#Q", dot, argv[0], argv[1], end);
done:
	if(ignore)
		return;
	p = runefmtstrflush(&fmt);
	if(p == nil)
		sysfatal("out of memory");
	ds(argv[1], p);
	free(p);
}
Пример #23
0
void
pagesetrefresh(Page *p)
{
	Runestr rs;
	Rune *s, *q, *t;
	char *v;
	int n;

	if(!p->doc || !p->doc->refresh)
		return;

	s = p->doc->refresh;
	q = runestrchr(s, L'=');
	if(q == nil)
		return;
	q++;
	if(!q)
		return;
	n = runestrlen(q);
	if(*q == L'''){
		q++;
		n -= 2;
	}
Пример #24
0
/*
 * Incoming window should be locked. 
 * It will be unlocked and returned window
 * will be locked in its place.
 */
Window*
errorwinforwin(Window *w)
{
	int i, n, nincl, owner;
	Rune **incl;
	Runestr dir;
	Text *t;

	t = &w->body;
	dir = dirname(t, nil, 0);
	if(dir.nr==1 && dir.r[0]=='.'){	/* sigh */
		free(dir.r);
		dir.r = nil;
		dir.nr = 0;
	}
	incl = nil;
	nincl = w->nincl;
	if(nincl > 0){
		incl = emalloc(nincl*sizeof(Rune*));
		for(i=0; i<nincl; i++){
			n = runestrlen(w->incl[i]);
			incl[i] = runemalloc(n+1);
			runemove(incl[i], w->incl[i], n);
		}
	}
	owner = w->owner;
	winunlock(w);
	for(;;){
		w = errorwin1(dir.r, dir.nr, incl, nincl);
		winlock(w, owner);
		if(w->col != nil)
			break;
		/* window deleted too fast */
		winunlock(w);
	}
	return w;
}
Пример #25
0
void
readfile(Column *c, char *s)
{
	Window *w;
	Rune rb[256];
	int nr;
	Runestr rs;

	w = coladd(c, nil, nil, -1);
	if(s[0] != '/')
		runesnprint(rb, sizeof rb, "%s/%s", wdir, s);
	else
		runesnprint(rb, sizeof rb, "%s", s);
	nr = runestrlen(rb);
	rs = cleanrname(runestr(rb, nr));
	winsetname(w, rs.r, rs.nr);
	textload(&w->body, 0, s, 1);
	w->body.file->mod = FALSE;
	w->dirty = FALSE;
	winsettag(w);
	winresize(w, w->r, FALSE, TRUE);
	textscrdraw(&w->body);
	textsetselect(&w->tag, w->tag.file->b.nc, w->tag.file->b.nc);
}
Пример #26
0
static
void
pageloadproc(void *v)
{
	Page *p;
	char buf[BUFSIZE], *s;
	int32_t n, l;
	int fd, i, ctype;

	threadsetname("pageloadproc");
	rfork(RFFDG);

	p = v;
	addrefresh(p, "opening: %S...", p->url->src.r);
	fd = urlopen(p->url);
	if(fd < 0){
		addrefresh(p, "%S: %r", p->url->src.r);
    Err:
		p->loading = FALSE;
		return;
	}
	if(runestrlen(p->url->ctype.r) == 0) /* assume .html when headers don't say anyting */
		goto Html;

	snprint(buf, sizeof(buf), "%S", p->url->ctype.r);
	for(i=0; mimetab[i]!=nil; i++)
		if(cistrncmp(buf, mimetab[i], strlen(mimetab[i])) == 0)
			break;

	if(mimetab[i]){
    Html:
		ctype = TextHtml;
	}else if(cistrncmp(buf, "text/", 5) == 0)
		ctype = TextPlain;
	else{
		close(fd);
		addrefresh(p, "%S: unsupported mime type: '%S'", p->url->act.r, p->url->ctype.r);
		goto Err;
	}
	addrefresh(p, "loading: %S...", p->url->src.r);
	s = nil;
	l = 0;
	while((n=read(fd, buf, sizeof(buf))) > 0){
		if(p->aborting){
			if(s){
				free(s);
				s = nil;
			}
			break;
		}
		s = erealloc(s, l+n+1);
		memmove(s+l, buf, n);
		l += n;
		s[l] = '\0';
	}
	close(fd);
	n = l;
	if(s){
		s = convert(p->url->ctype, s, &n);
		p->items = parsehtml((uint8_t *)s, n, p->url->act.r, ctype,
				     UTF_8, &p->doc);
		free(s);
		fixtext(p);
		if(ctype==TextHtml && p->aborting==FALSE){
			p->changed = TRUE;
			addrefresh(p, "");
			if(p->doc->doctitle){
				p->title.r = erunestrdup(p->doc->doctitle);
				p->title.nr = runestrlen(p->title.r);
			}
			p->loading = XXX;
			if(p->doc->kidinfo)
				loadchilds(p, p->doc->kidinfo);
			else if(p->doc->images)
				loadimages(p);
		}
	}
	p->changed = TRUE;
	p->loading = FALSE;
	addrefresh(p, "");
}
Пример #27
0
void
waitthread(void *v)
{
	Waitmsg *w;
	Command *c, *lc;
	uint pid;
	int found, ncmd;
	Rune *cmd;
	char *err;
	Text *t;
	Pid *pids, *p, *lastp;
	enum { WErr, WKill, WWait, WCmd, NWALT };
	Alt alts[NWALT+1];

	USED(v);
	threadsetname("waitthread");
	pids = nil;
	alts[WErr].c = cerr;
	alts[WErr].v = &err;
	alts[WErr].op = CHANRCV;
	alts[WKill].c = ckill;
	alts[WKill].v = &cmd;
	alts[WKill].op = CHANRCV;
	alts[WWait].c = cwait;
	alts[WWait].v = &w;
	alts[WWait].op = CHANRCV;
	alts[WCmd].c = ccommand;
	alts[WCmd].v = &c;
	alts[WCmd].op = CHANRCV;
	alts[NWALT].op = CHANEND;

	command = nil;
	for(;;){
		switch(alt(alts)){
		case WErr:
			qlock(&row.lk);
			warning(nil, "%s", err);
			free(err);
			flushimage(display, 1);
			qunlock(&row.lk);
			break;
		case WKill:
			found = FALSE;
			ncmd = runestrlen(cmd);
			for(c=command; c; c=c->next){
				/* -1 for blank */
				if(runeeq(c->name, c->nname-1, cmd, ncmd) == TRUE){
					if(postnote(PNGROUP, c->pid, "kill") < 0)
						warning(nil, "kill %S: %r\n", cmd);
					found = TRUE;
				}
			}
			if(!found)
				warning(nil, "Kill: no process %S\n", cmd);
			free(cmd);
			break;
		case WWait:
			pid = w->pid;
			lc = nil;
			for(c=command; c; c=c->next){
				if(c->pid == pid){
					if(lc)
						lc->next = c->next;
					else
						command = c->next;
					break;
				}
				lc = c;
			}
			qlock(&row.lk);
			t = &row.tag;
			textcommit(t, TRUE);
			if(c == nil){
				/* helper processes use this exit status */
				if(strncmp(w->msg, "libthread", 9) != 0){
					p = emalloc(sizeof(Pid));
					p->pid = pid;
					strncpy(p->msg, w->msg, sizeof(p->msg));
					p->next = pids;
					pids = p;
				}
			}else{
				if(search(t, c->name, c->nname)){
					textdelete(t, t->q0, t->q1, TRUE);
					textsetselect(t, 0, 0);
				}
				if(w->msg[0])
					warning(c->md, "%.*S: exit %s\n", c->nname-1, c->name, w->msg);
				flushimage(display, 1);
			}
			qunlock(&row.lk);
			free(w);
    Freecmd:
			if(c){
				if(c->iseditcmd)
					sendul(cedit, 0);
				free(c->text);
				free(c->name);
				fsysdelid(c->md);
				free(c);
			}
			break;
		case WCmd:
			/* has this command already exited? */
			lastp = nil;
			for(p=pids; p!=nil; p=p->next){
				if(p->pid == c->pid){
					if(p->msg[0])
						warning(c->md, "%s\n", p->msg);
					if(lastp == nil)
						pids = p->next;
					else
						lastp->next = p->next;
					free(p);
					goto Freecmd;
				}
				lastp = p;
			}
			c->next = command;
			command = c;
			qlock(&row.lk);
			t = &row.tag;
			textcommit(t, TRUE);
			textinsert(t, 0, c->name, c->nname, TRUE);
			textsetselect(t, 0, 0);
			flushimage(display, 1);
			qunlock(&row.lk);
			break;
		}
	}
}
Пример #28
0
void
render(URLwin *u, Bytes *t, Item *items, int curanchor)
{
	Item *il;
	Itext *it;
	Ifloat *ifl;
	Ispacer *is;
	Itable *ita;
	Iimage *im;
	Anchor *a;
	Table *tab;
	Tablecell *cell;
	char *href;

	inword = 0;
	col = 0;
	wordi = 0;

	for(il=items; il!=nil; il=il->next){
		if(il->state & IFbrk)
			renderbytes(t, "\n");
		if(il->state & IFbrksp)
			renderbytes(t, "\n");

		switch(il->tag){
		case Itexttag:
			it = (Itext*)il;
			if(it->state & IFwrap)
				renderrunes(t, it->s);
			else
				emitword(t, it->s, runestrlen(it->s));
			break;
		case Iruletag:
			if(t->n>0 && t->b[t->n-1]!='\n')
				renderbytes(t, "\n");
			renderbytes(t, "=======\n");
			break;
		case Iimagetag:
			if(!aflag)
				break;
			im = (Iimage*)il;
			if(im->imsrc){
				href = fullurl(u, im->imsrc);
				renderbytes(t, "[image %s]", href);
				free(href);
			}
			break;
		case Iformfieldtag:
			if(aflag)
				renderbytes(t, "[formfield]");
			break;
		case Itabletag:
			ita = (Itable*)il;
			tab = ita->table;
			for(cell=tab->cells; cell!=nil; cell=cell->next){
				render(u, t, cell->content, curanchor);
			}
			if(t->n>0 && t->b[t->n-1]!='\n')
				renderbytes(t, "\n");
			break;
		case Ifloattag:
			ifl = (Ifloat*)il;
			render(u, t, ifl->item, curanchor);
			break;
		case Ispacertag:
			is = (Ispacer*)il;
			if(is->spkind != ISPnull)
				renderbytes(t, " ");
			break;
		default:
			error("unknown item tag %d\n", il->tag);
		}
		if(il->anchorid != 0 && il->anchorid!=curanchor){
			for(a=u->docinfo->anchors; a!=nil; a=a->next)
				if(aflag && a->index == il->anchorid){
					href = fullurl(u, a->href);
					renderbytes(t, "[%s]", href);
					free(href);
					break;
				}
			curanchor = il->anchorid;
		}
	}
	if(t->n>0 && t->b[t->n-1]!='\n')
		renderbytes(t, "\n");
}
Пример #29
0
void
wkeyctl(Window *w, Rune r)
{

	uint q0;

	if(r == 0)
		return;
	if(w->deleted)
		return;
	fprint(2, "wkyctl: skipping all ctl chars\n");
#if 0
	uint q0 ,q1;
	int n, nb, nr;

	Rune *rp;
	int *notefd;
	/* navigation keys work only when mouse is not open */
	if(!w->mouseopen)
		switch(r){
		case Kdown:
			n = w->maxlines/3;
			goto case_Down;
		case Kscrollonedown:
			n = mousescrollsize(w->maxlines);
			if(n <= 0)
				n = 1;
			goto case_Down;
		case Kpgdown:
			n = 2*w->maxlines/3;
		case_Down:
			q0 = w->org+frcharofpt(w, Pt(w->Frame.r.min.x, w->Frame.r.min.y+n*w->font->height));
			wsetorigin(w, q0, TRUE);
			return;
		case Kup:
			n = w->maxlines/3;
			goto case_Up;
		case Kscrolloneup:
			n = mousescrollsize(w->maxlines);
			if(n <= 0)
				n = 1;
			goto case_Up;
		case Kpgup:
			n = 2*w->maxlines/3;
		case_Up:
			q0 = wbacknl(w, w->org, n);
			wsetorigin(w, q0, TRUE);
			return;
		case Kleft:
			if(w->q0 > 0){
				q0 = w->q0-1;
				wsetselect(w, q0, q0);
				wshow(w, q0);
			}
			return;
		case Kright:
			if(w->q1 < w->nr){
				q1 = w->q1+1;
				wsetselect(w, q1, q1);
				wshow(w, q1);
			}
			return;
		case Khome:
			wshow(w, 0);
			return;
		case Kend:
			wshow(w, w->nr);
			return;
		case 0x01:	/* ^A: beginning of line */
			if(w->q0==0 || w->q0==w->qh || w->run[w->q0-1]=='\n')
				return;
			nb = wbswidth(w, 0x15 /* ^U */);
			wsetselect(w, w->q0-nb, w->q0-nb);
			wshow(w, w->q0);
			return;
		case 0x05:	/* ^E: end of line */
			q0 = w->q0;
			while(q0 < w->nr && w->run[q0]!='\n')
				q0++;
			wsetselect(w, q0, q0);
			wshow(w, w->q0);
			return;
		}
	if(w->rawing && (w->q0==w->nr || w->mouseopen)){
		waddraw(w, &r, 1);
		return;
	}
	if(r==0x1B || (w->holding && r==0x7F)){	/* toggle hold */
		if(w->holding)
			--w->holding;
		else
			w->holding++;
		wrepaint(w);
		if(r == 0x1B)
			return;
	}
	if(r != 0x7F){
		wsnarf(w);
		wcut(w);
	}
	switch(r){
	case 0x7F:		/* send interrupt */
		w->qh = w->nr;
		wshow(w, w->qh);
		notefd = emalloc(sizeof(int));
		*notefd = w->notefd;
		proccreate(interruptproc, notefd, 4096);
		return;
	case 0x06:	/* ^F: file name completion */
	case Kins:		/* Insert: file name completion */
		rp = namecomplete(w);
		if(rp == nil)
			return;
		nr = runestrlen(rp);
		q0 = w->q0;
		q0 = winsert(w, rp, nr, q0);
		wshow(w, q0+nr);
		free(rp);
		return;
	case 0x08:	/* ^H: erase character */
	case 0x15:	/* ^U: erase line */
	case 0x17:	/* ^W: erase word */
		if(w->q0==0 || w->q0==w->qh)
			return;
		nb = wbswidth(w, r);
		q1 = w->q0;
		q0 = q1-nb;
		if(q0 < w->org){
			q0 = w->org;
			nb = q1-q0;
		}
		if(nb > 0){
			wdelete(w, q0, q0+nb);
			wsetselect(w, q0, q0);
		}
		return;
	}

	wshow(w, q0+1);
#endif
	/* otherwise ordinary character; just insert */
	q0 = w->q0;
	q0 = winsert(w, &r, 1, q0);
}
Пример #30
0
void
texttype(Text *t, Rune r)
{
	uint q0, q1;
	int nnb, nb, n, i;
	int nr;
	Rune *rp;
	Text *u;

	if(t->what!=Body && r=='\n')
		return;
	nr = 1;
	rp = &r;
	switch(r){
	case Kleft:
		if(t->q0 > 0){
			typecommit(t);
			textshow(t, t->q0-1, t->q0-1, TRUE);
		}
		return;
	case Kright:
		if(t->q1 < t->file->nc){
			typecommit(t);
			textshow(t, t->q1+1, t->q1+1, TRUE);
		}
		return;
	case Kdown:
		n = t->maxlines/3;
		goto case_Down;
	case Kscrollonedown:
		n = mousescrollsize(t->maxlines);
		if(n <= 0)
			n = 1;
		goto case_Down;
	case Kpgdown:
		n = 2*t->maxlines/3;
	case_Down:
		q0 = t->org+frcharofpt(t, Pt(t->r.min.x, t->r.min.y+n*t->font->height));
		textsetorigin(t, q0, TRUE);
		return;
	case Kup:
		n = t->maxlines/3;
		goto case_Up;
	case Kscrolloneup:
		n = mousescrollsize(t->maxlines);
		goto case_Up;
	case Kpgup:
		n = 2*t->maxlines/3;
	case_Up:
		q0 = textbacknl(t, t->org, n);
		textsetorigin(t, q0, TRUE);
		return;
	case Khome:
		typecommit(t);
		textshow(t, 0, 0, FALSE);
		return;
	case Kend:
		typecommit(t);
		textshow(t, t->file->nc, t->file->nc, FALSE);
		return;
	case 0x01:	/* ^A: beginning of line */
		typecommit(t);
		/* go to where ^U would erase, if not already at BOL */
		nnb = 0;
		if(t->q0>0 && textreadc(t, t->q0-1)!='\n')
			nnb = textbswidth(t, 0x15);
		textshow(t, t->q0-nnb, t->q0-nnb, TRUE);
		return;
	case 0x05:	/* ^E: end of line */
		typecommit(t);
		q0 = t->q0;
		while(q0<t->file->nc && textreadc(t, q0)!='\n')
			q0++;
		textshow(t, q0, q0, TRUE);
		return;
	}
	if(t->what == Body){
		seq++;
		filemark(t->file);
	}
	if(t->q1 > t->q0){
		if(t->ncache != 0)
			error("text.type");
		cut(t, t, nil, TRUE, TRUE, nil, 0);
		t->eq0 = ~0;
	}
	textshow(t, t->q0, t->q0, 1);
	switch(r){
	case 0x06:
	case Kins:
		rp = textcomplete(t);
		if(rp == nil)
			return;
		nr = runestrlen(rp);
		break;	/* fall through to normal insertion case */
	case 0x1B:
		if(t->eq0 != ~0)
			textsetselect(t, t->eq0, t->q0);
		if(t->ncache > 0)
			typecommit(t);
		return;
	case 0x08:	/* ^H: erase character */
	case 0x15:	/* ^U: erase line */
	case 0x17:	/* ^W: erase word */
		if(t->q0 == 0)	/* nothing to erase */
			return;
		nnb = textbswidth(t, r);
		q1 = t->q0;
		q0 = q1-nnb;
		/* if selection is at beginning of window, avoid deleting invisible text */
		if(q0 < t->org){
			q0 = t->org;
			nnb = q1-q0;
		}
		if(nnb <= 0)
			return;
		for(i=0; i<t->file->ntext; i++){
			u = t->file->text[i];
			u->nofill = TRUE;
			nb = nnb;
			n = u->ncache;
			if(n > 0){
				if(q1 != u->cq0+n)
					error("text.type backspace");
				if(n > nb)
					n = nb;
				u->ncache -= n;
				textdelete(u, q1-n, q1, FALSE);
				nb -= n;
			}
			if(u->eq0==q1 || u->eq0==~0)
				u->eq0 = q0;
			if(nb && u==t)
				textdelete(u, q0, q0+nb, TRUE);
			if(u != t)
				textsetselect(u, u->q0, u->q1);
			else
				textsetselect(t, q0, q0);
			u->nofill = FALSE;
		}
		for(i=0; i<t->file->ntext; i++)
			textfill(t->file->text[i]);
		return;
	case '\n':
		if(t->w->autoindent){
			/* find beginning of previous line using backspace code */
			nnb = textbswidth(t, 0x15); /* ^U case */
			rp = runemalloc(nnb + 1);
			nr = 0;
			rp[nr++] = r;
			for(i=0; i<nnb; i++){
				r = textreadc(t, t->q0-nnb+i);
				if(r != ' ' && r != '\t')
					break;
				rp[nr++] = r;
			}
		}
		break; /* fall through to normal code */
	}
	/* otherwise ordinary character; just insert, typically in caches of all texts */
	for(i=0; i<t->file->ntext; i++){
		u = t->file->text[i];
		if(u->eq0 == ~0)
			u->eq0 = t->q0;
		if(u->ncache == 0)
			u->cq0 = t->q0;
		else if(t->q0 != u->cq0+u->ncache)
			error("text.type cq1");
		textinsert(u, t->q0, rp, nr, FALSE);
		if(u != t)
			textsetselect(u, u->q0, u->q1);
		if(u->ncache+nr > u->ncachealloc){
			u->ncachealloc += 10 + nr;
			u->cache = runerealloc(u->cache, u->ncachealloc);
		}
		runemove(u->cache+u->ncache, rp, nr);
		u->ncache += nr;
	}
	if(rp != &r)
		free(rp);
	textsetselect(t, t->q0+nr, t->q0+nr);
	if(r=='\n' && t->w!=nil)
		wincommit(t->w, t);
}