bool senseye_connect(const char* key, FILE* log, struct senseye_cont* dcont, struct arg_arr** darg, enum SHMIF_FLAGS flags) { logout = log; if (!key){ if ( (key = getenv("ARCAN_CONNPATH")) == NULL){ FLOG("Senseye, attempting to connect to arcan using 'senseye' key"); key = "senseye"; } } dcont->priv = malloc(sizeof(struct senseye_priv)); if (!dcont->priv) return false; memset(dcont->priv, '\0', sizeof(struct senseye_priv)); dcont->refresh = cont_refresh; dcont->dispatch = cont_dispatch; dcont->context = cont_getctx; setenv("ARCAN_CONNPATH", key, 0); dcont->priv->cont = arcan_shmif_open(SEGID_SENSOR, flags, darg); unsetenv("ARCAN_CONNPATH"); opts.args = *darg; if (dcont->priv->cont.addr != NULL) return true; free(dcont->priv); dcont->priv = NULL; return false; }
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; bool running = true; arcan_shmif_resize(&cont, 320, 200); /* fill with red and transfer */ for (size_t row = 0; row < cont.addr->h; row++) for (size_t col = 0; col < cont.addr->w; col++) cont.vidp[ row * cont.addr->w + col ] = RGBA(255, 0, 0, 255); arcan_shmif_signal(&cont, SHMIF_SIGVID); while (running && arcan_shmif_wait(&cont, &ev)){ if (ev.category == EVENT_TARGET) switch (ev.tgt.kind){ case TARGET_COMMAND_EXIT: running = false; default: break; } } return EXIT_SUCCESS; }
int main(int argc, char** argv) #endif { struct arg_arr* aarr; struct arcan_shmif_cont cont = arcan_shmif_open( SEGID_APPLICATION, SHMIF_ACQUIRE_FATALFAIL, &aarr); arcan_event ev; bool running = true; arcan_shmif_resize(&cont, 640, 480); uint8_t step_r = 0; uint8_t step_g = 0; uint8_t step_b = 255; int frames = 0; while(running){ if (frames++ > 200){ printf("send resize\n"); arcan_shmif_resize(&cont, 128 + (rand() % 1024), 128 + (rand() % 1024)); printf("unlock resize\n"); frames = 0; } printf("frame(%zu, %zu)\n", cont.w, cont.h); for (size_t row = 0; row < cont.h; row++) for (size_t col = 0; col < cont.w; col++){ cont.vidp[ row * cont.addr->w + col ] = SHMIF_RGBA(step_r, step_g, step_b, 0xff); step_r++; step_g += step_r == 255; step_b += step_g == 255; } arcan_shmif_signal(&cont, SHMIF_SIGVID); int rv; while ( (rv = arcan_shmif_poll(&cont, &ev)) == 1){ if (ev.category == EVENT_TARGET) switch (ev.tgt.kind){ case TARGET_COMMAND_EXIT: running = false; break; default: break; } } } #ifndef ENABLE_FSRV_AVFEED return EXIT_SUCCESS; #endif }
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; }
int main(int argc, char** argv) #endif { struct arg_arr* aarr; struct arcan_shmif_cont cont = arcan_shmif_open( SEGID_APPLICATION, SHMIF_ACQUIRE_FATALFAIL, &aarr); struct arcan_shmif_initial* init; if (sizeof(struct arcan_shmif_initial) != arcan_shmif_initial(&cont, &init)){ printf("couldn't query initial primary segment properties\n"); #ifndef ENABLE_FSRV_AVFEED return EXIT_FAILURE; #endif } printf("initial properties:\n\ \twidth * height: %zu * %zu stride: %zu pitch: %zu\n\ \taudio buffers: %d, audio buffer size: %d\n\ \tdensity: %f\n\ \tlang: %s, text_lang: %s, country: %s, UTF+%d\n\ \tlat: %f, long: %f, elev: %f\n\ disp_px_w: %zu, disp_px_h: %zu, disp_rgb: %d, disp_refresh: %d\n\ render_node: %d\n", cont.w, cont.h, cont.stride, cont.pitch, (int) cont.abuf_cnt, (int) cont.abufsize, init->density, init->lang, init->text_lang, init->country, init->timezone, init->latitude, init->longitude, init->elevation, init->display_width_px, init->display_height_px, init->rgb_layout, (int)init->rate, init->render_node); for (size_t i = 0; i < 4; i++){ printf("font[%zu] = .fd = %d, .hint = %d, " ".size_mm = %f, .size_pt = %zu\n", i, init->fonts[i].fd, init->fonts[i].hinting, init->fonts[i].size_mm, SHMIF_PT_SIZE(init->density, init->fonts[i].size_mm)); } #ifndef ENABLE_FSRV_AVFEED return EXIT_SUCCESS; #endif }
int main(int argc, char** argv) #endif { struct arg_arr* aarr; struct arcan_shmif_cont cont = arcan_shmif_open( SEGID_APPLICATION, SHMIF_ACQUIRE_FATALFAIL, &aarr); arcan_shmif_signal(&cont, SHMIF_SIGVID); while (1){ arcan_shmif_resize_ext(&cont, cont.w, cont.h, (struct shmif_resize_ext){ .meta = SHMIF_META_CM }); if (arcan_shmif_substruct(&cont, SHMIF_META_CM).cramp) break; printf("no gamma, retrying in 1s\n"); sleep(1); }
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; }
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; }