wall2pnm.c
1#include <stdarg.h>
2#include <stdio.h>
3#include <stdlib.h>
4#include <X11/Xlib.h>
5#include <X11/Xatom.h>
6#include <X11/Xutil.h>
7
8static void
9die(const char *errstr, ...)
10{
11 va_list ap;
12
13 va_start(ap, errstr);
14 vfprintf(stderr, errstr, ap);
15 va_end(ap);
16 exit(1);
17}
18
19static Pixmap
20getrootpixmap(Display* display, Window *root)
21{
22 Pixmap pixmap = 0;
23 Atom act_type;
24 int act_format;
25 unsigned long nitems, bytes_after;
26 unsigned char *data = NULL;
27 Atom _XROOTPMAP_ID = XInternAtom(display, "_XROOTPMAP_ID", False);
28
29 if (XGetWindowProperty(display, *root, _XROOTPMAP_ID, 0, 1, False, XA_PIXMAP, &act_type, &act_format, &nitems, &bytes_after, &data) == Success && data) {
30 pixmap = *((Pixmap *) data);
31 XFree(data);
32 }
33
34 return pixmap;
35}
36
37static void
38writepnm(XImage *img, FILE *outfile)
39{
40 int x, y;
41 long pixel;
42
43 fprintf(outfile, "P6\n%d %d\n255\n", img->width, img->height);
44 for (y = 0; y < img->height; y++) {
45 for (x = 0; x < img->width && (pixel = XGetPixel(img, x, y)); x++)
46 fprintf(outfile, "%c%c%c",
47 (char)(pixel>>16),
48 (char)((pixel&0x00ff00)>>8),
49 (char)(pixel&0x0000ff));
50 }
51}
52
53int
54main(int argc, const char *argv[])
55{
56 FILE *outfile;
57 Window root;
58 Display *display;
59 XWindowAttributes wa;
60 Pixmap bg;
61 XImage *img = NULL;
62
63 if (argc < 2)
64 die("Usage: %s [filename]\n", argv[0]);
65
66 if (!(display = XOpenDisplay(getenv("DISPLAY"))))
67 die("Cannot connect to X Server %s\n", getenv("DISPLAY") ? getenv("DISPLAY") : "(default)");
68
69 root = RootWindow(display, DefaultScreen(display));
70 XGetWindowAttributes(display, root, &wa);
71
72 if ((bg = getrootpixmap(display, &root))) {
73 img = XGetImage(display, bg, 0, 0, wa.width, wa.height, ~0, ZPixmap);
74 XFreePixmap(display, bg);
75 }
76
77 if (!img)
78 die("Cannot create XImage\n");
79
80 if (!(outfile = fopen(argv[1], "wb")))
81 die("Cannot open output file %s", argv[1]);
82
83 writepnm(img, outfile);
84 XDestroyImage(img);
85 fclose(outfile);
86
87 return 0;
88}