diff options
| author | kj_sh604 | 2026-06-05 16:07:29 -0400 |
|---|---|---|
| committer | kj_sh604 | 2026-06-05 16:07:29 -0400 |
| commit | c5e0cd0b718c95e1120cb05efcbd96d29d1c0ec5 (patch) | |
| tree | ce2eaa8b45dadaa82836e8afb377d6352cc3da56 | |
| parent | 608a93f403009f25d3ef9deffbf48253808dbcc2 (diff) | |
refactor: src/screenshot.h
| -rw-r--r-- | src/screenshot.h | 96 |
1 files changed, 96 insertions, 0 deletions
diff --git a/src/screenshot.h b/src/screenshot.h new file mode 100644 index 0000000..96cee42 --- /dev/null +++ b/src/screenshot.h @@ -0,0 +1,96 @@ +#ifndef SCREENSHOT_H +#define SCREENSHOT_H + +#include <X11/Xlib.h> +#include <X11/Xutil.h> + +#ifdef USE_XSHM +#include <X11/extensions/XShm.h> +#endif + +typedef struct { + XImage *image; +#ifdef USE_XSHM + XShmSegmentInfo *shminfo; +#endif +} Screenshot; + +Screenshot *new_screenshot(Display *display, Window window); +void destroy_screenshot(Display *display, Screenshot *screenshot); + +// TODO(20260315T135543): maybe add error checking + +#ifdef SCREENSHOT_IMPL + +#include <stdlib.h> + +#ifdef USE_XSHM +#include <sys/shm.h> +#endif + +#define UNUSED(x) (void)(x) + +Screenshot *new_screenshot(Display *d, Window w) { + Screenshot *result = malloc(sizeof(Screenshot)); + + XWindowAttributes attributes; + XGetWindowAttributes(d, w, &attributes); + +#ifdef USE_XSHM + result->shminfo = malloc(sizeof(XShmSegmentInfo)); + + int screen = DefaultScreen(d); + + result->image = XShmCreateImage( + d, + DefaultVisual(d, screen), + DefaultDepthOfScreen(ScreenOfDisplay(d, screen)), + ZPixmap, + NULL, + result->shminfo, + attributes.width, + attributes.height + ); + + result->shminfo->shmid = shmget( + IPC_PRIVATE, + result->image->bytes_per_line * result->image->height, + IPC_CREAT | 0777 + ); + + result->shminfo->shmaddr = (char*)shmat(result->shminfo->shmid, 0, 0); + result->image->data = result->shminfo->shmaddr; + result->shminfo->readOnly = False; + + XShmAttach(d, result->shminfo); + + XShmGetImage(d, w, result->image, 0, 0, AllPlanes); +#else // USE_XSHM + result->image = XGetImage(d, w, 0, 0, + attributes.width, attributes.height, + AllPlanes, ZPixmap); +#endif // USE_XSHM + + return result; +} + +void destroy_screenshot(Display *d, Screenshot *s) { + if (!s) return; + +#ifdef USE_XSHM + XSync(d, False); + XShmDetach(d, s->shminfo); + XDestroyImage(s->image); + shmdt(s->shminfo->shmaddr); + shmctl(s->shminfo->shmid, IPC_RMID, 0); + free(s->shminfo); +#else + UNUSED(d); + XDestroyImage(s->image); +#endif + free(s); +} + +#endif // SCREENSHOT_IMPL + +#endif // SCREENSHOT_H |
