2 * Copyright (c) 2009 Marco Peereboom <marco@peereboom.us>
3 * Copyright (c) 2009 Ryan McBride <mcbride@countersiege.com>
5 * Permission to use, copy, modify, and distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18 * Copyright (C) 2005-2007 Carsten Haitzler
19 * Copyright (C) 2006-2007 Kim Woelders
21 * Permission is hereby granted, free of charge, to any person obtaining a copy
22 * of this software and associated documentation files (the "Software"), to
23 * deal in the Software without restriction, including without limitation the
24 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
25 * sell copies of the Software, and to permit persons to whom the Software is
26 * furnished to do so, subject to the following conditions:
28 * The above copyright notice and this permission notice shall be included in
29 * all copies of the Software, its documentation and marketing & publicity
30 * materials, and acknowledgment shall be given in the documentation, materials
31 * and software packages that this Software was used.
33 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
34 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
35 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
36 * THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
37 * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
38 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
41 * Basic hack mechanism (dlopen etc.) taken from e_hack.c in e17.
49 #include <X11/Xatom.h>
50 #include <X11/Intrinsic.h>
52 /* dlopened libs so we can find the symbols in the real one to call them */
53 static void *lib_xlib = NULL;
54 static void *lib_xtlib = NULL;
56 static Window root = None;
58 static Display *display = NULL;
60 void set_property(Display *, Window, char *, char *);
62 /* Find our root window */
71 root = DefaultRootWindow(dpy);
73 s = getenv("ENL_WM_ROOT");
77 sscanf(s, "%lx", &root);
82 typedef Atom (XIA) (Display *display, char *atom_name, Bool
85 typedef int (XCP) (Display *display, Window w, Atom property,
86 Atom type, int format, int mode, unsigned char *data,
89 #define SWM_PROPLEN (16)
91 set_property(Display *dpy, Window id, char *name, char *val)
94 char prop[SWM_PROPLEN];
95 static XIA *xia = NULL;
96 static XCP *xcp = NULL;
98 /* find the real Xlib and the real X function */
100 lib_xlib = dlopen("libX11.so", RTLD_GLOBAL | RTLD_LAZY);
102 xia = (XIA *) dlsym(lib_xlib, "XInternAtom");
104 xcp = (XCP *) dlsym(lib_xlib, "XChangeProperty");
106 /* Try to update the window's workspace property */
107 atom = (*xia)(dpy, name, False);
109 if (snprintf(prop, SWM_PROPLEN, "%s", val) < SWM_PROPLEN)
110 (*xcp)(dpy, id, atom, XA_STRING,
111 8, PropModeReplace, (unsigned char *)prop,
112 strlen((char *)prop));
115 typedef Window(CWF) (Display * _display, Window _parent, int _x,
116 int _y, unsigned int _width,
117 unsigned int _height,
118 unsigned int _border_width, int _depth,
119 unsigned int _class, Visual * _visual,
120 unsigned long _valuemask,
121 XSetWindowAttributes * _attributes);
123 /* XCreateWindow intercept hack */
125 XCreateWindow(Display *dpy, Window parent, int x, int y,
126 unsigned int width, unsigned int height,
127 unsigned int border_width,
128 int depth, unsigned int clss, Visual * visual,
129 unsigned long valuemask, XSetWindowAttributes * attributes)
131 static CWF *func = NULL;
135 /* find the real Xlib and the real X function */
137 lib_xlib = dlopen("libX11.so", RTLD_GLOBAL | RTLD_LAZY);
139 func = (CWF *) dlsym(lib_xlib, "XCreateWindow");
143 if (parent == DefaultRootWindow(dpy))
144 parent = MyRoot(dpy);
146 id = (*func) (dpy, parent, x, y, width, height, border_width,
147 depth, clss, visual, valuemask, attributes);
150 if ((env = getenv("_SWM_WS")) != NULL)
151 set_property(dpy, id, "_SWM_WS", env);
152 if ((env = getenv("_SWM_PID")) != NULL)
153 set_property(dpy, id, "_SWM_PID", env);
154 if ((env = getenv("_SWM_XTERM_FONTADJ")) != NULL) {
155 unsetenv("_SWM_XTERM_FONTADJ");
162 typedef Window(CSWF) (Display * _display, Window _parent, int _x,
163 int _y, unsigned int _width,
164 unsigned int _height,
165 unsigned int _border_width,
166 unsigned long _border,
167 unsigned long _background);
169 /* XCreateSimpleWindow intercept hack */
171 XCreateSimpleWindow(Display *dpy, Window parent, int x, int y,
172 unsigned int width, unsigned int height,
173 unsigned int border_width,
174 unsigned long border, unsigned long background)
176 static CSWF *func = NULL;
180 /* find the real Xlib and the real X function */
182 lib_xlib = dlopen("libX11.so", RTLD_GLOBAL | RTLD_LAZY);
184 func = (CSWF *) dlsym(lib_xlib, "XCreateSimpleWindow");
186 if (parent == DefaultRootWindow(dpy))
187 parent = MyRoot(dpy);
189 id = (*func) (dpy, parent, x, y, width, height,
190 border_width, border, background);
193 if ((env = getenv("_SWM_WS")) != NULL)
194 set_property(dpy, id, "_SWM_WS", env);
195 if ((env = getenv("_SWM_PID")) != NULL)
196 set_property(dpy, id, "_SWM_PID", env);
197 if ((env = getenv("_SWM_XTERM_FONTADJ")) != NULL) {
198 unsetenv("_SWM_XTERM_FONTADJ");
205 typedef int (RWF) (Display * _display, Window _window, Window _parent,
208 /* XReparentWindow intercept hack */
210 XReparentWindow(Display *dpy, Window window, Window parent, int x, int y)
212 static RWF *func = NULL;
214 /* find the real Xlib and the real X function */
216 lib_xlib = dlopen("libX11.so", RTLD_GLOBAL | RTLD_LAZY);
218 func = (RWF *) dlsym(lib_xlib, "XReparentWindow");
220 if (parent == DefaultRootWindow(dpy))
221 parent = MyRoot(dpy);
223 return (*func) (dpy, window, parent, x, y);
226 typedef void (ANEF) (XtAppContext app_context, XEvent *event_return);
230 * XtAppNextEvent Intercept Hack
231 * Normally xterm rejects "synthetic" (XSendEvent) events to prevent spoofing.
232 * We don't want to disable this completely, it's insecure. But hook here
233 * and allow these mostly harmless ones that we use to adjust fonts.
236 XtAppNextEvent(XtAppContext app_context, XEvent *event_return)
238 static ANEF *func = NULL;
239 static KeyCode kp_add = 0, kp_subtract = 0;
241 /* find the real Xlib and the real X function */
243 lib_xtlib = dlopen("libXt.so", RTLD_GLOBAL | RTLD_LAZY);
245 func = (ANEF *) dlsym(lib_xtlib, "XtAppNextEvent");
246 if (display != NULL) {
247 kp_add = XKeysymToKeycode(display, XK_KP_Add);
248 kp_subtract = XKeysymToKeycode(display, XK_KP_Subtract);
252 (*func) (app_context, event_return);
254 /* Return here if it's not an Xterm. */
258 /* Allow spoofing of font change keystrokes. */
259 if ((event_return->type == KeyPress ||
260 event_return->type == KeyRelease) &&
261 event_return->xkey.state == ShiftMask &&
262 (event_return->xkey.keycode == kp_add ||
263 event_return->xkey.keycode == kp_subtract))
264 event_return->xkey.send_event = 0;