xscreenshot.c (2199B)
1 /* see LICENSE / README for more info */ 2 #include <arpa/inet.h> 3 4 #include <err.h> 5 #include <errno.h> 6 #include <stdio.h> 7 #include <stdint.h> 8 #include <stdlib.h> 9 #include <string.h> 10 11 #include <X11/X.h> 12 #include <X11/Xlib.h> 13 #include <X11/Xutil.h> 14 15 int 16 main(int argc, char *argv[]) 17 { 18 XImage *img; 19 Display *dpy; 20 Window win; 21 XWindowAttributes attr; 22 uint32_t tmp, w, h; 23 uint16_t rgba[4]; 24 int sr, sg, fr, fg, fb; 25 char *ep; 26 27 if (!(dpy = XOpenDisplay(NULL))) 28 errx(1, "XOpenDisplay"); 29 30 /* identify window */ 31 if (argc > 1) { 32 if (!strcmp(argv[1], "-h") || !strcmp(argv[1], "-v")) { 33 fprintf(stderr, "usage: %s [winid]\n", argv[0]); 34 return 1; 35 } 36 errno = 0; 37 38 win = (Window)strtol(argv[1], &ep, 0); 39 if (errno || argv[1] == ep || *ep != '\0') { 40 fprintf(stderr, "strtol: invalid number: \"%s\"%s%s\n", 41 argv[1], 42 errno ? ": " : "", 43 errno ? strerror(errno) : ""); 44 exit(1); 45 } 46 } else { 47 win = RootWindow(dpy, 0); 48 } 49 50 XGrabServer(dpy); 51 XGetWindowAttributes(dpy, win, &attr); 52 img = XGetImage(dpy, win, 0, 0, attr.width, attr.height, 0xffffffff, 53 ZPixmap); 54 XUngrabServer(dpy); 55 XCloseDisplay(dpy); 56 if (!img) 57 errx(1, "XGetImage"); 58 59 switch (img->bits_per_pixel) { 60 case 16: /* only 5-6-5 format supported */ 61 sr = 11; 62 sg = 5; 63 fr = fb = 2047; 64 fg = 1023; 65 break; 66 case 24: 67 case 32: /* ignore alpha in case of 32-bit */ 68 sr = 16; 69 sg = 8; 70 fr = fg = fb = 257; 71 break; 72 default: 73 errx(1, "unsupported bpp: %d", img->bits_per_pixel); 74 } 75 76 /* write header with big endian width and height-values */ 77 fprintf(stdout, "farbfeld"); 78 tmp = htonl(img->width); 79 fwrite(&tmp, sizeof(uint32_t), 1, stdout); 80 tmp = htonl(img->height); 81 fwrite(&tmp, sizeof(uint32_t), 1, stdout); 82 83 /* write pixels */ 84 for (h = 0; h < (uint32_t)img->height; h++) { 85 for (w = 0; w < (uint32_t)img->width; w++) { 86 tmp = XGetPixel(img, w, h); 87 rgba[0] = htons(((tmp & img->red_mask) >> sr) * fr); 88 rgba[1] = htons(((tmp & img->green_mask) >> sg) * fg); 89 rgba[2] = htons((tmp & img->blue_mask) * fb); 90 rgba[3] = htons(65535); 91 92 if (fwrite(&rgba, 4 * sizeof(uint16_t), 1, stdout) != 1) 93 err(1, "fwrite"); 94 } 95 } 96 XDestroyImage(img); 97 98 return 0; 99 }