commit: a33724dc36ec4ac8d3c347d8903fe3a811c40ca5
parent:
author: Chris Noxz <chris@noxz.tech>
date: Mon, 21 Jun 2021 10:53:58 +0200
Initial commit
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;
+}