Ejemplo n.º 1
0
Subfont*
_getsubfont(Display *d, char *name)
{
	int fd;
	Subfont *f;

	fd = libopen(name, OREAD);
		
	if(fd < 0){
		_drawprint(2, "getsubfont: can't open %s: %r\n", name);
		return 0;
	}
	/*
	 * unlock display so i/o happens with display released, unless
	 * user is doing his own locking, in which case this could break things.
	 * _getsubfont is called only from string.c and stringwidth.c,
	 * which are known to be safe to have this done.
	 */
	if(d->local == 0)
		unlockdisplay(d);
	f = readsubfont(d, name, fd, d->local == 0);
	if(d->local == 0)
		lockdisplay(d);
	if(f == 0)
		_drawprint(2, "getsubfont: can't read %s: %r\n", name);
	libclose(fd);
	return f;
}
Ejemplo n.º 2
0
/*
 * return bounding box of character at index, in coords relative to
 * the top left position of the text.
 */
static Rectangle
tkentrybbox(Tk *tk, int index)
{
	TkEntry *tke;
	TkEnv *env;
	Display *d;
	int x, cw, locked;
	Rectangle r;

	tke = TKobj(TkEntry, tk);
	env = tk->env;

	d = env->top->display;

	locked = lockdisplay(d);
	x = entrytextwidth(tk, index);
	if (index < tke->textlen)
		cw = entrytextwidth(tk, index+1) - x;
	else
		cw = Inswidth;
	if(locked)
		unlockdisplay(d);

	r.min.x = x;
	r.min.y = 0;
	r.max.x = x + cw;
	r.max.y = env->font->height;
	return r;
}
Ejemplo n.º 3
0
static char*
tkentryicursor(Tk *tk, char *arg, char **val)
{
	TkEntry *tke = TKobj(TkEntry, tk);
	int index, locked;
	char *r, *buf;

	USED(val);
	buf = mallocz(Tkmaxitem, 0);
	if(buf == nil)
		return TkNomem;
	tkword(tk->env->top, arg, buf, buf+Tkmaxitem, nil);
	r = tkentryparseindex(tk, buf, &index);
	free(buf);
	if(r != nil)
		return r;
	tke->icursor = index;
	locked = lockdisplay(tk->env->top->display);
	tke->xicursor = entrytextwidth(tk, tke->icursor);
	if (locked)
		unlockdisplay(tk->env->top->display);

	blinkreset(tk);
	tk->dirty = tkrect(tk, 1);
	return nil;
}
Ejemplo n.º 4
0
Archivo: windw.c Proyecto: 8l/inferno
char*
tkupdate(TkTop *t)
{
	Tk* tk;
	int locked;
	TkWin *tkw;
	Display *d;
	char *e;
	int dirty = 0;
	if(t->noupdate)
		return nil;

	d = t->display;
	locked = lockdisplay(d);
	tk = t->windows;
	while(tk) {
		tkw = TKobj(TkWin, tk);
		if((tk->flag & (Tkmapped|Tksuspended)) == Tkmapped) {
			if (tkupdatewinsize(tk) == 0){
				e = tkdrawslaves(tk, ZP, &dirty);
				if(e != nil)
					return e;
			}
		}
		tk = tkw->next;
	}
	if (dirty || t->dirty) {
		flushimage(d, 1);
		t->dirty = 0;
	}
	if(locked)
		unlockdisplay(d);
	return nil;
}
Ejemplo n.º 5
0
Archivo: label.c Proyecto: 8l/inferno
void
tkfreelabel(Tk *tk)
{
	Image *i;
	int locked;
	Display *d;
	TkLabel *tkl;

	tkl = TKobj(TkLabel, tk);

	if(tkl->text != nil)
		free(tkl->text);
	if(tkl->command != nil)
		free(tkl->command);
	if(tkl->value != nil)
		free(tkl->value);
	if(tkl->variable != nil) {
		tkfreevar(tk->env->top, tkl->variable, tk->flag & Tkswept);
		free(tkl->variable);
	}
	if(tkl->img != nil)
		tkimgput(tkl->img);
	i = tkl->bitmap;
	if(i != nil) {
		d = i->display;
		locked = lockdisplay(d);
		freeimage(i);
		if(locked)
			unlockdisplay(d);
	}
	if(tkl->menu != nil)
		free(tkl->menu);
}
Ejemplo n.º 6
0
static char*
tkentryb1p(Tk *tk, char* arg, char **ret)
{
	TkEntry *tke = TKobj(TkEntry, tk);
	Point p;
	int i, locked, x;
	char buf[32], *e;
	USED(ret);

	x = atoi(arg);
	p = tkscrn2local(tk, Pt(x, 0));
	sprint(buf, "@%d", p.x);
	e = tkentryparseindex(tk, buf, &i);
	if (e != nil)
		return e;
	tke->sel0 = 0;
	tke->sel1 = 0;
	tke->icursor = i;
	tke->anchor = i;
	tke->flag &= ~Ewordsel;

	locked = lockdisplay(tk->env->top->display);
	tke->xsel0 = 0;
	tke->xsel1 = 0;
	tke->xicursor = entrytextwidth(tk, tke->icursor);
	if (locked)
		unlockdisplay(tk->env->top->display);

	tke->oldx = x;
	blinkreset(tk);
	tkrepeat(tk, autoselect, nil, TkRptpause, TkRptinterval);
	tk->dirty = tkrect(tk, 0);
	return nil;
}
Ejemplo n.º 7
0
Archivo: ctext.c Proyecto: 8l/inferno
int
tkcvstextsrch(TkCitem *i, int x, int y)
{
	TkCtext *t;
	Font *font;
	Display *d;
	char *p, *next;
	int n, len, locked;

	t = TKobj(TkCtext, i);

	n = 0;
	font = i->env->font;
	d = i->env->top->display;
	p = t->text;
	if(p == nil)
		return 0;
	while(*p) {
		next = tkcvstextgetl(t, font, p, &len);
		if(y <= font->height) {
			locked = lockdisplay(d);
			for(n = 0; n < len && x > stringnwidth(font, p, n+1); n++)
				;
			if(locked)
				unlockdisplay(d);
			break;
		}
		y -= font->height;
		p = next;
	}	
	return p - t->text + n;
}
Ejemplo n.º 8
0
Archivo: crect.c Proyecto: 8l/inferno
static void
tkmkstipple(Image *stipple)
{
	int locked;
	if (stipple != nil && !stipple->repl) {
		locked = lockdisplay(stipple->display);
		replclipr(stipple, 1, huger);
		if (locked)
			unlockdisplay(stipple->display);
	}
}
Ejemplo n.º 9
0
void
timeproc(void *dummy)
{
	for(;;){
		lockdisplay(display);
		drawtime();
		updatetimes();
		flushimage(display, 1);
		unlockdisplay(display);
		sleep(60000);
		setdate();
	}
}
Ejemplo n.º 10
0
void
resizethread(void *v)
{
	USED(v);

	while(recv(mc->resizec, 0) == 1){
		lockdisplay(display);
		if(getwindow(display, Refnone) < 0)
			sysfatal("attach to window: %r");
		resize();
		unlockdisplay(display);
	}
}
Ejemplo n.º 11
0
void
threadmain(int argc, char **argv)
{
	char *p;
	int lfd;

	p = "300x40@100,100";
	
	ARGBEGIN{
	case 'W':
		p = ARGF();
		break;
	case 't':
		textmode = 1;
		break;
	case 'k':
		nokill = 1;
		break;
	default:
		usage();
	}ARGEND;

	if(argc != 1)
		usage();

	winsize = p;

	title = argv[0];

	lfd = dup(0, -1);
	Binit(&b, lfd, OREAD);

	rbar = Rect(0, 0, 60, 1);
	if (!textmode){
		if(initdraw(0, nil, "bar") < 0)
			sysfatal("initdraw: %r");
		initcolor();
		if((mc = initmouse(nil, screen)) == nil)
			sysfatal("initmouse: %r");
		if((kc = initkeyboard(nil)) == nil)
			sysfatal("initkeyboard: %r");
		display->locking = 1;
		threadcreate(resizethread, nil, STACK);
		threadcreate(keyboardthread, nil, STACK);
		threadcreate(mousethread, nil, STACK);
		resize();
		unlockdisplay(display);
	}
	proccreate(updateproc, nil, STACK);
}
Ejemplo n.º 12
0
Archivo: main.c Proyecto: 99years/plan9
void
timeproc(void)
{
	for(;;){
		lockdisplay(display);
		drawtime();
		updatetimes();
		flushimage(display, 1);
		unlockdisplay(display);
		now = time(nil);
		sleep(((60 - now%60) + 1)*1000); /* wait for minute to change */
		setdate();
	}
}
Ejemplo n.º 13
0
Archivo: canvs.c Proyecto: 8l/inferno
void
tkfreecanv(Tk *tk)
{
	Display *d;
	int j, locked;
	TkCanvas *c;
	TkName *n, *nn;
	TkCtag *t, *tt;
	TkCitem *i, *next;

	c = TKobj(TkCanvas, tk);
	for(i = c->head; i; i = next) {
		next = i->next;
		tkcvsfreeitem(i);
	}

	if(c->xscroll != nil)
		free(c->xscroll);
	if(c->yscroll != nil)
		free(c->yscroll);

	for(j = 0; j < TkChash; j++) {
		for(n = c->thash[j]; n; n = nn) {
			nn = n->link;
			for(t = n->obj; t; t = tt) {
				tt = t->taglist;
				free(t);
			}
			tkfreebind(n->prop.binds);
			free(n);
		}
	}

	free(c->current);

	if((c->ialloc && c->image != nil) || c->mask != nil) {
		if (c->ialloc && c->image != nil)
			d = c->image->display;
		else
			d = c->mask->display;
		locked = lockdisplay(d);
		if (c->image != nil && c->ialloc)
			freeimage(c->image);
		if (c->mask != nil)
			freeimage(c->mask);
		if(locked)
			unlockdisplay(d);
	}
}
Ejemplo n.º 14
0
Archivo: canvs.c Proyecto: 8l/inferno
void
tkcvsfreeitem(TkCitem *i)
{
	int locked;
	Display *d;

	d = i->env->top->display;

	locked = lockdisplay(d);
	tkcimethod[i->type].free(i);
	if(locked)
		unlockdisplay(d);

	tkfreepoint(&i->p);
	tkputenv(i->env);
	free(i);
}
Ejemplo n.º 15
0
void
addface(Face *f)	/* always adds at 0 */
{
	Face **ofaces;
	Rectangle r0, r1, r;
	int y, nx, ny;

	if(f == nil)
		return;
	if(first != 0){
		first = 0;
		eresized(0);
	}
	findbit(f);

	nx = nacross;
	ny = (nfaces+(nx-1)) / nx;

	lockdisplay(display);
	for(y=ny; y>=0; y--){
		/* move them along */
		r0 = facerect(y*nx+0);
		r1 = facerect(y*nx+1);
		r = r1;
		r.max.x = r.min.x + (nx - 1)*(Facesize+Facesep);
		draw(screen, r, screen, nil, r0.min);
		/* copy one down from row above */
		if(y != 0){
			r = facerect((y-1)*nx+nx-1);
			draw(screen, r0, screen, nil, r.min);
		}
	}

	ofaces = faces;
	faces = emalloc((nfaces+1)*sizeof(Face*));
	memmove(faces+1, ofaces, nfaces*(sizeof(Face*)));
	free(ofaces);
	nfaces++;
	setlast();
	drawarrows();
	faces[0] = f;
	drawface(f, 0);
	flushimage(display, 1);
	unlockdisplay(display);
}
Ejemplo n.º 16
0
Image*
cachedpage(Document *doc, int angle, int page)
{
	static int lastpage = -1;
	static int rabusy;
	Image *im;
	int ra;

	if(doc->npage < 1)
		return display->white;

	im = _cachedpage(doc, angle, page, "");
	if(im == nil)
		return nil;

	/* readahead */
	ra = -1;
	if(!rabusy){
		if(page == lastpage+1)
			ra = page+1;
		else if(page == lastpage-1)
			ra = page-1;
	}
	lastpage = page;
	if(ra >= 0){
		rabusy = 1;
		switch(rfork(RFPROC|RFMEM|RFNOWAIT)){
		case -1:
			rabusy = 0;
			break;
		case 0:
			lockdisplay(display);
			_cachedpage(doc, angle, ra, "-ra");
			rabusy = 0;
			unlockdisplay(display);
			_exits(nil);
		default:
			break;
		}
	}
	return im;
}
Ejemplo n.º 17
0
Archivo: ctext.c Proyecto: 8l/inferno
void
tkcvstextsize(TkCitem *i)
{
	Point o;
	Font *font;
	TkCtext *t;
	Display *d;
	char *next, *p;
	int len, pixw, locked;

	t = TKobj(TkCtext, i);

	font = i->env->font;
	d = i->env->top->display;
	t->pixwidth = 0;
	t->pixheight = 0;

	p = t->text;
	if(p != nil) {
		locked = lockdisplay(d);
		while(*p) {
			next = tkcvstextgetl(t, font, p, &len);
			pixw = stringnwidth(font, p, len);
			if(pixw > t->pixwidth)
				t->pixwidth = pixw;
			t->pixheight += font->height;
			p = next;
		}
		if(locked)
			unlockdisplay(d);
	}

	o = tkcvsanchor(i->p.drawpt[0], t->pixwidth, t->pixheight, t->anchor);

	i->p.bb.min.x = o.x;
	i->p.bb.min.y = o.y - Cvsicursor;
	i->p.bb.max.x = o.x + t->pixwidth;
	i->p.bb.max.y = o.y + t->pixheight + Cvsicursor;
	i->p.bb = insetrect(i->p.bb, -2*t->sbw);
	t->anchorp = subpt(o, i->p.drawpt[0]);
}
Ejemplo n.º 18
0
Archivo: windw.c Proyecto: 8l/inferno
void
tkfreectxt(TkCtxt *c)
{
	int locked;
	Display *d;

	if(c == nil)
		return;

	tkextnfreectxt(c);

	d = c->display;
	locked = lockdisplay(d);
	tkfreecolcache(c);
	freeimage(c->i);
	freeimage(c->ia);
	if(locked)
		unlockdisplay(d);
	libqlfree(c->lock);
	free(c);
}
Ejemplo n.º 19
0
void
updateproc(void *v)
{
	char *p, *f[2];

	sleep(1000);
	while((p = Brdline(&b, '\n'))){
		p[Blinelen(&b)-1] = '\0';
		if(tokenize(p, f, 2) != 2)
			continue;
		n = strtoll(f[0], 0, 0);
		d = strtoll(f[1], 0, 0);
		if(!textmode){
			lockdisplay(display);
			drawbar();
			unlockdisplay(display);
		} else
			drawbar();
	}
	threadexitsall("success");
}
Ejemplo n.º 20
0
/*
 * recalculate derived values
 */
