flak rss random

xterm full reverse

Depending on whether it is day or night, I prefer a light screen or a dark screen. I would like switching between these two modes of operation to be quick and easy. Easy in this case means I am willing to run a command, but not ctrl-click on 21 different xterms.

The blunt force approach is to reverse the gamma.

                for (int i = 0; i < size; i++) {
                        double g = 65535.0 * i / size;
-                       crtc_gamma->red[i] = g * gammar;
-                       crtc_gamma->green[i] = g * gammag;
-                       crtc_gamma->blue[i] = g * gammab;
+                       crtc_gamma->red[size - 1 - i] = g * gammar;
+                       crtc_gamma->green[size - 1 - i] = g * gammag;
+                       crtc_gamma->blue[size - 1 - i] = g * gammab;
                }

This works, although it makes a mess of the browser, and I don’t necessarily want my code highlights reversed. Just black and white, foreground and background. Still interesting, but we can be more precise. Let’s target only xterms.

xterm has a convenient builtin function to reverse video, and allows key bindings. I will be using F11.

*VT100.translations:#override\n<Key>F11:set-reverse-video(toggle)

The #override is important. You don’t want an xterm that only responds to F11.

Now that we have xterm customized so that we can toggle video in one xterm, how about all of the xterms? Recycling some code from previous toys, we can loop over all the xterms and send them F11.

        rv = XQueryTree(disp, root, &w, &parent, &children, &nchildren);
        for (int i = 0; i < nchildren; i++) {
                getWindowName(disp, children[i], name, sizeof(name));
                if (strcmp(name, "xterm") != 0)
                        continue;
                reverse(disp, root, children[i]);
        }
        XFlush(disp);

int
getWindowName(Display *disp, Window w, char *buf, size_t buflen)
{
        XTextProperty prop;
        int rv;

        rv = XGetTextProperty(disp, w, &prop, XA_WM_ICON_NAME);
        if (!rv)
                snprintf(buf, buflen, "unknown");
        else
                snprintf(buf, buflen, "%s", prop.value);
        return 0;
}

void
reverse(Display *disp, Window root, Window w)
{
        KeySym keysym;
        KeyCode keycode;

        keysym = XK_F11;
        keycode = XKeysymToKeycode(disp, keysym);

        XSetInputFocus(disp, w, RevertToNone, CurrentTime);
        XTestFakeKeyEvent(disp, keycode, True, 0);
        XTestFakeKeyEvent(disp, keycode, False, 0);
}

Fairly generic code. It could be used to send any keypress to all the xterms (or any window), and the xterms can be configured to respond in various ways. But for today, it’s F11 and reverse video.

fullreverse.c

Posted 13 Dec 2018 21:14 by tedu Updated: 24 Dec 2023 17:17
Tagged: c programming x11