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