#include"relay.h" #include"img.h" #include #include #include #include #include #include #include static int scale_perform(CHiPubNode *n) { float *scales = CHi_Crawl(&n->sinks[0])->data.vec4; CHiImage *img = CHi_Crawl(&n->sinks[1])->data.sample; if(n->sources[0].data.sample) { CHi_Image_Free(n->sources[0].data.sample); } CHiImage *ret = n->sources[0].data.sample = CHi_Image_New(img->bpc, img->channels, img->stride, img->width, img->height, NULL); __m128i iscales = _mm_set_epi16( scales[3] * 65535, scales[0] * 65535, scales[1] * 65535, scales[2] * 65535, scales[3] * 65535, scales[0] * 65535, scales[1] * 65535, scales[2] * 65535 ); for(size_t y = 0; y < img->height; y++) { for(size_t x = 0; x < img->width; x += 16) { __m128i pixels8 = _mm_loadu_si128((__m128i*) ((uintptr_t) img->data16 + y * img->stride + x)); __m128i mulled = _mm_mulhi_epu16(pixels8, iscales); _mm_storeu_si128((__m128i*) ((uintptr_t) ret->data16 + y * img->stride + x), mulled); } } return 1; } CUTIVIS CHiPubNode *CHi_ComponentScale() { CHiPubNode *n = calloc(1, sizeof(*n)); n->type = CUTIHI_T('CCmp','nScl'); n->Start = n->Stop = NULL; n->Perform = scale_perform; n->clean = 0; n->sinkCount = 2; n->sinks = calloc(sizeof(*n->sinks), n->sinkCount); n->sourceCount = 1; n->sources = calloc(sizeof(*n->sources), n->sourceCount); return n; } static Display *dpy; typedef struct { CHiPubNode pub; XRecordContext rc; pthread_t thrd; atomic_int key; atomic_bool on; } CHiKeyhookNode; static void keyhook_handler(XPointer ud, XRecordInterceptData *recdata) { if(recdata->category != XRecordFromServer) { return; } int type = ((unsigned char*) recdata->data)[0] & 0x7F; int key = ((unsigned char*) recdata->data)[1]; int repeat = recdata->data[2] & 1; CHiKeyhookNode *n = (CHiKeyhookNode*) ud; printf("%i\n", key); if(!repeat && key == n->key) { if(type == KeyPress) { n->on = 1; } else if(type == KeyRelease) { n->on = 0; } } XRecordFreeData(recdata); } static void *keyhook_thread(void *ud) { CHiKeyhookNode *n = ud; XRecordRange *rr = XRecordAllocRange(); rr->device_events.first = KeyPress; rr->device_events.last = ButtonRelease; n->rc = XRecordCreateContext(dpy, 0, &(XRecordClientSpec) {XRecordAllClients}, 1, &rr, 1); XRecordEnableContext(dpy, n->rc, keyhook_handler, (XPointer) n); return NULL; } static int keyhook_perform(CHiPubNode *n) { ((CHiKeyhookNode*) n)->key = CHi_Crawl(&n->sinks[0])->data.vec4[0]; n->sources[0].type = CUTIHI_VAL_VEC4; if(n->ng->compilationStatus == CUTIHI_COMP_READY || n->sinks[1].data.vec4[0] == 0) { n->sources[0].data.vec4[0] = ((CHiKeyhookNode*) n)->on; } else if(((CHiKeyhookNode*) n)->on) { n->sources[0].data.vec4[0] = fminf(1, n->sources[0].data.vec4[0] + CHi_Time_GetDelta(n->ng) * n->sinks[1].data.vec4[0]); } else { n->sources[0].data.vec4[0] = fmaxf(0, n->sources[0].data.vec4[0] - CHi_Time_GetDelta(n->ng) * n->sinks[1].data.vec4[0]); } return 1; } static void keyhook_destroy(CHiPubNode *pubn) { CHiKeyhookNode *n = (void*) pubn; XRecordDisableContext(dpy, n->rc); XRecordFreeContext(dpy, n->rc); free(n); } CUTIVIS CHiPubNode *CHi_Keyhook() { CHiKeyhookNode *n = calloc(1, sizeof(*n)); n->pub.type = CUTIHI_T('CKey','hook'); n->pub.Start = n->pub.Stop = NULL; n->pub.Perform = keyhook_perform; n->pub.Destroy = keyhook_destroy; n->pub.clean = 0; n->pub.sinkCount = 2; n->pub.sinks = calloc(sizeof(*n->pub.sinks), n->pub.sinkCount); n->pub.sourceCount = 1; n->pub.sources = calloc(sizeof(*n->pub.sources), n->pub.sourceCount); n->on = 0; n->key = 0; if(!dpy) { dpy = XOpenDisplay(NULL); } pthread_create(&n->thrd, NULL, keyhook_thread, n); return &n->pub; }