コード例 #1
0
/* Retrieve pending events, and return the number of events */
static int getPendingEvents(void) {
	int count = 0;
	while (1) {
		Mouse mouse;
		Rune rune;
		int charCode, modifiers;
		int mouse_event = nbrecv(mousectl->c, (void*)&mouse);
		int resize_event = nbrecv(mousectl->resizec, NULL);
		int kbd_event = nbrecv(keyboardctl->c, (void*)&rune);
		
		if (mouse_event) {
			//Process mouse event
			mouse_position.x = mouse.xy.x - screen->r.min.x;
			mouse_position.y = mouse.xy.y - screen->r.min.y;
			mouse_button_state = mouse.buttons;
			qlock(&evt_buf_lock);
			if ((evts_end+2)%EVT_BUFFER_SIZE != evts_start) {
				sqMouseEvent* evt = (sqMouseEvent*)&evts[evts_end++];
				evts_end %= EVT_BUFFER_SIZE;
				evt->type = EventTypeMouse;
				evt->timeStamp = ioMSecs();
				evt->x = mouse_position.x;
				evt->y = mouse_position.y;
				evt->buttons = ioGetButtonState();
				evt->modifiers = 0;
				evt->reserved1 = evt->windowIndex = 0;
				count++;
			}
			qunlock(&evt_buf_lock);
		}

		if (resize_event) {
			getwindow(display, Refnone);
			fullDisplayUpdate();
		}

		if (kbd_event && splitRune(rune, &charCode, &modifiers)) {
			//Process keyboard event
			qlock(&evt_buf_lock);
			if ((evts_end+2)%EVT_BUFFER_SIZE != evts_start) {
				sqKeyboardEvent* evt = (sqKeyboardEvent*)&evts[evts_end++];
				evts_end %= EVT_BUFFER_SIZE;
				evt->type = EventTypeKeyboard;
				evt->timeStamp = ioMSecs();
				evt->pressCode = EventKeyChar;
				evt->charCode = charCode;
				evt->modifiers = modifiers;
				evt->reserved1 = evt->windowIndex = 0;
				count++;
			}
			qunlock(&evt_buf_lock);
		}
		if (!(resize_event || kbd_event || mouse_event))
			break;
	}
	return count;
}
コード例 #2
0
ファイル: acme.c プロジェクト: Nurb432/plan9front
void
keyboardthread(void *)
{
	Rune r;
	Timer *timer;
	Text *t;
	enum { KTimer, KKey, NKALT };
	static Alt alts[NKALT+1];

	alts[KTimer].c = nil;
	alts[KTimer].v = nil;
	alts[KTimer].op = CHANNOP;
	alts[KKey].c = keyboardctl->c;
	alts[KKey].v = &r;
	alts[KKey].op = CHANRCV;
	alts[NKALT].op = CHANEND;

	timer = nil;
	typetext = nil;
	threadsetname("keyboardthread");
	for(;;){
		switch(alt(alts)){
		case KTimer:
			timerstop(timer);
			t = typetext;
			if(t!=nil && t->what==Tag){
				winlock(t->w, 'K');
				wincommit(t->w, t);
				winunlock(t->w);
				flushimage(display, 1);
			}
			alts[KTimer].c = nil;
			alts[KTimer].op = CHANNOP;
			break;
		case KKey:
		casekeyboard:
			typetext = rowtype(&row, r, mouse->xy);
			t = typetext;
			if(t!=nil && t->col!=nil && !(r==Kdown || r==Kleft || r==Kright))	/* scrolling doesn't change activecol */
				activecol = t->col;
			if(t!=nil && t->w!=nil)
				t->w->body.file->curtext = &t->w->body;
			if(timer != nil)
				timercancel(timer);
			if(t!=nil && t->what==Tag) {
				timer = timerstart(500);
				alts[KTimer].c = timer->c;
				alts[KTimer].op = CHANRCV;
			}else{
				timer = nil;
				alts[KTimer].c = nil;
				alts[KTimer].op = CHANNOP;
			}
			if(nbrecv(keyboardctl->c, &r) > 0)
				goto casekeyboard;
			flushimage(display, 1);
			break;
		}
	}
}
コード例 #3
0
ファイル: channel.c プロジェクト: 99years/plan9
void*
nbrecvp(Channel *c)
{
	void *v;

	channelsize(c, sizeof(void*));
	if(nbrecv(c, &v) == 0)
		return nil;
	return v;
}
コード例 #4
0
ファイル: channel.c プロジェクト: 99years/plan9
ulong
nbrecvul(Channel *c)
{
	ulong v;

	channelsize(c, sizeof(ulong));
	if(nbrecv(c, &v) == 0)
		return 0;
	return v;
}
コード例 #5
0
ファイル: main.c プロジェクト: 99years/plan9
void
keyboardthread(void *)
{
	Timer *timer;
	Text *t;
	Rune r;

	static Alt alts[NKALT+1];

	alts[KTimer].c = nil;
	alts[KTimer].v = nil;
	alts[KTimer].op = CHANNOP;
	alts[KKey].c = keyboardctl->c;
	alts[KKey].v = &r;
	alts[KKey].op = CHANRCV;
	alts[NKALT].op = CHANEND;

	timer = nil;
	threadsetname("keyboardthread");
	for(;;){
		switch(alt(alts)){
		case KTimer:
			timerstop(timer);
			alts[KTimer].c = nil;
			alts[KTimer].op = CHANNOP;
			break;
		case KKey:
		casekeyboard:
			typetext = rowwhich(&row, mouse->xy, r, TRUE);
			t = typetext;
			if(t!=nil && t->col!=nil &&
			    !(r==Kdown || r==Kleft || r==Kright))
				/* scrolling doesn't change activecol */
				activecol = t->col;
			if(timer != nil)
				timercancel(timer);
			if(t!=nil){
				texttype(t, r);
				timer = timerstart(500);
				alts[KTimer].c = timer->c;
				alts[KTimer].op = CHANRCV;
			}else{
				timer = nil;
				alts[KTimer].c = nil;
				alts[KTimer].op = CHANNOP;
			}
			if(nbrecv(keyboardctl->c, &r) > 0)
				goto casekeyboard;
			flushimage(display, 1);
			break;
		}
	}
}
コード例 #6
0
ファイル: keyboard.c プロジェクト: brandondyck/plan9port
void
closekeyboard(Keyboardctl *kc)
{
    Rune r;

    if(kc == nil)
        return;

    /*	postnote(PNPROC, kc->pid, "kill"); */

    do;
    while(nbrecv(kc->c, &r) > 0);
    chanfree(kc->c);
    free(kc);
}
コード例 #7
0
ファイル: mouse.c プロジェクト: aahud/harvey
void
closemouse(Mousectl *mc)
{
	if(mc == nil)
		return;

	postnote(PNPROC, mc->pid, "kill");

	do; while(nbrecv(mc->c, (Mouse *)mc) > 0);

	close(mc->mfd);
	close(mc->cfd);
	free(mc->file);
	free(mc->c);
	free(mc->resizec);
	free(mc);
}
コード例 #8
0
ファイル: sockio.c プロジェクト: Goon83/SALB
/* brecv_timeout()
 *
 * Attempts to do nonblocking recv's until a timeout occurs.  Useful for
 * recovering from deadlocks in situations where you want to give up if a
 * message does not finish arriving within a certain time frame.
 *
 * Same args as brecv, but with an additional timeout argument that is an
 * integer number of seconds.   
 * 
 * returns number of bytes received, even if it did not recv all that was
 * asked.  If any error other than timeout occurs, it returns -1 and sets
 * errno accordingly.  */
