#include"relay.h" #include"img.h" #include #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->sinkCount = 2; n->sinks = calloc(sizeof(*n->sinks), n->sinkCount); n->sourceCount = 1; n->sources = calloc(sizeof(*n->sources), n->sourceCount); return n; } typedef struct { CHiPubNode pub; pthread_t thrd; char key[64]; atomic_bool on; atomic_bool active; } CHiKeyhookNode; static _Thread_local CHiKeyhookNode *lookwhatyoumademedo; static LRESULT CALLBACK keyhook_handler(int nCode, WPARAM wParam, LPARAM lParam) { bool eatKeystroke = false; CHiKeyhookNode *n = lookwhatyoumademedo; if(nCode == HC_ACTION) { switch(wParam) { case WM_KEYDOWN: case WM_SYSKEYDOWN: case WM_KEYUP: case WM_SYSKEYUP: { PKBDLLHOOKSTRUCT p = (PKBDLLHOOKSTRUCT) lParam; bool press = wParam == WM_KEYDOWN || wParam == WM_SYSKEYDOWN; char keyname[64]; GetKeyNameTextA(p->vkCode, keyname, sizeof(keyname)); if(!strcmp(keyname, n->key)) { n->on = press; } break; } } } return eatKeystroke ? true : CallNextHookEx(NULL, nCode, wParam, lParam); } static void *keyhook_thread(void *ud) { CHiKeyhookNode *n = ud; lookwhatyoumademedo = n; HHOOK hhkLowLevelKybd = SetWindowsHookEx(WH_KEYBOARD_LL, keyhook_handler, 0, 0); MSG msg; while(n->active && !GetMessage(&msg, NULL, NULL, NULL)) { TranslateMessage(&msg); DispatchMessage(&msg); } UnhookWindowsHookEx(hhkLowLevelKybd); return NULL; } static int keyhook_perform(CHiPubNode *n) { CHiKeyhookNode *me = (CHiKeyhookNode*) n; strncpy(me->key, CHi_Crawl(&n->sinks[0])->data.text, 63); me->key[63] = '\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; n->active = false; pthread_join(n->thrd, NULL); 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.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] = '\n'; n->active = true; pthread_create(&n->thrd, NULL, keyhook_thread, n); return &n->pub; }