Mercurial > pidgin
diff 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 |
line wrap: on
line diff
--- a/src/browser.c Sun Jan 26 14:10:49 2003 +0000 +++ b/src/browser.c Sun Jan 26 19:39:43 2003 +0000 @@ -34,6 +34,9 @@ #include <gdk/gdkwin32.h> #else #include <unistd.h> +#ifndef HOST_NAME_MAX +#define HOST_NAME_MAX 255 +#endif #include <gdk/gdkx.h> #endif #include <stdio.h> @@ -69,6 +72,10 @@ static GdkAtom GDKA_MOZILLA_COMMAND = 0; static GdkAtom GDKA_MOZILLA_RESPONSE = 0; +static char *window_check_mozilla_version(Window); +static const char *get_lock_data(); +static GdkFilterReturn netscape_response_cb(XEvent *, GdkEvent *, GdkWindow *); +static gboolean netscape_command(const char *); static int netscape_lock; @@ -202,6 +209,33 @@ GDKA_MOZILLA_RESPONSE = gdk_atom_intern(MOZILLA_RESPONSE_PROP, 0); } +static char *window_check_mozilla_version(Window window) { + + Atom type; + int format; + unsigned long nitems, bytesafter; + unsigned char *version = 0; + gchar *retval = NULL; + + if (XGetWindowProperty(gdk_display, window, + gdk_x11_atom_to_xatom(GDKA_MOZILLA_VERSION), + 0, (65536 / sizeof(long)), + False, XA_STRING, + &type, &format, &nitems, &bytesafter, + &version) != Success) { + return NULL; + } + + if (!version) { + return NULL; + } + + retval = g_strdup(version); + XFree(version); + + return retval; +} + static GdkWindow *mozilla_remote_find_window() { int i; @@ -210,7 +244,21 @@ unsigned int nkids; Window result = 0; Window tenative = 0; - unsigned char *tenative_version = 0; + unsigned char *tenative_version = 0, *version = 0; + static GdkWindow *remote_window = NULL; + + if (remote_window != NULL) { + version = window_check_mozilla_version(GDK_WINDOW_XID(remote_window)); + + if (version != NULL) { + g_free(version); + return remote_window; + } + g_free(version); + + gdk_window_destroy(remote_window); + remote_window = NULL; + } if (!XQueryTree(gdk_display, root, &root2, &parent, &kids, &nkids)) { debug_printf("%s: XQueryTree failed on display %s\n", progname, @@ -227,32 +275,25 @@ } for (i = nkids - 1; i >= 0; i--) { - Atom type; - int format; - unsigned long nitems, bytesafter; - unsigned char *version = 0; Window w = GClientWindow(gdk_display, kids[i]); - int status = XGetWindowProperty(gdk_display, w, - gdk_x11_atom_to_xatom(GDKA_MOZILLA_VERSION), - 0, (65536 / sizeof(long)), - False, XA_STRING, - &type, &format, &nitems, &bytesafter, - &version); + + version = window_check_mozilla_version(w); - if (!version) + if (version == NULL) { continue; + } if (strcmp((char *)version, expected_mozilla_version) && !tenative) { tenative = w; tenative_version = version; continue; } - XFree(version); - if (status == Success && type != None) { + + g_free(version); + result = w; break; } - } XFree(kids); @@ -279,35 +320,41 @@ } -static char *lock_data = 0; - -static void mozilla_remote_obtain_lock(GdkWindow * window) -{ - Bool locked = False; +static const char *get_lock_data() { + static char *lock_data = NULL; - if (!lock_data) { - lock_data = (char *)g_malloc(255); - sprintf(lock_data, "pid%d@", getpid()); - if (gethostname(lock_data + strlen(lock_data), 100)) { - return; + if (lock_data == NULL) { + char hostname[HOST_NAME_MAX + 1] = {0}; + + if (gethostname(hostname, HOST_NAME_MAX + 1) == 0) { + lock_data = g_strdup_printf("pid%d@%s", getpid(), hostname); + } else { + lock_data = g_strdup_printf("pid%d", getpid()); } } - do { + return lock_data; +} + +static gboolean mozilla_remote_obtain_lock(GdkWindow * window) +{ + gboolean locked = False; + const char *lock_data = get_lock_data(); int result; GdkAtom actual_type; gint actual_format; gint nitems; unsigned char *data = 0; - result = gdk_property_get(window, GDKA_MOZILLA_LOCK, + gdk_x11_grab_server(); + if (!gdk_property_get(window, GDKA_MOZILLA_LOCK, gdk_x11_xatom_to_atom (XA_STRING), 0, (65536 / sizeof(long)), 0, - &actual_type, &actual_format, &nitems, &data); - if (result != Success || actual_type == None) { + &actual_type, &actual_format, &nitems, &data)) { + /* It's not now locked - lock it. */ - debug_printf("%s: (writing " MOZILLA_LOCK_PROP - " \"%s\" to 0x%x)\n", progname, lock_data, (unsigned int)window); + debug_printf("%s: (writing " MOZILLA_LOCK_PROP " \"%s\" to 0x%x)\n", + progname, lock_data, (unsigned int) window); gdk_property_change(window, GDKA_MOZILLA_LOCK, gdk_x11_xatom_to_atom (XA_STRING), @@ -316,15 +363,9 @@ locked = True; } - if (!locked) { - /* Then just fuck it. */ if (data) g_free(data); - return; - } - if (data) - g_free(data); - } while (!locked); + gdk_x11_ungrab_server(); } @@ -332,9 +373,10 @@ { int result = 0; GdkAtom actual_type; - gint actual_format; + gint actual_format; gint nitems; unsigned char *data = 0; + const char *lock_data = get_lock_data(); debug_printf("%s: (deleting " MOZILLA_LOCK_PROP " \"%s\" from 0x%x)\n", progname, lock_data, (unsigned int)window); @@ -343,7 +385,8 @@ gdk_x11_xatom_to_atom (XA_STRING), 0, (65536 / sizeof(long)), 1, &actual_type, &actual_format, &nitems, &data); - if (result != Success) { + + if (result != TRUE) { debug_printf("%s: unable to read and delete " MOZILLA_LOCK_PROP " property\n", progname); return; } else if (!data || !*data) { @@ -356,12 +399,67 @@ return; } - if (data) - g_free(data); + XFree(data); } +static GdkFilterReturn netscape_response_cb(XEvent *event, GdkEvent *translated, GdkWindow *window) +{ + Atom actual_type, mozilla_response; + Window xid; + int actual_format; + unsigned long nitems, bytes_after; + unsigned char *data = 0; + char *error = NULL; -static int mozilla_remote_command(GdkWindow * window, const char *command, Bool raise_p) + if (window == NULL || GDK_WINDOW_OBJECT(window)->destroyed) { + do_error_dialog(_("Communication with the browser failed. Please close all " + "windows and try again."), NULL, GAIM_ERROR); + debug_printf("netscape_response_cb called with NULL window.\n"); + return GDK_FILTER_CONTINUE; + } + + mozilla_response = gdk_x11_atom_to_xatom(GDKA_MOZILLA_RESPONSE); + xid = GDK_WINDOW_XID(window); + + /* If the event isn't what we want then let gtk handle it */ + if (event->xany.type != PropertyNotify || + event->xproperty.state != PropertyNewValue || + event->xproperty.window != xid || + event->xproperty.atom != mozilla_response) { + return GDK_FILTER_CONTINUE; + } + + if (XGetWindowProperty (gdk_display, xid, mozilla_response, + 0, (65536 / sizeof (long)), + True, + XA_STRING, + &actual_type, &actual_format, + &nitems, &bytes_after, + &data) != Success + || data == NULL || (data[0] != '1' && data[0] != '2')) { + + do_error_dialog(_("Communication with the browser failed. Please close all " + "windows and try again."), NULL, GAIM_ERROR); + } + + if (data[0] == '1') { + /* Netscape isn't ready yet */ + debug_printf("Remote Netscape window isn't ready yet.\n"); + return GDK_FILTER_REMOVE; + } + + if (data[0] == '2') { + /* Yay! It worked */ + debug_printf("Successfully sent command to remote Netscape window.\n"); + } + + gdk_window_remove_filter(window, (GdkFilterFunc) netscape_response_cb, window); + mozilla_remote_free_lock(window); + netscape_lock = 0; + return GDK_FILTER_REMOVE; +} + +static void mozilla_remote_command(GdkWindow * window, const char *command, Bool raise_p) { int result = 0; Bool done = False;