JasonWoof Got questions, comments, patches, etc.? Contact Jason Woofenden
Add support for passing variables up to X11 via window properties; done by
[spectrwm.git] / lib / swm_hack.c
1 /* $scrotwm$ */
2 /*
3  * Copyright (c) 2009 Marco Peereboom <marco@peereboom.us>
4  * Copyright (c) 2009 Ryan McBride <mcbride@countersiege.com>
5  *
6  * Permission to use, copy, modify, and distribute this software for any
7  * purpose with or without fee is hereby granted, provided that the above
8  * copyright notice and this permission notice appear in all copies.
9  *
10  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17  */
18 /*
19  * Copyright (C) 2005-2007 Carsten Haitzler
20  * Copyright (C) 2006-2007 Kim Woelders
21  *
22  * Permission is hereby granted, free of charge, to any person obtaining a copy
23  * of this software and associated documentation files (the "Software"), to
24  * deal in the Software without restriction, including without limitation the
25  * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
26  * sell copies of the Software, and to permit persons to whom the Software is
27  * furnished to do so, subject to the following conditions:
28  *
29  * The above copyright notice and this permission notice shall be included in
30  * all copies of the Software, its documentation and marketing & publicity
31  * materials, and acknowledgment shall be given in the documentation, materials
32  * and software packages that this Software was used.
33  *
34  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
35  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
36  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
37  * THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
38  * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
39  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
40  */
41 /*
42  * Basic hack mechanism (dlopen etc.) taken from e_hack.c in e17.
43  */
44 #include <string.h>
45 #include <stdio.h>
46 #include <stdlib.h>
47 #include <dlfcn.h>
48 #include <X11/Xlib.h>
49 #include <X11/X.h>
50 #include <X11/Xatom.h>
51
52 /* dlopened xlib so we can find the symbols in the real xlib to call them */
53 static void        *lib_xlib = NULL;
54
55 static Window       root = None;
56
57 /* Find our root window */
58 static              Window
59 MyRoot(Display * dpy)
60 {
61         char               *s;
62
63         if (root != None)
64                 return root;
65
66         root = DefaultRootWindow(dpy);
67
68         s = getenv("ENL_WM_ROOT");
69         if (!s)
70                 return root;
71
72         sscanf(s, "%lx", &root);
73         return root;
74 }
75
76 #define SWM_PROPLEN     (16)
77 void
78 set_property(Display *dpy, Window id, char *name, char *val)
79 {
80         Atom                    atom = 0;
81         char                    prop[SWM_PROPLEN];
82
83         /* Try to update the window's workspace property */
84         atom = XInternAtom(dpy, name, False);
85         if (atom) 
86                 if (snprintf(prop, SWM_PROPLEN, "%s", val) < SWM_PROPLEN)
87                         XChangeProperty(dpy, id, atom, XA_STRING,
88                             8, PropModeReplace, prop, SWM_PROPLEN);
89 }
90
91 typedef             Window(CWF) (Display * _display, Window _parent, int _x,
92                                  int _y, unsigned int _width,
93                                  unsigned int _height,
94                                  unsigned int _border_width, int _depth,
95                                  unsigned int _class, Visual * _visual,
96                                  unsigned long _valuemask,
97                                  XSetWindowAttributes * _attributes);
98
99 /* XCreateWindow intercept hack */
100 Window
101 XCreateWindow(Display * display, Window parent, int x, int y,
102    unsigned int width, unsigned int height,
103    unsigned int border_width,
104    int depth, unsigned int clss, Visual * visual,
105    unsigned long valuemask, XSetWindowAttributes * attributes)
106 {
107         static CWF      *func = NULL;
108         char            *env;
109         Window          id;
110
111         /* find the real Xlib and the real X function */
112         if (!lib_xlib)
113                 lib_xlib = dlopen("libX11.so", RTLD_GLOBAL | RTLD_LAZY);
114         if (!func)
115                 func = (CWF *) dlsym(lib_xlib, "XCreateWindow");
116
117         if (parent == DefaultRootWindow(display))
118                 parent = MyRoot(display);
119         
120         id = (*func) (display, parent, x, y, width, height, border_width,
121             depth, clss, visual, valuemask, attributes);
122
123         if (id) {
124                 if ((env = getenv("_SWM_WS")) != NULL) 
125                         set_property(display, id, "_SWM_WS", env);
126                 if ((env = getenv("_SWM_PID")) != NULL)
127                         set_property(display, id, "_SWM_PID", env);
128         }
129         return (id);
130 }
131
132 typedef             Window(CSWF) (Display * _display, Window _parent, int _x,
133                                   int _y, unsigned int _width,
134                                   unsigned int _height,
135                                   unsigned int _border_width,
136                                   unsigned long _border,
137                                   unsigned long _background);
138
139 /* XCreateSimpleWindow intercept hack */
140 Window
141 XCreateSimpleWindow(Display * display, Window parent, int x, int y,
142     unsigned int width, unsigned int height,
143     unsigned int border_width,
144     unsigned long border, unsigned long background)
145 {
146         static CSWF     *func = NULL;
147         char            *env;
148         Window          id;
149
150         /* find the real Xlib and the real X function */
151         if (!lib_xlib)
152                 lib_xlib = dlopen("libX11.so", RTLD_GLOBAL | RTLD_LAZY);
153         if (!func)
154                 func = (CSWF *) dlsym(lib_xlib, "XCreateSimpleWindow");
155
156         if (parent == DefaultRootWindow(display))
157                 parent = MyRoot(display);
158
159         id = (*func) (display, parent, x, y, width, height,
160             border_width, border, background);
161
162         if (id) {
163                 if ((env = getenv("_SWM_WS")) != NULL) 
164                         set_property(display, id, "_SWM_WS", env);
165                 if ((env = getenv("_SWM_PID")) != NULL)
166                         set_property(display, id, "_SWM_PID", env);
167         }
168         return (id);
169 }
170
171 typedef int         (RWF) (Display * _display, Window _window, Window _parent,
172                            int x, int y);
173
174 /* XReparentWindow intercept hack */
175 int
176 XReparentWindow(Display * display, Window window, Window parent, int x, int y)
177 {
178         static RWF         *func = NULL;
179
180         /* find the real Xlib and the real X function */
181         if (!lib_xlib)
182                 lib_xlib = dlopen("libX11.so", RTLD_GLOBAL | RTLD_LAZY);
183         if (!func)
184                 func = (RWF *) dlsym(lib_xlib, "XReparentWindow");
185
186         if (parent == DefaultRootWindow(display))
187                 parent = MyRoot(display);
188
189         return (*func) (display, window, parent, x, y);
190 }