]> code.delx.au - spectrwm/blobdiff - lib/swm_hack.c
Let scrotwm adjust the font size on xterms as it squishes them in tiling
[spectrwm] / lib / swm_hack.c
index 459d8800cffb28f304b43c01a5b9dfaaf76eab0c..5d60d617b584f0635db47bc492b68575351de84f 100644 (file)
 #include <X11/Xlib.h>
 #include <X11/X.h>
 #include <X11/Xatom.h>
+#include <X11/Intrinsic.h>
 
-/* dlopened xlib so we can find the symbols in the real xlib to call them */
-static void        *lib_xlib = NULL;
+/* dlopened libs so we can find the symbols in the real one to call them */
+static void            *lib_xlib = NULL;
+static void            *lib_xtlib = NULL;
 
-static Window       root = None;
+static Window          root = None;
+static int             xterm = 0;
+static Display         *dpy = NULL;
 
 /* Find our root window */
 static              Window
@@ -111,8 +115,10 @@ XCreateWindow(Display * display, Window parent, int x, int y,
        /* find the real Xlib and the real X function */
        if (!lib_xlib)
                lib_xlib = dlopen("libX11.so", RTLD_GLOBAL | RTLD_LAZY);
-       if (!func)
+       if (!func) {
                func = (CWF *) dlsym(lib_xlib, "XCreateWindow");
+               dpy = display;
+       }
 
        if (parent == DefaultRootWindow(display))
                parent = MyRoot(display);
@@ -125,6 +131,10 @@ XCreateWindow(Display * display, Window parent, int x, int y,
                        set_property(display, id, "_SWM_WS", env);
                if ((env = getenv("_SWM_PID")) != NULL)
                        set_property(display, id, "_SWM_PID", env);
+               if ((env = getenv("_SWM_XTERM_FONTADJ")) != NULL) {
+                       unsetenv("_SWM_XTERM_FONTADJ");
+                       xterm = 1;
+               }
        }
        return (id);
 }
@@ -164,6 +174,10 @@ XCreateSimpleWindow(Display * display, Window parent, int x, int y,
                        set_property(display, id, "_SWM_WS", env);
                if ((env = getenv("_SWM_PID")) != NULL)
                        set_property(display, id, "_SWM_PID", env);
+               if ((env = getenv("_SWM_XTERM_FONTADJ")) != NULL) {
+                       unsetenv("_SWM_XTERM_FONTADJ");
+                       xterm = 1;
+               }
        }
        return (id);
 }
@@ -188,3 +202,44 @@ XReparentWindow(Display * display, Window window, Window parent, int x, int y)
 
        return (*func) (display, window, parent, x, y);
 }
+
+typedef                void (ANEF) (XtAppContext app_context, XEvent *event_return);
+int            evcount = 0;
+
+/*
+ * XtAppNextEvent Intercept Hack
+ * Normally xterm rejects "synthetic" (XSendEvent) events to prevent spoofing.
+ * We don't want to disable this completely, it's insecure. But hook here
+ * and allow these mostly harmless ones that we use to adjust fonts.
+ */
+void
+XtAppNextEvent(XtAppContext app_context, XEvent *event_return)
+{
+       static ANEF     *func = NULL;
+       static int      kp_add = 0, kp_subtract = 0;
+
+       /* find the real Xlib and the real X function */
+       if (!lib_xtlib)
+               lib_xtlib = dlopen("libXt.so", RTLD_GLOBAL | RTLD_LAZY);
+       if (!func) {
+               func = (ANEF *) dlsym(lib_xtlib, "XtAppNextEvent");
+               if (dpy != NULL) {
+                       kp_add = XKeysymToKeycode(dpy, XK_KP_Add);
+                       kp_subtract = XKeysymToKeycode(dpy, XK_KP_Subtract);
+               }
+       }
+
+       (*func) (app_context, event_return);
+
+       /* Return here if it's not an Xterm. */
+       if (!xterm)
+               return;
+       
+       /* Allow spoofing of font change keystrokes. */
+       if ((event_return->type == KeyPress ||  
+          event_return->type == KeyRelease) &&
+          event_return->xkey.state == ShiftMask &&
+          (event_return->xkey.keycode == kp_add ||
+          event_return->xkey.keycode == kp_subtract))
+               event_return->xkey.send_event = 0;
+}