wall2pnm

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

commit: a33724dc36ec4ac8d3c347d8903fe3a811c40ca5
parent: 
author: Chris Noxz <chris@noxz.tech>
date:   Mon, 21 Jun 2021 10:53:58 +0200
Initial commit
A.gitignore2+
AMakefile41+++++++++
Aconfig.mk23+++++
Awall2pnm.c88++++++++++++++++++++
4 files changed, 154 insertions(+)
diff --git a/.gitignore b/.gitignore
@@ -0,0 +1,2 @@
+wall2pnm
+*.o
diff --git a/Makefile b/Makefile
@@ -0,0 +1,41 @@
+.POSIX:
+
+include config.mk
+
+SRC = wall2pnm.c
+OBJ = $(SRC:.c=.o)
+
+all: options wall2pnm
+
+options:
+	@echo wall2pnm build options:
+	@echo "VERSION = $(VERSION)"
+	@echo "CFLAGS  = $(STCFLAGS)"
+	@echo "LDFLAGS = $(STLDFLAGS)"
+	@echo "CC      = $(CC)"
+
+.c.o:
+	@echo CC $<
+	@$(CC) $(STCFLAGS) -c $<
+
+${OBJ}: config.mk
+
+wall2pnm: $(OBJ)
+	@echo CC -o $@
+	@$(CC) -o $@ $(OBJ) $(STLDFLAGS)
+
+clean:
+	@echo cleaning
+	@rm -f wall2pnm $(OBJ)
+
+install: wall2pnm
+	@echo installing executables to ${PREFIX}/bin
+	@mkdir -p ${PREFIX}/bin
+	@cp -f wall2pnm ${PREFIX}/bin
+	@chmod 755 ${PREFIX}/bin/wall2pnm
+
+uninstall:
+	@echo removing executable files from ${PREFIX}/bin
+	@rm -f ${PREFIX}/bin/wall2pnm
+
+.PHONY: all options clean install uninstall
diff --git a/config.mk b/config.mk
@@ -0,0 +1,23 @@
+# wall2pnm version
+VERSION = 0.1
+
+# paths
+PREFIX = /usr/local
+MANPREFIX = $(PREFIX)/share/man
+
+X11INC = /usr/X11R6/include
+X11LIB = /usr/X11R6/lib
+
+# includes and libs
+INCS = -I. -I/usr/include -I${X11INC}
+LIBS = -L/usr/lib -lc -lcrypt -L${X11LIB} -lX11 -lXext
+
+# flags
+CPPFLAGS = -DVERSION=\"$(VERSION)\" -D_DEFAULT_SOURCE -D_XOPEN_SOURCE=600
+CFLAGS = -Wall -Wno-format-truncation -pedantic -std=c99 ${INCS} ${CPPFLAGS}
+LDFLAGS = -s ${LIBS}
+STCFLAGS = $(CPPFLAGS) $(CFLAGS)
+STLDFLAGS = $(LDFLAGS)
+
+# compiler and linker
+CC = gcc
diff --git a/wall2pnm.c b/wall2pnm.c
@@ -0,0 +1,88 @@
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <X11/Xlib.h>
+#include <X11/Xatom.h>
+#include <X11/Xutil.h>
+
+static void
+die(const char *errstr, ...)
+{
+	va_list ap;
+
+	va_start(ap, errstr);
+	vfprintf(stderr, errstr, ap);
+	va_end(ap);
+	exit(1);
+}
+
+static Pixmap
+getrootpixmap(Display* display, Window *root)
+{
+	Pixmap pixmap = 0;
+	Atom act_type;
+	int act_format;
+	unsigned long nitems, bytes_after;
+	unsigned char *data = NULL;
+	Atom _XROOTPMAP_ID = XInternAtom(display, "_XROOTPMAP_ID", False);
+
+	if (XGetWindowProperty(display, *root, _XROOTPMAP_ID, 0, 1, False, XA_PIXMAP, &act_type, &act_format, &nitems, &bytes_after, &data) == Success && data) {
+		pixmap = *((Pixmap *) data);
+		XFree(data);
+	}
+
+	return pixmap;
+}
+
+static void
+writepnm(XImage *img, FILE *outfile)
+{
+	int x, y;
+	long pixel;
+
+	fprintf(outfile, "P6\n%d %d\n255\n", img->width, img->height);
+	for (y = 0; y < img->height; y++) {
+		for (x = 0; x < img->width && (pixel = XGetPixel(img, x, y)); x++)
+			fprintf(outfile, "%c%c%c",
+				(char)(pixel>>16),
+				(char)((pixel&0x00ff00)>>8),
+				(char)(pixel&0x0000ff));
+	}
+}
+
+int
+main(int argc, const char *argv[])
+{
+	FILE *outfile;
+	Window root;
+	Display *display;
+	XWindowAttributes wa;
+	Pixmap bg;
+	XImage *img = NULL;
+
+	if (argc < 2)
+		die("Usage: %s [filename]\n", argv[0]);
+
+	if (!(display = XOpenDisplay(getenv("DISPLAY"))))
+		die("Cannot connect to X Server %s\n", getenv("DISPLAY") ? getenv("DISPLAY") : "(default)");
+
+	root = RootWindow(display, DefaultScreen(display));
+	XGetWindowAttributes(display, root, &wa);
+
+	if ((bg = getrootpixmap(display, &root))) {
+		img = XGetImage(display, bg, 0, 0, wa.width, wa.height, ~0, ZPixmap);
+		XFreePixmap(display, bg);
+	}
+
+	if (!img)
+		die("Cannot create XImage\n");
+
+	if (!(outfile = fopen(argv[1], "wb")))
+		die("Cannot open output file %s", argv[1]);
+
+	writepnm(img, outfile);
+	XDestroyImage(img);
+	fclose(outfile);
+
+	return 0;
+}