Skip to content

Instantly share code, notes, and snippets.

@rexim
Last active June 26, 2022 14:12
Show Gist options
  • Save rexim/2febe9f5a5376b476d33d5d16590ecfd to your computer and use it in GitHub Desktop.
Save rexim/2febe9f5a5376b476d33d5d16590ecfd to your computer and use it in GitHub Desktop.
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <X11/Xlib.h> /* of course */
#include <X11/Xutil.h> /* duuuh */
#include <sys/ipc.h>
#include <sys/shm.h>
#include <X11/extensions/XShm.h> /* obviously */
void save_image_as_ppm(XImage *image, const char *filepath)
{
FILE *f = fopen(filepath, "wb");
fprintf(f, "P6\n");
fprintf(f, "%d %d\n", image->width, image->height);
fprintf(f, "255\n");
for (int i = 0; i < image->width * image->height; ++i) {
putc(image->data[i * 4 + 2], f);
putc(image->data[i * 4 + 1], f);
putc(image->data[i * 4 + 0], f);
}
fclose(f);
}
int main(int argc, char *argv[])
{
Display *display = XOpenDisplay(NULL);
if (display == NULL) {
fprintf(stderr, "Could not open Display\n");
abort();
}
int major = 0, minor = 0;
Bool pixmaps = 0;
XShmQueryVersion(display, &major, &minor, &pixmaps);
printf("SHM Version %d.%d, Pixmaps supported: %s\n",
major, minor,
pixmaps ? "yesu" : "nah");
XVisualInfo vinfo;
XMatchVisualInfo(
display,
XDefaultScreen(display),
24,
TrueColor,
&vinfo);
XWindowAttributes attributes;
XGetWindowAttributes(
display,
DefaultRootWindow(display),
&attributes);
XShmSegmentInfo shminfo;
XImage *image = XShmCreateImage(
display, vinfo.visual, 24, ZPixmap, NULL,
&shminfo,
attributes.width,
attributes.height);
shminfo.shmid = shmget(
IPC_PRIVATE,
image->bytes_per_line * image->height,
IPC_CREAT | 0777);
shminfo.shmaddr = image->data = shmat(shminfo.shmid, 0, 0);
shminfo.readOnly = False;
Status err = XShmAttach(display, &shminfo);
assert(err != 0);
XSync(display, False);
XShmGetImage(display, DefaultRootWindow(display), image, 0, 0, AllPlanes);
XSync(display, False);
save_image_as_ppm(image, "screenshot.ppm");
XShmDetach(display, &shminfo);
XDestroyImage(image);
shmdt(shminfo.shmaddr);
shmctl(shminfo.shmid, IPC_RMID, 0);
XCloseDisplay(display);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment