Mercurial > pidgin.yaz
comparison src/browser.c @ 4428:b5669740e34c
[gaim-migrate @ 4703]
Two patches from Ray Strode to clean up browser launching (esp. Netscape and
Mozilla) and to show only available browsers in the prefs drop down list.
committer: Tailor Script <tailor@pidgin.im>
author | Sean Egan <seanegan@gmail.com> |
---|---|
date | Sun, 26 Jan 2003 19:39:43 +0000 |
parents | 02f4eacf4c58 |
children | bf770f11132b |
comparison
equal
deleted
inserted
replaced
4427:88920ce27a9f | 4428:b5669740e34c |
---|---|
32 #endif | 32 #endif |
33 #ifdef _WIN32 | 33 #ifdef _WIN32 |
34 #include <gdk/gdkwin32.h> | 34 #include <gdk/gdkwin32.h> |
35 #else | 35 #else |
36 #include <unistd.h> | 36 #include <unistd.h> |
37 #ifndef HOST_NAME_MAX | |
38 #define HOST_NAME_MAX 255 | |
39 #endif | |
37 #include <gdk/gdkx.h> | 40 #include <gdk/gdkx.h> |
38 #endif | 41 #endif |
39 #include <stdio.h> | 42 #include <stdio.h> |
40 #include <stdlib.h> | 43 #include <stdlib.h> |
41 #include <string.h> | 44 #include <string.h> |
67 static GdkAtom GDKA_MOZILLA_VERSION = 0; | 70 static GdkAtom GDKA_MOZILLA_VERSION = 0; |
68 static GdkAtom GDKA_MOZILLA_LOCK = 0; | 71 static GdkAtom GDKA_MOZILLA_LOCK = 0; |
69 static GdkAtom GDKA_MOZILLA_COMMAND = 0; | 72 static GdkAtom GDKA_MOZILLA_COMMAND = 0; |
70 static GdkAtom GDKA_MOZILLA_RESPONSE = 0; | 73 static GdkAtom GDKA_MOZILLA_RESPONSE = 0; |
71 | 74 |
75 static char *window_check_mozilla_version(Window); | |
76 static const char *get_lock_data(); | |
77 static GdkFilterReturn netscape_response_cb(XEvent *, GdkEvent *, GdkWindow *); | |
78 static gboolean netscape_command(const char *); | |
72 | 79 |
73 static int netscape_lock; | 80 static int netscape_lock; |
74 | 81 |
75 | 82 |
76 static Window VirtualRootWindowOfScreen(screen) | 83 static Window VirtualRootWindowOfScreen(screen) |
200 GDKA_MOZILLA_COMMAND = gdk_atom_intern(MOZILLA_COMMAND_PROP, 0); | 207 GDKA_MOZILLA_COMMAND = gdk_atom_intern(MOZILLA_COMMAND_PROP, 0); |
201 if (!GDKA_MOZILLA_RESPONSE) | 208 if (!GDKA_MOZILLA_RESPONSE) |
202 GDKA_MOZILLA_RESPONSE = gdk_atom_intern(MOZILLA_RESPONSE_PROP, 0); | 209 GDKA_MOZILLA_RESPONSE = gdk_atom_intern(MOZILLA_RESPONSE_PROP, 0); |
203 } | 210 } |
204 | 211 |
212 static char *window_check_mozilla_version(Window window) { | |
213 | |
214 Atom type; | |
215 int format; | |
216 unsigned long nitems, bytesafter; | |
217 unsigned char *version = 0; | |
218 gchar *retval = NULL; | |
219 | |
220 if (XGetWindowProperty(gdk_display, window, | |
221 gdk_x11_atom_to_xatom(GDKA_MOZILLA_VERSION), | |
222 0, (65536 / sizeof(long)), | |
223 False, XA_STRING, | |
224 &type, &format, &nitems, &bytesafter, | |
225 &version) != Success) { | |
226 return NULL; | |
227 } | |
228 | |
229 if (!version) { | |
230 return NULL; | |
231 } | |
232 | |
233 retval = g_strdup(version); | |
234 XFree(version); | |
235 | |
236 return retval; | |
237 } | |
238 | |
205 static GdkWindow *mozilla_remote_find_window() | 239 static GdkWindow *mozilla_remote_find_window() |
206 { | 240 { |
207 int i; | 241 int i; |
208 Window root = VirtualRootWindowOfScreen(DefaultScreenOfDisplay(gdk_display)); | 242 Window root = VirtualRootWindowOfScreen(DefaultScreenOfDisplay(gdk_display)); |
209 Window root2, parent, *kids; | 243 Window root2, parent, *kids; |
210 unsigned int nkids; | 244 unsigned int nkids; |
211 Window result = 0; | 245 Window result = 0; |
212 Window tenative = 0; | 246 Window tenative = 0; |
213 unsigned char *tenative_version = 0; | 247 unsigned char *tenative_version = 0, *version = 0; |
248 static GdkWindow *remote_window = NULL; | |
249 | |
250 if (remote_window != NULL) { | |
251 version = window_check_mozilla_version(GDK_WINDOW_XID(remote_window)); | |
252 | |
253 if (version != NULL) { | |
254 g_free(version); | |
255 return remote_window; | |
256 } | |
257 g_free(version); | |
258 | |
259 gdk_window_destroy(remote_window); | |
260 remote_window = NULL; | |
261 } | |
214 | 262 |
215 if (!XQueryTree(gdk_display, root, &root2, &parent, &kids, &nkids)) { | 263 if (!XQueryTree(gdk_display, root, &root2, &parent, &kids, &nkids)) { |
216 debug_printf("%s: XQueryTree failed on display %s\n", progname, | 264 debug_printf("%s: XQueryTree failed on display %s\n", progname, |
217 DisplayString(gdk_display)); | 265 DisplayString(gdk_display)); |
218 return NULL; | 266 return NULL; |
225 progname, DisplayString(gdk_display)); | 273 progname, DisplayString(gdk_display)); |
226 return NULL; | 274 return NULL; |
227 } | 275 } |
228 | 276 |
229 for (i = nkids - 1; i >= 0; i--) { | 277 for (i = nkids - 1; i >= 0; i--) { |
230 Atom type; | |
231 int format; | |
232 unsigned long nitems, bytesafter; | |
233 unsigned char *version = 0; | |
234 Window w = GClientWindow(gdk_display, kids[i]); | 278 Window w = GClientWindow(gdk_display, kids[i]); |
235 int status = XGetWindowProperty(gdk_display, w, | 279 |
236 gdk_x11_atom_to_xatom(GDKA_MOZILLA_VERSION), | 280 version = window_check_mozilla_version(w); |
237 0, (65536 / sizeof(long)), | 281 |
238 False, XA_STRING, | 282 if (version == NULL) { |
239 &type, &format, &nitems, &bytesafter, | |
240 &version); | |
241 | |
242 if (!version) | |
243 continue; | 283 continue; |
284 } | |
244 | 285 |
245 if (strcmp((char *)version, expected_mozilla_version) && !tenative) { | 286 if (strcmp((char *)version, expected_mozilla_version) && !tenative) { |
246 tenative = w; | 287 tenative = w; |
247 tenative_version = version; | 288 tenative_version = version; |
248 continue; | 289 continue; |
249 } | 290 } |
250 XFree(version); | 291 |
251 if (status == Success && type != None) { | 292 g_free(version); |
293 | |
252 result = w; | 294 result = w; |
253 break; | 295 break; |
254 } | 296 } |
255 } | |
256 | 297 |
257 XFree(kids); | 298 XFree(kids); |
258 | 299 |
259 if (result && tenative) { | 300 if (result && tenative) { |
260 debug_printf("%s: warning: both version %s (0x%x) and version\n" | 301 debug_printf("%s: warning: both version %s (0x%x) and version\n" |
277 return NULL; | 318 return NULL; |
278 } | 319 } |
279 } | 320 } |
280 | 321 |
281 | 322 |
282 static char *lock_data = 0; | 323 static const char *get_lock_data() { |
283 | 324 static char *lock_data = NULL; |
284 static void mozilla_remote_obtain_lock(GdkWindow * window) | 325 |
285 { | 326 if (lock_data == NULL) { |
286 Bool locked = False; | 327 char hostname[HOST_NAME_MAX + 1] = {0}; |
287 | 328 |
288 if (!lock_data) { | 329 if (gethostname(hostname, HOST_NAME_MAX + 1) == 0) { |
289 lock_data = (char *)g_malloc(255); | 330 lock_data = g_strdup_printf("pid%d@%s", getpid(), hostname); |
290 sprintf(lock_data, "pid%d@", getpid()); | 331 } else { |
291 if (gethostname(lock_data + strlen(lock_data), 100)) { | 332 lock_data = g_strdup_printf("pid%d", getpid()); |
292 return; | 333 } |
293 } | 334 } |
294 } | 335 |
295 | 336 return lock_data; |
296 do { | 337 } |
338 | |
339 static gboolean mozilla_remote_obtain_lock(GdkWindow * window) | |
340 { | |
341 gboolean locked = False; | |
342 const char *lock_data = get_lock_data(); | |
297 int result; | 343 int result; |
298 GdkAtom actual_type; | 344 GdkAtom actual_type; |
299 gint actual_format; | 345 gint actual_format; |
300 gint nitems; | 346 gint nitems; |
301 unsigned char *data = 0; | 347 unsigned char *data = 0; |
302 | 348 |
303 result = gdk_property_get(window, GDKA_MOZILLA_LOCK, | 349 gdk_x11_grab_server(); |
350 if (!gdk_property_get(window, GDKA_MOZILLA_LOCK, | |
304 gdk_x11_xatom_to_atom (XA_STRING), 0, | 351 gdk_x11_xatom_to_atom (XA_STRING), 0, |
305 (65536 / sizeof(long)), 0, | 352 (65536 / sizeof(long)), 0, |
306 &actual_type, &actual_format, &nitems, &data); | 353 &actual_type, &actual_format, &nitems, &data)) { |
307 if (result != Success || actual_type == None) { | 354 |
308 /* It's not now locked - lock it. */ | 355 /* It's not now locked - lock it. */ |
309 debug_printf("%s: (writing " MOZILLA_LOCK_PROP | 356 debug_printf("%s: (writing " MOZILLA_LOCK_PROP " \"%s\" to 0x%x)\n", |
310 " \"%s\" to 0x%x)\n", progname, lock_data, (unsigned int)window); | 357 progname, lock_data, (unsigned int) window); |
311 | 358 |
312 gdk_property_change(window, GDKA_MOZILLA_LOCK, | 359 gdk_property_change(window, GDKA_MOZILLA_LOCK, |
313 gdk_x11_xatom_to_atom (XA_STRING), | 360 gdk_x11_xatom_to_atom (XA_STRING), |
314 8, PropModeReplace, | 361 8, PropModeReplace, |
315 (unsigned char *)lock_data, strlen(lock_data)); | 362 (unsigned char *)lock_data, strlen(lock_data)); |
316 locked = True; | 363 locked = True; |
317 } | 364 } |
318 | 365 |
319 if (!locked) { | |
320 /* Then just fuck it. */ | |
321 if (data) | 366 if (data) |
322 g_free(data); | 367 g_free(data); |
323 return; | 368 gdk_x11_ungrab_server(); |
324 } | |
325 if (data) | |
326 g_free(data); | |
327 } while (!locked); | |
328 } | 369 } |
329 | 370 |
330 | 371 |
331 static void mozilla_remote_free_lock(GdkWindow * window) | 372 static void mozilla_remote_free_lock(GdkWindow * window) |
332 { | 373 { |
333 int result = 0; | 374 int result = 0; |
334 GdkAtom actual_type; | 375 GdkAtom actual_type; |
335 gint actual_format; | 376 gint actual_format; |
336 gint nitems; | 377 gint nitems; |
337 unsigned char *data = 0; | 378 unsigned char *data = 0; |
379 const char *lock_data = get_lock_data(); | |
338 | 380 |
339 debug_printf("%s: (deleting " MOZILLA_LOCK_PROP | 381 debug_printf("%s: (deleting " MOZILLA_LOCK_PROP |
340 " \"%s\" from 0x%x)\n", progname, lock_data, (unsigned int)window); | 382 " \"%s\" from 0x%x)\n", progname, lock_data, (unsigned int)window); |
341 | 383 |
342 result = gdk_property_get(window, GDKA_MOZILLA_LOCK, | 384 result = gdk_property_get(window, GDKA_MOZILLA_LOCK, |
343 gdk_x11_xatom_to_atom (XA_STRING), | 385 gdk_x11_xatom_to_atom (XA_STRING), |
344 0, (65536 / sizeof(long)), | 386 0, (65536 / sizeof(long)), |
345 1, &actual_type, &actual_format, &nitems, &data); | 387 1, &actual_type, &actual_format, &nitems, &data); |
346 if (result != Success) { | 388 |
389 if (result != TRUE) { | |
347 debug_printf("%s: unable to read and delete " MOZILLA_LOCK_PROP " property\n", progname); | 390 debug_printf("%s: unable to read and delete " MOZILLA_LOCK_PROP " property\n", progname); |
348 return; | 391 return; |
349 } else if (!data || !*data) { | 392 } else if (!data || !*data) { |
350 debug_printf("%s: invalid data on " MOZILLA_LOCK_PROP | 393 debug_printf("%s: invalid data on " MOZILLA_LOCK_PROP |
351 " of window 0x%x.\n", progname, (unsigned int)window); | 394 " of window 0x%x.\n", progname, (unsigned int)window); |
354 debug_printf("%s: " MOZILLA_LOCK_PROP | 397 debug_printf("%s: " MOZILLA_LOCK_PROP |
355 " was stolen! Expected \"%s\", saw \"%s\"!\n", progname, lock_data, data); | 398 " was stolen! Expected \"%s\", saw \"%s\"!\n", progname, lock_data, data); |
356 return; | 399 return; |
357 } | 400 } |
358 | 401 |
359 if (data) | 402 XFree(data); |
360 g_free(data); | 403 } |
361 } | 404 |
362 | 405 static GdkFilterReturn netscape_response_cb(XEvent *event, GdkEvent *translated, GdkWindow *window) |
363 | 406 { |
364 static int mozilla_remote_command(GdkWindow * window, const char *command, Bool raise_p) | 407 Atom actual_type, mozilla_response; |
408 Window xid; | |
409 int actual_format; | |
410 unsigned long nitems, bytes_after; | |
411 unsigned char *data = 0; | |
412 char *error = NULL; | |
413 | |
414 if (window == NULL || GDK_WINDOW_OBJECT(window)->destroyed) { | |
415 do_error_dialog(_("Communication with the browser failed. Please close all " | |
416 "windows and try again."), NULL, GAIM_ERROR); | |
417 debug_printf("netscape_response_cb called with NULL window.\n"); | |
418 return GDK_FILTER_CONTINUE; | |
419 } | |
420 | |
421 mozilla_response = gdk_x11_atom_to_xatom(GDKA_MOZILLA_RESPONSE); | |
422 xid = GDK_WINDOW_XID(window); | |
423 | |
424 /* If the event isn't what we want then let gtk handle it */ | |
425 if (event->xany.type != PropertyNotify || | |
426 event->xproperty.state != PropertyNewValue || | |
427 event->xproperty.window != xid || | |
428 event->xproperty.atom != mozilla_response) { | |
429 return GDK_FILTER_CONTINUE; | |
430 } | |
431 | |
432 if (XGetWindowProperty (gdk_display, xid, mozilla_response, | |
433 0, (65536 / sizeof (long)), | |
434 True, | |
435 XA_STRING, | |
436 &actual_type, &actual_format, | |
437 &nitems, &bytes_after, | |
438 &data) != Success | |
439 || data == NULL || (data[0] != '1' && data[0] != '2')) { | |
440 | |
441 do_error_dialog(_("Communication with the browser failed. Please close all " | |
442 "windows and try again."), NULL, GAIM_ERROR); | |
443 } | |
444 | |
445 if (data[0] == '1') { | |
446 /* Netscape isn't ready yet */ | |
447 debug_printf("Remote Netscape window isn't ready yet.\n"); | |
448 return GDK_FILTER_REMOVE; | |
449 } | |
450 | |
451 if (data[0] == '2') { | |
452 /* Yay! It worked */ | |
453 debug_printf("Successfully sent command to remote Netscape window.\n"); | |
454 } | |
455 | |
456 gdk_window_remove_filter(window, (GdkFilterFunc) netscape_response_cb, window); | |
457 mozilla_remote_free_lock(window); | |
458 netscape_lock = 0; | |
459 return GDK_FILTER_REMOVE; | |
460 } | |
461 | |
462 static void mozilla_remote_command(GdkWindow * window, const char *command, Bool raise_p) | |
365 { | 463 { |
366 int result = 0; | 464 int result = 0; |
367 Bool done = False; | 465 Bool done = False; |
368 char *new_command = 0; | 466 char *new_command = 0; |
369 | 467 |