wall2pnm

Tool for saving wallpaper as PNM
git clone https://noxz.tech/git/wall2pnm.git
wall2pnm

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}