-/* $scrotwm$ */
/*
* Copyright (c) 2009 Marco Peereboom <marco@peereboom.us>
* Copyright (c) 2009 Ryan McBride <mcbride@countersiege.com>
#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 *display = NULL;
+
+void set_property(Display *, Window, char *, char *);
/* Find our root window */
static Window
return root;
}
+
+typedef Atom (XIA) (Display *display, char *atom_name, Bool
+ only_if_exists);
+
+typedef int (XCP) (Display *display, Window w, Atom property,
+ Atom type, int format, int mode, unsigned char *data,
+ int nelements);
+
#define SWM_PROPLEN (16)
void
set_property(Display *dpy, Window id, char *name, char *val)
{
Atom atom = 0;
char prop[SWM_PROPLEN];
+ static XIA *xia = NULL;
+ static XCP *xcp = NULL;
+
+ /* find the real Xlib and the real X function */
+ if (!lib_xlib)
+ lib_xlib = dlopen("libX11.so", RTLD_GLOBAL | RTLD_LAZY);
+ if (!xia)
+ xia = (XIA *) dlsym(lib_xlib, "XInternAtom");
+ if (!xcp)
+ xcp = (XCP *) dlsym(lib_xlib, "XChangeProperty");
/* Try to update the window's workspace property */
- atom = XInternAtom(dpy, name, False);
- if (atom)
+ atom = (*xia)(dpy, name, False);
+ if (atom)
if (snprintf(prop, SWM_PROPLEN, "%s", val) < SWM_PROPLEN)
- XChangeProperty(dpy, id, atom, XA_STRING,
- 8, PropModeReplace, prop, SWM_PROPLEN);
+ (*xcp)(dpy, id, atom, XA_STRING,
+ 8, PropModeReplace, (unsigned char *)prop,
+ strlen((char *)prop));
}
typedef Window(CWF) (Display * _display, Window _parent, int _x,
/* XCreateWindow intercept hack */
Window
-XCreateWindow(Display * display, Window parent, int x, int y,
+XCreateWindow(Display *dpy, Window parent, int x, int y,
unsigned int width, unsigned int height,
unsigned int border_width,
int depth, unsigned int clss, Visual * visual,
/* 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");
+ display = dpy;
+ }
- if (parent == DefaultRootWindow(display))
- parent = MyRoot(display);
+ if (parent == DefaultRootWindow(dpy))
+ parent = MyRoot(dpy);
- id = (*func) (display, parent, x, y, width, height, border_width,
+ id = (*func) (dpy, parent, x, y, width, height, border_width,
depth, clss, visual, valuemask, attributes);
if (id) {
if ((env = getenv("_SWM_WS")) != NULL)
- set_property(display, id, "_SWM_WS", env);
+ set_property(dpy, id, "_SWM_WS", env);
if ((env = getenv("_SWM_PID")) != NULL)
- set_property(display, id, "_SWM_PID", env);
+ set_property(dpy, id, "_SWM_PID", env);
+ if ((env = getenv("_SWM_XTERM_FONTADJ")) != NULL) {
+ unsetenv("_SWM_XTERM_FONTADJ");
+ xterm = 1;
+ }
}
return (id);
}
/* XCreateSimpleWindow intercept hack */
Window
-XCreateSimpleWindow(Display * display, Window parent, int x, int y,
+XCreateSimpleWindow(Display *dpy, Window parent, int x, int y,
unsigned int width, unsigned int height,
unsigned int border_width,
unsigned long border, unsigned long background)
if (!func)
func = (CSWF *) dlsym(lib_xlib, "XCreateSimpleWindow");
- if (parent == DefaultRootWindow(display))
- parent = MyRoot(display);
+ if (parent == DefaultRootWindow(dpy))
+ parent = MyRoot(dpy);
- id = (*func) (display, parent, x, y, width, height,
+ id = (*func) (dpy, parent, x, y, width, height,
border_width, border, background);
if (id) {
if ((env = getenv("_SWM_WS")) != NULL)
- set_property(display, id, "_SWM_WS", env);
+ set_property(dpy, id, "_SWM_WS", env);
if ((env = getenv("_SWM_PID")) != NULL)
- set_property(display, id, "_SWM_PID", env);
+ set_property(dpy, id, "_SWM_PID", env);
+ if ((env = getenv("_SWM_XTERM_FONTADJ")) != NULL) {
+ unsetenv("_SWM_XTERM_FONTADJ");
+ xterm = 1;
+ }
}
return (id);
}
/* XReparentWindow intercept hack */
int
-XReparentWindow(Display * display, Window window, Window parent, int x, int y)
+XReparentWindow(Display *dpy, Window window, Window parent, int x, int y)
{
static RWF *func = NULL;
if (!func)
func = (RWF *) dlsym(lib_xlib, "XReparentWindow");
- if (parent == DefaultRootWindow(display))
- parent = MyRoot(display);
+ if (parent == DefaultRootWindow(dpy))
+ parent = MyRoot(dpy);
+
+ return (*func) (dpy, window, parent, x, 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 KeyCode 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 (display != NULL) {
+ kp_add = XKeysymToKeycode(display, XK_KP_Add);
+ kp_subtract = XKeysymToKeycode(display, 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;
}