Last active
June 26, 2022 14:12
-
-
Save rexim/2febe9f5a5376b476d33d5d16590ecfd to your computer and use it in GitHub Desktop.
MIT-SHM example https://www.x.org/releases/X11R7.7/doc/xextproto/shm.html
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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