| 58 #define MOZILLA_VERSION_PROP "_MOZILLA_VERSION" |
58 #define MOZILLA_VERSION_PROP "_MOZILLA_VERSION" |
| 59 #define MOZILLA_LOCK_PROP "_MOZILLA_LOCK" |
59 #define MOZILLA_LOCK_PROP "_MOZILLA_LOCK" |
| 60 #define MOZILLA_COMMAND_PROP "_MOZILLA_COMMAND" |
60 #define MOZILLA_COMMAND_PROP "_MOZILLA_COMMAND" |
| 61 #define MOZILLA_RESPONSE_PROP "_MOZILLA_RESPONSE" |
61 #define MOZILLA_RESPONSE_PROP "_MOZILLA_RESPONSE" |
| 62 |
62 |
| 63 static GdkAtom XA_MOZILLA_VERSION = 0; |
63 static GdkAtom XA_MOZILLA_VERSION = 0; |
| 64 static GdkAtom XA_MOZILLA_LOCK = 0; |
64 static GdkAtom XA_MOZILLA_LOCK = 0; |
| 65 static GdkAtom XA_MOZILLA_COMMAND = 0; |
65 static GdkAtom XA_MOZILLA_COMMAND = 0; |
| 66 static GdkAtom XA_MOZILLA_RESPONSE = 0; |
66 static GdkAtom XA_MOZILLA_RESPONSE = 0; |
| 67 |
67 |
| 68 |
68 |
| 69 static int netscape_lock; |
69 static int netscape_lock; |
| 70 |
70 |
| 71 |
71 |
| 72 static Window |
72 static Window VirtualRootWindowOfScreen(screen) |
| 73 VirtualRootWindowOfScreen(screen) |
73 Screen *screen; |
| 74 Screen *screen; |
74 { |
| 75 { |
75 static Screen *save_screen = (Screen *) 0; |
| 76 static Screen *save_screen = (Screen *)0; |
76 static Window root = (Window) 0; |
| 77 static Window root = (Window)0; |
77 |
| 78 |
78 if (screen != save_screen) { |
| 79 if (screen != save_screen) { |
79 Display *dpy = DisplayOfScreen(screen); |
| 80 Display *dpy = DisplayOfScreen(screen); |
80 Atom __SWM_VROOT = None; |
| 81 Atom __SWM_VROOT = None; |
81 unsigned int i; |
| 82 unsigned int i; |
82 Window rootReturn, parentReturn, *children; |
| 83 Window rootReturn, parentReturn, *children; |
83 unsigned int numChildren; |
| 84 unsigned int numChildren; |
84 |
| 85 |
85 root = RootWindowOfScreen(screen); |
| 86 root = RootWindowOfScreen(screen); |
86 |
| 87 |
87 /* go look for a virtual root */ |
| 88 /* go look for a virtual root */ |
88 __SWM_VROOT = XInternAtom(dpy, "__SWM_VROOT", False); |
| 89 __SWM_VROOT = XInternAtom(dpy, "__SWM_VROOT", False); |
89 if (XQueryTree(dpy, root, &rootReturn, &parentReturn, &children, &numChildren)) { |
| 90 if (XQueryTree(dpy, root, &rootReturn, &parentReturn, |
90 for (i = 0; i < numChildren; i++) { |
| 91 &children, &numChildren)) { |
91 Atom actual_type; |
| 92 for (i = 0; i < numChildren; i++) { |
92 int actual_format; |
| 93 Atom actual_type; |
93 unsigned long nitems, bytesafter; |
| 94 int actual_format; |
94 Window *newRoot = (Window *) 0; |
| 95 unsigned long nitems, bytesafter; |
95 |
| 96 Window *newRoot = (Window *)0; |
96 if (XGetWindowProperty(dpy, children[i], |
| 97 |
97 __SWM_VROOT, 0, 1, False, XA_WINDOW, |
| 98 if (XGetWindowProperty(dpy, children[i], |
98 &actual_type, &actual_format, |
| 99 __SWM_VROOT, 0, 1, False, XA_WINDOW, |
99 &nitems, &bytesafter, |
| 100 &actual_type, &actual_format, |
100 (unsigned char **)&newRoot) == Success && newRoot) { |
| 101 &nitems, &bytesafter, |
101 root = *newRoot; |
| 102 (unsigned char **) &newRoot) == Success |
102 break; |
| 103 && newRoot) { |
103 } |
| 104 root = *newRoot; |
104 } |
| 105 break; |
105 if (children) |
| 106 } |
106 XFree((char *)children); |
| 107 } |
107 } |
| 108 if (children) |
108 |
| 109 XFree((char *)children); |
109 save_screen = screen; |
| 110 } |
110 } |
| 111 |
111 |
| 112 save_screen = screen; |
112 return root; |
| 113 } |
|
| 114 |
|
| 115 return root; |
|
| 116 } |
113 } |
| 117 |
114 |
| 118 /* The following code is Copyright (C) 1989 X Consortium */ |
115 /* The following code is Copyright (C) 1989 X Consortium */ |
| 119 |
116 |
| 120 static Window TryChildren(); |
117 static Window TryChildren(); |
| 121 |
118 |
| 122 /* Find a window with WM_STATE, else return win itself, as per ICCCM */ |
119 /* Find a window with WM_STATE, else return win itself, as per ICCCM */ |
| 123 |
120 |
| 124 static Window GClientWindow (dpy, win) |
121 static Window GClientWindow(dpy, win) |
| 125 Display *dpy; |
122 Display *dpy; |
| 126 Window win; |
123 Window win; |
| 127 { |
124 { |
| 128 Atom WM_STATE; |
125 Atom WM_STATE; |
| 129 Atom type = None; |
126 Atom type = None; |
| 130 int format; |
127 int format; |
| 131 unsigned long nitems, after; |
128 unsigned long nitems, after; |
| 132 unsigned char *data; |
129 unsigned char *data; |
| 133 Window inf; |
130 Window inf; |
| 134 |
131 |
| 135 WM_STATE = XInternAtom(dpy, "WM_STATE", True); |
132 WM_STATE = XInternAtom(dpy, "WM_STATE", True); |
| 136 if (!WM_STATE) |
133 if (!WM_STATE) |
| 137 return win; |
134 return win; |
| 138 XGetWindowProperty(dpy, win, WM_STATE, 0, 0, False, AnyPropertyType, |
135 XGetWindowProperty(dpy, win, WM_STATE, 0, 0, False, AnyPropertyType, |
| 139 &type, &format, &nitems, &after, &data); |
136 &type, &format, &nitems, &after, &data); |
| 140 if (type) |
137 if (type) { |
| 141 { |
138 XFree(data); |
| |
139 return win; |
| |
140 } |
| |
141 |
| |
142 inf = TryChildren(dpy, win, WM_STATE); |
| |
143 if (!inf) |
| |
144 inf = win; |
| |
145 |
| 142 XFree(data); |
146 XFree(data); |
| 143 return win; |
147 |
| 144 } |
148 return inf; |
| 145 |
|
| 146 inf = TryChildren(dpy, win, WM_STATE); |
|
| 147 if (!inf) |
|
| 148 inf = win; |
|
| 149 |
|
| 150 XFree(data); |
|
| 151 |
|
| 152 return inf; |
|
| 153 } |
149 } |
| 154 |
150 |
| 155 static |
151 static |
| 156 Window TryChildren (dpy, win, WM_STATE) |
152 Window TryChildren(dpy, win, WM_STATE) |
| 157 Display *dpy; |
153 Display *dpy; |
| 158 Window win; |
154 Window win; |
| 159 Atom WM_STATE; |
155 Atom WM_STATE; |
| 160 { |
156 { |
| 161 Window root, parent; |
157 Window root, parent; |
| 162 Window *children; |
158 Window *children; |
| 163 unsigned int nchildren; |
159 unsigned int nchildren; |
| 164 unsigned int i; |
160 unsigned int i; |
| 165 Atom type = None; |
161 Atom type = None; |
| 166 int format; |
162 int format; |
| 167 unsigned long nitems, after; |
163 unsigned long nitems, after; |
| 168 unsigned char *data; |
164 unsigned char *data; |
| 169 Window inf = 0; |
165 Window inf = 0; |
| 170 |
166 |
| 171 if (!XQueryTree(dpy, win, &root, &parent, &children, &nchildren)) |
167 if (!XQueryTree(dpy, win, &root, &parent, &children, &nchildren)) |
| 172 return 0; |
168 return 0; |
| 173 for (i = 0; !inf && (i < nchildren); i++) { |
169 for (i = 0; !inf && (i < nchildren); i++) { |
| 174 XGetWindowProperty(dpy, children[i], WM_STATE, 0, 0, False, |
170 XGetWindowProperty(dpy, children[i], WM_STATE, 0, 0, False, |
| 175 AnyPropertyType, &type, &format, &nitems, |
171 AnyPropertyType, &type, &format, &nitems, &after, &data); |
| 176 &after, &data); |
172 if (type) |
| 177 if (type) |
173 inf = children[i]; |
| 178 inf = children[i]; |
174 |
| 179 |
175 XFree(data); |
| 180 XFree(data); |
176 } |
| 181 } |
177 for (i = 0; !inf && (i < nchildren); i++) |
| 182 for (i = 0; !inf && (i < nchildren); i++) |
178 inf = TryChildren(dpy, children[i], WM_STATE); |
| 183 inf = TryChildren(dpy, children[i], WM_STATE); |
179 if (children) |
| 184 if (children) XFree((char *)children); |
180 XFree((char *)children); |
| 185 return inf; |
181 return inf; |
| 186 } |
182 } |
| 187 |
183 |
| 188 /* END X Consortium code */ |
184 /* END X Consortium code */ |
| 189 |
185 |
| 190 |
186 |
| 192 static void mozilla_remote_init_atoms() |
188 static void mozilla_remote_init_atoms() |
| 193 { |
189 { |
| 194 if (!XA_MOZILLA_VERSION) |
190 if (!XA_MOZILLA_VERSION) |
| 195 XA_MOZILLA_VERSION = gdk_atom_intern(MOZILLA_VERSION_PROP, 0); |
191 XA_MOZILLA_VERSION = gdk_atom_intern(MOZILLA_VERSION_PROP, 0); |
| 196 if (!XA_MOZILLA_LOCK) |
192 if (!XA_MOZILLA_LOCK) |
| 197 XA_MOZILLA_LOCK = gdk_atom_intern(MOZILLA_LOCK_PROP, 0); |
193 XA_MOZILLA_LOCK = gdk_atom_intern(MOZILLA_LOCK_PROP, 0); |
| 198 if (! XA_MOZILLA_COMMAND) |
194 if (!XA_MOZILLA_COMMAND) |
| 199 XA_MOZILLA_COMMAND = gdk_atom_intern(MOZILLA_COMMAND_PROP, 0); |
195 XA_MOZILLA_COMMAND = gdk_atom_intern(MOZILLA_COMMAND_PROP, 0); |
| 200 if (! XA_MOZILLA_RESPONSE) |
196 if (!XA_MOZILLA_RESPONSE) |
| 201 XA_MOZILLA_RESPONSE = gdk_atom_intern(MOZILLA_RESPONSE_PROP, 0); |
197 XA_MOZILLA_RESPONSE = gdk_atom_intern(MOZILLA_RESPONSE_PROP, 0); |
| 202 } |
198 } |
| 203 |
199 |
| 204 static GdkWindow *mozilla_remote_find_window() |
200 static GdkWindow *mozilla_remote_find_window() |
| 205 { |
201 { |
| 206 int i; |
202 int i; |
| 207 Window root = VirtualRootWindowOfScreen(DefaultScreenOfDisplay(gdk_display)); |
203 Window root = VirtualRootWindowOfScreen(DefaultScreenOfDisplay(gdk_display)); |
| 208 Window root2, parent, *kids; |
204 Window root2, parent, *kids; |
| 209 unsigned int nkids; |
205 unsigned int nkids; |
| 210 Window result = 0; |
206 Window result = 0; |
| 211 Window tenative = 0; |
207 Window tenative = 0; |
| 212 unsigned char *tenative_version = 0; |
208 unsigned char *tenative_version = 0; |
| 213 |
209 |
| 214 if (!XQueryTree (gdk_display, root, &root2, &parent, &kids, &nkids)) |
210 if (!XQueryTree(gdk_display, root, &root2, &parent, &kids, &nkids)) { |
| 215 { |
211 debug_printf("%s: XQueryTree failed on display %s\n", progname, |
| 216 sprintf (debug_buff, "%s: XQueryTree failed on display %s\n", progname, |
212 DisplayString(gdk_display)); |
| 217 DisplayString (gdk_display)); |
213 return NULL; |
| 218 debug_print(debug_buff); |
214 } |
| 219 return NULL; |
215 |
| 220 } |
216 /* root != root2 is possible with virtual root WMs. */ |
| 221 |
217 |
| 222 /* root != root2 is possible with virtual root WMs. */ |
218 if (!(kids && nkids)) { |
| 223 |
219 debug_printf("%s: root window has no children on display %s\n", |
| 224 if (!(kids && nkids)) { |
220 progname, DisplayString(gdk_display)); |
| 225 sprintf (debug_buff, "%s: root window has no children on display %s\n", |
221 return NULL; |
| 226 progname, DisplayString (gdk_display)); |
222 } |
| 227 debug_print(debug_buff); |
223 |
| 228 return NULL; |
224 for (i = nkids - 1; i >= 0; i--) { |
| 229 } |
225 Atom type; |
| 230 |
226 int format; |
| 231 for (i = nkids-1; i >= 0; i--) |
227 unsigned long nitems, bytesafter; |
| 232 { |
228 unsigned char *version = 0; |
| 233 Atom type; |
229 Window w = GClientWindow(gdk_display, kids[i]); |
| 234 int format; |
230 int status = XGetWindowProperty(gdk_display, w, XA_MOZILLA_VERSION, |
| 235 unsigned long nitems, bytesafter; |
231 0, (65536 / sizeof(long)), |
| 236 unsigned char *version = 0; |
232 False, XA_STRING, |
| 237 Window w = GClientWindow (gdk_display, kids[i]); |
233 &type, &format, &nitems, &bytesafter, |
| 238 int status = XGetWindowProperty (gdk_display, w, XA_MOZILLA_VERSION, |
234 &version); |
| 239 0, (65536 / sizeof (long)), |
235 |
| 240 False, XA_STRING, |
236 if (!version) |
| 241 &type, &format, &nitems, &bytesafter, |
237 continue; |
| 242 &version); |
238 |
| 243 |
239 if (strcmp((char *)version, expected_mozilla_version) && !tenative) { |
| 244 if (! version) |
240 tenative = w; |
| 245 continue; |
241 tenative_version = version; |
| 246 |
242 continue; |
| 247 if (strcmp ((char *) version, expected_mozilla_version) && |
243 } |
| 248 !tenative) |
244 XFree(version); |
| 249 { |
245 if (status == Success && type != None) { |
| 250 tenative = w; |
246 result = w; |
| 251 tenative_version = version; |
247 break; |
| 252 continue; |
248 } |
| 253 } |
249 } |
| 254 XFree(version); |
|
| 255 if (status == Success && type != None) |
|
| 256 { |
|
| 257 result = w; |
|
| 258 break; |
|
| 259 } |
|
| 260 } |
|
| 261 |
250 |
| 262 XFree(kids); |
251 XFree(kids); |
| 263 |
252 |
| 264 if (result && tenative) |
253 if (result && tenative) { |
| 265 { |
254 debug_printf("%s: warning: both version %s (0x%x) and version\n" |
| 266 sprintf (debug_buff, |
255 "\t%s (0x%x) are running. Using version %s.\n", |
| 267 "%s: warning: both version %s (0x%x) and version\n" |
256 progname, tenative_version, (unsigned int)tenative, |
| 268 "\t%s (0x%x) are running. Using version %s.\n", |
257 expected_mozilla_version, (unsigned int)result, expected_mozilla_version); |
| 269 progname, tenative_version, (unsigned int) tenative, |
258 XFree(tenative_version); |
| 270 expected_mozilla_version, (unsigned int) result, |
259 return gdk_window_foreign_new(result); |
| 271 expected_mozilla_version); |
260 } else if (tenative) { |
| 272 debug_print(debug_buff); |
261 debug_printf("%s: warning: expected version %s but found version\n" |
| 273 XFree(tenative_version); |
262 "\t%s (0x%x) instead.\n", |
| 274 return gdk_window_foreign_new(result); |
263 progname, expected_mozilla_version, |
| 275 } |
264 tenative_version, (unsigned int)tenative); |
| 276 else if (tenative) |
265 XFree(tenative_version); |
| 277 { |
266 return gdk_window_foreign_new(tenative); |
| 278 sprintf (debug_buff, |
267 } else if (result) { |
| 279 "%s: warning: expected version %s but found version\n" |
268 return gdk_window_foreign_new(result); |
| 280 "\t%s (0x%x) instead.\n", |
269 } else { |
| 281 progname, expected_mozilla_version, |
270 debug_printf("%s: not running on display %s\n", progname, DisplayString(gdk_display)); |
| 282 tenative_version, (unsigned int) tenative); |
271 return NULL; |
| 283 debug_print(debug_buff); |
272 } |
| 284 XFree(tenative_version); |
|
| 285 return gdk_window_foreign_new(tenative); |
|
| 286 } |
|
| 287 else if (result) |
|
| 288 { |
|
| 289 return gdk_window_foreign_new(result); |
|
| 290 } |
|
| 291 else |
|
| 292 { |
|
| 293 sprintf (debug_buff, "%s: not running on display %s\n", progname, |
|
| 294 DisplayString (gdk_display)); |
|
| 295 debug_print(debug_buff); |
|
| 296 return NULL; |
|
| 297 } |
|
| 298 } |
273 } |
| 299 |
274 |
| 300 |
275 |
| 301 static char *lock_data = 0; |
276 static char *lock_data = 0; |
| 302 |
277 |
| 303 static void mozilla_remote_obtain_lock (GdkWindow *window) |
278 static void mozilla_remote_obtain_lock(GdkWindow * window) |
| 304 { |
279 { |
| 305 Bool locked = False; |
280 Bool locked = False; |
| 306 |
281 |
| 307 if (!lock_data) { |
282 if (!lock_data) { |
| 308 lock_data = (char *)g_malloc (255); |
283 lock_data = (char *)g_malloc(255); |
| 309 sprintf (lock_data, "pid%d@", getpid ()); |
284 sprintf(lock_data, "pid%d@", getpid()); |
| 310 if (gethostname (lock_data + strlen (lock_data), 100)) { |
285 if (gethostname(lock_data + strlen(lock_data), 100)) { |
| 311 return; |
286 return; |
| 312 } |
287 } |
| 313 } |
288 } |
| 314 |
289 |
| 315 do { |
290 do { |
| 316 int result; |
291 int result; |
| 317 GdkAtom actual_type; |
292 GdkAtom actual_type; |
| 318 gint actual_format; |
293 gint actual_format; |
| 319 gint nitems; |
294 gint nitems; |
| 320 unsigned char *data = 0; |
295 unsigned char *data = 0; |
| 321 |
296 |
| 322 result = gdk_property_get (window, XA_MOZILLA_LOCK, |
297 result = gdk_property_get(window, XA_MOZILLA_LOCK, |
| 323 XA_STRING, 0, |
298 XA_STRING, 0, |
| 324 (65536 / sizeof (long)), 0, |
299 (65536 / sizeof(long)), 0, |
| 325 &actual_type, &actual_format, |
300 &actual_type, &actual_format, &nitems, &data); |
| 326 &nitems, &data); |
301 if (result != Success || actual_type == None) { |
| 327 if (result != Success || actual_type == None) |
302 /* It's not now locked - lock it. */ |
| 328 { |
303 debug_printf("%s: (writing " MOZILLA_LOCK_PROP |
| 329 /* It's not now locked - lock it. */ |
304 " \"%s\" to 0x%x)\n", progname, lock_data, (unsigned int)window); |
| 330 sprintf (debug_buff, "%s: (writing " MOZILLA_LOCK_PROP |
305 |
| 331 " \"%s\" to 0x%x)\n", |
306 gdk_property_change(window, XA_MOZILLA_LOCK, XA_STRING, |
| 332 progname, lock_data, (unsigned int) window); |
307 8, PropModeReplace, |
| 333 debug_print(debug_buff); |
308 (unsigned char *)lock_data, strlen(lock_data)); |
| 334 |
309 locked = True; |
| 335 gdk_property_change(window, XA_MOZILLA_LOCK, XA_STRING, |
310 } |
| 336 8, PropModeReplace, |
311 |
| 337 (unsigned char *) lock_data, |
312 if (!locked) { |
| 338 strlen (lock_data)); |
313 /* Then just fuck it. */ |
| 339 locked = True; |
314 if (data) |
| 340 } |
315 g_free(data); |
| 341 |
316 return; |
| 342 if (!locked) { |
317 } |
| 343 /* Then just fuck it. */ |
318 if (data) |
| 344 if (data) |
319 g_free(data); |
| 345 g_free(data); |
320 } while (!locked); |
| 346 return; |
321 } |
| 347 } |
322 |
| 348 if (data) |
323 |
| 349 g_free(data); |
324 static void mozilla_remote_free_lock(GdkWindow * window) |
| 350 } while (!locked); |
325 { |
| 351 } |
326 int result = 0; |
| 352 |
327 GdkAtom actual_type; |
| 353 |
328 gint actual_format; |
| 354 static void mozilla_remote_free_lock (GdkWindow *window) |
329 gint nitems; |
| 355 { |
330 unsigned char *data = 0; |
| 356 int result = 0; |
331 |
| 357 GdkAtom actual_type; |
332 debug_printf("%s: (deleting " MOZILLA_LOCK_PROP |
| 358 gint actual_format; |
333 " \"%s\" from 0x%x)\n", progname, lock_data, (unsigned int)window); |
| 359 gint nitems; |
334 |
| 360 unsigned char *data = 0; |
335 result = gdk_property_get(window, XA_MOZILLA_LOCK, XA_STRING, |
| 361 |
336 0, (65536 / sizeof(long)), |
| 362 sprintf (debug_buff, "%s: (deleting " MOZILLA_LOCK_PROP |
337 1, &actual_type, &actual_format, &nitems, &data); |
| 363 " \"%s\" from 0x%x)\n", |
338 if (result != Success) { |
| 364 progname, lock_data, (unsigned int) window); |
339 debug_printf("%s: unable to read and delete " MOZILLA_LOCK_PROP " property\n", progname); |
| 365 debug_print(debug_buff); |
340 return; |
| 366 |
341 } else if (!data || !*data) { |
| 367 result = gdk_property_get(window, XA_MOZILLA_LOCK, XA_STRING, |
342 debug_printf("%s: invalid data on " MOZILLA_LOCK_PROP |
| 368 0, (65536 / sizeof (long)), |
343 " of window 0x%x.\n", progname, (unsigned int)window); |
| 369 1, &actual_type, &actual_format, |
344 return; |
| 370 &nitems, &data); |
345 } else if (strcmp((char *)data, lock_data)) { |
| 371 if (result != Success) |
346 debug_printf("%s: " MOZILLA_LOCK_PROP |
| 372 { |
347 " was stolen! Expected \"%s\", saw \"%s\"!\n", progname, lock_data, data); |
| 373 sprintf (debug_buff, "%s: unable to read and delete " MOZILLA_LOCK_PROP |
348 return; |
| 374 " property\n", |
349 } |
| 375 progname); |
350 |
| 376 debug_print(debug_buff); |
351 if (data) |
| 377 return; |
352 g_free(data); |
| 378 } |
353 } |
| 379 else if (!data || !*data) |
354 |
| 380 { |
355 |
| 381 sprintf (debug_buff, "%s: invalid data on " MOZILLA_LOCK_PROP |
356 static int mozilla_remote_command(GdkWindow * window, const char *command, Bool raise_p) |
| 382 " of window 0x%x.\n", |
357 { |
| 383 progname, (unsigned int) window); |
358 int result = 0; |
| 384 debug_print(debug_buff); |
359 Bool done = False; |
| 385 return; |
360 char *new_command = 0; |
| 386 } |
361 |
| 387 else if (strcmp ((char *) data, lock_data)) |
362 /* The -noraise option is implemented by passing a "noraise" argument |
| 388 { |
363 to each command to which it should apply. |
| 389 sprintf (debug_buff, "%s: " MOZILLA_LOCK_PROP |
364 */ |
| 390 " was stolen! Expected \"%s\", saw \"%s\"!\n", |
365 if (!raise_p) { |
| 391 progname, lock_data, data); |
366 char *close; |
| 392 debug_print(debug_buff); |
367 new_command = g_malloc(strlen(command) + 20); |
| 393 return; |
368 strcpy(new_command, command); |
| 394 } |
369 close = strrchr(new_command, ')'); |
| 395 |
370 if (close) |
| 396 if (data) |
371 strcpy(close, ", noraise)"); |
| 397 g_free(data); |
372 else |
| 398 } |
373 strcat(new_command, "(noraise)"); |
| 399 |
374 command = new_command; |
| 400 |
375 } |
| 401 static int |
376 |
| 402 mozilla_remote_command (GdkWindow *window, const char *command, |
377 debug_printf("%s: (writing " MOZILLA_COMMAND_PROP " \"%s\" to 0x%x)\n", |
| 403 Bool raise_p) |
378 progname, command, (unsigned int)window); |
| 404 { |
|
| 405 int result = 0; |
|
| 406 Bool done = False; |
|
| 407 char *new_command = 0; |
|
| 408 |
|
| 409 /* The -noraise option is implemented by passing a "noraise" argument |
|
| 410 to each command to which it should apply. |
|
| 411 */ |
|
| 412 if (!raise_p) |
|
| 413 { |
|
| 414 char *close; |
|
| 415 new_command = g_malloc (strlen (command) + 20); |
|
| 416 strcpy (new_command, command); |
|
| 417 close = strrchr (new_command, ')'); |
|
| 418 if (close) |
|
| 419 strcpy (close, ", noraise)"); |
|
| 420 else |
|
| 421 strcat (new_command, "(noraise)"); |
|
| 422 command = new_command; |
|
| 423 } |
|
| 424 |
|
| 425 sprintf (debug_buff, "%s: (writing " MOZILLA_COMMAND_PROP " \"%s\" to 0x%x)\n", |
|
| 426 progname, command, (unsigned int) window); |
|
| 427 debug_print(debug_buff); |
|
| 428 |
379 |
| 429 gdk_property_change(window, XA_MOZILLA_COMMAND, XA_STRING, 8, |
380 gdk_property_change(window, XA_MOZILLA_COMMAND, XA_STRING, 8, |
| 430 GDK_PROP_MODE_REPLACE, (unsigned char *) command, |
381 GDK_PROP_MODE_REPLACE, (unsigned char *)command, strlen(command)); |
| 431 strlen (command)); |
|
| 432 |
382 |
| 433 while (!done) { |
383 while (!done) { |
| 434 GdkEvent *event; |
384 GdkEvent *event; |
| 435 |
385 |
| 436 event = gdk_event_get(); |
386 event = gdk_event_get(); |
| 437 |
387 |
| 438 if (!event) |
388 if (!event) |
| 439 continue; |
389 continue; |
| 440 |
390 |
| 441 if (event->any.window != window) { |
391 if (event->any.window != window) { |
| 442 gtk_main_do_event(event); |
392 gtk_main_do_event(event); |
| 443 continue; |
393 continue; |
| 444 } |
394 } |
| 445 |
395 |
| 446 if (event->type == GDK_DESTROY && |
396 if (event->type == GDK_DESTROY && event->any.window == window) { |
| 447 event->any.window == window) { |
397 |
| 448 |
398 /* Print to warn user... */ |
| 449 /* Print to warn user...*/ |
399 debug_printf("%s: window 0x%x was destroyed.\n", progname, (unsigned int)window); |
| 450 sprintf (debug_buff, "%s: window 0x%x was destroyed.\n", |
400 result = 6; |
| 451 progname, (unsigned int) window); |
401 goto DONE; |
| 452 debug_print(debug_buff); |
|
| 453 result = 6; |
|
| 454 goto DONE; |
|
| 455 } else if (event->type == GDK_PROPERTY_NOTIFY && |
402 } else if (event->type == GDK_PROPERTY_NOTIFY && |
| 456 event->property.state == GDK_PROPERTY_NEW_VALUE && |
403 event->property.state == GDK_PROPERTY_NEW_VALUE && |
| 457 event->property.window == window && |
404 event->property.window == window && |
| 458 event->property.atom == XA_MOZILLA_RESPONSE) { |
405 event->property.atom == XA_MOZILLA_RESPONSE) { |
| 459 GdkAtom actual_type; |
406 GdkAtom actual_type; |
| 460 gint actual_format, nitems; |
407 gint actual_format, nitems; |
| 461 unsigned char *data = 0; |
408 unsigned char *data = 0; |
| 462 |
409 |
| 463 result = gdk_property_get (window, XA_MOZILLA_RESPONSE, |
410 result = gdk_property_get(window, XA_MOZILLA_RESPONSE, |
| 464 XA_STRING, 0, |
411 XA_STRING, 0, |
| 465 (65536 / sizeof (long)), |
412 (65536 / sizeof(long)), |
| 466 1, |
413 1, &actual_type, &actual_format, &nitems, &data); |
| 467 &actual_type, &actual_format, |
414 |
| 468 &nitems, &data); |
415 |
| 469 |
|
| 470 |
|
| 471 if (result == Success && data && *data) { |
416 if (result == Success && data && *data) { |
| 472 sprintf (debug_buff, "%s: (server sent " MOZILLA_RESPONSE_PROP |
417 debug_printf("%s: (server sent " MOZILLA_RESPONSE_PROP |
| 473 " \"%s\" to 0x%x.)\n", |
418 " \"%s\" to 0x%x.)\n", |
| 474 progname, data, (unsigned int) window); |
419 progname, data, (unsigned int)window); |
| 475 debug_print(debug_buff); |
|
| 476 } |
420 } |
| 477 |
421 |
| 478 if (result != Success) { |
422 if (result != Success) { |
| 479 sprintf (debug_buff, "%s: failed reading " MOZILLA_RESPONSE_PROP |
423 debug_printf("%s: failed reading " MOZILLA_RESPONSE_PROP |
| 480 " from window 0x%0x.\n", |
424 " from window 0x%0x.\n", progname, (unsigned int)window); |
| 481 progname, (unsigned int) window); |
|
| 482 debug_print(debug_buff); |
|
| 483 result = 6; |
425 result = 6; |
| 484 done = True; |
426 done = True; |
| 485 } else if (!data || strlen((char *) data) < 5) { |
427 } else if (!data || strlen((char *)data) < 5) { |
| 486 sprintf (debug_buff, "%s: invalid data on " MOZILLA_RESPONSE_PROP |
428 debug_printf("%s: invalid data on " MOZILLA_RESPONSE_PROP |
| 487 " property of window 0x%0x.\n", |
429 " property of window 0x%0x.\n", |
| 488 progname, (unsigned int) window); |
430 progname, (unsigned int)window); |
| 489 debug_print(debug_buff); |
|
| 490 result = 6; |
431 result = 6; |
| 491 done = True; |
432 done = True; |
| 492 } else if (*data == '1') { /* positive preliminary reply */ |
433 } else if (*data == '1') { /* positive preliminary reply */ |
| 493 sprintf (debug_buff, "%s: %s\n", progname, data + 4); |
434 debug_printf("%s: %s\n", progname, data + 4); |
| 494 debug_print(debug_buff); |
|
| 495 /* keep going */ |
435 /* keep going */ |
| 496 done = False; |
436 done = False; |
| 497 } else if (!strncmp ((char *)data, "200", 3)) { |
437 } else if (!strncmp((char *)data, "200", 3)) { |
| 498 result = 0; |
438 result = 0; |
| 499 done = True; |
439 done = True; |
| 500 } else if (*data == '2') { |
440 } else if (*data == '2') { |
| 501 sprintf (debug_buff, "%s: %s\n", progname, data + 4); |
441 debug_printf("%s: %s\n", progname, data + 4); |
| 502 debug_print(debug_buff); |
|
| 503 result = 0; |
442 result = 0; |
| 504 done = True; |
443 done = True; |
| 505 } else if (*data == '3') { |
444 } else if (*data == '3') { |
| 506 sprintf (debug_buff, "%s: internal error: " |
445 debug_printf("%s: internal error: " |
| 507 "server wants more information? (%s)\n", |
446 "server wants more information? (%s)\n", progname, data); |
| 508 progname, data); |
|
| 509 debug_print(debug_buff); |
|
| 510 result = 3; |
447 result = 3; |
| 511 done = True; |
448 done = True; |
| 512 } else if (*data == '4' || *data == '5') { |
449 } else if (*data == '4' || *data == '5') { |
| 513 sprintf (debug_buff, "%s: %s\n", progname, data + 4); |
450 debug_printf("%s: %s\n", progname, data + 4); |
| 514 debug_print(debug_buff); |
|
| 515 result = (*data - '0'); |
451 result = (*data - '0'); |
| 516 done = True; |
452 done = True; |
| 517 } else { |
453 } else { |
| 518 sprintf (debug_buff, |
454 debug_printf("%s: unrecognised " MOZILLA_RESPONSE_PROP |
| 519 "%s: unrecognised " MOZILLA_RESPONSE_PROP |
455 " from window 0x%x: %s\n", |
| 520 " from window 0x%x: %s\n", |
456 progname, (unsigned int)window, data); |
| 521 progname, (unsigned int) window, data); |
|
| 522 debug_print(debug_buff); |
|
| 523 result = 6; |
457 result = 6; |
| 524 done = True; |
458 done = True; |
| 525 } |
459 } |
| 526 |
460 |
| 527 if (data) |
461 if (data) |
| 528 g_free(data); |
462 g_free(data); |
| 529 } |
463 } |
| 530 else if (event->type == GDK_PROPERTY_NOTIFY && |
464 else if (event->type == GDK_PROPERTY_NOTIFY && |
| 531 event->property.window == window && |
465 event->property.window == window && |
| 532 event->property.state == GDK_PROPERTY_DELETE && |
466 event->property.state == GDK_PROPERTY_DELETE && |
| 533 event->property.atom == XA_MOZILLA_COMMAND) { |
467 event->property.atom == XA_MOZILLA_COMMAND) { |
| 534 sprintf (debug_buff, "%s: (server 0x%x has accepted " |
468 debug_printf("%s: (server 0x%x has accepted " |
| 535 MOZILLA_COMMAND_PROP ".)\n", |
469 MOZILLA_COMMAND_PROP ".)\n", progname, (unsigned int)window); |
| 536 progname, (unsigned int) window); |
|
| 537 debug_print(debug_buff); |
|
| 538 } |
470 } |
| 539 gdk_event_free(event); |
471 gdk_event_free(event); |
| 540 } |
472 } |
| 541 |
473 |
| 542 DONE: |
474 DONE: |
| 543 |
475 |
| 544 if (new_command) |
476 if (new_command) |
| 545 g_free (new_command); |
477 g_free(new_command); |
| 546 |
478 |
| 547 return result; |
479 return result; |
| 548 } |
480 } |
| 549 |
481 |
| 550 |
482 |
| 551 gint check_netscape(char *msg) |
483 gint check_netscape(char *msg) |
| 552 { |
484 { |
| 553 int status; |
485 int status; |
| 554 GdkWindow *window; |
486 GdkWindow *window; |
| 555 |
487 |
| 556 mozilla_remote_init_atoms (); |
488 mozilla_remote_init_atoms(); |
| 557 window = mozilla_remote_find_window(); |
489 window = mozilla_remote_find_window(); |
| 558 |
490 |
| 559 if (window && (((GdkWindowPrivate *)window)->destroyed == FALSE)) { |
491 if (window && (((GdkWindowPrivate *) window)->destroyed == FALSE)) { |
| 560 |
492 |
| 561 XSelectInput(gdk_display, ((GdkWindowPrivate *)window)->xwindow, |
493 XSelectInput(gdk_display, ((GdkWindowPrivate *) window)->xwindow, |
| 562 (PropertyChangeMask|StructureNotifyMask)); |
494 (PropertyChangeMask | StructureNotifyMask)); |
| 563 |
495 |
| 564 |
496 |
| 565 mozilla_remote_obtain_lock(window); |
497 mozilla_remote_obtain_lock(window); |
| 566 |
498 |
| 567 status = mozilla_remote_command(window, msg, False); |
499 status = mozilla_remote_command(window, msg, False); |
| 568 |
500 |
| 569 if (status != 6) |
501 if (status != 6) |
| 570 mozilla_remote_free_lock(window); |
502 mozilla_remote_free_lock(window); |
| 571 |
503 |
| 572 gtk_timeout_add(1000, (GtkFunction)clean_pid, NULL); |
504 gtk_timeout_add(1000, (GtkFunction)clean_pid, NULL); |
| 573 |
505 |
| 574 netscape_lock = 0; |
506 netscape_lock = 0; |
| 575 |
507 |
| 576 g_free(msg); |
508 g_free(msg); |
| 577 return FALSE; |
509 return FALSE; |
| 578 } else |
510 } else |
| 579 return TRUE; |
511 return TRUE; |
| 580 } |
512 } |
| 581 |
513 |
| 582 |
514 |
| 583 static void netscape_command(char *command) |
515 static void netscape_command(char *command) |
| 584 { |
516 { |
| 585 int status; |
517 int status; |
| 586 pid_t pid; |
518 pid_t pid; |
| 587 GdkWindow *window; |
519 GdkWindow *window; |
| 588 |
520 |
| 589 if (netscape_lock) |
521 if (netscape_lock) |
| 590 return; |
522 return; |
| 591 |
523 |