Esempio n. 1
0
void
pipectl(void *v)
{
	Window *w;
	Event *e;

	w = v;
	proccreate(wineventproc, w, STACK);

	windormant(w);
	winsetaddr(w, "0", 0);
	for(;;){
		e = recvp(w->cevent);
		switch(e->c1){
		default:
		Unknown:
			fprint(2, "unknown message %c%c\n", e->c1, e->c2);
			break;

		case 'E':	/* write to body; can't affect us */
			break;
	
		case 'F':	/* generated by our actions; ignore */
			break;
	
		case 'K':	/* ignore */
			break;
	
		case 'M':
			switch(e->c2){
			case 'x':
			case 'X':
				execevent(w, e, pipecommand);
				break;
	
			case 'l':	/* reflect all searches back to acme */
			case 'L':
				if(e->flag & 2)
					recvp(w->cevent);
				winwriteevent(w, e);
				break;
	
			case 'I':	/* modify away; we don't care */
			case 'i':
			case 'D':
			case 'd':
				break;
	
			default:
				goto Unknown;
			}
		}
	}
}
Esempio n. 2
0
File: main.c Progetto: npe9/harvey
void
mainctl(void *v)
{
	Window *w;
	Event *e;
	int delta, pendingS, pendingK;
	uint32_t hostpt, endpt;
	char tmp[32];

	w = v;
	proccreate(wineventproc, w, STACK);

	hostpt = 0;
	endpt = 0;
	winsetaddr(w, "0", 0);
	pendingS = 0;
	pendingK = 0;
	for(;;){
		if(debug)
			fprint(2, "input range %lud-%lud\n", hostpt, endpt);
		e = recvp(w->cevent);
		if(debug)
			fprint(2, "msg: %C %C %d %d %d %d %q\n",
				e->c1 ? e->c1 : ' ', e->c2 ? e->c2 : ' ', e->q0, e->q1, e->flag, e->nb, e->b);
		switch(e->c1){
		default:
		Unknown:
			fprint(2, "unknown message %c%c\n", e->c1, e->c2);
			break;

		case 'C':	/* input needed for /dev/cons */
			if(pendingS)
				pendingK = 1;
			else
				hostpt += sendinput(w, hostpt, &endpt);
			break;

		case 'S':	/* output to stdout */
			sprint(tmp, "#%lud", hostpt);
			winsetaddr(w, tmp, 0);
			write(w->data, e->b, e->nb);
			pendingS += e->nr;
			break;
	
		case 'E':	/* write to tag or body; body happens due to sendit */
			delta = e->q1-e->q0;
			if(e->c2=='I'){
				endpt += delta;
				if(e->q0 < hostpt)
					hostpt += delta;
				else
					hostpt += sendinput(w, hostpt, &endpt);
				break;
			}
			if(!islower(e->c2))
				fprint(2, "win msg: %C %C %d %d %d %d %q\n",
					e->c1, e->c2, e->q0, e->q1, e->flag, e->nb, e->b);
			break;
	
		case 'F':	/* generated by our actions (specifically case 'S' above) */
			delta = e->q1-e->q0;
			if(e->c2=='D'){
				/* we know about the delete by _sendinput */
				break;
			}
			if(e->c2=='I'){
				pendingS -= e->q1 - e->q0;
				if(pendingS < 0)
					fprint(2, "win: pendingS = %d\n", pendingS);
				if(e->q0 != hostpt)
					fprint(2, "win: insert at %d expected %lud\n", e->q0, hostpt);
				endpt += delta;
				hostpt += delta;
				sendp(writechan, nil);
				if(pendingS == 0 && pendingK){
					pendingK = 0;
					hostpt += sendinput(w, hostpt, &endpt);
				}
				break;
			}
			if(!islower(e->c2))
				fprint(2, "win msg: %C %C %d %d %d %d %q\n",
					e->c1, e->c2, e->q0, e->q1, e->flag, e->nb, e->b);
			break;

		case 'K':
			delta = e->q1-e->q0;
			switch(e->c2){
			case 'D':
				endpt -= delta;
				if(e->q1 < hostpt)
					hostpt -= delta;
				else if(e->q0 < hostpt)
					hostpt = e->q0;
				break;
			case 'I':
				delta = e->q1 - e->q0;
				endpt += delta;
				if(endpt < e->q1)	/* just in case */
					endpt = e->q1;
				if(e->q0 < hostpt)
					hostpt += delta;
				if(e->nr>0 && e->r[e->nr-1]==0x7F){
					write(notepg, "interrupt", 9);
					hostpt = endpt;
					break;
				}
				if(e->q0 >= hostpt
				&& hasboundary(e->r, e->nr)){
					/*
					 * If we are between the S message (which
					 * we processed by inserting text in the
					 * window) and the F message notifying us
					 * that the text has been inserted, then our
					 * impression of the hostpt and acme's
					 * may be different.  This could be seen if you
					 * hit enter a bunch of times in a con
					 * session.  To work around the unreliability,
					 * only send input if we don't have an S pending.
					 * The same race occurs between when a character
					 * is typed and when we get notice of it, but
					 * since characters tend to be typed at the end
					 * of the buffer, we don't run into it.  There's
					 * no workaround possible for this typing race,
					 * since we can't tell when the user has typed
					 * something but we just haven't been notified.
					 */
					if(pendingS)
						pendingK = 1;
					else
						hostpt += sendinput(w, hostpt, &endpt);
				}
				break;
			}
			break;
	
		case 'M':	/* mouse */
			delta = e->q1-e->q0;
			switch(e->c2){
			case 'x':
			case 'X':
				execevent(w, e, command);
				break;
	
			case 'l':	/* reflect all searches back to acme */
			case 'L':
				if(e->flag & 2)
					recvp(w->cevent);
				winwriteevent(w, e);
				break;
	
			case 'I':
				endpt += delta;
				if(e->q0 < hostpt)
					hostpt += delta;
				else
					hostpt += sendinput(w, hostpt, &endpt);
				break;

			case 'D':
				endpt -= delta;
				if(e->q1 < hostpt)
					hostpt -= delta;
				else if(e->q0 < hostpt)
					hostpt = e->q0;
				break;
			case 'd':	/* modify away; we don't care */
			case 'i':
				break;
	
			default:
				goto Unknown;
			}
		}
	}
}