Add preliminary support for Opera Mobile
[browser-switch] / config-ui / browser-switchboard-cp.c
1 /*
2  * browser-switchboard-cp.c -- a hildon-control-panel applet for
3  * selecting the default browser for Browser Switchboard
4  * 
5  * Copyright (C) 2009-2010 Steven Luo
6  * Copyright (C) 2009-2010 Faheem Pervez
7  * 
8  * Derived from services-cp.c from maemo-control-services
9  * Copyright (c) 2008 Janne Kataja <janne.kataja@iki.fi>
10  * Copyright (c) 2008 Nokia Corporation
11  * 
12  * This program is free software; you can redistribute it and/or modify
13  * it under the terms of the GNU General Public License as published by
14  * the Free Software Foundation; either version 2, or (at your option)
15  * any later version.
16  *
17  * This program is distributed in the hope that it will be useful,
18  * but WITHOUT ANY WARRANTY; without even the implied warranty of
19  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20  * GNU General Public License for more details.
21  *
22  * You should have received a copy of the GNU General Public License
23  * along with this program; if not, write to the Free Software
24  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
25  * USA.
26  */
27
28
29 #include <stdlib.h>
30 #include <string.h>
31 #include <stdio.h>
32 #include <unistd.h>
33 #include <errno.h>
34 #include <glib.h>
35 #include <glib/gstdio.h>
36 #include <gtk/gtk.h>
37
38 #ifdef HILDON
39 #include <hildon/hildon-banner.h>
40 #include <hildon/hildon-program.h>
41
42 #ifdef FREMANTLE
43 #include <hildon/hildon-touch-selector.h>
44 #include <hildon/hildon-picker-button.h>
45 #include <hildon/hildon-caption.h>
46 #include <hildon/hildon-entry.h>
47 #endif /* FREMANTLE */
48
49 #ifdef HILDON_CP_APPLET
50 #include <hildon-cp-plugin/hildon-cp-plugin-interface.h>
51 #endif /* HILDON_CP_APPLET */
52 #endif /* HILDON */
53
54 #include "configfile.h"
55
56 #define CONTINUOUS_MODE_DEFAULT 0
57
58 #if defined(HILDON) && defined(FREMANTLE)
59 #define _HILDON_SIZE_DEFAULT (HILDON_SIZE_AUTO_WIDTH|HILDON_SIZE_FINGER_HEIGHT)
60 #endif
61
62 struct browser_entry {
63         char *config;
64         char *displayname;
65 };
66 struct browser_entry browsers[] = {
67         { "microb", "MicroB" }, /* First entry is the default! */
68         { "tear", "Tear" },
69         { "fennec", "Mobile Firefox (Fennec)" },
70         { "opera", "Opera Mobile" },
71         { "midori", "Midori" },
72         { "other", "Other" },
73         { NULL, NULL },
74 };
75
76 char *logger_name = NULL;
77
78 struct config_widgets {
79 #if defined(HILDON) && defined(FREMANTLE)
80         GtkWidget *continuous_mode_selector;
81         GtkWidget *default_browser_selector;
82 #else
83         GtkWidget *continuous_mode_off_radio;
84         GtkWidget *continuous_mode_on_radio;
85         GtkWidget *default_browser_combo;
86 #endif
87         GtkWidget *other_browser_cmd_entry;
88         GtkWidget *other_browser_cmd_entry_label;
89 };
90 struct config_widgets cw;
91 GtkWidget *dialog;
92
93
94 /**********************************************************************
95  * Configuration routines
96  **********************************************************************/
97
98 #if defined(HILDON) && defined(FREMANTLE)
99
100 static inline int get_continuous_mode(void) {
101         return hildon_touch_selector_get_active(HILDON_TOUCH_SELECTOR(cw.continuous_mode_selector), 0);
102 }
103 static inline void set_continuous_mode(int state) {
104         hildon_touch_selector_set_active(HILDON_TOUCH_SELECTOR(cw.continuous_mode_selector), 0, state);
105 }
106
107 static inline char *get_default_browser(void) {
108         return browsers[hildon_touch_selector_get_active(HILDON_TOUCH_SELECTOR(cw.default_browser_selector), 0)].config;
109 }
110
111 #else /* !defined(HILDON) || !defined(FREMANTLE) */
112
113 static inline int get_continuous_mode(void) {
114         return gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(cw.continuous_mode_on_radio));
115 }
116 static inline void set_continuous_mode(int state) {
117         if (state)
118                 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(cw.continuous_mode_on_radio), TRUE);
119         else
120                 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(cw.continuous_mode_off_radio), TRUE);
121 }
122
123 static inline char *get_default_browser(void) {
124         return browsers[gtk_combo_box_get_active(GTK_COMBO_BOX(cw.default_browser_combo))].config;
125 }
126
127 #endif /* defined(HILDON) && defined(FREMANTLE) */
128
129 static void set_default_browser(char *browser) {
130         gint i;
131
132         /* Loop through browsers looking for a match */
133         for (i = 0; browsers[i].config && strcmp(browsers[i].config, browser);
134                         ++i);
135
136         if (!browsers[i].config)
137                 /* No match found, set to the default browser */
138                 i = 0;
139
140 #if defined(HILDON) && defined(FREMANTLE)
141         hildon_touch_selector_set_active(HILDON_TOUCH_SELECTOR(cw.default_browser_selector), 0, i);
142 #else
143         gtk_combo_box_set_active(GTK_COMBO_BOX(cw.default_browser_combo), i);
144 #endif
145 }
146
147 static inline char *get_other_browser_cmd(void) {
148         return (char *)gtk_entry_get_text(GTK_ENTRY(cw.other_browser_cmd_entry));
149 }
150 static inline void set_other_browser_cmd(char *cmd) {
151         gtk_entry_set_text(GTK_ENTRY(cw.other_browser_cmd_entry), cmd);
152 }
153
154 static void load_config(void) {
155         FILE *fp;
156         int continuous_mode_seen = 0;
157         int default_browser_seen = 0;
158         int other_browser_cmd_seen = 0;
159         struct swb_config_line line;
160
161         if (!(fp = open_config_file()))
162                 return;
163
164         /* Parse the config file
165            TODO: should we handle errors differently than EOF? */
166         if (!parse_config_file_begin())
167                 goto out;
168         while (!parse_config_file_line(fp, &line)) {
169                 if (line.parsed) {
170                         if (!strcmp(line.key, "continuous_mode")) {
171                                 if (!continuous_mode_seen) {
172                                         set_continuous_mode(atoi(line.value));
173                                         continuous_mode_seen = 1;
174                                 }
175                                 free(line.value);
176                         } else if (!strcmp(line.key, "default_browser")) {
177                                 if (!default_browser_seen) {
178                                         set_default_browser(line.value);
179                                         default_browser_seen = 1;
180                                 }
181                                 free(line.value);
182                         } else if (!strcmp(line.key, "other_browser_cmd")) {
183                                 if (!other_browser_cmd_seen) {
184                                         set_other_browser_cmd(line.value);
185                                         other_browser_cmd_seen = 1;
186                                 }
187                                 free(line.value);
188                         } else if (!strcmp(line.key, "logging")) {
189                                 if (!logger_name)
190                                         logger_name = line.value;
191                         }
192                 }
193                 free(line.key);
194         }
195         parse_config_file_end();
196
197 out:
198         fclose(fp);
199         return;
200 }
201
202 static void save_config(void) {
203         FILE *fp = NULL, *tmpfp = NULL;
204         char *homedir, *tempfile, *newfile;
205         size_t len;
206         int continuous_mode_seen = 0;
207         int default_browser_seen = 0;
208         int other_browser_cmd_seen = 0;
209         struct swb_config_line line;
210
211         /* If CONFIGFILE_DIR doesn't exist already, try to create it */
212         if (!(homedir = getenv("HOME")))
213                 homedir = DEFAULT_HOMEDIR;
214         len = strlen(homedir) + strlen(CONFIGFILE_DIR) + 1;
215         if (!(newfile = calloc(len, sizeof(char))))
216                 return;
217         snprintf(newfile, len, "%s%s", homedir, CONFIGFILE_DIR);
218         if (access(newfile, F_OK) == -1 && errno == ENOENT) {
219                 mkdir(newfile, 0750);
220         }
221         free(newfile);
222
223         /* Put together the path to the new config file and the tempfile */
224         len = strlen(homedir) + strlen(CONFIGFILE_LOC) + 1;
225         if (!(newfile = calloc(len, sizeof(char))))
226                 return;
227         /* 4 = strlen(".tmp") */
228         if (!(tempfile = calloc(len+4, sizeof(char)))) {
229                 free(newfile);
230                 return;
231         }
232         snprintf(newfile, len, "%s%s", homedir, CONFIGFILE_LOC);
233         snprintf(tempfile, len+4, "%s%s", newfile, ".tmp");
234
235         /* Open the temporary file for writing */
236         if (!(tmpfp = fopen(tempfile, "w")))
237                 /* TODO: report the error somehow? */
238                 goto out;
239
240         /* Open the old config file, if it exists */
241         if ((fp = open_config_file()) && parse_config_file_begin()) {
242                 /* Copy the old config file over to the new one line by line,
243                    replacing old config values with new ones
244                    TODO: should we handle errors differently than EOF? */
245                 while (!parse_config_file_line(fp, &line)) {
246                         if (line.parsed) {
247                                 /* Is a config line, print the new value here */
248                                 if (!strcmp(line.key, "continuous_mode")) {
249                                         if (!continuous_mode_seen) {
250                                                 fprintf(tmpfp, "%s = %d\n",
251                                                         line.key,
252                                                         get_continuous_mode());
253                                                 continuous_mode_seen = 1;
254                                         }
255                                 } else if (!strcmp(line.key,
256                                                         "default_browser")) {
257                                         if (!default_browser_seen) {
258                                                 fprintf(tmpfp, "%s = \"%s\"\n",
259                                                         line.key,
260                                                         get_default_browser());
261                                                 default_browser_seen = 1;
262                                         }
263                                 } else if (!strcmp(line.key,
264                                                         "other_browser_cmd")) {
265                                         if (!other_browser_cmd_seen &&
266                                             strlen(get_other_browser_cmd())>0) {
267                                                 fprintf(tmpfp, "%s = \"%s\"\n",
268                                                         line.key,
269                                                         get_other_browser_cmd());
270                                                 other_browser_cmd_seen = 1;
271                                         }
272                                 } else if (!strcmp(line.key,
273                                                         "logging")) {
274                                         if (logger_name) {
275                                                 fprintf(tmpfp, "%s = \"%s\"\n",
276                                                         line.key,
277                                                         logger_name);
278                                                 free(logger_name);
279                                                 logger_name = NULL;
280                                         }
281                                 }
282                         } else {
283                                 /* Just copy the old line over */
284                                 fprintf(tmpfp, "%s\n", line.key);
285                         }
286                         free(line.key);
287                         free(line.value);
288                 }
289                 parse_config_file_end();
290         }
291
292         /* If we haven't written them yet, write out the new config values */
293         if (!continuous_mode_seen)
294                 fprintf(tmpfp, "%s = %d\n",
295                         "continuous_mode", get_continuous_mode());
296         if (!default_browser_seen)
297                 fprintf(tmpfp, "%s = \"%s\"\n",
298                         "default_browser", get_default_browser());
299         if (!other_browser_cmd_seen && strlen(get_other_browser_cmd()) > 0)
300                 fprintf(tmpfp, "%s = \"%s\"\n",
301                         "other_browser_cmd", get_other_browser_cmd());
302         if (logger_name)
303                 fprintf(tmpfp, "%s = \"%s\"\n",
304                         "logging", logger_name);
305
306         /* Replace the old config file with the new one */
307         fclose(tmpfp);
308         tmpfp = NULL;
309         rename(tempfile, newfile);
310
311 out:
312         free(newfile);
313         free(tempfile);
314         if (tmpfp)
315                 fclose(tmpfp);
316         if (fp)
317                 fclose(fp);
318         return;
319 }
320
321 static void do_reconfig(void) {
322         save_config();
323
324         /* Try to send SIGHUP to any running browser-switchboard process
325            This causes it to reread config files if in continuous_mode, or
326            die so that the config will be reloaded on next start otherwise */
327         system("kill -HUP `pidof browser-switchboard` > /dev/null 2>&1");
328 }
329
330
331 /**********************************************************************
332  * Callbacks
333  **********************************************************************/
334
335 #if defined(HILDON) && defined(FREMANTLE)
336 static void default_browser_selector_callback(GtkWidget *widget,
337                 gint column, gpointer data) {
338 #else
339 static void default_browser_combo_callback(GtkWidget *widget, gpointer data) {
340 #endif
341         if (!strcmp(get_default_browser(), "other")) {
342                 gtk_editable_set_editable(GTK_EDITABLE(cw.other_browser_cmd_entry), TRUE);
343                 gtk_widget_set_sensitive(cw.other_browser_cmd_entry, TRUE);
344                 gtk_widget_set_sensitive(cw.other_browser_cmd_entry_label, TRUE);
345         } else {
346                 gtk_editable_set_editable(GTK_EDITABLE(cw.other_browser_cmd_entry), FALSE); /* FREMANTLE: give the text the greyed-out look */
347                 gtk_widget_set_sensitive(cw.other_browser_cmd_entry, FALSE);
348                 gtk_widget_set_sensitive(cw.other_browser_cmd_entry_label, FALSE);
349         }
350 }
351
352
353 /**********************************************************************
354  * Interface
355  **********************************************************************/
356
357 #if defined(HILDON) && defined(FREMANTLE)
358 /*
359  * Fremantle Hildon dialog
360  */
361 static GtkDialog *swb_config_dialog(gpointer cp_window) {
362         GtkWidget *dialog_vbox;
363
364         GtkWidget *default_browser_selector_button;
365         GtkWidget *continuous_mode_selector_button;
366         int i;
367         HildonGtkInputMode input_mode;
368
369         dialog = gtk_dialog_new_with_buttons(
370                 "Browser Switchboard",
371                 GTK_WINDOW(cp_window),
372                 GTK_DIALOG_MODAL,
373                 GTK_STOCK_OK,
374                 GTK_RESPONSE_OK,
375                 GTK_STOCK_CANCEL,
376                 GTK_RESPONSE_CANCEL,
377                 NULL);
378
379         dialog_vbox = GTK_DIALOG(dialog)->vbox;
380
381         /* Config options */
382         cw.default_browser_selector = hildon_touch_selector_new_text();
383         for (i = 0; browsers[i].config; ++i)
384                 hildon_touch_selector_append_text(HILDON_TOUCH_SELECTOR(cw.default_browser_selector), browsers[i].displayname);
385         hildon_touch_selector_set_active(HILDON_TOUCH_SELECTOR(cw.default_browser_selector), 0, 0);
386         default_browser_selector_button = hildon_picker_button_new(_HILDON_SIZE_DEFAULT, HILDON_BUTTON_ARRANGEMENT_HORIZONTAL);
387         hildon_button_set_title(HILDON_BUTTON(default_browser_selector_button),
388                                 "Default browser:");
389         hildon_picker_button_set_selector(HILDON_PICKER_BUTTON(default_browser_selector_button), HILDON_TOUCH_SELECTOR(cw.default_browser_selector));
390         hildon_button_set_alignment(HILDON_BUTTON(default_browser_selector_button),
391                                     0, 0.5, 0, 0);
392         g_signal_connect(G_OBJECT(cw.default_browser_selector), "changed",
393                          G_CALLBACK(default_browser_selector_callback), NULL);
394         gtk_box_pack_start(GTK_BOX(dialog_vbox),
395                            default_browser_selector_button, FALSE, FALSE, 0);
396
397         cw.other_browser_cmd_entry = hildon_entry_new(_HILDON_SIZE_DEFAULT);
398         /* Disable autocapitalization and dictionary features for the entry */
399         input_mode = hildon_gtk_entry_get_input_mode(GTK_ENTRY(cw.other_browser_cmd_entry));
400         input_mode &= ~(HILDON_GTK_INPUT_MODE_AUTOCAP |
401                         HILDON_GTK_INPUT_MODE_DICTIONARY);
402         hildon_gtk_entry_set_input_mode(GTK_ENTRY(cw.other_browser_cmd_entry), input_mode);
403
404         cw.other_browser_cmd_entry_label = hildon_caption_new(NULL,
405                         "Command (%s for URI):",
406                         cw.other_browser_cmd_entry,
407                         NULL, HILDON_CAPTION_OPTIONAL);
408         gtk_widget_set_sensitive(cw.other_browser_cmd_entry, FALSE);
409         gtk_widget_set_sensitive(cw.other_browser_cmd_entry_label, FALSE);
410         hildon_gtk_widget_set_theme_size(cw.other_browser_cmd_entry_label, _HILDON_SIZE_DEFAULT);
411         gtk_box_pack_start(GTK_BOX(dialog_vbox),
412                            cw.other_browser_cmd_entry_label, FALSE, FALSE, 0);
413
414         cw.continuous_mode_selector = hildon_touch_selector_new_text();
415         hildon_touch_selector_append_text(HILDON_TOUCH_SELECTOR(cw.continuous_mode_selector), "Lower memory usage");
416         hildon_touch_selector_append_text(HILDON_TOUCH_SELECTOR(cw.continuous_mode_selector), "Faster browser startup time");
417
418         continuous_mode_selector_button = hildon_picker_button_new(_HILDON_SIZE_DEFAULT, HILDON_BUTTON_ARRANGEMENT_VERTICAL);
419         hildon_button_set_title(HILDON_BUTTON(continuous_mode_selector_button),
420                                 "Optimize Browser Switchboard for:");
421         hildon_picker_button_set_selector(HILDON_PICKER_BUTTON(continuous_mode_selector_button), HILDON_TOUCH_SELECTOR(cw.continuous_mode_selector));
422         hildon_button_set_alignment(HILDON_BUTTON(continuous_mode_selector_button),
423                                     0, 0, 0, 0);
424         set_continuous_mode(CONTINUOUS_MODE_DEFAULT);
425         gtk_box_pack_start(GTK_BOX(dialog_vbox),
426                            continuous_mode_selector_button, FALSE, FALSE, 0);
427
428         gtk_widget_show_all(dialog);
429         return GTK_DIALOG(dialog);
430 }
431
432 #else /* !defined(HILDON) || !defined(FREMANTLE) */
433 /*
434  * GTK+/Diablo Hildon dialog
435  */
436 static GtkDialog *swb_config_dialog(gpointer cp_window) {
437         GtkWidget *dialog_vbox;
438
439         GtkWidget *options_table;
440         GtkWidget *default_browser_combo_label;
441         GtkWidget *continuous_mode_label;
442         int i;
443 #ifdef HILDON
444         HildonGtkInputMode input_mode;
445 #endif
446
447         dialog = gtk_dialog_new_with_buttons(
448                 "Browser Switchboard",
449                 GTK_WINDOW(cp_window),
450                 GTK_DIALOG_MODAL,
451                 GTK_STOCK_OK,
452                 GTK_RESPONSE_OK,
453                 GTK_STOCK_CANCEL,
454                 GTK_RESPONSE_CANCEL,
455                 NULL);
456
457         dialog_vbox = GTK_DIALOG(dialog)->vbox;
458
459         /* Config options */
460         options_table = gtk_table_new(3, 2, FALSE);
461         gtk_table_set_row_spacings(GTK_TABLE(options_table), 5);
462         gtk_box_pack_start(GTK_BOX(dialog_vbox), options_table, FALSE, FALSE, 0);
463
464         cw.default_browser_combo = gtk_combo_box_new_text();
465         for (i = 0; browsers[i].config; ++i)
466                 gtk_combo_box_append_text(GTK_COMBO_BOX(cw.default_browser_combo),
467                                           browsers[i].displayname);
468         gtk_combo_box_set_active(GTK_COMBO_BOX(cw.default_browser_combo), 0);
469         default_browser_combo_label = gtk_label_new("Default browser:");
470         gtk_misc_set_alignment(GTK_MISC(default_browser_combo_label), 1, 0.5);
471         g_signal_connect(G_OBJECT(cw.default_browser_combo), "changed",
472                          G_CALLBACK(default_browser_combo_callback), NULL);
473         gtk_table_attach(GTK_TABLE(options_table),
474                         default_browser_combo_label,
475                         0, 1,
476                         0, 1,
477                         GTK_FILL, GTK_FILL|GTK_EXPAND,
478                         5, 0);
479         gtk_table_attach(GTK_TABLE(options_table),
480                         cw.default_browser_combo,
481                         1, 2,
482                         0, 1,
483                         GTK_FILL|GTK_EXPAND, GTK_FILL|GTK_EXPAND,
484                         5, 0);
485
486         cw.other_browser_cmd_entry = gtk_entry_new();
487 #ifdef HILDON
488         /* Disable autocapitalization and dictionary features for the entry */
489         input_mode = hildon_gtk_entry_get_input_mode(GTK_ENTRY(cw.other_browser_cmd_entry));
490         input_mode &= ~(HILDON_GTK_INPUT_MODE_AUTOCAP |
491                         HILDON_GTK_INPUT_MODE_DICTIONARY);
492         hildon_gtk_entry_set_input_mode(GTK_ENTRY(cw.other_browser_cmd_entry), input_mode);
493 #endif
494         cw.other_browser_cmd_entry_label = gtk_label_new("Command (%s for URI):");
495         gtk_misc_set_alignment(GTK_MISC(cw.other_browser_cmd_entry_label), 1, 0.5);
496         gtk_widget_set_sensitive(cw.other_browser_cmd_entry, FALSE);
497         gtk_widget_set_sensitive(cw.other_browser_cmd_entry_label, FALSE);
498         gtk_table_attach(GTK_TABLE(options_table),
499                         cw.other_browser_cmd_entry_label,
500                         0, 1,
501                         1, 2,
502                         GTK_FILL, GTK_FILL|GTK_EXPAND,
503                         5, 0);
504         gtk_table_attach(GTK_TABLE(options_table),
505                         cw.other_browser_cmd_entry,
506                         1, 2,
507                         1, 2,
508                         GTK_FILL|GTK_EXPAND, GTK_FILL|GTK_EXPAND,
509                         5, 0);
510         gtk_table_set_row_spacing(GTK_TABLE(options_table), 1, 15);
511
512         continuous_mode_label = gtk_label_new("Optimize Browser Switchboard for:");
513         gtk_misc_set_alignment(GTK_MISC(continuous_mode_label), 0, 0.5);
514         cw.continuous_mode_off_radio = gtk_radio_button_new_with_label(NULL,
515                         "Lower memory usage");
516         cw.continuous_mode_on_radio = gtk_radio_button_new_with_label_from_widget(
517                         GTK_RADIO_BUTTON(cw.continuous_mode_off_radio),
518                         "Faster browser startup time");
519         set_continuous_mode(CONTINUOUS_MODE_DEFAULT);
520         gtk_table_attach(GTK_TABLE(options_table),
521                         continuous_mode_label,
522                         0, 2,
523                         2, 3,
524                         GTK_FILL, GTK_FILL|GTK_EXPAND,
525                         5, 0);
526         gtk_table_attach(GTK_TABLE(options_table),
527                         cw.continuous_mode_off_radio,
528                         0, 2,
529                         3, 4,
530                         GTK_FILL, GTK_FILL|GTK_EXPAND,
531                         20, 0);
532         gtk_table_attach(GTK_TABLE(options_table),
533                         cw.continuous_mode_on_radio,
534                         0, 2,
535                         4, 5,
536                         GTK_FILL, GTK_FILL|GTK_EXPAND,
537                         20, 5);
538         gtk_table_set_row_spacing(GTK_TABLE(options_table), 3, 0);
539
540
541         gtk_widget_show_all(dialog);
542         return GTK_DIALOG(dialog);
543 }
544
545 #endif /* defined(HILDON) && defined(FREMANTLE) */
546
547
548 /**********************************************************************
549  * Entry
550  **********************************************************************/
551
552 #ifdef HILDON_CP_APPLET
553 /*
554  * Application was started from control panel.
555  */
556 osso_return_t execute(osso_context_t *osso,
557                       gpointer userdata, gboolean user_activated) {
558         GtkDialog *dialog;
559         gint response;
560
561         if (osso == NULL)
562                 return OSSO_ERROR;
563
564         dialog = GTK_DIALOG(swb_config_dialog(userdata));
565         load_config();
566
567         response = gtk_dialog_run(dialog);
568         if (response == GTK_RESPONSE_OK)
569                 do_reconfig();
570
571         gtk_widget_destroy(GTK_WIDGET(dialog));
572
573         return OSSO_OK;
574 }
575 #else
576 /*
577  * Application was started from command line.
578  */
579 int main(int argc, char *argv[]) {
580         GtkDialog *dialog;
581         gint response;
582 #ifdef HILDON
583         HildonProgram *program = NULL;
584 #endif
585
586         gtk_init(&argc, &argv);
587 #ifdef HILDON
588         program = HILDON_PROGRAM(hildon_program_get_instance());
589 #endif
590
591         g_set_application_name("Browser Switchboard");
592
593         dialog = GTK_DIALOG(swb_config_dialog(NULL));
594         load_config();
595
596         response = gtk_dialog_run(dialog);
597         if (response == GTK_RESPONSE_OK)
598                 do_reconfig();
599
600         gtk_widget_destroy(GTK_WIDGET(dialog));
601
602         exit(0);
603 }
604 #endif /* HILDON_CP_APPLET */