static shmif_pixel pack_byte(uint8_t val, bool rand, int pack) { shmif_pixel r = rand ? SHMIF_RGBA(random(), random(), random(), random()) : SHMIF_RGBA(val, val, val, val); if (pack != PACK_TIGHT) r |= SHMIF_RGBA(0x00, 0x00, 0x00, 0xff); return r; }
/* * Build the output buffer and push/synch to an external recipient, * taking mapping function, alpha population functions, and timing- * related metadata. */ static void ch_step(struct rwstat_ch* ch) { struct rwstat_ch_priv* chp = ch->priv; struct arcan_event outev = { .category = EVENT_EXTERNAL, .ext.kind = EVENT_EXTERNAL_FRAMESTATUS, .ext.framestatus.framenumber = ch->priv->cnt_local, .ext.framestatus.pts = ch->priv->cnt_total, }; size_t ntw = chp->base * chp->base; ch->event(ch, &outev); /* * Notify about the packing mode active for this frame. This is * needed for the parent to be able to determine what each byte * corresponds to. */ if (chp->status_dirty){ outev.ext.kind = EVENT_EXTERNAL_STREAMINFO; outev.ext.streaminf.streamid = 0; outev.ext.streaminf.datakind = 0; outev.ext.streaminf.langid[0] = 'a' + chp->pack; outev.ext.streaminf.langid[1] = 'a' + chp->map; outev.ext.streaminf.langid[2] = 'a' + chp->pack_sz; chp->status_dirty = false; ch->event(ch, &outev); } if ( 1 == (chp->clock & (RW_CLK_SLIDE)) ) rebuild_hgram(chp); if (chp->amode == RW_ALPHA_ENTBASE) update_entalpha(chp, chp->ent_base); else if (chp->amode == RW_ALPHA_PTN) update_ptnalpha(chp); for (size_t i = 0; i < chp->buf_sz; i += chp->pack_sz) pack_bytes(chp, &chp->buf[i], i / chp->pack_sz); chp->cont->addr->vpts = ch->priv->cnt_total; arcan_shmif_signal(chp->cont, SHMIF_SIGVID); chp->cnt_local = chp->cnt_total; /* non-sparse mappings require an output flush */ if (chp->map == MAP_TUPLE || chp->map == MAP_TUPLE_ACC){ shmif_pixel val = SHMIF_RGBA(0x00, 0x00, 0x00, 0xff); for (size_t i = 0; i < ntw; i++) chp->cont->vidp[i] = val; } } static void ch_event(struct rwstat_ch* ch, arcan_event* ev) { arcan_shmif_enqueue(ch->priv->cont, ev); }
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 }
static void ch_map(struct rwstat_ch* ch, enum rwstat_mapping map) { struct rwstat_ch_priv* chp = ch->priv; chp->map = map; if (chp->cmap){ free(chp->cmap); chp->cmap = NULL; } size_t hsz = ch->priv->base * ch->priv->base; /* some mapping modes need a LUT for the ofs = F(X,Y) */ if (map == MAP_WRAP || map == MAP_TUPLE || map == MAP_TUPLE_ACC) ; else if (map == MAP_HILBERT){ uint16_t* cmap = malloc( 2 * 2 * hsz ); for (size_t i = 0; i < hsz; i++){ int x, y; hilbert_d2xy(ch->priv->base, i, &x, &y); cmap[i * 2 + 0] = x; cmap[i * 2 + 1] = y; } chp->cmap = cmap; } /* changing mapping mode may require different packing dimensions reset the * buffer to reflect change in mapping mode, this doesn't matter in CLK_BYTES * but for other modes */ if (map == MAP_TUPLE || map == MAP_TUPLE_ACC){ shmif_pixel val = SHMIF_RGBA(0x00, 0x00, 0x00, 0xff); size_t ntw = chp->base * chp->base; for (size_t i = 0; i < ntw; i++) chp->cont->vidp[i] = val; } chp->status_dirty = true; ch_step(ch); }
#include <stdlib.h> #include <stdint.h> #include <stdio.h> #include <unistd.h> #include <stdbool.h> #include <pthread.h> #include <time.h> #include <math.h> #include <arcan_shmif.h> static shmif_pixel palette[] = { SHMIF_RGBA(0xff, 0x00, 0x00, 0xff), SHMIF_RGBA(0x00, 0xff, 0x00, 0xff), SHMIF_RGBA(0x00, 0x00, 0xff, 0xff), SHMIF_RGBA(0xff, 0xff, 0x00, 0xff), SHMIF_RGBA(0xff, 0x00, 0xff, 0xff), SHMIF_RGBA(0x00, 0xff, 0xff, 0xff), SHMIF_RGBA(0xff, 0xff, 0xff, 0xff) }; static float tones[] = { 16.35, 18.35, 20.60, 21.83, 24.50, 27.50, 30.87, 32.70, 30.87, 27.50, 24.50, 21.83, 20.60, 18.35 }; static int pi = 0; static int ti = 0; static float pos = 0; static long long time_ms()
static inline void pack_bytes( struct rwstat_ch_priv* chp, uint8_t* buf, size_t ofs) { int x = 0, y = 0; shmif_pixel val = 0; uint8_t alpha = 0xff; switch (chp->map){ case MAP_WRAP: x = ofs % chp->base; y = ofs / chp->base; break; case MAP_TUPLE: x = (float)buf[0] * chp->sf_x; y = (float)buf[1] * chp->sf_y; buf += 2; break; case MAP_TUPLE_ACC: { x = (float)buf[0] * chp->sf_x; y = (float)buf[1] * chp->sf_y; buf += 2; shmif_pixel ov = chp->cont->vidp[ y * chp->cont->pitch + x]; uint8_t v = (ov & 0x000000ff); v = v < 254 ? v + 1 : v; val = SHMIF_RGBA(v, v, v, 0xff); goto postpack; } break; case MAP_HILBERT: x = chp->cmap[ofs * 2 + 0]; y = chp->cmap[ofs * 2 + 1]; break; } switch (chp->pack){ case PACK_TIGHT: val = SHMIF_RGBA(buf[0], buf[1], buf[2], 0x00); alpha = buf[3]; break; case PACK_TNOALPHA: val = SHMIF_RGBA(buf[0], buf[1], buf[2], 0x00); alpha = chp->alpha[ofs]; break; case PACK_INTENS: val = SHMIF_RGBA(buf[0], buf[0], buf[0], 0x00); alpha = chp->alpha[ofs]; break; } postpack: if (chp->amode == RW_ALPHA_DELTA){ shmif_pixel vp = chp->cont->vidp[y * chp->cont->pitch + x]; alpha = 0xff * ((vp & 0x00ffffff) != val); } val |= SHMIF_RGBA(0, 0, 0, alpha); chp->cont->vidp[ y * chp->cont->pitch + x ] = val; }
* [ ] scrollbar / content feedback support */ #include <arcan_shmif.h> #include <pthread.h> #include "font.h" static void got_icon(struct arcan_shmif_cont* cont) { char buf[256]; arcan_shmif_enqueue(cont, &(arcan_event){ .ext.kind = ARCAN_EVENT(CLOCKREQ), .ext.clock.rate = 20}); uint8_t gv = 0; draw_box(cont, 0, 0, cont->w, cont->h, SHMIF_RGBA(0, 128, 0, 255)); arcan_shmif_signal(cont, SHMIF_SIGVID | SHMIF_SIGBLK_ONCE); arcan_event ev; while (arcan_shmif_wait(cont, &ev)){ if (ev.category == EVENT_TARGET) switch(ev.tgt.kind){ /* synch icon dimensions with displayhint */ case TARGET_COMMAND_DISPLAYHINT: arcan_shmif_resize(cont, ev.tgt.ioevs[0].iv, ev.tgt.ioevs[1].iv); break; case TARGET_COMMAND_STEPFRAME: /* repeat "fire-once" event time with some pseudorandom */ if (ev.tgt.ioevs[1].iv > 1){ arcan_shmif_enqueue(cont, &(arcan_event){