diff options
| -rw-r--r-- | README.md | 11 | ||||
| -rwxr-xr-x | colitur-mu | bin | 46728 -> 47040 bytes | |||
| -rw-r--r-- | mu_x11.c | 29 |
3 files changed, 40 insertions, 0 deletions
@@ -76,6 +76,17 @@ and everything after it silently disappears, which looks like a layout or buffer-overflow bug and is neither. `set_clip()` clamps to the buffer bounds before converting. +### Verifying a frame without a screenshot + + MUX_DUMP=/tmp/frame.ppm ./colitur-mu # writes one frame, then exits + convert /tmp/frame.ppm /tmp/frame.png + +This reads back the off-screen PIXMAP, not the window. A window's contents +are not retained while it is obscured or sitting on an unfocused tag, so +`import`/`xwd` against one can return solid black while the program is +drawing perfectly -- which cost real time to work out once. A pixmap is +always there. + ### Which to use `colitur-x` renders; `colitur-mu` renders and lets you change the invocation. Binary files differ@@ -11,6 +11,7 @@ #include <X11/Xlib.h> #include <X11/Xft/Xft.h> #include <stdio.h> +#include <stdlib.h> #include <string.h> #include "vendor/microui.h" #include "mu_x11.h" @@ -145,4 +146,32 @@ void mux_present(mu_Context *ctx, int w, int h, mu_Color bg) XftDrawSetClip(xd, NULL); XCopyArea(dpy, buf, win, gc, 0, 0, w, h, 0, 0); XFlush(dpy); + + /* MUX_DUMP=path writes the frame out as a PPM and exits. Reading back + the off-screen PIXMAP rather than the window is what makes this + reliable: a window's contents are not retained when it is obscured or + on an unfocused tag, so screenshotting one can return black even + though the program is drawing perfectly. A pixmap is always there. */ + { + const char *path = getenv("MUX_DUMP"); + if (!path) return; + XImage *im = XGetImage(dpy, buf, 0, 0, w, h, AllPlanes, ZPixmap); + if (!im) { fprintf(stderr, "MUX_DUMP: XGetImage failed\n"); exit(1); } + FILE *f = fopen(path, "wb"); + if (!f) { fprintf(stderr, "MUX_DUMP: cannot write %s\n", path); exit(1); } + fprintf(f, "P6\n%d %d\n255\n", w, h); + for (int yy = 0; yy < h; yy++) + for (int xx = 0; xx < w; xx++) { + unsigned long px = XGetPixel(im, xx, yy); + unsigned char rgb[3] = { + (unsigned char)((px >> 16) & 0xff), + (unsigned char)((px >> 8) & 0xff), + (unsigned char)(px & 0xff) }; + fwrite(rgb, 1, 3, f); + } + fclose(f); + XDestroyImage(im); + fprintf(stderr, "MUX_DUMP: wrote %s (%dx%d)\n", path, w, h); + exit(0); + } } |
