Trivial warning fixes: () -> (void) and comma at end of enum
[obnox/wireshark/wip.git] / gtk / webbrowser.c
1 /* The GIMP -- an image manipulation program
2  * Copyright (C) 1995 Spencer Kimball and Peter Mattis
3  *
4  * Web Browser Plug-in
5  * Copyright (C) 2003  Henrik Brix Andersen <brix@gimp.org>
6  *
7  * This program is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 2 of the License, or
10  * (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20  */
21
22 /* Ethereal - this file is copied from "The GIMP" V2.0.2
23  * You will find the original file in the gimp distribution zip under:
24  * \plug-ins\common\webbrowser.c
25  *
26  * It was modified to suit the Ethereal environment (#if 0)!
27  */
28
29 #include "config.h"
30
31 #include <string.h> /* strlen, strstr */
32
33 #include <gtk/gtk.h>
34
35 #include <epan/filesystem.h>
36
37 #include "prefs.h"
38 #include "webbrowser.h"
39 #include "compat_macros.h"
40 #include "simple_dialog.h"
41
42 #if defined(G_OS_WIN32)
43 /* Win32 - use Windows shell services to start a browser */
44 #include <windows.h>
45 #elif defined (HAVE_OS_X_FRAMEWORKS)
46 /* Mac OS X - use Launch Services to start a browser */
47 #include <CoreFoundation/CFBase.h>
48 #include <CoreFoundation/CFString.h>
49 #include <CoreFoundation/CFURL.h>
50 #include <ApplicationServices/ApplicationServices.h>
51 #else
52 /* Everything else - launch the browser ourselves */
53 #define MUST_LAUNCH_BROWSER_OURSELVES
54 #endif
55
56 #ifdef MUST_LAUNCH_BROWSER_OURSELVES
57 static gchar*   strreplace       (const gchar      *string,
58                                   const gchar      *delimiter,
59                                   const gchar      *replacement);
60 #endif
61
62 gboolean
63 browser_needs_pref(void)
64 {
65 #ifdef MUST_LAUNCH_BROWSER_OURSELVES
66     return TRUE;
67 #else
68     return FALSE;
69 #endif
70 }
71
72
73 gboolean
74 browser_open_url (const gchar *url)
75 {
76 #if defined(G_OS_WIN32)
77
78   return ((gint) ShellExecute (HWND_DESKTOP, "open", url, NULL, NULL, SW_SHOWNORMAL) > 32);
79
80 #elif defined(HAVE_OS_X_FRAMEWORKS)
81
82   CFStringRef url_CFString;
83   CFURLRef url_CFURL;
84   OSStatus status;
85
86   /*
87    * XXX - if URLs passed to "browser_open_url()" contain non-ASCII
88    * characters, we'd have to choose an appropriate value from the
89    * CFStringEncodings enum.
90    */
91   url_CFString = CFStringCreateWithCString(NULL, url, kCFStringEncodingASCII);
92   url_CFURL = CFURLCreateWithString(NULL, url_CFString, NULL);
93   /*
94    * XXX - this is a Launch Services result code, and we should probably
95    * display a dialog box if it's not 0, describing what the error was.
96    * Then again, we should probably do the same for the ShellExecute call,
97    * unless that call itself happens to pop up a dialog box for all errors.
98    */
99   status = LSOpenCFURLRef(url_CFURL, NULL);
100   CFRelease(url_CFURL);
101   CFRelease(url_CFString);
102   return (status == 0);
103
104 #elif (GLIB_MAJOR_VERSION >= 2)
105
106
107   GError    *error = NULL;
108   gchar     *browser;
109   gchar     *argument;
110   gchar     *cmd;
111   gchar    **argv;
112   gboolean   retval;
113
114   g_return_val_if_fail (url != NULL, FALSE);
115
116   /*  browser = gimp_gimprc_query ("web-browser");*/
117   browser = g_strdup(prefs.gui_webbrowser);
118
119   if (browser == NULL || ! strlen (browser))
120     {
121       simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK, 
122           "Web browser not specified.\n"
123           "Please correct the web browser setting in the Preferences dialog.");
124       g_free (browser);
125       return FALSE;
126     }
127
128   /* quote the url since it might contains special chars */
129   argument = g_shell_quote (url);
130
131   /* replace %s with URL */
132   if (strstr (browser, "%s"))
133     cmd = strreplace (browser, "%s", argument);
134   else
135     cmd = g_strconcat (browser, " ", argument, NULL);
136
137   g_free (argument);
138
139   /* parse the cmd line */
140   if (! g_shell_parse_argv (cmd, NULL, &argv, &error))
141     {
142       simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK, 
143           PRIMARY_TEXT_START "Could not parse web browser command: \"%s\"" PRIMARY_TEXT_END
144           "\n\n\"%s\"\n\n%s", 
145           browser, error->message,
146           "Please correct the web browser setting in the Preferences dialog.");
147       g_error_free (error);
148       return FALSE;
149     }
150
151   retval = g_spawn_async (NULL, argv, NULL,
152                           G_SPAWN_SEARCH_PATH,
153                           NULL, NULL,
154                           NULL, &error);
155
156   if (! retval)
157     {
158       simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK, 
159           PRIMARY_TEXT_START "Could not execute web browser: \"%s\"" PRIMARY_TEXT_END
160           "\n\n\"%s\"\n\n%s", 
161           browser, error->message,
162           "Please correct the web browser setting in the Preferences dialog.");
163       g_error_free (error);
164     }
165
166   g_free (browser);
167   g_free (cmd);
168   g_strfreev (argv);
169
170   return retval;
171
172 #else
173   /* GLIB version 1.x doesn't support the functions used above,
174      so simply do nothing for now, to be able to compile.
175      XXX - has to be improved */
176   return FALSE;
177 #endif
178 }
179
180 #ifdef MUST_LAUNCH_BROWSER_OURSELVES
181
182 static gchar*
183 strreplace (const gchar *string,
184             const gchar *delimiter,
185             const gchar *replacement)
186 {
187   gchar  *ret;
188   gchar **tmp;
189
190   g_return_val_if_fail (string != NULL, NULL);
191   g_return_val_if_fail (delimiter != NULL, NULL);
192   g_return_val_if_fail (replacement != NULL, NULL);
193
194   tmp = g_strsplit (string, delimiter, 0);
195   ret = g_strjoinv (replacement, tmp);
196   g_strfreev (tmp);
197
198   return ret;
199 }
200
201 #endif /* MUST_LAUNCH_BROWSER_OURSELVES */
202
203 /** Convert local absolute path to uri.
204  *
205  * @param filename to (absolute pathed) filename to convert
206  * @return a newly allocated uri, you must g_free it later
207  */
208 static gchar *
209 filename2uri(gchar *filename)
210 {
211     int i = 0;
212     gchar *file_tmp;
213     GString *filestr;
214
215
216     filestr = g_string_sized_new(200);
217
218     /* this escaping is somewhat slow but should working fine */
219     for(i=0; filename[i]; i++) {
220         switch(filename[i]) {
221         case(' '):
222             g_string_append(filestr, "%20");
223             break;
224         case('%'):
225             g_string_append(filestr, "%%");
226             break;
227         case('\\'):
228             g_string_append_c(filestr, '/');
229             break;
230             /* XXX - which other chars need to be escaped? */
231         default:
232             g_string_append_c(filestr, filename[i]);
233         }
234     }
235
236
237     /* prepend URI header "file:" appropriate for the system */
238 #ifdef G_OS_WIN32
239     /* XXX - how do we handle UNC names (e.g. //servername/sharename/dir1/dir2/capture-file.cap) */
240     g_string_prepend(filestr, "file:///");
241 #else
242     g_string_prepend(filestr, "file://");
243 #endif
244
245     file_tmp = filestr->str;
246
247     g_string_free(filestr, FALSE /* don't free segment data */);
248
249     return file_tmp;
250 }
251
252 /* browse a file relative to the data dir */
253 void
254 browser_open_data_file(const gchar *filename)
255 {
256     gchar *file_path;
257     gchar *uri;
258
259     /* build filename */
260     file_path = g_strdup_printf("%s/%s", get_datafile_dir(), filename);
261
262     /* convert filename to uri */
263     uri = filename2uri(file_path);
264
265     /* show the uri */
266     browser_open_url (uri);
267
268     g_free(file_path);
269     g_free(uri);
270 }