summaryrefslogtreecommitdiff
path: root/src/preload/e_hack.c
blob: 6562d807e9100929bd85bbc9675a54ab104e1d38 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
#include "config.h"
#include "e_hack.h"

/* FIXME:
 * * gnome-terminal does this funky thing where a new gnome-temrinal process
 * tries to message an  existing one asking it to create a new terminal. this
 * means none of these properties ever end up on a new term window - in fact
 * only the ones that are on the first term process. we need a way of knowing
 * this, OR making sure no new iwndows other than the first appear with these
 * properties. this also leads to handling splash windows - we might want then
 * the first 2 or 3 windows with it.
 * 
 * we need to discuss this... it's an interesting hack that solves a LOT of
 * things (and that we can maybe in future expand to hacking away at gtk and
 * qt directly)
 * 
 * anyway - for now this is fairly harmless and just adds a property to all
 * top-level app windows
 */

/* prototypes */
static void __e_hack_set_properties(Display *display, Window window);

/* dlopened xlib so we can find the symbols in the real xlib to call them */
static void *lib_xlib = NULL;

/* the function that actually sets the properties on toplevel window */
static void
__e_hack_set_properties(Display *display, Window window)
{
   static Atom a_hack = 0;
   char *env = NULL;
   char buf[4096];
   char buf2[4096];
   uid_t uid;
   pid_t pid, ppid;
   struct utsname ubuf;

   if (!a_hack) a_hack = XInternAtom(display, "__E_HACK", False);
   buf[0] = 0;
   buf[sizeof(buf) - 1] = 0;
   uid = getuid();
   snprintf(buf2, sizeof(buf2), "uid: %i\n", uid);
   strncat(buf, buf2, sizeof(buf) - strlen(buf) - 1);
   pid = getpid();
   snprintf(buf2, sizeof(buf2), "pid: %i\n", pid);
   strncat(buf, buf2, sizeof(buf) - strlen(buf) - 1);
   ppid = getppid();
   snprintf(buf2, sizeof(buf2), "ppid: %i\n", ppid);
   strncat(buf, buf2, sizeof(buf) - strlen(buf) - 1);
   if (!uname(&ubuf))
     {
	snprintf(buf2, sizeof(buf2), "machine_name: %s\n", ubuf.nodename);
	strncat(buf, buf2, sizeof(buf) - strlen(buf) - 1);
     }
   if ((env = getenv("E_LAUNCH_ID")))
     {
	snprintf(buf2, sizeof(buf2), "launch_id: %s\n", env);
	strncat(buf, buf2, sizeof(buf) - strlen(buf) - 1);
     }
   if ((env = getenv("USER")))
     {
	snprintf(buf2, sizeof(buf2), "username: %s\n", env);
	strncat(buf, buf2, sizeof(buf) - strlen(buf) - 1);
     }
   if ((env = getenv("E_DESK")))
     {
	snprintf(buf2, sizeof(buf2), "e_desk: %s\n", env);
	strncat(buf, buf2, sizeof(buf) - strlen(buf) - 1);
     }
   if ((env = getenv("E_ZONE")))
     {
	snprintf(buf2, sizeof(buf2), "e_zone: %s\n", env);
	strncat(buf, buf2, sizeof(buf) - strlen(buf) - 1);
     }
   if ((env = getenv("E_CONTAINER")))
     {
	snprintf(buf2, sizeof(buf2), "e_container: %s\n", env);
	strncat(buf, buf2, sizeof(buf) - strlen(buf) - 1);
     }
   if ((env = getenv("E_MANAGER")))
     {
	snprintf(buf2, sizeof(buf2), "e_manager: %s\n", env);
	strncat(buf, buf2, sizeof(buf) - strlen(buf) - 1);
     }
   XChangeProperty(display, window, a_hack, XA_STRING, 8, PropModeReplace, (unsigned char *)buf, strlen(buf));
}

