
screen_capture_lite turned out to be pretty broken and so I brought back my old X11 implementation for the Window node, for Unices only. Hopefully SCL actually works on Windows because lemme tell you, I do not want to go knee-deep in that. Additionally, SAIL was replaced with stb_image because I couldn't get SAIL to build under MinGW.
150 lines
3.9 KiB
C
150 lines
3.9 KiB
C
#include"relay.h"
|
|
|
|
#include"img.h"
|
|
#include<tmmintrin.h>
|
|
#include<stdio.h>
|
|
#include<pthread.h>
|
|
#include<stdatomic.h>
|
|
#include<math.h>
|
|
#include<windows.h>
|
|
#include<winuser.h>
|
|
#include<pthread.h>
|
|
|
|
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;
|
|
}
|