diff options
author | John Mark Bell <jmb@netsurf-browser.org> | 2009-12-17 23:55:02 +0000 |
---|---|---|
committer | John Mark Bell <jmb@netsurf-browser.org> | 2009-12-17 23:55:02 +0000 |
commit | 355799ce0bbb078237dfc1ae9874bbc5342acbc4 (patch) | |
tree | 7ca980c01c0d4d1d55a3b7b15418c95c5618afae /desktop/searchweb.c | |
parent | 4346b2b62b940182575e6612e46234355afa083c (diff) | |
download | netsurf-355799ce0bbb078237dfc1ae9874bbc5342acbc4.tar.gz netsurf-355799ce0bbb078237dfc1ae9874bbc5342acbc4.tar.bz2 |
Merge branches/MarkieB/gtkmain to trunk.
svn path=/trunk/netsurf/; revision=9729
Diffstat (limited to 'desktop/searchweb.c')
-rw-r--r-- | desktop/searchweb.c | 292 |
1 files changed, 292 insertions, 0 deletions
diff --git a/desktop/searchweb.c b/desktop/searchweb.c new file mode 100644 index 000000000..c6dfaa6df --- /dev/null +++ b/desktop/searchweb.c @@ -0,0 +1,292 @@ +/* + * Copyright 2009 Mark Benjamin <netsurf-browser.org.MarkBenjamin@dfgh.net> + * + * This file is part of NetSurf, http://www.netsurf-browser.org/ + * + * NetSurf is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * NetSurf is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + + /** \file + * web search (core) + */ +#include "utils/config.h" + +#include <ctype.h> +#include <string.h> +#include "content/content.h" +#include "content/fetchcache.h" +#include "content/fetch.h" +#include "desktop/browser.h" +#include "desktop/gui.h" +#include "desktop/options.h" +#include "desktop/searchweb.h" +#include "utils/config.h" +#include "utils/log.h" +#include "utils/messages.h" +#include "utils/url.h" +#include "utils/utils.h" + +static struct search_provider { + char *name; /**< readable name such as 'google', 'yahoo', etc */ + char *hostname; /**< host address such as www.google.com */ + char *searchstring; /** < such as "www.google.com?search=%s" */ + char *ico; /** < location of domain's favicon */ +} current_search_provider; + +static struct content *search_ico = NULL; +char *search_engines_file_location; +char *search_default_ico_location; + +/** + * creates a new browser window according to the search term + * \param searchterm such as "my search term" + */ + +bool search_web_new_window(struct browser_window *bw, const char *searchterm) +{ + char *encsearchterm; + char *url; + if (url_escape(searchterm,0, true, NULL, &encsearchterm) != + URL_FUNC_OK) + return false; + url = search_web_get_url(encsearchterm); + free(encsearchterm); + browser_window_create(url, bw, NULL, false, true); + free(url); + return true; +} + +/** simplistic way of checking whether an entry from the url bar is an + * url / a search; could be improved to properly test terms + */ + +bool search_is_url(const char *url) +{ + char *url2, *host; + + if (url_normalize(url, &url2) != URL_FUNC_OK) + return false; + + if (url_host(url2, &host) != URL_FUNC_OK) + return false; + + return true; +} + +/** + * caches the details of the current web search provider + * \param reference the enum value of the provider + * browser init code [as well as changing preferences code] should call + * search_web_provider_details(option_search_provider) + */ + +void search_web_provider_details(int reference) +{ + char buf[300]; + int ref = 0; + if (search_engines_file_location == NULL) + return; + FILE *f = fopen(search_engines_file_location, "r"); + if (f == NULL) + return; + while (fgets(buf, sizeof(buf), f) != NULL) { + if (buf[0] == '\0') + continue; + buf[strlen(buf)-1] = '\0'; + if (ref++ == (int)reference) + break; + } + if (current_search_provider.name != NULL) + free(current_search_provider.name); + current_search_provider.name = strdup(strtok(buf, "|")); + if (current_search_provider.hostname != NULL) + free(current_search_provider.hostname); + current_search_provider.hostname = strdup(strtok(NULL, "|")); + if (current_search_provider.searchstring != NULL) + free(current_search_provider.searchstring); + current_search_provider.searchstring = strdup(strtok(NULL, "|")); + if (current_search_provider.ico != NULL) + free(current_search_provider.ico); + current_search_provider.ico = strdup(strtok(NULL, "|")); + return; +} + +/** + * escapes a search term then creates the appropriate url from it + */ + +char *search_web_from_term(const char *searchterm) +{ + char *encsearchterm, *url; + if (url_escape(searchterm, 0, true, NULL, &encsearchterm) + != URL_FUNC_OK) + return strdup(searchterm); + url = search_web_get_url(encsearchterm); + free(encsearchterm); + return url; +} + +/** accessor for global search provider name */ + +char *search_web_provider_name(void) +{ + if (current_search_provider.name) + return strdup(current_search_provider.name); + return strdup("google"); +} + +/** accessor for global search provider hostname */ + +char *search_web_provider_host(void) +{ + if (current_search_provider.hostname) + return strdup(current_search_provider.hostname); + return strdup("www.google.com"); +} + +/** accessor for global search provider ico name */ + +char *search_web_ico_name(void) +{ + if (current_search_provider.ico) + return strdup(current_search_provider.ico); + return strdup("http://www.google.com/favicon.ico"); +} + +/** + * creates a full url from an encoded search term + */ + +char *search_web_get_url(const char *encsearchterm) +{ + char *pref, *ret; + int len; + if (current_search_provider.searchstring) + pref = strdup(current_search_provider.searchstring); + else + pref = strdup("http://www.google.com/search?q=%s"); + if (pref == NULL) { + warn_user(messages_get("NoMemory"), 0); + return NULL; + } + len = strlen(encsearchterm) + strlen(pref); + ret = malloc(len -1); /* + '\0' - "%s" */ + if (ret == NULL) { + warn_user(messages_get("NoMemory"), 0); + free(pref); + return NULL; + } + snprintf(ret, len-1, pref, encsearchterm); + free(pref); + return ret; +} + +/** + * function to retrieve the search web ico, from cache / from local + * filesystem / from the web + * \param localdefault true when there is no appropriate favicon + * update the search_ico cache else delay until fetcher callback + */ + +void search_web_retrieve_ico(bool localdefault) +{ + char *url; + if (localdefault) { + if (search_default_ico_location == NULL) + return; + url = malloc(SLEN("file://") + strlen( + search_default_ico_location) + 1); + if (url == NULL) { + warn_user(messages_get("NoMemory"), 0); + return; + } + strcpy(url, "file://"); + strcat(url, search_default_ico_location); + } else { + url = search_web_ico_name(); + } + + struct content *icocontent = NULL; + if (url == NULL) { + warn_user(messages_get("NoMemory"), 0); + return; + } + icocontent = fetchcache(url, search_web_ico_callback, + 0, 0, 20, 20, true, 0, + 0, false, false); + free(url); + if (icocontent == NULL) + return; + + fetchcache_go(icocontent, 0, search_web_ico_callback, + 0, 0, 20, 20, + 0, 0, false, 0); + + if (icocontent == NULL) + LOG(("web search ico loading delayed")); + else + search_ico = icocontent; +} + +/** + * returns a reference to the static global search_ico [ / NULL] + * caller may adjust ico's settings; clearing / free()ing is the core's + * responsibility + */ + +struct content *search_web_ico(void) +{ + return search_ico; +} + +/** + * callback function to cache ico then notify front when successful + * else retry default from local file system + */ + +void search_web_ico_callback(content_msg msg, struct content *ico, + intptr_t p1, intptr_t p2, union content_msg_data data) +{ + + switch (msg) { + case CONTENT_MSG_LOADING: + case CONTENT_MSG_READY: + break; + + case CONTENT_MSG_DONE: + LOG(("got favicon '%s'", ico->url)); + if (ico->type == CONTENT_ICO) { + search_ico = ico; /* cache */ + gui_window_set_search_ico(search_ico); + } else { + search_web_retrieve_ico(true); + } + break; + + case CONTENT_MSG_LAUNCH: + case CONTENT_MSG_ERROR: + LOG(("favicon %s error: %s", ico->url, data.error)); + ico = 0; + search_web_retrieve_ico(true); + break; + + case CONTENT_MSG_STATUS: + case CONTENT_MSG_NEWPTR: + case CONTENT_MSG_AUTH: + case CONTENT_MSG_SSL: + break; + + default: + assert(0); + } +} |