/* XCreateWindow intercept hack */
Window
XCreateWindow(
	      Display *display,
	      Window parent,
	      int x, int y,
	      unsigned int width, unsigned int height,
	      unsigned int border_width,
	      int depth,
	      unsigned int class,
	      Visual *visual,
	      unsigned long valuemask,
	      XSetWindowAttributes *attributes
	      )
{
   static Window (*func)
      (
       Display *display,
       Window parent,
       int x, int y,
       unsigned int width, unsigned int height,
       unsigned int border_width,
       int depth,
       unsigned int class,
       Visual *visual,
       unsigned long valuemask,
       XSetWindowAttributes *attributes
       ) = NULL;
   int i;

   /* find the real Xlib and the real X function */
   if (!lib_xlib) lib_xlib = dlopen("libX11.so", RTLD_GLOBAL | RTLD_LAZY);
   if (!func) func = dlsym (lib_xlib, "XCreateWindow");

   /* multihead screen handling loop */
   for (i = 0; i < ScreenCount(display); i++)
     {
	/* if the window is created as a toplevel window */
	if (parent == RootWindow(display, i))
	  {
	     Window window;
	     
	     /* create it */
	     window = (*func) (display, parent, x, y, width, height, 
				border_width, depth, class, visual, valuemask, 
				attributes);
	     /* set properties */
	     __e_hack_set_properties(display, window);
	     /* return it */
	     return window;
	  }
     }
   /* normal child window - create as usual */
   return (*func) (display, parent, x, y, width, height, border_width, depth,
		   class, visual, valuemask, attributes);
}

/* XCreateSimpleWindow intercept hack */
Window
XCreateSimpleWindow(
		    Display *display,
		    Window parent,
		    int x, int y,
		    unsigned int width, unsigned int height,
		    unsigned int border_width,
		    unsigned long border,
		    unsigned long background
		    )
{
   static Window (*func)
      (
       Display *display,
       Window parent,
       int x, int y,
       unsigned int width, unsigned int height,
       unsigned int border_width,
       unsigned long border,
       unsigned long background
       ) = NULL;
   int i;
   
   /* find the real Xlib and the real X function */
   if (!lib_xlib) lib_xlib = dlopen("libX11.so", RTLD_GLOBAL | RTLD_LAZY);
   if (!func) func = dlsym (lib_xlib, "XCreateSimpleWindow");
   
   /* multihead screen handling loop */
   for (i = 0; i < ScreenCount(display); i++)
     {
	/* if the window is created as a toplevel window */
	if (parent == RootWindow(display, i))
	  {
	     Window window;
	     
	     /* create it */
	     window = (*func) (display, parent, x, y, width, height, 
				border_width, border, background);
	     /* set properties */
	     __e_hack_set_properties(display, window);
	     /* return it */
	     return window;
	  }
     }
   /* normal child window - create as usual */
   return (*func) (display, parent, x, y, width, height, 
		   border_width, border, background);
}

/* XReparentWindow intercept hack */
int
XReparentWindow(
		Display *display,
		Window window,
		Window parent,
		int x, int y
		)
{
   static int (*func)
      (
       Display *display,
       Window window,
       Window parent,
       int x, int y
       ) = NULL;
   int i;
   
   /* find the real Xlib and the real X function */
   if (!lib_xlib) lib_xlib = dlopen("libX11.so", RTLD_GLOBAL | RTLD_LAZY);
   if (!func) func = dlsym (lib_xlib, "XReparentWindow");
   
   /* multihead screen handling loop */
   for (i = 0; i < ScreenCount(display); i++)
     {
	/* if the window is created as a toplevel window */
	if (parent == RootWindow(display, i))
	  {
	     /* set properties */
	     __e_hack_set_properties(display, window);
	     /* reparent it */
	     return (*func) (display, window, parent, x, y);
	  }
     }
   /* normal child window reparenting - reparent as usual */
   return (*func) (display, window, parent, x, y);
}