Exemple #1
0
static void dispatch_event(arcan_event* ev,
	struct rwstat_ch* ch, struct senseye_priv* chp)
{
	if (rwstat_consume_event(ch, ev))
		return;

	if (ev->category == EVENT_TARGET)
	switch (ev->tgt.kind){
		case TARGET_COMMAND_REQFAIL:
			chp->running = false;
		break;

		case TARGET_COMMAND_PAUSE:
			chp->paused = true;
		break;

		case TARGET_COMMAND_DISPLAYHINT:{
			size_t base = ev->tgt.ioevs[0].iv;
			if (base > 0 && (base & (base - 1)) == 0 &&
				arcan_shmif_resize(&chp->cont, base, base))
				ch->resize(ch, base);
			else
				FLOG("Senseye:FDsense: bad displayhint: %d\n", ev->tgt.ioevs[0].iv);
		}

/* resize buffer to new base */
		break;

		case TARGET_COMMAND_UNPAUSE:
			chp->paused = false;
		break;

		case TARGET_COMMAND_STEPFRAME:
			chp->framecount = ev->tgt.ioevs[0].iv;
		break;

		case TARGET_COMMAND_EXIT:
			chp->running = false;
		break;

		default:
#ifdef _DEBUG
			printf("unhandled event : %s\n", arcan_shmif_eventstr(ev, NULL, 0));
#endif
		break;
		}
}
Exemple #2
0
static void on_cl_event(
	struct arcan_shmif_cont* cont, int chid, struct arcan_event* ev, void* tag)
{
	if (!cont){
		debug_print(1, "ignore incoming event on unknown context");
		return;
	}
	if (arcan_shmif_descrevent(ev)){
/*
 * Events needed to be handled here:
 * NEWSEGMENT, map it, add it to the context channel list.
 */
		debug_print(1, "incoming descr- event ignored");
	}
	else {
		debug_print(2, "client event: %s on ch %d",
			arcan_shmif_eventstr(ev, NULL, 0), chid);
		arcan_shmif_enqueue(cont, ev);
	}
}
Exemple #3
0
int main(int argc, char** argv)
{
	int id = SEGID_APPLICATION;
	struct arg_arr* aarr;
	if (argc > 1){
		if (strcmp(argv[1], "-game") == 0)
			id = SEGID_GAME;
		else if (strcmp(argv[1], "-terminal") == 0)
			id = SEGID_TERMINAL;
		else if (strcmp(argv[1], "-vm") == 0)
			id = SEGID_VM;
		else{
			printf("usage: \n\tiodump to identify as normal application"
				"\n\tiodump -game to identify as game"
				"\n\tiodump -terminal to identify as terminal"
				"\n\tiodump -vm to identify as vm\n"
			);
				return EXIT_FAILURE;
			}
		}

	struct arcan_shmif_cont cont = arcan_shmif_open(
		id, SHMIF_ACQUIRE_FATALFAIL, &aarr);
	printf("open\n");

	arcan_event ev;

/* just send garbage so the correct events are being propagated */
	arcan_shmif_signal(&cont, SHMIF_SIGVID);
	printf("loop\n");
	while (arcan_shmif_wait(&cont, &ev)){
		if (ev.category == EVENT_TARGET){
			switch (ev.tgt.kind){
			case TARGET_COMMAND_BCHUNK_IN:
				printf("bchunk in\n");
				dump_eof(ev.tgt.ioevs[0].iv);
			break;
			case TARGET_COMMAND_BCHUNK_OUT:
				printf("bchunk out\n");
				write_eof(ev.tgt.ioevs[0].iv);
			break;
			case TARGET_COMMAND_MESSAGE:
				printf("message: %s\n", ev.tgt.message);
			break;
			case TARGET_COMMAND_EXIT:
				return EXIT_SUCCESS;
			default:
				printf("event: %s\n", arcan_shmif_eventstr(&ev, NULL, 0));
			break;
			}
		}
		else if (ev.category == EVENT_IO){
			switch (ev.io.datatype){
				case EVENT_IDATATYPE_TRANSLATED:
					printf("(%s)[kbd(%d):%s] %d:mask=%d,sym:%d,code:%d,utf8:%s\n",
						ev.io.label,
						ev.io.devid, ev.io.input.translated.active ? "pressed" : "released",
						(int)ev.io.subid, (int)ev.io.input.translated.modifiers,
						(int)ev.io.input.translated.keysym,
						(int)ev.io.input.translated.scancode,
						ev.io.input.translated.utf8
					);

				break;
				case EVENT_IDATATYPE_ANALOG:
					printf("(%s)[%s(%d):%d] rel: %s, v(%d){%d, %d, %d, %d}\n",
						ev.io.label,
						ev.io.devkind == EVENT_IDEVKIND_MOUSE ? "mouse" : "analog",
						ev.io.devid, ev.io.subid,
						ev.io.input.analog.gotrel ? "yes" : "no",
						(int)ev.io.input.analog.nvalues,
						(int)ev.io.input.analog.axisval[0],
						(int)ev.io.input.analog.axisval[1],
						(int)ev.io.input.analog.axisval[2],
						(int)ev.io.input.analog.axisval[3]
					);
				break;
				case EVENT_IDATATYPE_TOUCH:
					printf("(%s)[touch(%d)] %d: @%d,%d pressure: %f, size: %f\n",
					ev.io.label,
					ev.io.devid,
					ev.io.subid,
					(int) ev.io.input.touch.x,
					(int) ev.io.input.touch.y,
					ev.io.input.touch.pressure,
					ev.io.input.touch.size
				);
				break;
				case EVENT_IDATATYPE_DIGITAL:
					if (ev.io.devkind == EVENT_IDEVKIND_MOUSE)
						printf("[mouse(%d):%d], %s:%s\n", ev.io.devid,
							ev.io.subid, msub_to_lbl(ev.io.subid),
							ev.io.input.digital.active ? "pressed" : "released"
						);
					else
						printf("[digital(%d):%d], %s\n", ev.io.devid,
							ev.io.subid, ev.io.input.digital.active ? "pressed" : "released");
				break;
				default:
				break;
			}
		}
	}

	return EXIT_SUCCESS;
}
Exemple #4
0
int a12helper_a12srv_shmifcl(
	struct a12_state* S, const char* cp, int fd_in, int fd_out)
{
	if (!cp)
		cp = getenv("ARCAN_CONNPATH");
	else
		setenv("ARCAN_CONNPATH", cp, 1);

