git.strcat.st

/strcat/ss.git/ - summarytreelogarchive

subject
init
commit
a2d81d4aa46a4aeded8c96e715021000f8a0e139
date
2026-04-21T03:05:13Z
message
diff
 Makefile |  12 +++++++
 ss.c     | 108 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 120 insertions(+)

diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000..46b2951
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,12 @@
+CFLAGS   = -std=c89 -Wall -Wextra -Werror -pedantic
+CPPFLAGS = -I/usr/X11R6/include
+LDFLAGS  = -L/usr/X11R6/lib
+LDLIBS   = -lX11
+
+all: ss 
+
+ss: ss.c
+	cc $(CPPFLAGS) $(CFLAGS) -o ss ss.c $(LDFLAGS) $(LDLIBS)
+
+clean:
+	rm -f ss
diff --git a/ss.c b/ss.c
new file mode 100644
index 0000000..04940bf
--- /dev/null
+++ b/ss.c
@@ -0,0 +1,108 @@
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+
+static unsigned long
+lowbit(unsigned long x)
+{
+	return x & (~x + 1UL);
+}
+
+static unsigned char
+chan(unsigned long pixel, unsigned long mask)
+{
+	unsigned long base;
+	unsigned long max;
+	unsigned long v;
+
+	if (mask == 0)
+	    return 0;
+	base = lowbit(mask);
+	max = mask / base;
+	v = (pixel & mask) / base;
+	if (max == 0)
+	    return 0;
+	return (unsigned char)((v * 255UL + (max / 2UL)) / max);
+}
+
+int
+main(int argc, char **argv)
+{
+	Display *dpy;
+	Window root;
+	XImage *img;
+	FILE *f;
+	unsigned int w;
+	unsigned int h;
+	int x;
+	int y;
+	int sw;
+	int sh;
+	int ix;
+	int iy;
+	char tail;
+
+	if (argc != 3) {
+	    fprintf(stderr, "usage: ss WIDTHxHEIGHT+X+Y file.ppm\n");
+	    return 1;
+	}
+	if (sscanf(argv[1], "%ux%u+%d+%d%c", &w, &h, &x, &y, &tail) != 4 || w == 0 || h == 0) {
+	    fprintf(stderr, "invalid geometry: %s\n", argv[1]);
+	    return 1;
+	}
+	if ((dpy = XOpenDisplay(NULL)) == NULL) {
+	    fprintf(stderr, "failed to open X display\n");
+	    return 1;
+	}
+
+	sw = DisplayWidth(dpy, DefaultScreen(dpy));
+	sh = DisplayHeight(dpy, DefaultScreen(dpy));
+	if (x < 0 || y < 0 || x + (int)w > sw || y + (int)h > sh) {
+	    fprintf(stderr, "geometry out of bounds (%dx%d screen)\n", sw, sh);
+	    XCloseDisplay(dpy);
+	    return 1;
+	}
+
+	root = DefaultRootWindow(dpy);
+	img = XGetImage(dpy, root, x, y, w, h, AllPlanes, ZPixmap);
+	if (img == NULL) {
+	    fprintf(stderr, "XGetImage failed\n");
+	    XCloseDisplay(dpy);
+	    return 1;
+	}
+
+	f = fopen(argv[2], "wb");
+	if (f == NULL) {
+	    fprintf(stderr, "failed to open output: %s\n", argv[2]);
+	    XDestroyImage(img);
+	    XCloseDisplay(dpy);
+	    return 1;
+	}
+
+	fprintf(f, "P6\n%u %u\n255\n", w, h);
+	for (iy = 0; iy < (int)h; iy++) {
+	    for (ix = 0; ix < (int)w; ix++) {
+	        unsigned long p;
+	        unsigned char rgb[3];
+
+	        p = XGetPixel(img, ix, iy);
+	        rgb[0] = chan(p, img->red_mask);
+	        rgb[1] = chan(p, img->green_mask);
+	        rgb[2] = chan(p, img->blue_mask);
+	        if (fwrite(rgb, 1, 3, f) != 3) {
+	            fprintf(stderr, "write failed: %s\n", argv[2]);
+	            fclose(f);
+	            XDestroyImage(img);
+	            XCloseDisplay(dpy);
+	            return 1;
+	        }
+	    }
+	}
+
+	fclose(f);
+	XDestroyImage(img);
+	XCloseDisplay(dpy);
+	return 0;
+}