diff options
author | Vincent Sanders <vince@kyllikki.org> | 2021-02-20 12:28:52 +0000 |
---|---|---|
committer | Vincent Sanders <vince@kyllikki.org> | 2021-02-22 23:04:02 +0000 |
commit | 84ec9c2b2a8884c7bdb7e0fa461c8b2d9c495cb3 (patch) | |
tree | e85b1249fd941ddaa820f726920014083ff14c8b /frontends/gtk | |
parent | 3cf92011c27a0ae650eae61d5b7749e0a5c0f381 (diff) | |
download | netsurf-84ec9c2b2a8884c7bdb7e0fa461c8b2d9c495cb3.tar.gz netsurf-84ec9c2b2a8884c7bdb7e0fa461c8b2d9c495cb3.tar.bz2 |
tidy up GTK frontend initialisation
Diffstat (limited to 'frontends/gtk')
-rw-r--r-- | frontends/gtk/gui.c | 1058 |
1 files changed, 544 insertions, 514 deletions
diff --git a/frontends/gtk/gui.c b/frontends/gtk/gui.c index d4b0c71ee..a826b053a 100644 --- a/frontends/gtk/gui.c +++ b/frontends/gtk/gui.c @@ -75,412 +75,19 @@ bool nsgtk_complete = false; -char *nsgtk_config_home; /* exported global defined in gtk/gui.h */ - -GdkPixbuf *favicon_pixbuf; /** favicon default pixbuf */ -GdkPixbuf *win_default_icon_pixbuf; /** default window icon pixbuf */ - -GtkBuilder *warning_builder; - -char **respaths; /** resource search path vector */ - -/** - * Cause an abnormal program termination. - * - * \note This never returns and is intended to terminate without any cleanup. - * - * \param error The message to display to the user. - */ -static void die(const char * const error) -{ - fprintf(stderr, "%s", error); - exit(EXIT_FAILURE); -} - -/** - * Create an array of valid paths to search for resources. - * - * The idea is that all the complex path computation to find resources - * is performed here, once, rather than every time a resource is - * searched for. - */ -static char ** -nsgtk_init_resource_path(const char *config_home) -{ - char *resource_path; - int resource_path_len; - const gchar * const *langv; - char **pathv; /* resource path string vector */ - char **respath; /* resource paths vector */ - - if (config_home != NULL) { - resource_path_len = snprintf(NULL, 0, - "%s:${NETSURFRES}:%s", - config_home, - GTK_RESPATH); - resource_path = malloc(resource_path_len + 1); - if (resource_path == NULL) { - return NULL; - } - snprintf(resource_path, resource_path_len + 1, - "%s:${NETSURFRES}:%s", - config_home, - GTK_RESPATH); - } else { - resource_path_len = snprintf(NULL, 0, - "${NETSURFRES}:%s", - GTK_RESPATH); - resource_path = malloc(resource_path_len + 1); - if (resource_path == NULL) { - return NULL; - } - snprintf(resource_path, - resource_path_len + 1, - "${NETSURFRES}:%s", - GTK_RESPATH); - } - - pathv = filepath_path_to_strvec(resource_path); - - langv = g_get_language_names(); - - respath = filepath_generate(pathv, langv); - - filepath_free_strvec(pathv); - - free(resource_path); - - return respath; -} - - -/** - * Set option defaults for gtk frontend. - * - * \param defaults The option table to update. - * \return error status. - */ -static nserror set_defaults(struct nsoption_s *defaults) -{ - char *fname; - GtkSettings *settings; - GtkIconSize tooliconsize; - GtkToolbarStyle toolbarstyle; - - /* cookie file default */ - fname = NULL; - netsurf_mkpath(&fname, NULL, 2, nsgtk_config_home, "Cookies"); - if (fname != NULL) { - nsoption_setnull_charp(cookie_file, fname); - } - - /* cookie jar default */ - fname = NULL; - netsurf_mkpath(&fname, NULL, 2, nsgtk_config_home, "Cookies"); - if (fname != NULL) { - nsoption_setnull_charp(cookie_jar, fname); - } - - /* url database default */ - fname = NULL; - netsurf_mkpath(&fname, NULL, 2, nsgtk_config_home, "URLs"); - if (fname != NULL) { - nsoption_setnull_charp(url_file, fname); - } - - /* bookmark database default */ - fname = NULL; - netsurf_mkpath(&fname, NULL, 2, nsgtk_config_home, "Hotlist"); - if (fname != NULL) { - nsoption_setnull_charp(hotlist_path, fname); - } - - /* download directory default */ - fname = getenv("HOME"); - if (fname != NULL) { - nsoption_setnull_charp(downloads_directory, strdup(fname)); - } - - if ((nsoption_charp(cookie_file) == NULL) || - (nsoption_charp(cookie_jar) == NULL) || - (nsoption_charp(url_file) == NULL) || - (nsoption_charp(hotlist_path) == NULL) || - (nsoption_charp(downloads_directory) == NULL)) { - NSLOG(netsurf, INFO, - "Failed initialising default resource paths"); - return NSERROR_BAD_PARAMETER; - } - - /* set default font names */ - nsoption_set_charp(font_sans, strdup("Sans")); - nsoption_set_charp(font_serif, strdup("Serif")); - nsoption_set_charp(font_mono, strdup("Monospace")); - nsoption_set_charp(font_cursive, strdup("Serif")); - nsoption_set_charp(font_fantasy, strdup("Serif")); - - /* Default toolbar button type to system defaults */ - - settings = gtk_settings_get_default(); - g_object_get(settings, - "gtk-toolbar-icon-size", &tooliconsize, - "gtk-toolbar-style", &toolbarstyle, NULL); - - switch (toolbarstyle) { - case GTK_TOOLBAR_ICONS: - if (tooliconsize == GTK_ICON_SIZE_SMALL_TOOLBAR) { - nsoption_set_int(button_type, 1); - } else { - nsoption_set_int(button_type, 2); - } - break; - - case GTK_TOOLBAR_TEXT: - nsoption_set_int(button_type, 4); - break; - - case GTK_TOOLBAR_BOTH: - case GTK_TOOLBAR_BOTH_HORIZ: - /* no labels in default configuration */ - default: - /* No system default, so use large icons */ - nsoption_set_int(button_type, 2); - break; - } - - /* set default items in toolbar */ - nsoption_set_charp(toolbar_items, - strdup("back/history/forward/reloadstop/url_bar/websearch/openmenu")); - - /* set default for menu and tool bar visibility */ - nsoption_set_charp(bar_show, strdup("tool")); - - return NSERROR_OK; -} - -#if GTK_CHECK_VERSION(3,14,0) - -/** - * adds named icons into gtk theme - */ -static nserror nsgtk_add_named_icons_to_theme(void) -{ - gtk_icon_theme_add_resource_path(gtk_icon_theme_get_default(), - "/org/netsurf/icons"); - return NSERROR_OK; -} - -#else - -static nserror -add_builtin_icon(const char *prefix, const char *name, int x, int y) -{ - GdkPixbuf *pixbuf; - nserror res; - char *resname; - int resnamelen; - - /* resource name string length allowing for / .png and termination */ - resnamelen = strlen(prefix) + strlen(name) + 5 + 1 + 4 + 1; - resname = malloc(resnamelen); - if (resname == NULL) { - return NSERROR_NOMEM; - } - snprintf(resname, resnamelen, "icons%s/%s.png", prefix, name); - - res = nsgdk_pixbuf_new_from_resname(resname, &pixbuf); - NSLOG(netsurf, DEEPDEBUG, "%d %s", res, resname); - free(resname); - if (res != NSERROR_OK) { - pixbuf = gdk_pixbuf_new(GDK_COLORSPACE_RGB, false, 8, x, y); - } - gtk_icon_theme_add_builtin_icon(name, y, pixbuf); - - return NSERROR_OK; -} - -/** - * adds named icons into gtk theme - */ -static nserror nsgtk_add_named_icons_to_theme(void) -{ - /* these must also be in gtk/resources.c pixbuf_resource *and* - * gtk/res/netsurf.gresource.xml - */ - add_builtin_icon("", "local-history", 8, 32); - add_builtin_icon("", "show-cookie", 24, 24); - add_builtin_icon("/24x24/actions", "page-info-insecure", 24, 24); - add_builtin_icon("/24x24/actions", "page-info-internal", 24, 24); - add_builtin_icon("/24x24/actions", "page-info-local", 24, 24); - add_builtin_icon("/24x24/actions", "page-info-secure", 24, 24); - add_builtin_icon("/24x24/actions", "page-info-warning", 24, 24); - add_builtin_icon("/48x48/actions", "page-info-insecure", 48, 48); - add_builtin_icon("/48x48/actions", "page-info-internal", 48, 48); - add_builtin_icon("/48x48/actions", "page-info-local", 48, 48); - add_builtin_icon("/48x48/actions", "page-info-secure", 48, 48); - add_builtin_icon("/48x48/actions", "page-info-warning", 48, 48); - - return NSERROR_OK; -} - -#endif - - -/** - * setup GTK specific parts of the browser. - * - * \param argc The number of arguments on the command line - * \param argv A string vector of command line arguments. - * \respath A string vector of the path elements of resources - */ -static nserror nsgtk_setup(int argc, char** argv, char **respath) -{ - char buf[PATH_MAX]; - char *resource_filename; - char *addr = NULL; - nsurl *url; - nserror res; - - /* Initialise gtk accelerator table */ - res = nsgtk_accelerator_init(respaths); - if (res != NSERROR_OK) { - NSLOG(netsurf, INFO, - "Unable to load gtk accelerator configuration"); - /* not fatal if this does not load */ - } - - /* initialise warning dialog */ - res = nsgtk_builder_new_from_resname("warning", &warning_builder); - if (res != NSERROR_OK) { - NSLOG(netsurf, INFO, "Unable to initialise warning dialog"); - return res; - } - - gtk_builder_connect_signals(warning_builder, NULL); - - /* set default icon if its available */ - res = nsgdk_pixbuf_new_from_resname("netsurf.xpm", - &win_default_icon_pixbuf); - if (res == NSERROR_OK) { - NSLOG(netsurf, INFO, "Seting default window icon"); - gtk_window_set_default_icon(win_default_icon_pixbuf); - } - - /* Search engine sources */ - resource_filename = filepath_find(respath, "SearchEngines"); - search_web_init(resource_filename); - if (resource_filename != NULL) { - NSLOG(netsurf, INFO, "Using '%s' as Search Engines file", - resource_filename); - free(resource_filename); - } - search_web_select_provider(nsoption_int(search_provider)); - - /* Default favicon */ - res = nsgdk_pixbuf_new_from_resname("favicon.png", &favicon_pixbuf); - if (res != NSERROR_OK) { - favicon_pixbuf = gdk_pixbuf_new(GDK_COLORSPACE_RGB, - false, 8, 16, 16); - } - - /* add named icons to gtk theme */ - res = nsgtk_add_named_icons_to_theme(); - if (res != NSERROR_OK) { - NSLOG(netsurf, INFO, "Unable to add named icons to GTK theme."); - return res; - } - - /* initialise throbber */ - res = nsgtk_throbber_init(); - if (res != NSERROR_OK) { - NSLOG(netsurf, INFO, "Unable to initialise throbber."); - return res; - } - - /* Initialise completions - cannot fail */ - nsgtk_completion_init(); - - /* The tree view system needs to know the screen's DPI, so we - * find that out here, rather than when we create a first browser - * window. - */ - browser_set_dpi(gdk_screen_get_resolution(gdk_screen_get_default())); - NSLOG(netsurf, INFO, "Set CSS DPI to %d", browser_get_dpi()); - - filepath_sfinddef(respath, buf, "mime.types", "/etc/"); - gtk_fetch_filetype_init(buf); - - save_complete_init(); - - urldb_load(nsoption_charp(url_file)); - urldb_load_cookies(nsoption_charp(cookie_file)); - hotlist_init(nsoption_charp(hotlist_path), - nsoption_charp(hotlist_path)); - - /* Initialise top level UI elements */ - res = nsgtk_download_init(); - if (res != NSERROR_OK) { - NSLOG(netsurf, INFO, "Unable to initialise download window."); - return res; - } - - /* If there is a url specified on the command line use it */ - if (argc > 1) { - struct stat fs; - if (stat(argv[1], &fs) == 0) { - size_t addrlen; - char *rp = realpath(argv[1], NULL); - assert(rp != NULL); - - /* calculate file url length including terminator */ - addrlen = SLEN("file://") + strlen(rp) + 1; - addr = malloc(addrlen); - assert(addr != NULL); - snprintf(addr, addrlen, "file://%s", rp); - free(rp); - } else { - addr = strdup(argv[1]); - } - } - if (addr != NULL) { - /* managed to set up based on local launch */ - } else if (nsoption_charp(homepage_url) != NULL) { - addr = strdup(nsoption_charp(homepage_url)); - } else { - addr = strdup(NETSURF_HOMEPAGE); - } - - /* create an initial browser window */ - res = nsurl_create(addr, &url); - if (res == NSERROR_OK) { - res = browser_window_create(BW_CREATE_HISTORY, - url, - NULL, - NULL, - NULL); - nsurl_unref(url); - } - - free(addr); - - return res; -} - - - -/** - * Ensures output logging stream is correctly configured - */ -static bool nslog_stream_configure(FILE *fptr) -{ - /* set log stream to be non-buffering */ - setbuf(fptr, NULL); - - return true; -} +/* exported global defined in gtk/gui.h */ +char *nsgtk_config_home; +/** favicon default pixbuf */ +GdkPixbuf *favicon_pixbuf; +/** default window icon pixbuf */ +GdkPixbuf *win_default_icon_pixbuf; +GtkBuilder *warning_builder; +/** resource search path vector */ +char **respaths; /* exported function documented in gtk/warn.h */ @@ -498,7 +105,7 @@ nserror nsgtk_warning(const char *warning, const char *detail) "labelWarning")); snprintf(buf, sizeof(buf), "%s %s", messages_get(warning), - detail ? detail : ""); + detail ? detail : ""); buf[sizeof(buf) - 1] = 0; gtk_label_set_text(WarningLabel, buf); @@ -509,8 +116,7 @@ nserror nsgtk_warning(const char *warning, const char *detail) } - - +/* exported interface documented in gtk/gui.h */ uint32_t gtk_gui_gdkkey_to_nskey(GdkEventKey *key) { /* this function will need to become much more complex to support @@ -640,6 +246,63 @@ uint32_t gtk_gui_gdkkey_to_nskey(GdkEventKey *key) /** + * Create an array of valid paths to search for resources. + * + * The idea is that all the complex path computation to find resources + * is performed here, once, rather than every time a resource is + * searched for. + */ +static char ** +nsgtk_init_resource_path(const char *config_home) +{ + char *resource_path; + int resource_path_len; + const gchar * const *langv; + char **pathv; /* resource path string vector */ + char **respath; /* resource paths vector */ + + if (config_home != NULL) { + resource_path_len = snprintf(NULL, 0, + "%s:${NETSURFRES}:%s", + config_home, + GTK_RESPATH); + resource_path = malloc(resource_path_len + 1); + if (resource_path == NULL) { + return NULL; + } + snprintf(resource_path, resource_path_len + 1, + "%s:${NETSURFRES}:%s", + config_home, + GTK_RESPATH); + } else { + resource_path_len = snprintf(NULL, 0, + "${NETSURFRES}:%s", + GTK_RESPATH); + resource_path = malloc(resource_path_len + 1); + if (resource_path == NULL) { + return NULL; + } + snprintf(resource_path, + resource_path_len + 1, + "${NETSURFRES}:%s", + GTK_RESPATH); + } + + pathv = filepath_path_to_strvec(resource_path); + + langv = g_get_language_names(); + + respath = filepath_generate(pathv, langv); + + filepath_free_strvec(pathv); + + free(resource_path); + + return respath; +} + + +/** * create directory name and check it is acessible and a directory. */ static nserror @@ -677,6 +340,7 @@ check_dirname(const char *path, const char *leaf, char **dirname_out) return ret; } + /** * Get the path to the config directory. * @@ -744,6 +408,7 @@ static nserror get_config_home(char **config_home_out) return NSERROR_OK; } + static nserror create_config_home(char **config_home_out) { char *config_home = NULL; @@ -794,6 +459,192 @@ static nserror create_config_home(char **config_home_out) return NSERROR_OK; } + +/** + * Ensures output logging stream is correctly configured + */ +static bool nslog_stream_configure(FILE *fptr) +{ + /* set log stream to be non-buffering */ + setbuf(fptr, NULL); + + return true; +} + + +/** + * Set option defaults for gtk frontend. + * + * \param defaults The option table to update. + * \return error status. + */ +static nserror set_defaults(struct nsoption_s *defaults) +{ + char *fname; + GtkSettings *settings; + GtkIconSize tooliconsize; + GtkToolbarStyle toolbarstyle; + + /* cookie file default */ + fname = NULL; + netsurf_mkpath(&fname, NULL, 2, nsgtk_config_home, "Cookies"); + if (fname != NULL) { + nsoption_setnull_charp(cookie_file, fname); + } + + /* cookie jar default */ + fname = NULL; + netsurf_mkpath(&fname, NULL, 2, nsgtk_config_home, "Cookies"); + if (fname != NULL) { + nsoption_setnull_charp(cookie_jar, fname); + } + + /* url database default */ + fname = NULL; + netsurf_mkpath(&fname, NULL, 2, nsgtk_config_home, "URLs"); + if (fname != NULL) { + nsoption_setnull_charp(url_file, fname); + } + + /* bookmark database default */ + fname = NULL; + netsurf_mkpath(&fname, NULL, 2, nsgtk_config_home, "Hotlist"); + if (fname != NULL) { + nsoption_setnull_charp(hotlist_path, fname); + } + + /* download directory default */ + fname = getenv("HOME"); + if (fname != NULL) { + nsoption_setnull_charp(downloads_directory, strdup(fname)); + } + + if ((nsoption_charp(cookie_file) == NULL) || + (nsoption_charp(cookie_jar) == NULL) || + (nsoption_charp(url_file) == NULL) || + (nsoption_charp(hotlist_path) == NULL) || + (nsoption_charp(downloads_directory) == NULL)) { + NSLOG(netsurf, INFO, + "Failed initialising default resource paths"); + return NSERROR_BAD_PARAMETER; + } + + /* set default font names */ + nsoption_set_charp(font_sans, strdup("Sans")); + nsoption_set_charp(font_serif, strdup("Serif")); + nsoption_set_charp(font_mono, strdup("Monospace")); + nsoption_set_charp(font_cursive, strdup("Serif")); + nsoption_set_charp(font_fantasy, strdup("Serif")); + + /* Default toolbar button type to system defaults */ + + settings = gtk_settings_get_default(); + g_object_get(settings, + "gtk-toolbar-icon-size", &tooliconsize, + "gtk-toolbar-style", &toolbarstyle, NULL); + + switch (toolbarstyle) { + case GTK_TOOLBAR_ICONS: + if (tooliconsize == GTK_ICON_SIZE_SMALL_TOOLBAR) { + nsoption_set_int(button_type, 1); + } else { + nsoption_set_int(button_type, 2); + } + break; + + case GTK_TOOLBAR_TEXT: + nsoption_set_int(button_type, 4); + break; + + case GTK_TOOLBAR_BOTH: + case GTK_TOOLBAR_BOTH_HORIZ: + /* no labels in default configuration */ + default: + /* No system default, so use large icons */ + nsoption_set_int(button_type, 2); + break; + } + + /* set default items in toolbar */ + nsoption_set_charp(toolbar_items, + strdup("back/history/forward/reloadstop/url_bar/websearch/openmenu")); + + /* set default for menu and tool bar visibility */ + nsoption_set_charp(bar_show, strdup("tool")); + + return NSERROR_OK; +} + + +/** + * Initialise user options + * + * Initialise the browser configuration options. These are set by: + * - set generic defaults suitable for the gtk frontend + * - user choices loaded from Choices file + * - command line parameters + */ +static nserror nsgtk_option_init(int *pargc, char** argv) +{ + nserror ret; + char *choices = NULL; + + /* user options setup */ + ret = nsoption_init(set_defaults, &nsoptions, &nsoptions_default); + if (ret != NSERROR_OK) { + return ret; + } + + /* Attempt to load the user choices */ + ret = netsurf_mkpath(&choices, NULL, 2, nsgtk_config_home, "Choices"); + if (ret == NSERROR_OK) { + nsoption_read(choices, nsoptions); + free(choices); + } + + /* overide loaded options with those from commandline */ + nsoption_commandline(pargc, argv, nsoptions); + + /* ensure all options fall within sensible bounds */ + + /* Attempt to handle nonsense status bar widths. These may exist + * in people's Choices as the GTK front end used to abuse the + * status bar width option by using it for an absolute value in px. + * The GTK front end now correctly uses it as a proportion of window + * width. Here we assume that a value of less than 15% is wrong + * and set to the default two thirds. */ + if (nsoption_int(toolbar_status_size) < 1500) { + nsoption_set_int(toolbar_status_size, 6667); + } + + return NSERROR_OK; +} + + +/** + * initialise message translation + */ +static nserror nsgtk_messages_init(char **respaths) +{ + const char *messages; + nserror ret; + const uint8_t *data; + size_t data_size; + + ret = nsgtk_data_from_resname("Messages", &data, &data_size); + if (ret == NSERROR_OK) { + ret = messages_add_from_inline(data, data_size); + } else { + /* Obtain path to messages */ + ret = nsgtk_path_from_resname("Messages", &messages); + if (ret == NSERROR_OK) { + ret = messages_add_from_file(messages); + } + } + return ret; +} + + /** * Get the path to the cache directory. * @@ -842,6 +693,10 @@ static nserror get_cache_home(char **cache_home_out) return NSERROR_OK; } + +/** + * create a cache directory + */ static nserror create_cache_home(char **cache_home_out) { char *cache_home = NULL; @@ -849,7 +704,7 @@ static nserror create_cache_home(char **cache_home_out) char *xdg_cache_dir; nserror ret; - NSLOG(netsurf, INFO, "Attempting to create configuration directory"); + NSLOG(netsurf, INFO, "Attempting to create cache directory"); /* $XDG_CACHE_HOME defines the base directory * relative to which user specific cache files @@ -892,62 +747,288 @@ static nserror create_cache_home(char **cache_home_out) return NSERROR_OK; } -static nserror nsgtk_option_init(int *pargc, char** argv) + +/** + * GTK specific initialisation + */ +static nserror nsgtk_init(int *pargc, char ***pargv, char **cache_home) { nserror ret; - char *choices = NULL; - /* user options setup */ - ret = nsoption_init(set_defaults, &nsoptions, &nsoptions_default); + /* Locate the correct user configuration directory path */ + ret = get_config_home(&nsgtk_config_home); + if (ret == NSERROR_NOT_FOUND) { + /* no config directory exists yet so try to create one */ + ret = create_config_home(&nsgtk_config_home); + } + if (ret != NSERROR_OK) { + NSLOG(netsurf, INFO, + "Unable to locate a configuration directory."); + nsgtk_config_home = NULL; + } + + /* Initialise gtk */ + gtk_init(pargc, pargv); + + /* initialise logging. Not fatal if it fails but not much we + * can do about it either. + */ + nslog_init(nslog_stream_configure, pargc, *pargv); + + /* build the common resource path list */ + respaths = nsgtk_init_resource_path(nsgtk_config_home); + if (respaths == NULL) { + fprintf(stderr, "Unable to locate resources\n"); + return 1; + } + + /* initialise the gtk resource handling */ + ret = nsgtk_init_resources(respaths); if (ret != NSERROR_OK) { + fprintf(stderr, "GTK resources failed to initialise (%s)\n", + messages_get_errorcode(ret)); return ret; } - /* Attempt to load the user choices */ - ret = netsurf_mkpath(&choices, NULL, 2, nsgtk_config_home, "Choices"); - if (ret == NSERROR_OK) { - nsoption_read(choices, nsoptions); - free(choices); + /* Initialise user options */ + ret = nsgtk_option_init(pargc, *pargv); + if (ret != NSERROR_OK) { + fprintf(stderr, "Options failed to initialise (%s)\n", + messages_get_errorcode(ret)); + return ret; } - /* overide loaded options with those from commandline */ - nsoption_commandline(pargc, argv, nsoptions); + /* Initialise translated messages */ + ret = nsgtk_messages_init(respaths); + if (ret != NSERROR_OK) { + fprintf(stderr, "Unable to load translated messages (%s)\n", + messages_get_errorcode(ret)); + NSLOG(netsurf, INFO, "Unable to load translated messages"); + /** \todo decide if message load faliure should be fatal */ + } - /* ensure all options fall within sensible bounds */ + /* Locate the correct user cache directory path */ + ret = get_cache_home(cache_home); + if (ret == NSERROR_NOT_FOUND) { + /* no cache directory exists yet so try to create one */ + ret = create_cache_home(cache_home); + } + if (ret != NSERROR_OK) { + NSLOG(netsurf, INFO, "Unable to locate a cache directory."); + } - /* Attempt to handle nonsense status bar widths. These may exist - * in people's Choices as the GTK front end used to abuse the - * status bar width option by using it for an absolute value in px. - * The GTK front end now correctly uses it as a proportion of window - * width. Here we assume that a value of less than 15% is wrong - * and set to the default two thirds. */ - if (nsoption_int(toolbar_status_size) < 1500) { - nsoption_set_int(toolbar_status_size, 6667); + + return NSERROR_OK; +} + + +#if GTK_CHECK_VERSION(3,14,0) + +/** + * adds named icons into gtk theme + */ +static nserror nsgtk_add_named_icons_to_theme(void) +{ + gtk_icon_theme_add_resource_path(gtk_icon_theme_get_default(), + "/org/netsurf/icons"); + return NSERROR_OK; +} + +#else + +static nserror +add_builtin_icon(const char *prefix, const char *name, int x, int y) +{ + GdkPixbuf *pixbuf; + nserror res; + char *resname; + int resnamelen; + + /* resource name string length allowing for / .png and termination */ + resnamelen = strlen(prefix) + strlen(name) + 5 + 1 + 4 + 1; + resname = malloc(resnamelen); + if (resname == NULL) { + return NSERROR_NOMEM; + } + snprintf(resname, resnamelen, "icons%s/%s.png", prefix, name); + + res = nsgdk_pixbuf_new_from_resname(resname, &pixbuf); + NSLOG(netsurf, DEEPDEBUG, "%d %s", res, resname); + free(resname); + if (res != NSERROR_OK) { + pixbuf = gdk_pixbuf_new(GDK_COLORSPACE_RGB, false, 8, x, y); } + gtk_icon_theme_add_builtin_icon(name, y, pixbuf); return NSERROR_OK; } +/** + * adds named icons into gtk theme + */ +static nserror nsgtk_add_named_icons_to_theme(void) +{ + /* these must also be in gtk/resources.c pixbuf_resource *and* + * gtk/res/netsurf.gresource.xml + */ + add_builtin_icon("", "local-history", 8, 32); + add_builtin_icon("", "show-cookie", 24, 24); + add_builtin_icon("/24x24/actions", "page-info-insecure", 24, 24); + add_builtin_icon("/24x24/actions", "page-info-internal", 24, 24); + add_builtin_icon("/24x24/actions", "page-info-local", 24, 24); + add_builtin_icon("/24x24/actions", "page-info-secure", 24, 24); + add_builtin_icon("/24x24/actions", "page-info-warning", 24, 24); + add_builtin_icon("/48x48/actions", "page-info-insecure", 48, 48); + add_builtin_icon("/48x48/actions", "page-info-internal", 48, 48); + add_builtin_icon("/48x48/actions", "page-info-local", 48, 48); + add_builtin_icon("/48x48/actions", "page-info-secure", 48, 48); + add_builtin_icon("/48x48/actions", "page-info-warning", 48, 48); -static nserror nsgtk_messages_init(char **respaths) + return NSERROR_OK; +} + +#endif + + +/** + * setup GTK specific parts of the browser. + * + * \param argc The number of arguments on the command line + * \param argv A string vector of command line arguments. + * \respath A string vector of the path elements of resources + */ +static nserror nsgtk_setup(int argc, char** argv, char **respath) { - const char *messages; - nserror ret; - const uint8_t *data; - size_t data_size; + char buf[PATH_MAX]; + char *resource_filename; + char *addr = NULL; + nsurl *url; + nserror res; - ret = nsgtk_data_from_resname("Messages", &data, &data_size); - if (ret == NSERROR_OK) { - ret = messages_add_from_inline(data, data_size); - } else { - /* Obtain path to messages */ - ret = nsgtk_path_from_resname("Messages", &messages); - if (ret == NSERROR_OK) { - ret = messages_add_from_file(messages); + /* Initialise gtk accelerator table */ + res = nsgtk_accelerator_init(respaths); + if (res != NSERROR_OK) { + NSLOG(netsurf, INFO, + "Unable to load gtk accelerator configuration"); + /* not fatal if this does not load */ + } + + /* initialise warning dialog */ + res = nsgtk_builder_new_from_resname("warning", &warning_builder); + if (res != NSERROR_OK) { + NSLOG(netsurf, INFO, "Unable to initialise warning dialog"); + return res; + } + + gtk_builder_connect_signals(warning_builder, NULL); + + /* set default icon if its available */ + res = nsgdk_pixbuf_new_from_resname("netsurf.xpm", + &win_default_icon_pixbuf); + if (res == NSERROR_OK) { + NSLOG(netsurf, INFO, "Seting default window icon"); + gtk_window_set_default_icon(win_default_icon_pixbuf); + } + + /* Search engine sources */ + resource_filename = filepath_find(respath, "SearchEngines"); + search_web_init(resource_filename); + if (resource_filename != NULL) { + NSLOG(netsurf, INFO, "Using '%s' as Search Engines file", + resource_filename); + free(resource_filename); + } + search_web_select_provider(nsoption_int(search_provider)); + + /* Default favicon */ + res = nsgdk_pixbuf_new_from_resname("favicon.png", &favicon_pixbuf); + if (res != NSERROR_OK) { + favicon_pixbuf = gdk_pixbuf_new(GDK_COLORSPACE_RGB, + false, 8, 16, 16); + } + + /* add named icons to gtk theme */ + res = nsgtk_add_named_icons_to_theme(); + if (res != NSERROR_OK) { + NSLOG(netsurf, INFO, "Unable to add named icons to GTK theme."); + return res; + } + + /* initialise throbber */ + res = nsgtk_throbber_init(); + if (res != NSERROR_OK) { + NSLOG(netsurf, INFO, "Unable to initialise throbber."); + return res; + } + + /* Initialise completions - cannot fail */ + nsgtk_completion_init(); + + /* The tree view system needs to know the screen's DPI, so we + * find that out here, rather than when we create a first browser + * window. + */ + browser_set_dpi(gdk_screen_get_resolution(gdk_screen_get_default())); + NSLOG(netsurf, INFO, "Set CSS DPI to %d", browser_get_dpi()); + + filepath_sfinddef(respath, buf, "mime.types", "/etc/"); + gtk_fetch_filetype_init(buf); + + save_complete_init(); + + urldb_load(nsoption_charp(url_file)); + urldb_load_cookies(nsoption_charp(cookie_file)); + hotlist_init(nsoption_charp(hotlist_path), + nsoption_charp(hotlist_path)); + + /* Initialise top level UI elements */ + res = nsgtk_download_init(); + if (res != NSERROR_OK) { + NSLOG(netsurf, INFO, "Unable to initialise download window."); + return res; + } + + /* If there is a url specified on the command line use it */ + if (argc > 1) { + struct stat fs; + if (stat(argv[1], &fs) == 0) { + size_t addrlen; + char *rp = realpath(argv[1], NULL); + assert(rp != NULL); + + /* calculate file url length including terminator */ + addrlen = SLEN("file://") + strlen(rp) + 1; + addr = malloc(addrlen); + assert(addr != NULL); + snprintf(addr, addrlen, "file://%s", rp); + free(rp); + } else { + addr = strdup(argv[1]); } } - return ret; + if (addr != NULL) { + /* managed to set up based on local launch */ + } else if (nsoption_charp(homepage_url) != NULL) { + addr = strdup(nsoption_charp(homepage_url)); + } else { + addr = strdup(NETSURF_HOMEPAGE); + } + + /* create an initial browser window */ + res = nsurl_create(addr, &url); + if (res == NSERROR_OK) { + res = browser_window_create(BW_CREATE_HISTORY, + url, + NULL, + NULL, + NULL); + nsurl_unref(url); + } + + free(addr); + + return res; } @@ -1084,8 +1165,8 @@ static void nsgtk_finalise(void) */ int main(int argc, char** argv) { + nserror res; char *cache_home = NULL; - nserror ret; struct netsurf_table nsgtk_table = { .misc = nsgtk_misc_table, .window = nsgtk_window_table, @@ -1099,94 +1180,43 @@ int main(int argc, char** argv) .layout = nsgtk_layout_table, }; - ret = netsurf_register(&nsgtk_table); - if (ret != NSERROR_OK) { - die("NetSurf operation table failed registration\n"); - } - - /* Locate the correct user configuration directory path */ - ret = get_config_home(&nsgtk_config_home); - if (ret == NSERROR_NOT_FOUND) { - /* no config directory exists yet so try to create one */ - ret = create_config_home(&nsgtk_config_home); - } - if (ret != NSERROR_OK) { - NSLOG(netsurf, INFO, - "Unable to locate a configuration directory."); - nsgtk_config_home = NULL; - } - - /* Initialise gtk */ - gtk_init(&argc, &argv); - - /* initialise logging. Not fatal if it fails but not much we - * can do about it either. - */ - nslog_init(nslog_stream_configure, &argc, argv); - - /* build the common resource path list */ - respaths = nsgtk_init_resource_path(nsgtk_config_home); - if (respaths == NULL) { - fprintf(stderr, "Unable to locate resources\n"); - return 1; - } - - /* initialise the gtk resource handling */ - ret = nsgtk_init_resources(respaths); - if (ret != NSERROR_OK) { - fprintf(stderr, "GTK resources failed to initialise (%s)\n", - messages_get_errorcode(ret)); - return 1; - } - - /* Initialise user options */ - ret = nsgtk_option_init(&argc, argv); - if (ret != NSERROR_OK) { - fprintf(stderr, "Options failed to initialise (%s)\n", - messages_get_errorcode(ret)); + res = netsurf_register(&nsgtk_table); + if (res != NSERROR_OK) { + fprintf(stderr, + "NetSurf operation table failed registration (%s)\n", + messages_get_errorcode(res)); return 1; } - /* Initialise translated messages */ - ret = nsgtk_messages_init(respaths); - if (ret != NSERROR_OK) { - fprintf(stderr, "Unable to load translated messages (%s)\n", - messages_get_errorcode(ret)); - NSLOG(netsurf, INFO, "Unable to load translated messages"); - /** \todo decide if message load faliure should be fatal */ - } - - /* Locate the correct user cache directory path */ - ret = get_cache_home(&cache_home); - if (ret == NSERROR_NOT_FOUND) { - /* no cache directory exists yet so try to create one */ - ret = create_cache_home(&cache_home); - } - if (ret != NSERROR_OK) { - NSLOG(netsurf, INFO, "Unable to locate a cache directory."); + /* gtk specific initialisation */ + res = nsgtk_init(&argc, &argv, &cache_home); + if (res != NSERROR_OK) { + fprintf(stderr, "NetSurf gtk failed to initialise (%s)\n", + messages_get_errorcode(res)); + return 2; } /* core initialisation */ - ret = netsurf_init(cache_home); + res = netsurf_init(cache_home); free(cache_home); - if (ret != NSERROR_OK) { + if (res != NSERROR_OK) { fprintf(stderr, "NetSurf core failed to initialise (%s)\n", - messages_get_errorcode(ret)); - return 1; + messages_get_errorcode(res)); + return 3; } /* gtk specific initalisation and main run loop */ - ret = nsgtk_setup(argc, argv, respaths); - if (ret != NSERROR_OK) { - fprintf(stderr, "NetSurf gtk setup failed (%s)\n", - messages_get_errorcode(ret)); + res = nsgtk_setup(argc, argv, respaths); + if (res != NSERROR_OK) { nsgtk_finalise(); - return 2; - } + fprintf(stderr, "NetSurf gtk setup failed (%s)\n", + messages_get_errorcode(res)); + return 4; + } nsgtk_main(); nsgtk_finalise(); - + return 0; } |