static void
recalcentry(Tk *tk)
{
	TkEntry *tke = TKobj(TkEntry, tk);
	int x, avail, locked;

	locked = lockdisplay(tk->env->top->display);

	tke->xlen = entrytextwidth(tk, tke->textlen) + Inswidth;

	avail = tk->act.width - 2*xinset(tk);
	if (tke->xlen < avail) {
		switch(tke->flag & Ejustify) {
		default:
			tke->x0 = 0;
			break;
		case Eright:
			tke->x0 = -(avail - tke->xlen);
			break;
		case Ecenter:
			tke->x0 = -(avail - tke->xlen) / 2;
			break;
		}
	}

	tke->v0 = x2index(tk, tke->x0, &tke->xv0);
	tke->v1 = x2index(tk, tk->act.width + tke->x0, &x);
	/* perhaps include partial last character */
	if (tke->v1 < tke->textlen && x < avail + tke->x0)
		tke->v1++;
	tke->xsel0 = entrytextwidth(tk, tke->sel0);
	tke->xsel1 = entrytextwidth(tk, tke->sel1);
	tke->xicursor = entrytextwidth(tk, tke->icursor);

	if (locked)
		unlockdisplay(tk->env->top->display);
}
Ejemplo n.º 21
0
static void
resize(Vnc *v, int first)
{
    int fd;
    Point d;

    d = addpt(v->dim, Pt(2*Borderwidth, 2*Borderwidth));
    lockdisplay(display);

    if(getwindow(display, Refnone) < 0)
        sysfatal("internal error: can't get the window image");

    /*
     * limit the window to at most the vnc server's size
     */
    if(first || d.x < Dx(screen->r) || d.y < Dy(screen->r)) {
        fd = open("/dev/wctl", OWRITE);
        if(fd >= 0) {
            fprint(fd, "resize -dx %d -dy %d", d.x, d.y);
            close(fd);
        }
    }
    unlockdisplay(display);
}
Ejemplo n.º 22
0
static char*
tkentryinsert(Tk *tk, char *arg, char **val)
{
	TkTop *top;
	TkEntry *tke;
	int ins, i, n, locked;
	char *e, *t, *text, *buf;
	Rune *etext;

	USED(val);
	tke = TKobj(TkEntry, tk);

	top = tk->env->top;
	buf = mallocz(Tkmaxitem, 0);
	if(buf == nil)
		return TkNomem;
	arg = tkword(top, arg, buf, buf+Tkmaxitem, nil);
	e = tkentryparseindex(tk, buf, &ins);
	free(buf);
	if(e != nil)
		return e;

	if(*arg == '\0')
		return nil;

	n = strlen(arg) + 1;
	if(n < Tkmaxitem)
		n = Tkmaxitem;
	text = malloc(n);
	if(text == nil)
		return TkNomem;

	tkword(top, arg, text, text+n, nil);
	n = utflen(text);
	etext = realloc(tke->text, (tke->textlen+n+1)*sizeof(Rune));
	if(etext == nil) {
		free(text);
		return TkNomem;
	}
	tke->text = etext;

	memmove(tke->text+ins+n, tke->text+ins, (tke->textlen-ins)*sizeof(Rune));
	t = text;
	for(i=0; i<n; i++)
		t += chartorune(tke->text+ins+i, t);
	free(text);

	tke->textlen += n;

	tke->sel0 = adjustforins(ins, n, tke->sel0);
	tke->sel1 = adjustforins(ins, n, tke->sel1);
	tke->icursor = adjustforins(ins, n, tke->icursor);
	tke->anchor = adjustforins(ins, n, tke->anchor);

	locked = lockdisplay(tk->env->top->display);
	if (ins < tke->v0)
		tke->x0 += entrytextwidth(tk, tke->v0 + n) + (tke->x0 - tke->xv0);
	if (locked)
		unlockdisplay(tk->env->top->display);
	recalcentry(tk);

	e = tkentrysh(tk);
	blinkreset(tk);
	tk->dirty = tkrect(tk, 1);

	return e;
}
Ejemplo n.º 23
0
void
main(int argc, char **argv)
{
	int p, fd, dfd, cfd, shared;
	char *keypattern, *addr;
	Point d;
	TLSconn conn;

	keypattern = nil;
	shared = 0;
	ARGBEGIN{
	case 'c':
		bpp12 = 1;
		break;
	case 'e':
		encodings = EARGF(usage());
		break;
	case 's':
		shared = 1;
		break;
	case 't':
		tls = 1;
		break;
	case 'v':
		verbose = 1;
		break;
	case 'k':
		keypattern = EARGF(usage());
		break;
	default:
		usage();
	}ARGEND;

	if(argc != 1)
		usage();

	addr = netmkvncaddr(argv[0]);
	serveraddr = argv[0];
	dfd = dial(addr, nil, nil, &cfd);
	if(dfd < 0)
		sysfatal("cannot dial %s: %r", addr);
	if(tls){
		dfd = tlsClient(dfd, &conn);
		if(dfd < 0)
			sysfatal("tlsClient: %r");
		/* XXX check thumbprint */
	}
	vnc = vncinit(dfd, cfd, nil);

	if(vnchandshake(vnc) < 0)
		sysfatal("handshake failure: %r");
	if(vncauth(vnc, keypattern) < 0)
		sysfatal("authentication failure: %r");
	if(vncstart(vnc, shared) < 0)
		sysfatal("init failure: %r");

	initdraw(0, 0, "vncv");
	display->locking = 1;
	unlockdisplay(display);

	d = addpt(vnc->dim, Pt(2*Borderwidth, 2*Borderwidth));
	if(verbose)
		fprint(2, "screen size %P, desktop size %P\n", display->image->r.max, d);

	choosecolor(vnc);
	sendencodings(vnc);
	initmouse();

	rfork(RFREND);
	atexit(shutdown);
	pids[0] = getpid();

	switch(p = rfork(RFPROC|RFMEM)){
	case -1:
		sysfatal("rfork: %r");
	default:
		break;
	case 0:
		atexit(shutdown);
		readfromserver(vnc);
		exits(nil);
	}
	pids[1] = p;

	switch(p = rfork(RFPROC|RFMEM)){
	case -1:
		sysfatal("rfork: %r");
	default:
		break;
	case 0:
		atexit(shutdown);
		checksnarf(vnc);
		exits(nil);
	}
	pids[2] = p;

	fd = open("/dev/label", OWRITE);
	if(fd >= 0){
		fprint(fd, "vnc %s", serveraddr);
		close(fd);
	}
	if(access("/dev/snarf", AEXIST) >= 0){
		switch(p = rfork(RFPROC|RFMEM)){
		case -1:
			sysfatal("rfork: %r");
		default:
			break;
		case 0:
			atexit(shutdown);
			readkbd(vnc);
			exits(nil);
		}
	}
	pids[3] = p;

	readmouse(vnc);
	exits(nil);
}
Ejemplo n.º 24
0
int
tktdispwidth(Tk *tk, TkTtabstop *tb, TkTitem *i, Font *f, int x, int pos, int nchars)
{
	int w, del, locked;
	TkTtabstop *tbprev;
	Display *d;
	TkText *tkt;
	TkEnv env;

	tkt = TKobj(TkText, tk);
	d = tk->env->top->display;
	if (tb == nil)
		tb = tkt->tabs;

	switch(i->kind) {
	case TkTrune:
		pos = tktutfpos(i->istring, pos);
		/* FALLTHRU */
	case TkTascii:
		if(f == nil) {
			if(!tktanytags(i))
				f = tk->env->font;
			else {
				tkttagopts(tk, i, nil, &env, nil, 1);
				f = env.font;
			}
		}
		locked = 0;
		if(!(tkt->tflag&TkTdlocked))
			locked = lockdisplay(d);
		if(nchars >= 0)
			w = stringnwidth(f, i->istring+pos, nchars);
		else
			w = stringwidth(f, i->istring+pos);
		if(locked)
			unlockdisplay(d);
		break;
	case TkTtab:
		if(tb == nil)
			w = 0;
		else {
			tbprev = nil;
			while(tb->pos <= x && tb->next != nil) {
					tbprev = tb;
					tb = tb->next;
				}
			w = tb->pos - x;
			if(w <= 0) {
				del = tb->pos;
				if(tbprev != nil)
					del -= tbprev->pos;
				while(w <= 0)
					w += del;
			}
			/* todo: other kinds of justification */
		}
		break;
	case TkTwin:
		if(i->iwin->sub == 0)
			w = 0;
		else
			w = i->iwin->sub->act.width + 2*i->iwin->padx + 2*i->iwin->sub->borderwidth;
		break;
	default:
		w = 0;
	}
	return w;
}
Ejemplo n.º 25
0
static void
extract(void)
{
	Slave *s;
	Ebuf *eb;
	int i, n;
	uchar ebuf[EMAXMSG+1];

	/* avoid generating a message if there's nothing to show. */
	/* this test isn't perfect, though; could do flushimage(display, 0) then call extract */
	/* also: make sure we don't interfere if we're multiprocessing the display */
	if(display->locking){
		/* if locking is being done by program, this means it can't depend on automatic flush in emouse() etc. */
		if(canqlock(&display->qlock)){
			if(display->bufp > display->buf)
				flushimage(display, 1);
			unlockdisplay(display);
		}
	}else
		if(display->bufp > display->buf)
			flushimage(display, 1);
loop:
	if((n=read(epipe[0], ebuf, EMAXMSG+1)) < 0
	|| ebuf[0] >= MAXSLAVE)
		drawerror(display, "eof on event pipe");
	if(n == 0)
		goto loop;
	i = ebuf[0];
	if(i >= nslave || n <= 1)
		drawerror(display, "events: protocol error: short read");
	s = &eslave[i];
	if(i == Stimer){
		s->head = (Ebuf *)1;
		return;
	}
	if(i == Skeyboard && n != (1+UTFmax))
		drawerror(display, "events: protocol error: keyboard");
	if(i == Smouse){
		if(n < 1+1+2*12)
			drawerror(display, "events: protocol error: mouse");
		if(ebuf[1] == 'r')
			eresized(1);
		/* squash extraneous mouse events */
		if((eb=s->tail) && memcmp(eb->buf+1+2*12, ebuf+1+1+2*12, 12)==0){
			memmove(eb->buf, &ebuf[1], n - 1);
			return;
		}
	}
	/* try to save space by only allocating as much buffer as we need */
	eb = malloc(sizeof(*eb) - sizeof(eb->buf) + n - 1);
	if(eb == 0)
		drawerror(display, "events: protocol error 4");
	eb->n = n - 1;
	memmove(eb->buf, &ebuf[1], n - 1);
	eb->next = 0;
	if(s->head)
		s->tail->next = eb;
	else
		s->head = eb;
	s->tail = eb;
}
Ejemplo n.º 26
0
void
viewer(Document *dd)
{
	int i, fd, n, oldpage;
	int nxt;
	Menu menu, midmenu;
	Mouse m;
	Event e;
	Point dxy, oxy, xy0;
	Image *tmp;

	static char *fwditems[] = { "this page", "next page", "exit", 0 };
 	static char *miditems[] = {
 		"orig size",
 		"zoom in",
 		"fit window",
 		"rotate 90",
 		"upside down",
 		"",
 		"next",
 		"prev",
		"zerox",
 		"",
 		"reverse",
 		"discard",
 		"write",
 		"",
 		"quit",
 		0
 	};
	char *s;
	enum { Eplumb = 4 };
	Plumbmsg *pm;

	doc = dd;    /* save global for menuhit */
	ul = screen->r.min;
	einit(Emouse|Ekeyboard);
	if(doc->addpage != nil)
		eplumb(Eplumb, "image");

	esetcursor(&reading);

	/*
	 * im is a global pointer to the current image.
	 * eventually, i think we will have a layer between
	 * the display routines and the ps/pdf/whatever routines
	 * to perhaps cache and handle images of different
	 * sizes, etc.
	 */
	im = 0;
	page = reverse ? doc->npage-1 : 0;

	if(doc->fwdonly) {
		menu.item = fwditems;
		menu.gen = 0;
		menu.lasthit = 0;
	} else {
		menu.item = 0;
		menu.gen = menugen;
		menu.lasthit = 0;
	}

	midmenu.item = miditems;
	midmenu.gen = 0;
	midmenu.lasthit = Next;

	if(doc->docname != nil)
		setlabel(doc->docname);
	showpage(page, &menu);
	esetcursor(nil);

	nxt = 0;
	for(;;) {
		/*
		 * throughout, if doc->fwdonly is set, we restrict the functionality
		 * a fair amount.  we don't care about doc->npage anymore, and
		 * all that can be done is select the next page.
		 */
		unlockdisplay(display);
		i = eread(Emouse|Ekeyboard|Eplumb, &e);
		lockdisplay(display);
		switch(i){
		case Ekeyboard:
			if(e.kbdc <= 0xFF && isdigit(e.kbdc)) {
				nxt = nxt*10+e.kbdc-'0';
				break;
			} else if(e.kbdc != '\n')
				nxt = 0;
			switch(e.kbdc) {
			case 'r':	/* reverse page order */
				if(doc->fwdonly)
					break;
				reverse = !reverse;
				menu.lasthit = doc->npage-1-menu.lasthit;

				/*
				 * the theory is that if we are reversing the
				 * document order and are on the first or last
				 * page then we're just starting and really want
		 	 	 * to view the other end.  maybe the if
				 * should be dropped and this should happen always.
				 */
				if(page == 0 || page == doc->npage-1) {
					page = doc->npage-1-page;
					showpage(page, &menu);
				}
				break;
			case 'w':	/* write bitmap of current screen */
				esetcursor(&reading);
				s = writebitmap();
				if(s)
					string(screen, addpt(screen->r.min, Pt(5,5)), display->black, ZP,
						display->defaultfont, s);
				esetcursor(nil);
				flushimage(display, 1);
				break;
			case 'd':	/* remove image from working set */
				if(doc->rmpage && page < doc->npage) {
					if(doc->rmpage(doc, page) >= 0) {
						if(doc->npage < 0)
							wexits(0);
						if(page >= doc->npage)
							page = doc->npage-1;
						showpage(page, &menu);
					}
				}
				break;
			case 'q':
			case 0x04: /* ctrl-d */
				wexits(0);
			case 'u':
				if(im==nil)
					break;
				angle = (angle+180) % 360;
				showpage(page, &menu);
				break;
			case '-':
			case '\b':
			case Kleft:
				if(page > 0 && !doc->fwdonly) {
					--page;
					showpage(page, &menu);
				}
				break;
			case '\n':
				if(nxt) {
					nxt--;
					if(nxt >= 0 && nxt < doc->npage && !doc->fwdonly)
						showpage(page=nxt, &menu);
					nxt = 0;
					break;
				}
				goto Gotonext;
			case Kright:
			case ' ':
			Gotonext:
				if(doc->npage && ++page >= doc->npage && !doc->fwdonly)
					wexits(0);
				showpage(page, &menu);
				break;

			/*
			 * The upper y coordinate of the image is at ul.y in screen->r.
			 * Panning up means moving the upper left corner down.  If the
			 * upper left corner is currently visible, we need to go back a page.
			 */
			case Kup:
				if(screen->r.min.y <= ul.y && ul.y < screen->r.max.y){
					if(page > 0 && !doc->fwdonly){
						--page;
						showbottom = 1;
						showpage(page, &menu);
					}
				} else {
					i = Dy(screen->r)/2;
					if(i > 10)
						i -= 10;
					if(i+ul.y > screen->r.min.y)
						i = screen->r.min.y - ul.y;
					translate(Pt(0, i));
				}
				break;

			/*
			 * If the lower y coordinate is on the screen, we go to the next page.
			 * The lower y coordinate is at ul.y + Dy(im->r).
			 */
			case Kdown:
				i = ul.y + Dy(im->r);
				if(screen->r.min.y <= i && i <= screen->r.max.y){
					ul.y = screen->r.min.y;
					goto Gotonext;
				} else {
					i = -Dy(screen->r)/2;
					if(i < -10)
						i += 10;
					if(i+ul.y+Dy(im->r) <= screen->r.max.y)
						i = screen->r.max.y - Dy(im->r) - ul.y - 1;
					translate(Pt(0, i));
				}
				break;
			default:
				esetcursor(&query);
				sleep(1000);
				esetcursor(nil);
				break;
			}
			break;

		case Emouse:
			m = e.mouse;
			switch(m.buttons){
			case Left:
				oxy = m.xy;
				xy0 = oxy;
				do {
					dxy = subpt(m.xy, oxy);
					oxy = m.xy;
					translate(dxy);
					unlockdisplay(display);
					m = emouse();
					lockdisplay(display);
				} while(m.buttons == Left);
				if(m.buttons) {
					dxy = subpt(xy0, oxy);
					translate(dxy);
				}
				break;

			case Middle:
				if(doc->npage == 0)
					break;

				unlockdisplay(display);
				n = emenuhit(Middle, &m, &midmenu);
				lockdisplay(display);
				if(n == -1)
					break;
				switch(n){
				case Next: 	/* next */
					if(reverse)
						page--;
					else
						page++;
					if(page < 0) {
						if(reverse) return;
						else page = 0;
					}

					if((page >= doc->npage) && !doc->fwdonly)
						return;

					showpage(page, &menu);
					nxt = 0;
					break;
				case Prev:	/* prev */
					if(reverse)
						page++;
					else
						page--;
					if(page < 0) {
						if(reverse) return;
						else page = 0;
					}

					if((page >= doc->npage) && !doc->fwdonly && !reverse)
						return;

					showpage(page, &menu);
					nxt = 0;
					break;
				case Zerox:	/* prev */
					zerox();
					break;
				case Zin:	/* zoom in */
					{
						double delta;
						Rectangle r;

						r = egetrect(Middle, &m);
						if((rectclip(&r, rectaddpt(im->r, ul)) == 0) ||
							Dx(r) == 0 || Dy(r) == 0)
							break;
						/* use the smaller side to expand */
						if(Dx(r) < Dy(r))
							delta = (double)Dx(im->r)/(double)Dx(r);
						else
							delta = (double)Dy(im->r)/(double)Dy(r);

						esetcursor(&reading);
						tmp = xallocimage(display,
								Rect(0, 0, (int)((double)Dx(im->r)*delta), (int)((double)Dy(im->r)*delta)),
								im->chan, 0, DBlack);
						if(tmp == nil) {
							fprint(2, "out of memory during zoom: %r\n");
							wexits("memory");
						}
						resample(im, tmp);
						im = tmp;
						delayfreeimage(tmp);
						esetcursor(nil);
						ul = screen->r.min;
						redraw(screen);
						flushimage(display, 1);
						break;
					}
				case Fit:	/* fit */
					{
						double delta;
						Rectangle r;

						delta = (double)Dx(screen->r)/(double)Dx(im->r);
						if((double)Dy(im->r)*delta > Dy(screen->r))
							delta = (double)Dy(screen->r)/(double)Dy(im->r);

						r = Rect(0, 0, (int)((double)Dx(im->r)*delta), (int)((double)Dy(im->r)*delta));
						esetcursor(&reading);
						tmp = xallocimage(display, r, im->chan, 0, DBlack);
						if(tmp == nil) {
							fprint(2, "out of memory during fit: %r\n");
							wexits("memory");
						}
						resample(im, tmp);
						im = tmp;
						delayfreeimage(tmp);
						esetcursor(nil);
						ul = screen->r.min;
						redraw(screen);
						flushimage(display, 1);
						break;
					}
				case Rot:	/* rotate 90 */
					angle = (angle+90) % 360;
					showpage(page, &menu);
					break;
				case Upside: 	/* upside-down */
					angle = (angle+180) % 360;
					showpage(page, &menu);
					break;
				case Restore:	/* restore */
					showpage(page, &menu);
					break;
				case Reverse:	/* reverse */
					if(doc->fwdonly)
						break;
					reverse = !reverse;
					menu.lasthit = doc->npage-1-menu.lasthit;

					if(page == 0 || page == doc->npage-1) {
						page = doc->npage-1-page;
						showpage(page, &menu);
					}
					break;
				case Write: /* write */
					esetcursor(&reading);
					s = writebitmap();
					if(s)
						string(screen, addpt(screen->r.min, Pt(5,5)), display->black, ZP,
							display->defaultfont, s);
					esetcursor(nil);
					flushimage(display, 1);
					break;
				case Del: /* delete */
					if(doc->rmpage && page < doc->npage) {
						if(doc->rmpage(doc, page) >= 0) {
							if(doc->npage < 0)
								wexits(0);
							if(page >= doc->npage)
								page = doc->npage-1;
							showpage(page, &menu);
						}
					}
					break;
				case Exit:	/* exit */
					return;
				case Empty1:
				case Empty2:
				case Empty3:
					break;

				};



			case Right:
				if(doc->npage == 0)
					break;

				oldpage = page;
				unlockdisplay(display);
				n = emenuhit(RMenu, &m, &menu);
				lockdisplay(display);
				if(n == -1)
					break;

				if(doc->fwdonly) {
					switch(n){
					case 0:	/* this page */
						break;
					case 1:	/* next page */
						showpage(++page, &menu);
						break;
					case 2:	/* exit */
						return;
					}
					break;
				}

				if(n == doc->npage)
					return;
				else
					page = reverse ? doc->npage-1-n : n;

				if(oldpage != page)
					showpage(page, &menu);
				nxt = 0;
				break;
			}
			break;

		case Eplumb:
			pm = e.v;
			if(pm->ndata <= 0){
				plumbfree(pm);
				break;
			}
			if(plumbquit(pm))
				exits(nil);
			if(showdata(pm)) {
				s = estrdup("/tmp/pageplumbXXXXXXX");
				fd = opentemp(s);
				write(fd, pm->data, pm->ndata);
				/* lose fd reference on purpose; the file is open ORCLOSE */
			} else if(pm->data[0] == '/') {
				s = estrdup(pm->data);
			} else {
				s = emalloc(strlen(pm->wdir)+1+pm->ndata+1);
				sprint(s, "%s/%s", pm->wdir, pm->data);
				cleanname(s);
			}
			if((i = doc->addpage(doc, s)) >= 0) {
				page = i;
				unhide();
				showpage(page, &menu);
			}
			free(s);
			plumbfree(pm);
			break;
		}
	}
}
Ejemplo n.º 27
0
static char*
tkentryparseindex(Tk *tk, char *buf, int *index)
{
	TkEntry *tke = TKobj(TkEntry, tk);
	TkEnv *env;
	char *mod;
	int i, x, locked, modstart;

	modstart = 0;
	for(mod = buf; *mod != '\0'; mod++)
		if(*mod == '-' || *mod == '+') {
			modstart = *mod;
			*mod = '\0';
			break;
		}
	if(strcmp(buf, "end") == 0)
		i = tke->textlen;
	else
	if(strcmp(buf, "anchor") == 0)
		i = tke->anchor;
	else
	if(strcmp(buf, "insert") == 0)
		i = tke->icursor;
	else
	if(strcmp(buf, "sel.first") == 0)
		i = tke->sel0;
	else
	if(strcmp(buf, "sel.last") == 0)
		i = tke->sel1;
	else
	if(buf[0] >= '0' && buf[0] <= '9')
		i = atoi(buf);
	else
	if(buf[0] == '@') {
		x = atoi(buf+1) - xinset(tk);
		if(tke->textlen == 0) {
			*index = 0;
			return nil;
		}
		env = tk->env;
		locked = lockdisplay(env->top->display);
		i = x2index(tk, x + tke->x0, nil);	/* XXX could possibly select nearest character? */
		if(locked)
			unlockdisplay(env->top->display);
	}
	else
		return TkBadix;

	if(i < 0 || i > tke->textlen)
		return TkBadix;
	if(modstart) {
		*mod = modstart;
		i += atoi(mod);
		if(i < 0)
			i = 0;
		if(i > tke->textlen)
			i = tke->textlen;
	}
	*index = i;
	return nil;
}
Ejemplo n.º 28
0
static char*
tkentrydelete(Tk *tk, char *arg, char **val)
{
	TkTop *top;
	TkEntry *tke;
	int d0, d1, locked;
	char *e, *buf;
	Rune *text;

	USED(val);

	tke = TKobj(TkEntry, tk);

	top = tk->env->top;
	buf = mallocz(Tkmaxitem, 0);
	if(buf == nil)
		return TkNomem;
	arg = tkword(top, arg, buf, buf+Tkmaxitem, nil);
	e = tkentryparseindex(tk, buf, &d0);
	if(e != nil) {
		free(buf);
		return e;
	}

	d1 = d0+1;
	tkword(top, arg, buf, buf+Tkmaxitem, nil);
	if(buf[0] != '\0') {
		e = tkentryparseindex(tk, buf, &d1);
		if(e != nil) {
			free(buf);
			return e;
		}
	}
	free(buf);
	if(d1 <= d0 || tke->textlen == 0 || d0 >= tke->textlen)
		return nil;

	memmove(tke->text+d0, tke->text+d1, (tke->textlen-d1)*sizeof(Rune));
	tke->textlen -= d1 - d0;

	text = realloc(tke->text, (tke->textlen+1) * sizeof(Rune));
	if (text != nil)
		tke->text = text;
	tke->sel0 = adjustfordel(d0, d1, tke->sel0);
	tke->sel1 = adjustfordel(d0, d1, tke->sel1);
	tke->icursor = adjustfordel(d0, d1, tke->icursor);
	tke->anchor = adjustfordel(d0, d1, tke->anchor);

	locked = lockdisplay(tk->env->top->display);
	if (d1 < tke->v0)
		tke->x0 = entrytextwidth(tk, tke->v0 - (d1 - d0)) + (tke->x0 - tke->xv0);
	else if (d0 < tke->v0)
		tke->x0 = entrytextwidth(tk, d0);
	if (locked)
		unlockdisplay(tk->env->top->display);
	recalcentry(tk);

	e = tkentrysh(tk);
	blinkreset(tk);
	tk->dirty = tkrect(tk, 1);

	return e;
}
Ejemplo n.º 29
0
static int
extract(int canblock)
{
	Ebuf *eb;
	int i, n, max;
	fd_set rset, wset, xset;
	struct timeval tv, *timeout;
	Wsysmsg w;
	vlong t0;

	/*
	 * Flush draw buffer before waiting for responses.
	 * Avoid doing so if buffer is empty.
	 * Also make sure that we don't interfere with app-specific locking.
	 */
	if(display->locking){
		/* 
		 * if locking is being done by program, 
		 * this means it can't depend on automatic 
		 * flush in emouse() etc.
		 */
		if(canqlock(&display->qlock)){
			if(display->bufp > display->buf)
				flushimage(display, 1);
			unlockdisplay(display);
		}
	}else
		if(display->bufp > display->buf)
			flushimage(display, 1);

	/*
	 * Set up for select.
	 */
	FD_ZERO(&rset);
	FD_ZERO(&wset);
	FD_ZERO(&xset);
	max = -1;
	timeout = nil;
	for(i=0; i<nslave; i++){
		if(!eslave[i].inuse)
			continue;
		if(i == Smouse){
			if(eslave[i].rpc == nil)
				eslave[i].rpc = startrpc(Trdmouse);
			if(eslave[i].rpc){
				/* if ready, don't block in select */
				if(eslave[i].rpc->p)
					canblock = 0;
				FD_SET(display->srvfd, &rset);
				FD_SET(display->srvfd, &xset);
				if(display->srvfd > max)
					max = display->srvfd;
			}
		}else if(i == Skeyboard){
			if(eslave[i].rpc == nil)
				eslave[i].rpc = startrpc(Trdkbd);
			if(eslave[i].rpc){
				/* if ready, don't block in select */
				if(eslave[i].rpc->p)
					canblock = 0;
				FD_SET(display->srvfd, &rset);
				FD_SET(display->srvfd, &xset);
				if(display->srvfd > max)
					max = display->srvfd;
			}
		}else if(i == Stimer){
			t0 = nsec();
			if(t0 >= eslave[i].nexttick){
				tv.tv_sec = 0;
				tv.tv_usec = 0;
			}else{
				tv.tv_sec = (eslave[i].nexttick-t0)/1000000000;
				tv.tv_usec = (eslave[i].nexttick-t0)%1000000000 / 1000;
			}
			timeout = &tv;
		}else{
			FD_SET(eslave[i].fd, &rset);
			FD_SET(eslave[i].fd, &xset);
			if(eslave[i].fd > max)
				max = eslave[i].fd;
		}
	}
	
	if(!canblock){
		tv.tv_sec = 0;
		tv.tv_usec = 0;
		timeout = &tv;
	}

	if(select(max+1, &rset, &wset, &xset, timeout) < 0)
		drawerror(display, "select failure");

	/*
	 * Look to see what can proceed.
	 */
	n = 0;
	for(i=0; i<nslave; i++){
		if(!eslave[i].inuse)
			continue;
		if(i == Smouse){
			if(finishrpc(eslave[i].rpc, &w)){
				eslave[i].rpc = nil;
				eb = newebuf(&eslave[i], sizeof(Mouse));
				_drawmouse = w.mouse;
				eb->u.mouse = w.mouse;
				if(w.resized)
					eresized(1);
				n++;
			}
		}else if(i == Skeyboard){
			if(finishrpc(eslave[i].rpc, &w)){
				eslave[i].rpc = nil;
				eb = newebuf(&eslave[i], sizeof(Rune)+2);	/* +8: alignment */
				eb->u.rune = w.rune;
				n++;
			}
		}else if(i == Stimer){
			t0 = nsec();
			while(t0 > eslave[i].nexttick){
				eslave[i].nexttick += eslave[i].n*1000000LL;
				eslave[i].head = (Ebuf*)1;
				n++;
			}
		}else{
			if(FD_ISSET(eslave[i].fd, &rset)){
				eb = newebuf(&eslave[i], eslave[i].n);
				eb->n = read(eslave[i].fd, eb->u.buf, eslave[i].n);
				n++;
			}
		}
	}
	return n;
}
Ejemplo n.º 30
0
char*
tkentryselect(Tk *tk, char *arg, char **val)
{
	TkTop *top;
	int start, from, to, locked;
	TkEntry *tke;
	char *e, *buf;

	buf = mallocz(Tkmaxitem, 0);
	if(buf == nil)
		return TkNomem;

	tke = TKobj(TkEntry, tk);

	top = tk->env->top;
	arg = tkword(top, arg, buf, buf+Tkmaxitem, nil);
	if(strcmp(buf, "clear") == 0) {
		tke->sel0 = 0;
		tke->sel1 = 0;
	}
	else
	if(strcmp(buf, "from") == 0) {
		tkword(top, arg, buf, buf+Tkmaxitem, nil);
		e = tkentryparseindex(tk, buf, &tke->anchor);
		tke->flag &= ~Ewordsel;
		free(buf);
		return e;
	}
	else
	if(strcmp(buf, "to") == 0) {
		tkword(top, arg, buf, buf+Tkmaxitem, nil);
		e = tkentryparseindex(tk, buf, &to);
		if(e != nil) {
			free(buf);
			return e;
		}
		
		if(to < tke->anchor) {
			if(tke->flag & Ewordsel)
				while(to > 0 && tkiswordchar(tke->text[to-1]))
					--to;
			tke->sel0 = to;
			tke->sel1 = tke->anchor;
		}
		else
		if(to >= tke->anchor) {
			if(tke->flag & Ewordsel)
				while(to < tke->textlen &&
						tkiswordchar(tke->text[to]))
					to++;
			tke->sel0 = tke->anchor;
			tke->sel1 = to;
		}
		tkentrysee(tk, to, 0);
		recalcentry(tk);
	}
	else
	if(strcmp(buf, "word") == 0) {	/* inferno invention */
		tkword(top, arg, buf, buf+Tkmaxitem, nil);
		e = tkentryparseindex(tk, buf, &start);
		if(e != nil) {
			free(buf);
			return e;
		}
		from = start;
		while(from > 0 && tkiswordchar(tke->text[from-1]))
			--from;
		to = start;
		while(to < tke->textlen && tkiswordchar(tke->text[to]))
			to++;
		tke->sel0 = from;
		tke->sel1 = to;
		tke->anchor = from;
		tke->icursor = from;
		tke->flag |= Ewordsel;
		locked = lockdisplay(tk->env->top->display);
		tke->xicursor = entrytextwidth(tk, tke->icursor);
		if (locked)
			unlockdisplay(tk->env->top->display);
	}
	else
	if(strcmp(buf, "present") == 0) {
		e = tkvalue(val, "%d", tke->sel1 > tke->sel0);
		free(buf);
		return e;
	}
	else
	if(strcmp(buf, "range") == 0) {
		arg = tkword(top, arg, buf, buf+Tkmaxitem, nil);
		e = tkentryparseindex(tk, buf, &from);
		if(e != nil) {
			free(buf);
			return e;
		}
		tkword(top, arg, buf, buf+Tkmaxitem, nil);
		e = tkentryparseindex(tk, buf, &to);
		if(e != nil) {
			free(buf);
			return e;
		}
		tke->sel0 = from;
		tke->sel1 = to;
		if(to <= from) {
			tke->sel0 = 0;
			tke->sel1 = 0;
		}
	}
	else
	if(strcmp(buf, "adjust") == 0) {
		tkword(top, arg, buf, buf+Tkmaxitem, nil);
		e = tkentryparseindex(tk, buf, &to);
		if(e != nil) {
			free(buf);
			return e;
		}
		if(tke->sel0 == 0 && tke->sel1 == 0) {
			tke->sel0 = tke->anchor;
			tke->sel1 = to;
		}
		else {
			if(abs(tke->sel0-to) < abs(tke->sel1-to)) {
				tke->sel0 = to;
				tke->anchor = tke->sel1;
			}
			else {
				tke->sel1 = to;
				tke->anchor = tke->sel0;
			}
		}
		if(tke->sel0 > tke->sel1) {
			to = tke->sel0;
			tke->sel0 = tke->sel1;
			tke->sel1 = to;
		}
	}
	else {
		free(buf);
		return TkBadcm;
	}
	locked = lockdisplay(tk->env->top->display);
	tke->xsel0 = entrytextwidth(tk, tke->sel0);
	tke->xsel1 = entrytextwidth(tk, tke->sel1);
	if (locked)
		unlockdisplay(tk->env->top->display);
	tk->dirty = tkrect(tk, 1);
	free(buf);
	return nil;
}