#include"node.h" #include #include #include #include #include #include #include #include #include #include #include"img.h" #include"linearity.h" static Display *d; static Window root; static int find_window(Display *d, Window *w, const char *contains) { if(contains) { int found = 0; Atom atom = XInternAtom(d, "_NET_CLIENT_LIST", 1); Atom actualType; int format; unsigned long numItems, bytesAfter; Window *list; XTextProperty windowName; int status = XGetWindowProperty(d, root, atom, 0L, ~0L, 0, AnyPropertyType, &actualType, &format, &numItems, &bytesAfter, (unsigned char**) &list); if(status >= Success) { for(int i = 0; i < numItems; i++) { status = XGetWMName(d, list[i], &windowName); if(status >= Success) { if(windowName.value && strstr(windowName.value, contains)) { *w = list[i]; found = 1; break; } } } } XFree(list); return found; } else { *w = root; return 1; } } typedef struct { CHiPubNode pub; Window xcache; XImage *ximg; XShmSegmentInfo shminfo; CHiImage *vcache; } CHiWindowNode; static int window_perform(CHiPubNode *n) { CHiWindowNode *w = (CHiWindowNode*) n; Window toshoot; if(!find_window(d, &toshoot, CHi_Crawl(&n->sinks[0])->data.text)) return 0; size_t stride; if(!w->xcache || w->xcache != toshoot) { w->xcache = toshoot; XWindowAttributes attrs; XGetWindowAttributes(d, toshoot, &attrs); w->ximg = XShmCreateImage(d, attrs.visual, 32, ZPixmap, NULL, &w->shminfo, attrs.width, attrs.height); stride = ((w->ximg->bytes_per_line + 15) & ~15); w->shminfo.shmid = shmget(IPC_PRIVATE, stride * w->ximg->height, IPC_CREAT | 0777); w->shminfo.shmaddr = w->ximg->data = shmat(w->shminfo.shmid, 0, 0); w->shminfo.readOnly = False; XShmAttach(d, &w->shminfo); w->vcache = CHi_Image_New(2, 4, 8 * attrs.width, attrs.width, attrs.height, NULL); } else { stride = ((w->ximg->bytes_per_line + 15) & ~15); } XWindowAttributes toshootattrs; XGetWindowAttributes(d, w->xcache, &toshootattrs); XShmGetImage(d, w->xcache, w->ximg, 0, 0, AllPlanes); // Turn u8 image to u16 #pragma omp parallel for for(size_t y = 0; y < w->vcache->height; y++) { for(size_t x = 0; x < w->vcache->width; x += 2) { __m128i c = _mm_loadu_si128((__m128i*) ((uintptr_t) w->ximg->data + y * w->ximg->bytes_per_line + x * 4)); c = _mm_shuffle_epi8(c, _mm_set_epi8(7, -128, 6, -128, 5, -128, 4, -128, 3, -128, 2, -128, 1, -128, 0, -128)); c = apply_gamma_epi16(c, _mm_set_ps(1, 2.2f, 2.2f, 2.2f)); _mm_storeu_si128((__m128i*) ((uintptr_t) w->vcache->data16 + y * w->vcache->stride + x * 8), c); } } n->sources[0].type = CUTIHI_VAL_SAMPLE; n->sources[0].data.sample = w->vcache; n->clean = 0; return 1; } CUTIVIS CHiPubNode *CHi_Window() { if(!d) { d = XOpenDisplay(NULL); root = RootWindow(d, DefaultScreen(d)); } CHiWindowNode *n = malloc(sizeof(*n)); n->pub.type = CUTIHI_T('CWin','dow '); n->pub.Start = n->pub.Stop = NULL; n->pub.Perform = window_perform; n->pub.clean = 0; n->pub.sinkCount = 1; n->pub.sinks = calloc(sizeof(*n->pub.sinks), 1); n->pub.sourceCount = 1; n->pub.sources = calloc(sizeof(*n->pub.sources), 1); n->xcache = 0; n->vcache = NULL; return &n->pub; } // All of the following are ews CUTIVIS size_t CHi_Window_GetSourceCount() { Atom atom = XInternAtom(d, "_NET_CLIENT_LIST", 1); Atom actualType; int format; unsigned long numItems, bytesAfter; Window *list; int status = XGetWindowProperty(d, root, atom, 0L, ~0L, 0, AnyPropertyType, &actualType, &format, &numItems, &bytesAfter, (unsigned char**) &list); return status >= Success ? numItems : 0; } CUTIVIS const char *CHi_Window_GetSourceName(size_t idx) { int found = 0; Atom atom = XInternAtom(d, "_NET_CLIENT_LIST", 1); Atom actualType; int format; unsigned long numItems, bytesAfter; Window *list; XTextProperty windowName; int status = XGetWindowProperty(d, root, atom, 0L, ~0L, 0, AnyPropertyType, &actualType, &format, &numItems, &bytesAfter, (unsigned char**) &list); if(status >= Success) { status = XGetWMName(d, list[idx], &windowName); if(status >= Success) { found = 1; } } return found ? strdup(windowName.value ? windowName.value : "") : NULL; } CUTIVIS uintptr_t CHi_Window_GetSourceData(size_t idx) { Atom atom = XInternAtom(d, "_NET_CLIENT_LIST", 1); Atom actualType; int format; unsigned long numItems, bytesAfter; Window *list; int status = XGetWindowProperty(d, root, atom, 0L, ~0L, 0, AnyPropertyType, &actualType, &format, &numItems, &bytesAfter, (unsigned char**) &list); if(status >= Success) { return list[idx]; } return 0; } CUTIVIS size_t CHi_Window_GetNextSource(size_t i) { return i + 1; }