Пример #1
0
void
writecolmap(Display *d, RGB *m)
{
	int i, n, fd;
	char buf[64], *t;
	ulong r, g, b;

	sprint(buf, "/dev/draw/%d/colormap", d->dirno);
	fd = open(buf, OWRITE);
	if(fd < 0)
		drawerror(d, "writecolmap: open colormap failed");
	t = malloc(8192);
	if (t == nil)
		drawerror(d, "writecolmap: no memory");
	n = 0;
	for(i = 0; i < 256; i++) {
		r = m[i].red>>24;
		g = m[i].green>>24;
		b = m[i].blue>>24;
		n += sprint(t+n, "%d %lud %lud %lud\n", 255-i, r, g, b);
	}
	i = write(fd, t, n);
	free(t);
	close(fd);
	if(i != n)
		drawerror(d, "writecolmap: bad write");
}
Пример #2
0
int
_frcanfit(Frame *f, Point pt, Frbox *b)
{
	int left, w, nr;
	uchar *p;
	Rune r;

	left = f->r.max.x-pt.x;
	if(b->nrune < 0)
		return b->minwid <= left;
	if(left >= b->wid)
		return b->nrune;
	for(nr=0,p=b->ptr; *p; p+=w,nr++){
		r = *p;
		if(r < Runeself)
			w = 1;
		else
			w = chartorune(&r, (char*)p);
		left -= stringnwidth(f->font, (char*)p, 1);
		if(left < 0)
			return nr;
	}
	drawerror(f->display, "_frcanfit can't");
	return 0;
}
Пример #3
0
int
ecanmouse(void)
{
	if(Smouse < 0)
		drawerror(display, "events: mouse not initialized");
	return ecanread(Emouse);
}
Пример #4
0
static int
eforkslave(ulong key)
{
	int i, pid;

	for(i=0; i<MAXSLAVE; i++)
		if((key & ~(1<<i)) == 0 && eslave[i].pid == 0){
			if(nslave <= i)
				nslave = i + 1;
			/*
			 * share the file descriptors so the last child
			 * out closes all connections to the window server.
			 */
			switch(pid = rfork(RFPROC)){
			case 0:
				return MAXSLAVE+i;
			case -1:
				fprint(2, "events: fork error\n");
				exits("fork");
			}
			eslave[i].pid = pid;
			eslave[i].head = eslave[i].tail = 0;
			return i;
		}
	drawerror(display, "events: bad slave assignment");
	return 0;
}
Пример #5
0
Point
_frdraw(Frame *f, Point pt)
{
    Frbox *b;
    int nb, n;

    for(b=f->box,nb=0; nb<f->nbox; nb++, b++) {
        _frcklinewrap0(f, &pt, b);
        if(pt.y == f->r.max.y) {
            f->nchars -= _frstrlen(f, nb);
            _frdelbox(f, nb, f->nbox-1);
            break;
        }
        if(b->nrune > 0) {
            n = _frcanfit(f, pt, b);
            if(n == 0)
                drawerror(f->display, "_frcanfit==0");
            if(n != b->nrune) {
                _frsplitbox(f, nb, n);
                b = &f->box[nb];
            }
            pt.x += b->wid;
        } else {
            if(b->bc == '\n') {
                pt.x = f->r.min.x;
                pt.y+=f->font->height;
            } else
                pt.x += _frnewwid(f, pt, b);
        }
    }
    return pt;
}
Пример #6
0
Mouse
emouse(void)
{
	Mouse m;
	Ebuf *eb;
	static but[2];
	int b;

	if(Smouse < 0)
		drawerror(display, "events: mouse not initialized");
	for(;;){
		eb = ebread(&eslave[Smouse]);
		if(!ecanmouse())
			break;
		free(eb);	/* drop queued mouse events */
	}
	m.xy.x = atoi((char*)eb->buf+1+0*12);
	m.xy.y = atoi((char*)eb->buf+1+1*12);
	b = atoi((char*)eb->buf+1+2*12);
	m.buttons = b;
	m.msec = atoi((char*)eb->buf+1+3*12);
	if (logfid)
		fprint(logfid, "b: %d xy: %P\n", m.buttons, m.xy);
	free(eb);
	return m;
}
Пример #7
0
int
ecankbd(void)
{
	if(Skeyboard < 0)
		drawerror(display, "events: keyboard not initialzed");
	return ecanread(Ekeyboard);
}
Пример #8
0
ulong
etimer(ulong key, int n)
{
	if(Stimer != -1)
		drawerror(display, "events: timer started twice");
	Stimer = newkey(key);
	if(n <= 0)
		n = 1000;
	eslave[Stimer].n = n;
	eslave[Stimer].nexttick = nsec()+n*1000000LL;
	return 1<<Stimer;
}
Пример #9
0
int
ekbd(void)
{
	Ebuf *eb;
	int c;

	if(Skeyboard < 0)
		drawerror(display, "events: keyboard not initialzed");
	eb = ebread(&eslave[Skeyboard]);
	c = eb->u.rune;
	free(eb);
	return c;
}
Пример #10
0
Mouse
emouse(void)
{
	Mouse m;
	Ebuf *eb;

	if(Smouse < 0)
		drawerror(display, "events: mouse not initialized");
	eb = ebread(&eslave[Smouse]);
	m = eb->u.mouse;
	free(eb);
	return m;
}
Пример #11
0
int
ekbd(void)
{
	Ebuf *eb;
	Rune r;

	if(Skeyboard < 0)
		drawerror(display, "events: keyboard not initialzed");
	eb = ebread(&eslave[Skeyboard]);
	chartorune(&r, (char*)eb->buf);
	free(eb);
	return r;
}
Пример #12
0
void
einit(ulong keys)
{
	int ctl, fd;
	char buf[256];

	parentpid = getpid();
	if(pipe(epipe) < 0)
		drawerror(display, "events: einit pipe");
	atexit(ekill);
	atnotify(enote, 1);
	snprint(buf, sizeof buf, "%s/mouse", display->devdir);
	mousefd = open(buf, ORDWR|OCEXEC);
	if(mousefd < 0)
		drawerror(display, "einit: can't open mouse\n");
	snprint(buf, sizeof buf, "%s/cursor", display->devdir);
	cursorfd = open(buf, ORDWR|OCEXEC);
	if(cursorfd < 0)
		drawerror(display, "einit: can't open cursor\n");
	if(keys&Ekeyboard){
		snprint(buf, sizeof buf, "%s/cons", display->devdir);
		fd = open(buf, OREAD);
		if(fd < 0)
			drawerror(display, "events: can't open console");
		snprint(buf, sizeof buf, "%s/consctl", display->devdir);
		ctl = open("/dev/consctl", OWRITE|OCEXEC);
		if(ctl < 0)
			drawerror(display, "events: can't open consctl");
		write(ctl, "rawon", 5);
		for(Skeyboard=0; Ekeyboard & ~(1<<Skeyboard); Skeyboard++)
			;
		ekeyslave(fd);
	}
	if(keys&Emouse){
		estart(Emouse, mousefd, 1+4*12);
		for(Smouse=0; Emouse & ~(1<<Smouse); Smouse++)
			;
	}
}
Пример #13
0
static int
newkey(ulong key)
{
	int i;

	for(i=0; i<MAXSLAVE; i++)
		if((key & ~(1<<i)) == 0 && eslave[i].inuse == 0){
			if(nslave <= i)
				nslave = i + 1;
			eslave[i].inuse = 1;
			return i;
		}
	drawerror(display, "events: bad slave assignment");
	return 0;
}
Пример #14
0
ulong
estartfn(ulong key, int fd, int n, int (*fn)(int, Event*, uchar*, int))
{
	int i;

	if(fd < 0)
		drawerror(display, "events: bad file descriptor");
	if(n <= 0 || n > EMAXMSG)
		n = EMAXMSG;
	i = newkey(key);
	eslave[i].fn = fn;
	eslave[i].fd = fd;
	eslave[i].n = n;
	return 1<<i;
}
Пример #15
0
static Ebuf*
newebuf(Slave *s, int n)
{
	Ebuf *eb;
	
	eb = malloc(sizeof(*eb) - sizeof(eb->u.buf) + n);
	if(eb == nil)
		drawerror(display, "events: out of memory");
	eb->n = n;
	eb->next = 0;
	if(s->head)
		s->tail = s->tail->next = eb;
	else
		s->head = s->tail = eb;
	return eb;
}
Пример #16
0
int
ecanread(ulong keys)
{
	Dir *d;
	int i;
	ulong l;

	for(;;){
		for(i=0; i<nslave; i++)
			if((keys & (1<<i)) && eslave[i].head)
				return 1;
		d = dirfstat(epipe[0]);
		if(d == nil)
			drawerror(display, "events: ecanread stat error");
		l = d->length;
		free(d);
		if(l == 0)
			return 0;
		extract();
	}
}
Пример #17
0
ulong
etimer(ulong key, int n)
{
	char t[2];

	if(Stimer != -1)
		drawerror(display, "events: timer started twice");
	Stimer = eforkslave(key);
	if(Stimer < MAXSLAVE)
		return 1<<Stimer;
	if(n <= 0)
		n = 1000;
	t[0] = t[1] = Stimer - MAXSLAVE;
	do
		sleep(n);
	while(write(epipe[1], t, 2) == 2);
	t[0] = MAXSLAVE;
	write(epipe[1], t, 1);
	_exits(0);
	return 0;
}
Пример #18
0
ulong
estartfn(ulong key, int fd, int n, int (*fn)(int, Event*, uchar*, int))
{
	char buf[EMAXMSG+1];
	int i, r;

	if(fd < 0)
		drawerror(display, "events: bad file descriptor");
	if(n <= 0 || n > EMAXMSG)
		n = EMAXMSG;
	i = eforkslave(key);
	if(i < MAXSLAVE){
		eslave[i].fn = fn;
		return 1<<i;
	}
	buf[0] = i - MAXSLAVE;
	while((r = read(fd, buf+1, n))>0)
		if(write(epipe[1], buf, r+1)!=r+1)
			break;
	buf[0] = MAXSLAVE;
	write(epipe[1], buf, 1);
	_exits(0);
	return 0;
}
Пример #19
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;
}
Пример #20
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;
}