int brecv_timeout(int s, void *vbuf, int len, int timeout)
{
	char *buf = (char *) vbuf;
	int recv_size = len;    /* amt we hope for each iteration */
	int recv_total = 0;     /* total amt recv'd thus far */
	char * recv_ptr = buf;   /* where to put the data */
	int initial_tries = 8;  /* number of initial attempts to make */
	int i = 0;
	int ret = -1;
	struct pollfd poll_conn;

	/* This determines the backoff times.  It will do a few attempts with the
	 * initial backoff first, then wait and do a final one after the
	 * remainder of the time is up.  Note that the initial backoff will be
	 * zero if a small overall timeout is specified by the caller.
	 */
	int initial_backoff = timeout/initial_tries;
	int final_backoff = timeout - (timeout/initial_tries);

	/* we don't accept -1 for infinite timeout.  That is the job of brecv. */
	if(timeout < 0)
	{
		errno = EINVAL;
		return(-1);
	}

	/* initial attempts */
	do
	{
		/* nbrecv() handles EINTR on its own */
		if((ret = nbrecv(s, recv_ptr, recv_size)) < 0)
		{
			/* bail out at any error */
			return(ret);
		}

		/* update our progress */
		recv_size -= ret;
		recv_total += ret;
		recv_ptr += ret;

		/* if we didn't finish, then poll for a while. */
		if(recv_total < len)
		{
			poll_conn.fd = s;
			poll_conn.events = POLLIN;
brecv_timeout_poll1_restart:
			ret = poll(&poll_conn, 1, (initial_backoff*1000));
			if(ret < 0)
			{
				if (errno == EINTR) goto brecv_timeout_poll1_restart;
				/* bail out on any "real" error */
				return(ret);
			}
		}
		i++;
	}
	while((i < initial_tries) && (recv_total < len));
	
	/* see if we are done */
	if (recv_total == len) {
		return(len);
	}

	/* not done yet, give it one last chance: */
	poll_conn.fd = s;
	poll_conn.events = POLLIN;
brecv_timeout_poll2_restart:
	ret = poll(&poll_conn, 1, (final_backoff*1000));
	if(ret < 0)
	{
		if (errno == EINTR) goto brecv_timeout_poll2_restart;
		/* bail out on any "real" error */
		return(ret);
	}

	if((ret = nbrecv(s, recv_ptr, recv_size)) < 0)
	{
		fprintf(stderr,  "brecv_timeout: giving up");
		return(ret);
	}

	recv_size -= ret;
	recv_total += ret;

	return(recv_total);
}