diff --git a/content/fetchers/about.c b/content/fetchers/about.c
index c0507aaa4..c93fdbad4 100644
--- a/content/fetchers/about.c
+++ b/content/fetchers/about.c
@@ -175,6 +175,120 @@ fetch_about_credits_handler_aborted:
return false;
}
+static bool fetch_about_config_handler(struct fetch_about_context *ctx)
+{
+ char buffer[1024];
+ int code = 200;
+ int slen;
+ unsigned int opt_loop = 0;
+ int res = 0;
+
+ /* content is going to return ok */
+ fetch_set_http_code(ctx->fetchh, code);
+
+ /* content type */
+ if (fetch_about_send_header(ctx, "Content-Type: text/html"))
+ goto fetch_about_config_handler_aborted;
+
+ slen = snprintf(buffer, sizeof buffer,
+ "
NetSurf Browser Config"
+ ""
+ "NetSurf Browser Config
"
+ " | | |
");
+
+ do {
+ res = snoptionf(buffer + slen, sizeof buffer - slen, opt_loop,
+ "%k | %t | %V |
");
+ if (res <= 0)
+ break; /* last option */
+
+ if (res >= (sizeof buffer - slen)) {
+ /* last entry would not fit in buffer, submit buffer */
+ if (fetch_about_send_callback(FETCH_DATA, ctx, buffer,
+ slen, FETCH_ERROR_NO_ERROR))
+ goto fetch_about_config_handler_aborted;
+ slen = 0;
+ } else {
+ /* normal addition */
+ slen += res;
+ opt_loop++;
+ }
+ } while (res > 0);
+
+ slen += snprintf(buffer + slen, sizeof buffer - slen,
+ "
");
+
+ if (fetch_about_send_callback(FETCH_DATA, ctx, buffer, slen,
+ FETCH_ERROR_NO_ERROR))
+ goto fetch_about_config_handler_aborted;
+
+ fetch_about_send_callback(FETCH_FINISHED, ctx, 0, 0,
+ FETCH_ERROR_NO_ERROR);
+
+ return true;
+
+fetch_about_config_handler_aborted:
+ return false;
+}
+
+/** Generate the text of a Choices file which represents the current
+ * in use options.
+ */
+static bool fetch_about_choices_handler(struct fetch_about_context *ctx)
+{
+ char buffer[1024];
+ int code = 200;
+ int slen;
+ unsigned int opt_loop = 0;
+ int res = 0;
+
+ /* content is going to return ok */
+ fetch_set_http_code(ctx->fetchh, code);
+
+ /* content type */
+ if (fetch_about_send_header(ctx, "Content-Type: text/plain"))
+ goto fetch_about_choices_handler_aborted;
+
+ slen = snprintf(buffer, sizeof buffer,
+ "# Automatically generated current NetSurf browser Choices\n");
+
+ do {
+ res = snoptionf(buffer + slen,
+ sizeof buffer - slen,
+ opt_loop,
+ "%k:%v\n");
+ if (res <= 0)
+ break; /* last option */
+
+ if (res >= (sizeof buffer - slen)) {
+ /* last entry would not fit in buffer, submit buffer */
+ if (fetch_about_send_callback(FETCH_DATA, ctx, buffer,
+ slen, FETCH_ERROR_NO_ERROR))
+ goto fetch_about_choices_handler_aborted;
+ slen = 0;
+ } else {
+ /* normal addition */
+ slen += res;
+ opt_loop++;
+ }
+ } while (res > 0);
+
+ if (fetch_about_send_callback(FETCH_DATA, ctx, buffer, slen,
+ FETCH_ERROR_NO_ERROR))
+ goto fetch_about_choices_handler_aborted;
+
+ fetch_about_send_callback(FETCH_FINISHED, ctx, 0, 0,
+ FETCH_ERROR_NO_ERROR);
+
+ return true;
+
+fetch_about_choices_handler_aborted:
+ return false;
+}
+
+
struct about_handlers {
const char *name;
fetch_about_handler handler;
@@ -182,6 +296,8 @@ struct about_handlers {
struct about_handlers about_handler_list[] = {
{ "credits", fetch_about_credits_handler },
+ { "config", fetch_about_config_handler },
+ { "Choices", fetch_about_choices_handler },
{ "blank", fetch_about_blank_handler } /* The default */
};
diff --git a/desktop/options.c b/desktop/options.c
index 520be7563..4176080c9 100644
--- a/desktop/options.c
+++ b/desktop/options.c
@@ -226,20 +226,26 @@ colour option_sys_colour_WindowText = 0x000000;
EXTRA_OPTION_DEFINE
+enum option_type_e {
+ OPTION_BOOL,
+ OPTION_INTEGER,
+ OPTION_STRING,
+ OPTION_COLOUR
+} ;
-struct {
+struct option_entry_s {
const char *key;
- enum { OPTION_BOOL, OPTION_INTEGER, OPTION_STRING, OPTION_COLOUR } type;
+ enum option_type_e type;
void *p;
-} option_table[] = {
+};
+
+struct option_entry_s option_table[] = {
{ "http_proxy", OPTION_BOOL, &option_http_proxy },
{ "http_proxy_host", OPTION_STRING, &option_http_proxy_host },
{ "http_proxy_port", OPTION_INTEGER, &option_http_proxy_port },
{ "http_proxy_auth", OPTION_INTEGER, &option_http_proxy_auth },
- { "http_proxy_auth_user",
- OPTION_STRING, &option_http_proxy_auth_user },
- { "http_proxy_auth_pass",
- OPTION_STRING, &option_http_proxy_auth_pass },
+ { "http_proxy_auth_user", OPTION_STRING, &option_http_proxy_auth_user },
+ { "http_proxy_auth_pass", OPTION_STRING, &option_http_proxy_auth_pass },
{ "font_size", OPTION_INTEGER, &option_font_size },
{ "font_min_size", OPTION_INTEGER, &option_font_min_size },
{ "font_sans", OPTION_STRING, &option_font_sans },
@@ -251,8 +257,7 @@ struct {
{ "accept_charset", OPTION_STRING, &option_accept_charset },
{ "memory_cache_size", OPTION_INTEGER, &option_memory_cache_size },
{ "disc_cache_age", OPTION_INTEGER, &option_disc_cache_age },
- { "block_advertisements",
- OPTION_BOOL, &option_block_ads },
+ { "block_advertisements", OPTION_BOOL, &option_block_ads },
{ "minimum_gif_delay", OPTION_INTEGER, &option_minimum_gif_delay },
{ "send_referer", OPTION_BOOL, &option_send_referer },
{ "animate_images", OPTION_BOOL, &option_animate_images },
@@ -262,30 +267,25 @@ struct {
{ "ca_path", OPTION_STRING, &option_ca_path },
{ "cookie_file", OPTION_STRING, &option_cookie_file },
{ "cookie_jar", OPTION_STRING, &option_cookie_jar },
- { "homepage_url", OPTION_STRING, &option_homepage_url },
- { "search_url_bar", OPTION_BOOL, &option_search_url_bar},
- { "search_provider", OPTION_INTEGER, &option_search_provider},
+ { "homepage_url", OPTION_STRING, &option_homepage_url },
+ { "search_url_bar", OPTION_BOOL, &option_search_url_bar},
+ { "search_provider", OPTION_INTEGER, &option_search_provider},
{ "url_suggestion", OPTION_BOOL, &option_url_suggestion },
{ "window_x", OPTION_INTEGER, &option_window_x },
{ "window_y", OPTION_INTEGER, &option_window_y },
{ "window_width", OPTION_INTEGER, &option_window_width },
{ "window_height", OPTION_INTEGER, &option_window_height },
- { "window_screen_width",
- OPTION_INTEGER, &option_window_screen_width },
- { "window_screen_height",
- OPTION_INTEGER, &option_window_screen_height },
- { "toolbar_status_size",
- OPTION_INTEGER, &option_toolbar_status_width },
+ { "window_screen_width", OPTION_INTEGER, &option_window_screen_width },
+ { "window_screen_height", OPTION_INTEGER, &option_window_screen_height },
+ { "toolbar_status_size", OPTION_INTEGER, &option_toolbar_status_width },
{ "scale", OPTION_INTEGER, &option_scale },
{ "incremental_reflow", OPTION_BOOL, &option_incremental_reflow },
{ "min_reflow_period", OPTION_INTEGER, &option_min_reflow_period },
{ "core_select_menu", OPTION_BOOL, &option_core_select_menu },
/* Fetcher options */
{ "max_fetchers", OPTION_INTEGER, &option_max_fetchers },
- { "max_fetchers_per_host",
- OPTION_INTEGER, &option_max_fetchers_per_host },
- { "max_cached_fetch_handles",
- OPTION_INTEGER, &option_max_cached_fetch_handles },
+ { "max_fetchers_per_host", OPTION_INTEGER, &option_max_fetchers_per_host },
+ { "max_cached_fetch_handles", OPTION_INTEGER, &option_max_cached_fetch_handles },
{ "suppress_curl_debug",OPTION_BOOL, &option_suppress_curl_debug },
{ "target_blank", OPTION_BOOL, &option_target_blank },
{ "button_2_tab", OPTION_BOOL, &option_button_2_tab },
@@ -298,10 +298,8 @@ struct {
{ "suppress_images", OPTION_BOOL, &option_suppress_images},
{ "remove_backgrounds", OPTION_BOOL, &option_remove_backgrounds},
{ "enable_loosening", OPTION_BOOL, &option_enable_loosening},
- { "enable_PDF_compression",
- OPTION_BOOL, &option_enable_PDF_compression},
- { "enable_PDF_password",
- OPTION_BOOL, &option_enable_PDF_password},
+ { "enable_PDF_compression", OPTION_BOOL, &option_enable_PDF_compression},
+ { "enable_PDF_password", OPTION_BOOL, &option_enable_PDF_password},
/* Interface colours */
{ "gui_colour_bg_1", OPTION_COLOUR, &option_gui_colour_bg_1},
{ "gui_colour_fg_1", OPTION_COLOUR, &option_gui_colour_fg_1},
@@ -343,15 +341,8 @@ struct {
#define option_table_entries (sizeof option_table / sizeof option_table[0])
-/**
- * Read options from a file.
- *
- * \param path name of file to read options from
- *
- * Option variables corresponding to lines in the file are updated. Missing
- * options are unchanged. If the file fails to open, options are unchanged.
- */
+/* exported interface documented in options.h */
void options_read(const char *path)
{
char s[100];
@@ -382,32 +373,32 @@ void options_read(const char *path)
continue;
switch (option_table[i].type) {
- case OPTION_BOOL:
- *((bool *) option_table[i].p) =
- value[0] == '1';
- break;
+ case OPTION_BOOL:
+ *((bool *) option_table[i].p) =
+ value[0] == '1';
+ break;
- case OPTION_INTEGER:
- *((int *) option_table[i].p) =
- atoi(value);
- break;
+ case OPTION_INTEGER:
+ *((int *) option_table[i].p) =
+ atoi(value);
+ break;
- case OPTION_COLOUR:
- sscanf(value, "%x", &rgbcolour);
- *((colour *) option_table[i].p) =
- ((0x000000FF &
- rgbcolour) << 16) |
- ((0x0000FF00 &
- rgbcolour) << 0) |
- ((0x00FF0000 &
- rgbcolour) >> 16);
- break;
+ case OPTION_COLOUR:
+ sscanf(value, "%x", &rgbcolour);
+ *((colour *) option_table[i].p) =
+ ((0x000000FF &
+ rgbcolour) << 16) |
+ ((0x0000FF00 &
+ rgbcolour) << 0) |
+ ((0x00FF0000 &
+ rgbcolour) >> 16);
+ break;
- case OPTION_STRING:
- free(*((char **) option_table[i].p));
- *((char **) option_table[i].p) =
- strdup(value);
- break;
+ case OPTION_STRING:
+ free(*((char **) option_table[i].p));
+ *((char **) option_table[i].p) =
+ strdup(value);
+ break;
}
break;
}
@@ -429,14 +420,7 @@ void options_read(const char *path)
}
-/**
- * Save options to a file.
- *
- * \param path name of file to write options to
- *
- * Errors are ignored.
- */
-
+/* exported interface documented in options.h */
void options_write(const char *path)
{
unsigned int i;
@@ -452,29 +436,29 @@ void options_write(const char *path)
for (i = 0; i != option_table_entries; i++) {
fprintf(fp, "%s:", option_table[i].key);
switch (option_table[i].type) {
- case OPTION_BOOL:
- fprintf(fp, "%c", *((bool *) option_table[i].p) ?
- '1' : '0');
- break;
+ case OPTION_BOOL:
+ fprintf(fp, "%c", *((bool *) option_table[i].p) ?
+ '1' : '0');
+ break;
- case OPTION_INTEGER:
- fprintf(fp, "%i", *((int *) option_table[i].p));
- break;
+ case OPTION_INTEGER:
+ fprintf(fp, "%i", *((int *) option_table[i].p));
+ break;
- case OPTION_COLOUR:
- rgbcolour = ((0x000000FF & *((colour *)
- option_table[i].p)) << 16) |
- ((0x0000FF00 & *((colour *)
- option_table[i].p)) << 0) |
- ((0x00FF0000 & *((colour *)
- option_table[i].p)) >> 16);
- fprintf(fp, "%06x", rgbcolour);
- break;
+ case OPTION_COLOUR:
+ rgbcolour = ((0x000000FF & *((colour *)
+ option_table[i].p)) << 16) |
+ ((0x0000FF00 & *((colour *)
+ option_table[i].p)) << 0) |
+ ((0x00FF0000 & *((colour *)
+ option_table[i].p)) >> 16);
+ fprintf(fp, "%06x", rgbcolour);
+ break;
- case OPTION_STRING:
- if (*((char **) option_table[i].p))
- fprintf(fp, "%s", *((char **) option_table[i].p));
- break;
+ case OPTION_STRING:
+ if (*((char **) option_table[i].p))
+ fprintf(fp, "%s", *((char **) option_table[i].p));
+ break;
}
fprintf(fp, "\n");
}
@@ -482,44 +466,141 @@ void options_write(const char *path)
fclose(fp);
}
-/**
- * Dump user options to stderr
- */
-void options_dump(void)
+
+/* exported interface documented in options.h */
+int snoptionf(char *string, size_t size, unsigned int option, const char *fmt)
{
- unsigned int i;
- colour rgbcolour;
+ size_t slen = 0; /* current output string length */
+ int fmtc = 0; /* current index into format string */
+ struct option_entry_s *option_entry;
+ colour rgbcolour; /* RRGGBB */
- for (i = 0; i != option_table_entries; i++) {
- fprintf(stderr, "%s:", option_table[i].key);
- switch (option_table[i].type) {
- case OPTION_BOOL:
- fprintf(stderr, "%c",
- *((bool *) option_table[i].p) ?
- '1' : '0');
+ if (option >= option_table_entries)
+ return -1;
+
+ option_entry = option_table + option;
+
+ while((slen < size) && (fmt[fmtc] != 0)) {
+ if (fmt[fmtc] == '%') {
+ fmtc++;
+ switch (fmt[fmtc]) {
+ case 'k':
+ slen += snprintf(string + slen, size - slen, "%s", option_entry->key);
break;
- case OPTION_INTEGER:
- fprintf(stderr, "%i",
- *((int *) option_table[i].p));
+ case 't':
+ switch (option_entry->type) {
+ case OPTION_BOOL:
+ slen += snprintf(string + slen,
+ size - slen,
+ "boolean");
+ break;
+
+ case OPTION_INTEGER:
+ slen += snprintf(string + slen,
+ size - slen,
+ "integer");
+ break;
+
+ case OPTION_COLOUR:
+ slen += snprintf(string + slen,
+ size - slen,
+ "colour");
+ break;
+
+ case OPTION_STRING:
+ slen += snprintf(string + slen,
+ size - slen,
+ "string");
+ break;
+
+ }
break;
- case OPTION_COLOUR:
- rgbcolour = ((0x000000FF | *((colour *)
- option_table[i].p)) << 16) &
+
+ case 'V':
+ switch (option_entry->type) {
+ case OPTION_BOOL:
+ slen += snprintf(string + slen, size - slen, "%s", *((bool *)option_entry->p) ? "true" : "false");
+ break;
+
+ case OPTION_INTEGER:
+ slen += snprintf(string + slen, size - slen, "%i", *((int *)option_entry->p));
+ break;
+
+ case OPTION_COLOUR:
+ rgbcolour = ((0x000000FF | *((colour *)
+ option_entry->p)) << 16) &
((0x0000FF00 | *((colour *)
- option_table[i].p)) << 0) &
+ option_entry->p)) << 0) &
((0x00FF0000 | *((colour *)
- option_table[i].p)) >> 16);
- fprintf(stderr, "%x", rgbcolour);
+ option_entry->p)) >> 16);
+ slen += snprintf(string + slen, size - slen, "%x", rgbcolour, (~rgbcolour) & 0xffffff, rgbcolour);
+ break;
+
+ case OPTION_STRING:
+ if (*((char **)option_entry->p) != NULL) {
+ slen += snprintf(string + slen, size - slen, "%s", *((char **)option_entry->p));
+ } else {
+ slen += snprintf(string + slen,
+ size - slen,
+ "NULL");
+ }
+ break;
+ }
break;
- case OPTION_STRING:
- if (*((char **) option_table[i].p))
- fprintf(stderr, "%s",
- *((char **) option_table[i].p));
+ case 'v':
+ switch (option_entry->type) {
+ case OPTION_BOOL:
+ slen += snprintf(string + slen, size - slen, "%c", *((bool *)option_entry->p) ? '1' : '0');
+ break;
+
+ case OPTION_INTEGER:
+ slen += snprintf(string + slen, size - slen, "%i", *((int *)option_entry->p));
+ break;
+
+ case OPTION_COLOUR:
+ rgbcolour = ((0x000000FF | *((colour *)
+ option_entry->p)) << 16) &
+ ((0x0000FF00 | *((colour *)
+ option_entry->p)) << 0) &
+ ((0x00FF0000 | *((colour *)
+ option_entry->p)) >> 16);
+ slen += snprintf(string + slen, size - slen, "%x", rgbcolour);
+ break;
+
+ case OPTION_STRING:
+ if (*((char **)option_entry->p) != NULL) {
+ slen += snprintf(string + slen, size - slen, "%s", *((char **)option_entry->p));
+ }
+
+ break;
+ }
break;
+ }
+ fmtc++;
+ } else {
+ string[slen] = fmt[fmtc];
+ slen++;
+ fmtc++;
}
- fprintf(stderr, "\n");
}
+ return slen;
+}
+
+/* exported interface documented in options.h */
+void options_dump(FILE *outf)
+{
+ char buffer[256];
+ int opt_loop = 0;
+ int res;
+
+ do {
+ res = snoptionf(buffer, sizeof buffer, opt_loop, "%k:%v\n");
+ if (res > 0) {
+ fprintf(outf, "%s", buffer);
+ }
+ opt_loop++;
+ } while (res > 0);
}
diff --git a/desktop/options.h b/desktop/options.h
index 5231322ad..c75ba18a8 100644
--- a/desktop/options.h
+++ b/desktop/options.h
@@ -36,10 +36,12 @@
#define _NETSURF_DESKTOP_OPTIONS_H_
#include
+#include
#include "desktop/plot_style.h"
-enum { OPTION_HTTP_PROXY_AUTH_NONE = 0, OPTION_HTTP_PROXY_AUTH_BASIC = 1,
- OPTION_HTTP_PROXY_AUTH_NTLM = 2 };
+enum { OPTION_HTTP_PROXY_AUTH_NONE = 0,
+ OPTION_HTTP_PROXY_AUTH_BASIC = 1,
+ OPTION_HTTP_PROXY_AUTH_NTLM = 2 };
extern bool option_http_proxy;
extern char *option_http_proxy_host;
@@ -143,8 +145,48 @@ extern colour option_sys_colour_WindowFrame;
extern colour option_sys_colour_WindowText;
+/**
+ * Read options from a file.
+ *
+ * \param path name of file to read options from
+ *
+ * Option variables corresponding to lines in the file are updated. Missing
+ * options are unchanged. If the file fails to open, options are unchanged.
+ */
void options_read(const char *path);
+
+/**
+ * Save options to a file.
+ *
+ * \param path name of file to write options to
+ *
+ * Errors are ignored.
+ */
void options_write(const char *path);
-void options_dump(void);
+
+/**
+ * Dump user options to stream
+ *
+ * \param outf output stream to dump options to.
+ */
+void options_dump(FILE *outf);
+
+/**
+ * Fill a buffer with an option using a format.
+ *
+ * The format string is copied into the output buffer with the
+ * following replaced:
+ * %k - The options key
+ * %t - The options type
+ * %V - value - HTML type formatting
+ * %v - value - plain formatting
+ *
+ * \param string The buffer in which to place teh results.
+ * \param size The size of the string buffer.
+ * \param option The opaque option number.
+ * \param fmt The format string.
+ * \return The number of bytes written to \a string or -1 on error
+ */
+int snoptionf(char *string, size_t size, unsigned int option, const char *fmt);
#endif
diff --git a/riscos/gui.c b/riscos/gui.c
index fdfe5a522..4d8b5a17c 100644
--- a/riscos/gui.c
+++ b/riscos/gui.c
@@ -872,7 +872,7 @@ void ro_gui_signal(int sig)
xhourglass_on();
xhourglass_colours(0x0000ffff, 0x000000ff,
&old_sand, &old_glass);
- options_dump();
+ options_dump(stderr);
/*rufl_dump_state();*/
#ifndef __ELF__