]>
code.delx.au - spectrwm/blob - lib/swm_hack.c
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
;
99 /* load the function pointer with RTLD_NEXT
100 * this might be the real X function or another
101 * preloaded intercept
104 lib_xlib
= RTLD_NEXT
;
106 /* find the real Xlib and the real X function */
108 lib_xlib
= dlopen("libX11.so", RTLD_GLOBAL
| RTLD_LAZY
);
110 if (lib_xlib
&& !xia
)
111 xia
= (XIA
*) dlsym(lib_xlib
, "XInternAtom");
112 if (lib_xlib
&& !xcp
)
113 xcp
= (XCP
*) dlsym(lib_xlib
, "XChangeProperty");
115 fprintf(stderr
, "libswmhack.so: ERROR: %s\n", dlerror());
119 /* Try to update the window's workspace property */
120 atom
= (*xia
)(dpy
, name
, False
);
122 if (snprintf(prop
, SWM_PROPLEN
, "%s", val
) < SWM_PROPLEN
)
123 (*xcp
)(dpy
, id
, atom
, XA_STRING
,
124 8, PropModeReplace
, (unsigned char *)prop
,
125 strlen((char *)prop
));
128 typedef Window(CWF
) (Display
* _display
, Window _parent
, int _x
,
129 int _y
, unsigned int _width
,
130 unsigned int _height
,
131 unsigned int _border_width
, int _depth
,
132 unsigned int _class
, Visual
* _visual
,
133 unsigned long _valuemask
,
134 XSetWindowAttributes
* _attributes
);
136 /* XCreateWindow intercept hack */
138 XCreateWindow(Display
*dpy
, Window parent
, int x
, int y
,
139 unsigned int width
, unsigned int height
,
140 unsigned int border_width
,
141 int depth
, unsigned int clss
, Visual
* visual
,
142 unsigned long valuemask
, XSetWindowAttributes
* attributes
)
144 static CWF
*func
= NULL
;
149 /* load the function pointer with RTLD_NEXT
150 * this might be the real X function or another
151 * preloaded intercept
154 lib_xlib
= RTLD_NEXT
;
156 /* find the real Xlib and the real X function */
158 lib_xlib
= dlopen("libX11.so", RTLD_GLOBAL
| RTLD_LAZY
);
160 if (lib_xlib
&& !func
) {
161 func
= (CWF
*) dlsym(lib_xlib
, "XCreateWindow");
165 fprintf(stderr
, "libswmhack.so: ERROR: %s\n", dlerror());
166 return BadImplementation
;
169 if (parent
== DefaultRootWindow(dpy
))
170 parent
= MyRoot(dpy
);
172 id
= (*func
) (dpy
, parent
, x
, y
, width
, height
, border_width
,
173 depth
, clss
, visual
, valuemask
, attributes
);
176 if ((env
= getenv("_SWM_WS")) != NULL
)
177 set_property(dpy
, id
, "_SWM_WS", env
);
178 if ((env
= getenv("_SWM_PID")) != NULL
)
179 set_property(dpy
, id
, "_SWM_PID", env
);
180 if ((env
= getenv("_SWM_XTERM_FONTADJ")) != NULL
) {
181 unsetenv("_SWM_XTERM_FONTADJ");
188 typedef Window(CSWF
) (Display
* _display
, Window _parent
, int _x
,
189 int _y
, unsigned int _width
,
190 unsigned int _height
,
191 unsigned int _border_width
,
192 unsigned long _border
,
193 unsigned long _background
);
195 /* XCreateSimpleWindow intercept hack */
197 XCreateSimpleWindow(Display
*dpy
, Window parent
, int x
, int y
,
198 unsigned int width
, unsigned int height
,
199 unsigned int border_width
,
200 unsigned long border
, unsigned long background
)
202 static CSWF
*func
= NULL
;
207 /* load the function pointer with RTLD_NEXT
208 * this might be the real X function or another
209 * preloaded intercept
212 lib_xlib
= RTLD_NEXT
;
214 /* find the real Xlib and the real X function */
216 lib_xlib
= dlopen("libX11.so", RTLD_GLOBAL
| RTLD_LAZY
);
218 if (lib_xlib
&& !func
)
219 func
= (CSWF
*) dlsym(lib_xlib
, "XCreateSimpleWindow");
221 fprintf(stderr
, "libswmhack.so: ERROR: %s\n", dlerror());
222 return BadImplementation
;
225 if (parent
== DefaultRootWindow(dpy
))
226 parent
= MyRoot(dpy
);
228 id
= (*func
) (dpy
, parent
, x
, y
, width
, height
,
229 border_width
, border
, background
);
232 if ((env
= getenv("_SWM_WS")) != NULL
)
233 set_property(dpy
, id
, "_SWM_WS", env
);
234 if ((env
= getenv("_SWM_PID")) != NULL
)
235 set_property(dpy
, id
, "_SWM_PID", env
);
236 if ((env
= getenv("_SWM_XTERM_FONTADJ")) != NULL
) {
237 unsetenv("_SWM_XTERM_FONTADJ");
244 typedef int (RWF
) (Display
* _display
, Window _window
, Window _parent
,
247 /* XReparentWindow intercept hack */
249 XReparentWindow(Display
*dpy
, Window window
, Window parent
, int x
, int y
)
251 static RWF
*func
= NULL
;
254 /* load the function pointer with RTLD_NEXT
255 * this might be the real X function or another
256 * preloaded intercept
259 lib_xlib
= RTLD_NEXT
;
261 /* find the real Xlib and the real X function */
263 lib_xlib
= dlopen("libX11.so", RTLD_GLOBAL
| RTLD_LAZY
);
265 if (lib_xlib
&& !func
)
266 func
= (RWF
*) dlsym(lib_xlib
, "XReparentWindow");
268 fprintf(stderr
, "libswmhack.so: ERROR: %s\n", dlerror());
269 return BadImplementation
;
272 if (parent
== DefaultRootWindow(dpy
))
273 parent
= MyRoot(dpy
);
275 return (*func
) (dpy
, window
, parent
, x
, y
);
278 typedef void (ANEF
) (XtAppContext app_context
, XEvent
*event_return
);
282 * XtAppNextEvent Intercept Hack
283 * Normally xterm rejects "synthetic" (XSendEvent) events to prevent spoofing.
284 * We don't want to disable this completely, it's insecure. But hook here
285 * and allow these mostly harmless ones that we use to adjust fonts.
288 XtAppNextEvent(XtAppContext app_context
, XEvent
*event_return
)
290 static ANEF
*func
= NULL
;
291 static KeyCode kp_add
= 0, kp_subtract
= 0;
294 /* load the function pointer with RTLD_NEXT
295 * this might be the real X function or another
296 * preloaded intercept
299 lib_xtlib
= RTLD_NEXT
;
301 /* find the real Xlib and the real X function */
303 lib_xtlib
= dlopen("libXt.so", RTLD_GLOBAL
| RTLD_LAZY
);
305 if (lib_xtlib
&& !func
) {
306 func
= (ANEF
*) dlsym(lib_xtlib
, "XtAppNextEvent");
307 if (display
!= NULL
) {
308 kp_add
= XKeysymToKeycode(display
, XK_KP_Add
);
309 kp_subtract
= XKeysymToKeycode(display
, XK_KP_Subtract
);
313 fprintf(stderr
, "libswmhack.so: ERROR: %s\n", dlerror());
317 (*func
) (app_context
, event_return
);
319 /* Return here if it's not an Xterm. */
323 /* Allow spoofing of font change keystrokes. */
324 if ((event_return
->type
== KeyPress
||
325 event_return
->type
== KeyRelease
) &&
326 event_return
->xkey
.state
== ShiftMask
&&
327 (event_return
->xkey
.keycode
== kp_add
||
328 event_return
->xkey
.keycode
== kp_subtract
))
329 event_return
->xkey
.send_event
= 0;