xscreenshot

screen capture tool (mirror)
git clone git@git.2f30.org/xscreenshot.git
Log | Files | Refs | README | LICENSE

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 }