	if (!cp){
		debug_print(1, "No connection point was specified");
		return -ENOENT;
	}

/* Channel - connection mapping */
	struct cl_state cl_state = {};

/* Open / set the primary connection */
	cl_state.wnd[0] = arcan_shmif_open(SEGID_UNKNOWN, SHMIF_NOACTIVATE, NULL);
	if (!cl_state.wnd[0].addr){
		debug_print(1, "Couldn't connect to an arcan display server");
		return -ENOENT;
	}
	cl_state.n_segments = 1;
	debug_print(1, "Segment connected");

	a12_set_destination(S, &cl_state.wnd[0], 0);

/* set to non-blocking */
	int flags = fcntl(fd_in, F_GETFL);
	fcntl(fd_in, F_SETFL, flags | O_NONBLOCK);

	uint8_t* outbuf;
	size_t outbuf_sz = 0;
	debug_print(1, "got proxy connection, waiting for source");

	int status;
	while (-1 != (status = a12helper_poll_triple(
		cl_state.wnd[0].epipe, fd_in, outbuf_sz ? fd_out : -1, 4))){

		if (status & A12HELPER_WRITE_OUT){
			if (outbuf_sz || (outbuf_sz = a12_channel_flush(S, &outbuf))){
				ssize_t nw = write(fd_out, outbuf, outbuf_sz);
				if (nw > 0){
					outbuf += nw;
					outbuf_sz -= nw;
				}
			}
		}

		if (status & A12HELPER_DATA_IN){
			uint8_t inbuf[9000];
			ssize_t nr = read(fd_in, inbuf, 9000);
			if (-1 == nr && errno != EAGAIN && errno != EWOULDBLOCK && errno != EINTR){
				debug_print(1, "failed to read from input: %d", errno);
				break;
			}

			debug_print(2, "unpack %zd bytes", nr);
			a12_channel_unpack(S, inbuf, nr, NULL, on_cl_event);
		}

/* 1 client can have multiple segments */
		for (size_t i = 0, count = cl_state.n_segments; i < 256 && count; i++){
			if (!cl_state.wnd[i].addr)
				continue;

			count--;
			struct arcan_event newev;
			int sc;
			while (( sc = arcan_shmif_poll(&cl_state.wnd[i], &newev)) > 0){
/* we got a descriptor passing event, some of these we could/should discard,
 * while others need to be forwarded as a binary- chunk stream and kept out-
 * of order on the other side */
				if (arcan_shmif_descrevent(&newev)){
					debug_print(1, "(cl:%zu) ign-descr-event: %s",
						i, arcan_shmif_eventstr(&newev, NULL, 0));
				}
				else {
					debug_print(2, "enqueue %s", arcan_shmif_eventstr(&newev, NULL, 0));
					a12_channel_enqueue(S, &newev);
				}
			}
		}

/* we might have gotten data to flush, so use that as feedback */
		if (!outbuf_sz){
			outbuf_sz = a12_channel_flush(S, &outbuf);
			if (outbuf_sz)
				debug_print(2, "output buffer size: %zu", outbuf_sz);
		}
	}

/* though a proper cleanup would cascade, it doesn't help being careful */
	for (size_t i = 0, count = cl_state.n_segments; i < 256 && count; i++){
		if (!cl_state.wnd[i].addr)
				continue;
		arcan_shmif_drop(&cl_state.wnd[i]);
		cl_state.wnd[i].addr = NULL;
	}

	return 0;
}