Beispiel #1
0
static void ch_close(struct senseye_ch* ch)
{
	if (!ch || !ch->in_pr)
		return;

	ch_flush(ch);

	struct senseye_priv* chp = ch->in_pr;
	arcan_shmif_drop(&chp->cont);
	ch->in->free(&ch->in);
	chp->running = false;
}
Beispiel #2
0
int main(int argc, char** argv)
{
	struct arg_arr* aarr;
	struct arcan_shmif_cont cont = arcan_shmif_open(
		SEGID_APPLICATION, SHMIF_ACQUIRE_FATALFAIL, &aarr);

	arcan_event ev = {
		.ext.kind = ARCAN_EVENT(CLOCKREQ),
		.ext.clock.rate = 2,
		.ext.clock.dynamic = (argc > 1 && strcmp(argv[1], "dynamic") == 0)
	};
	arcan_shmif_enqueue(&cont, &ev);

	ev.ext.clock.dynamic = false;
	int tbl[] = {20, 40, 42, 44, 60, 80, 86, 88, 100, 120};
	int step = 0;

	for (size_t i=0; i < sizeof(tbl)/sizeof(tbl[0]); i++){
		ev.ext.clock.once = true;
		ev.ext.clock.rate = tbl[i];
		ev.ext.clock.id = i + 2; /* 0 index and 1 is reserved */
		arcan_shmif_enqueue(&cont, &ev);
	}

	while(arcan_shmif_wait(&cont, &ev) != 0){
		if (ev.category == EVENT_TARGET)
			switch(ev.tgt.kind){
				case TARGET_COMMAND_STEPFRAME:
					printf("step: %d, source: %d\n",
						ev.tgt.ioevs[0].iv, ev.tgt.ioevs[1].iv);
					if (ev.tgt.ioevs[1].iv > 1){
						if (step == ev.tgt.ioevs[1].iv-2)
							printf("custom timer %d OK\n", step);
						else
							printf("timer out of synch, expected %d got %d\n",
							step, ev.tgt.ioevs[1].iv-2);
						step++;
					}
				break;
				case TARGET_COMMAND_EXIT:
					goto done; /* break(1), please */
				default:
				break;
			}
	}

done:
	arcan_shmif_drop(&cont);
	return EXIT_SUCCESS;
}
Beispiel #3
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;
}