Merge branch 'master' of git://git.netsurf-browser.org/netsurf

This commit is contained in:
Michael Drake 2013-06-03 17:10:14 +01:00
commit 8747398c98
13 changed files with 579 additions and 255 deletions

View File

@ -196,6 +196,12 @@ static void ami_gui_window_update_box_deferred(struct gui_window *g, bool draw);
static void ami_do_redraw(struct gui_window_2 *g); static void ami_do_redraw(struct gui_window_2 *g);
static void ami_schedule_redraw_remove(struct gui_window_2 *gwin); static void ami_schedule_redraw_remove(struct gui_window_2 *gwin);
/* accessors for default options - user option is updated if it is set as per default */
#define nsoption_default_set_int(OPTION, VALUE) \
if (nsoptions_default[NSOPTION_##OPTION].value.i == nsoptions[NSOPTION_##OPTION].value.i) \
nsoptions[NSOPTION_##OPTION].value.i = VALUE; \
nsoptions_default[NSOPTION_##OPTION].value.i = VALUE
STRPTR ami_locale_langs(void) STRPTR ami_locale_langs(void)
{ {
struct Locale *locale; struct Locale *locale;
@ -285,6 +291,8 @@ bool ami_gui_check_resource(char *fullpath, const char *file)
ami_gui_map_filename(&remapped, fullpath, file, "Resource.map"); ami_gui_map_filename(&remapped, fullpath, file, "Resource.map");
path_add_part(fullpath, 1024, remapped); path_add_part(fullpath, 1024, remapped);
LOG(("Checking for %s", fullpath));
if(lock = Lock(fullpath, ACCESS_READ)) if(lock = Lock(fullpath, ACCESS_READ))
{ {
UnLock(lock); UnLock(lock);
@ -406,9 +414,9 @@ static UWORD ami_system_colour_scrollbar_fgpen(struct DrawInfo *drinfo)
* set option from pen * set option from pen
*/ */
static nserror static nserror
colour_option_from_pen(struct nsoption_s *opts, colour_option_from_pen(UWORD pen,
UWORD pen,
enum nsoption_e option, enum nsoption_e option,
struct Screen *screen,
colour def_colour) colour def_colour)
{ {
ULONG colour[3]; ULONG colour[3];
@ -416,46 +424,74 @@ colour_option_from_pen(struct nsoption_s *opts,
if((option < NSOPTION_SYS_COLOUR_START) || if((option < NSOPTION_SYS_COLOUR_START) ||
(option > NSOPTION_SYS_COLOUR_END) || (option > NSOPTION_SYS_COLOUR_END) ||
(opts[option].type != OPTION_COLOUR)) { (nsoptions[option].type != OPTION_COLOUR)) {
return NSERROR_BAD_PARAMETER; return NSERROR_BAD_PARAMETER;
} }
if(scrn != NULL) { if(screen != NULL) {
drinfo = GetScreenDrawInfo(scrn); drinfo = GetScreenDrawInfo(screen);
if(drinfo != NULL) { if(drinfo != NULL) {
if(pen == AMINS_SCROLLERPEN) pen = ami_system_colour_scrollbar_fgpen(drinfo); if(pen == AMINS_SCROLLERPEN) pen = ami_system_colour_scrollbar_fgpen(drinfo);
/* Get the colour of the pen being used for "pen" */ /* Get the colour of the pen being used for "pen" */
GetRGB32(scrn->ViewPort.ColorMap, drinfo->dri_Pens[pen], 1, (ULONG *)&colour); GetRGB32(screen->ViewPort.ColorMap, drinfo->dri_Pens[pen], 1, (ULONG *)&colour);
/* convert it to a color */ /* convert it to a color */
def_colour = ((colour[0] & 0xff000000) >> 24) | def_colour = ((colour[0] & 0xff000000) >> 24) |
((colour[1] & 0xff000000) >> 16) | ((colour[1] & 0xff000000) >> 16) |
((colour[2] & 0xff000000) >> 8); ((colour[2] & 0xff000000) >> 8);
FreeScreenDrawInfo(scrn, drinfo); FreeScreenDrawInfo(screen, drinfo);
} }
} }
opts[option].value.c = def_colour; if (nsoptions_default[option].value.c == nsoptions[option].value.c)
nsoptions[option].value.c = def_colour;
nsoptions_default[option].value.c = def_colour;
return NSERROR_OK; return NSERROR_OK;
} }
static void ami_set_screen_defaults(struct Screen *scrn) static void ami_set_screen_defaults(struct Screen *screen)
{ {
if((nsoption_int(window_x) == 0) && nsoption_default_set_int(window_x, 0);
(nsoption_int(window_y) == 0) && nsoption_default_set_int(window_y, screen->BarHeight + 1);
(nsoption_int(window_width) == 0) && nsoption_default_set_int(window_width, screen->Width);
(nsoption_int(window_height) == 0)) { nsoption_default_set_int(window_height, screen->Height - screen->BarHeight - 1);
nsoption_set_int(window_x, 0);
nsoption_set_int(window_y, scrn->BarHeight + 1); nsoption_default_set_int(redraw_tile_size_x, screen->Width);
nsoption_set_int(window_width, scrn->Width); nsoption_default_set_int(redraw_tile_size_y, screen->Height);
nsoption_set_int(window_height, scrn->Height - scrn->BarHeight - 1);
} /* set system colours for amiga ui */
colour_option_from_pen(FILLPEN, NSOPTION_sys_colour_ActiveBorder, screen, 0x00000000);
/* TODO: Update screen colour defaults here */ colour_option_from_pen(FILLPEN, NSOPTION_sys_colour_ActiveCaption, screen, 0x00dddddd);
colour_option_from_pen(BACKGROUNDPEN, NSOPTION_sys_colour_AppWorkspace, screen, 0x00eeeeee);
colour_option_from_pen(BACKGROUNDPEN, NSOPTION_sys_colour_Background, screen, 0x00aa0000);
colour_option_from_pen(FOREGROUNDPEN, NSOPTION_sys_colour_ButtonFace, screen, 0x00aaaaaa);
colour_option_from_pen(FORESHINEPEN, NSOPTION_sys_colour_ButtonHighlight, screen, 0x00cccccc);
colour_option_from_pen(FORESHADOWPEN, NSOPTION_sys_colour_ButtonShadow, screen, 0x00bbbbbb);
colour_option_from_pen(TEXTPEN, NSOPTION_sys_colour_ButtonText, screen, 0x00000000);
colour_option_from_pen(FILLTEXTPEN, NSOPTION_sys_colour_CaptionText, screen, 0x00000000);
colour_option_from_pen(DISABLEDTEXTPEN, NSOPTION_sys_colour_GrayText, screen, 0x00777777);
colour_option_from_pen(SELECTPEN, NSOPTION_sys_colour_Highlight, screen, 0x00ee0000);
colour_option_from_pen(SELECTTEXTPEN, NSOPTION_sys_colour_HighlightText, screen, 0x00000000);
colour_option_from_pen(INACTIVEFILLPEN, NSOPTION_sys_colour_InactiveBorder, screen, 0x00000000);
colour_option_from_pen(INACTIVEFILLPEN, NSOPTION_sys_colour_InactiveCaption, screen, 0x00ffffff);
colour_option_from_pen(INACTIVEFILLTEXTPEN, NSOPTION_sys_colour_InactiveCaptionText, screen, 0x00cccccc);
colour_option_from_pen(BACKGROUNDPEN, NSOPTION_sys_colour_InfoBackground, screen, 0x00aaaaaa);/* This is wrong, HelpHint backgrounds are pale yellow but doesn't seem to be a DrawInfo pen defined for it. */
colour_option_from_pen(TEXTPEN, NSOPTION_sys_colour_InfoText, screen, 0x00000000);
colour_option_from_pen(MENUBACKGROUNDPEN, NSOPTION_sys_colour_Menu, screen, 0x00aaaaaa);
colour_option_from_pen(MENUTEXTPEN, NSOPTION_sys_colour_MenuText, screen, 0x00000000);
colour_option_from_pen(AMINS_SCROLLERPEN, NSOPTION_sys_colour_Scrollbar, screen, 0x00aaaaaa);
colour_option_from_pen(FORESHADOWPEN, NSOPTION_sys_colour_ThreeDDarkShadow, screen, 0x00555555);
colour_option_from_pen(FOREGROUNDPEN, NSOPTION_sys_colour_ThreeDFace, screen, 0x00dddddd);
colour_option_from_pen(FORESHINEPEN, NSOPTION_sys_colour_ThreeDHighlight, screen, 0x00aaaaaa);
colour_option_from_pen(HALFSHINEPEN, NSOPTION_sys_colour_ThreeDLightShadow, screen, 0x00999999);
colour_option_from_pen(HALFSHADOWPEN, NSOPTION_sys_colour_ThreeDShadow, screen, 0x00777777);
colour_option_from_pen(BACKGROUNDPEN, NSOPTION_sys_colour_Window, screen, 0x00aaaaaa);
colour_option_from_pen(INACTIVEFILLPEN, NSOPTION_sys_colour_WindowFrame, screen, 0x00000000);
colour_option_from_pen(TEXTPEN, NSOPTION_sys_colour_WindowText, screen, 0x00000000);
} }
@ -554,36 +590,6 @@ static nserror ami_set_options(struct nsoption_s *defaults)
nsoption_set_bool(truecolour_mouse_pointers, false); nsoption_set_bool(truecolour_mouse_pointers, false);
#endif #endif
/* set system colours for amiga ui */
colour_option_from_pen(defaults, FILLPEN, NSOPTION_sys_colour_ActiveBorder, 0x00000000);
colour_option_from_pen(defaults, FILLPEN, NSOPTION_sys_colour_ActiveCaption, 0x00dddddd);
colour_option_from_pen(defaults, BACKGROUNDPEN, NSOPTION_sys_colour_AppWorkspace, 0x00eeeeee);
colour_option_from_pen(defaults, BACKGROUNDPEN, NSOPTION_sys_colour_Background, 0x00aa0000);
colour_option_from_pen(defaults, FOREGROUNDPEN, NSOPTION_sys_colour_ButtonFace, 0x00aaaaaa);
colour_option_from_pen(defaults, FORESHINEPEN, NSOPTION_sys_colour_ButtonHighlight, 0x00cccccc);
colour_option_from_pen(defaults, FORESHADOWPEN, NSOPTION_sys_colour_ButtonShadow, 0x00bbbbbb);
colour_option_from_pen(defaults, TEXTPEN, NSOPTION_sys_colour_ButtonText, 0x00000000);
colour_option_from_pen(defaults, FILLTEXTPEN, NSOPTION_sys_colour_CaptionText, 0x00000000);
colour_option_from_pen(defaults, DISABLEDTEXTPEN, NSOPTION_sys_colour_GrayText, 0x00777777);
colour_option_from_pen(defaults, SELECTPEN, NSOPTION_sys_colour_Highlight, 0x00ee0000);
colour_option_from_pen(defaults, SELECTTEXTPEN, NSOPTION_sys_colour_HighlightText, 0x00000000);
colour_option_from_pen(defaults, INACTIVEFILLPEN, NSOPTION_sys_colour_InactiveBorder, 0x00000000);
colour_option_from_pen(defaults, INACTIVEFILLPEN, NSOPTION_sys_colour_InactiveCaption, 0x00ffffff);
colour_option_from_pen(defaults, INACTIVEFILLTEXTPEN, NSOPTION_sys_colour_InactiveCaptionText, 0x00cccccc);
colour_option_from_pen(defaults, BACKGROUNDPEN, NSOPTION_sys_colour_InfoBackground, 0x00aaaaaa);/* This is wrong, HelpHint backgrounds are pale yellow but doesn't seem to be a DrawInfo pen defined for it. */
colour_option_from_pen(defaults, TEXTPEN, NSOPTION_sys_colour_InfoText, 0x00000000);
colour_option_from_pen(defaults, MENUBACKGROUNDPEN, NSOPTION_sys_colour_Menu, 0x00aaaaaa);
colour_option_from_pen(defaults, MENUTEXTPEN, NSOPTION_sys_colour_MenuText, 0x00000000);
colour_option_from_pen(defaults, AMINS_SCROLLERPEN, NSOPTION_sys_colour_Scrollbar, 0x00aaaaaa);
colour_option_from_pen(defaults, FORESHADOWPEN, NSOPTION_sys_colour_ThreeDDarkShadow, 0x00555555);
colour_option_from_pen(defaults, FOREGROUNDPEN, NSOPTION_sys_colour_ThreeDFace, 0x00dddddd);
colour_option_from_pen(defaults, FORESHINEPEN, NSOPTION_sys_colour_ThreeDHighlight, 0x00aaaaaa);
colour_option_from_pen(defaults, HALFSHINEPEN, NSOPTION_sys_colour_ThreeDLightShadow, 0x00999999);
colour_option_from_pen(defaults, HALFSHADOWPEN, NSOPTION_sys_colour_ThreeDShadow, 0x00777777);
colour_option_from_pen(defaults, BACKGROUNDPEN, NSOPTION_sys_colour_Window, 0x00aaaaaa);
colour_option_from_pen(defaults, INACTIVEFILLPEN, NSOPTION_sys_colour_WindowFrame, 0x00000000);
colour_option_from_pen(defaults, TEXTPEN, NSOPTION_sys_colour_WindowText, 0x00000000);
return NSERROR_OK; return NSERROR_OK;
} }
@ -677,8 +683,7 @@ void gui_init(int argc, char** argv)
static void ami_gui_newprefs_hook(struct Hook *hook, APTR window, APTR reserved) static void ami_gui_newprefs_hook(struct Hook *hook, APTR window, APTR reserved)
{ {
gui_system_colour_finalize(); ami_set_screen_defaults(scrn);
gui_system_colour_init();
} }
void ami_openscreen(void) void ami_openscreen(void)
@ -772,6 +777,7 @@ void ami_openscreenfirst(void)
static void gui_init2(int argc, char** argv) static void gui_init2(int argc, char** argv)
{ {
struct Screen *screen;
nsurl *url; nsurl *url;
nserror error; nserror error;
struct browser_window *bw = NULL; struct browser_window *bw = NULL;
@ -791,6 +797,16 @@ static void gui_init2(int argc, char** argv)
/* Treeview init code ends up calling a font function which needs this */ /* Treeview init code ends up calling a font function which needs this */
glob = &browserglob; glob = &browserglob;
/* ...and this ensures the treeview at least gets the WB colour palette to work with */
if(scrn == NULL) {
if(screen = LockPubScreen("Workbench")) {
ami_set_screen_defaults(screen);
UnlockPubScreen(NULL, screen);
}
} else {
ami_set_screen_defaults(scrn);
}
/**/ /**/
ami_hotlist_initialise(nsoption_charp(hotlist_file)); ami_hotlist_initialise(nsoption_charp(hotlist_file));
@ -901,7 +917,7 @@ static void gui_init2(int argc, char** argv)
} }
} }
nsoption_setnull_charp(homepage_url, (char *)strdup(NETSURF_HOMEPAGE)); nsoption_setnull_charp(homepage_url, (char *)strdup(NETSURF_HOMEPAGE));
if(!notalreadyrunning) if(!notalreadyrunning)
{ {
@ -917,7 +933,6 @@ static void gui_init2(int argc, char** argv)
sendcmd = ASPrintf("OPEN \"%s\" NEW",nsoption_charp(homepage_url)); sendcmd = ASPrintf("OPEN \"%s\" NEW",nsoption_charp(homepage_url));
} }
IDoMethod(arexx_obj,AM_EXECUTE,sendcmd,"NETSURF",NULL,NULL,NULL,NULL); IDoMethod(arexx_obj,AM_EXECUTE,sendcmd,"NETSURF",NULL,NULL,NULL,NULL);
IDoMethod(arexx_obj,AM_EXECUTE,"TOFRONT","NETSURF",NULL,NULL,NULL,NULL);
FreeVec(sendcmd); FreeVec(sendcmd);
netsurf_quit=true; netsurf_quit=true;
@ -3730,6 +3745,8 @@ struct gui_window *gui_create_browser_window(struct browser_window *bw,
if(locked_screen) UnlockPubScreen(NULL,scrn); if(locked_screen) UnlockPubScreen(NULL,scrn);
search_web_retrieve_ico(false); search_web_retrieve_ico(false);
ScreenToFront(scrn);
return g; return g;
} }

View File

@ -1818,6 +1818,7 @@ void ami_gui_opts_use(bool save)
nsoption_set_bool(hide_docky_icon, true); nsoption_set_bool(hide_docky_icon, true);
} }
#ifdef WITH_PDF_EXPORT
GetAttr(INTEGER_Number,gow->objects[GID_OPTS_MARGIN_TOP],(ULONG *)&nsoption_int(margin_top)); GetAttr(INTEGER_Number,gow->objects[GID_OPTS_MARGIN_TOP],(ULONG *)&nsoption_int(margin_top));
GetAttr(INTEGER_Number,gow->objects[GID_OPTS_MARGIN_LEFT],(ULONG *)&nsoption_int(margin_left)); GetAttr(INTEGER_Number,gow->objects[GID_OPTS_MARGIN_LEFT],(ULONG *)&nsoption_int(margin_left));
@ -1862,6 +1863,7 @@ void ami_gui_opts_use(bool save)
} else { } else {
nsoption_set_bool(enable_PDF_password, false); nsoption_set_bool(enable_PDF_password, false);
} }
#endif
if(rescan_fonts == true) { if(rescan_fonts == true) {
ami_font_finiscanner(); ami_font_finiscanner();

View File

@ -154,8 +154,6 @@ void ami_init_layers(struct gui_globals *gg, ULONG width, ULONG height)
palette_mapped = false; palette_mapped = false;
} }
if(nsoption_int(redraw_tile_size_x) <= 0) nsoption_set_int(redraw_tile_size_x, scrn->Width);
if(nsoption_int(redraw_tile_size_y) <= 0) nsoption_set_int(redraw_tile_size_y, scrn->Height);
if(!width) width = nsoption_int(redraw_tile_size_x); if(!width) width = nsoption_int(redraw_tile_size_x);
if(!height) height = nsoption_int(redraw_tile_size_y); if(!height) height = nsoption_int(redraw_tile_size_y);

View File

@ -568,9 +568,9 @@ main(int argc, char** argv)
die("Options failed to initialise"); die("Options failed to initialise");
} }
options = filepath_find(respaths, "Choices"); options = filepath_find(respaths, "Choices");
nsoption_read(options, NULL); nsoption_read(options, nsoptions);
free(options); free(options);
nsoption_commandline(&argc, argv, NULL); nsoption_commandline(&argc, argv, nsoptions);
/* common initialisation */ /* common initialisation */
messages = filepath_find(respaths, "Messages"); messages = filepath_find(respaths, "Messages");
@ -625,6 +625,9 @@ main(int argc, char** argv)
netsurf_exit(); netsurf_exit();
/* finalise options */
nsoption_finalise(nsoptions, nsoptions_default);
return 0; return 0;
} }

View File

@ -554,12 +554,14 @@ int main(int argc, char** argv)
/* user options setup */ /* user options setup */
ret = nsoption_init(set_defaults, &nsoptions, &nsoptions_default); ret = nsoption_init(set_defaults, &nsoptions, &nsoptions_default);
if (ret != NSERROR_OK) { if (ret != NSERROR_OK) {
die("Options failed to initialise"); fprintf(stderr, "Options failed to initialise (%s)\n",
messages_get_errorcode(ret));
return 1;
} }
options = filepath_find(respaths, "Choices"); options = filepath_find(respaths, "Choices");
nsoption_read(options, NULL); nsoption_read(options, nsoptions);
free(options); free(options);
nsoption_commandline(&argc, argv, NULL); nsoption_commandline(&argc, argv, nsoptions);
check_options(respaths); /* check user options */ check_options(respaths); /* check user options */
/* common initialisation */ /* common initialisation */
@ -567,7 +569,9 @@ int main(int argc, char** argv)
ret = netsurf_init(messages); ret = netsurf_init(messages);
free(messages); free(messages);
if (ret != NSERROR_OK) { if (ret != NSERROR_OK) {
die("NetSurf failed to initialise"); fprintf(stderr, "NetSurf core failed to initialise (%s)\n",
messages_get_errorcode(ret));
return 1;
} }
/* run the browser */ /* run the browser */
@ -581,6 +585,9 @@ int main(int argc, char** argv)
/* common finalisation */ /* common finalisation */
netsurf_exit(); netsurf_exit();
/* finalise options */
nsoption_finalise(nsoptions, nsoptions_default);
return 0; return 0;
} }

View File

@ -35,7 +35,7 @@ D_JSAPI_BINDING += $(patsubst %.c,%.d,$(2))
$(2): $(1) $(OBJROOT)/created $(2): $(1) $(OBJROOT)/created
$$(VQ)echo " GENBIND: $(1)" $$(VQ)echo " GENBIND: $(1)"
$(Q)nsgenbind -I javascript/WebIDL -d $(patsubst %.c,%.d,$(2)) -h $(3) -o $(2) $(1) $(Q)nsgenbind -g -I javascript/WebIDL -d $(patsubst %.c,%.d,$(2)) -h $(3) -o $(2) $(1)
$(3): $(2) $(3): $(2)

View File

@ -17,4 +17,8 @@ interface Console {
void timeEnd(DOMString timerName); void timeEnd(DOMString timerName);
void trace(); void trace();
void warn(DOMString msg, Substitition... subst); void warn(DOMString msg, Substitition... subst);
};
partial interface Window {
readonly attribute Console console;
}; };

View File

@ -23,7 +23,7 @@
#ifndef _NETSURF_JAVASCRIPT_JSAPI_H_ #ifndef _NETSURF_JAVASCRIPT_JSAPI_H_
#define _NETSURF_JAVASCRIPT_JSAPI_H_ #define _NETSURF_JAVASCRIPT_JSAPI_H_
/* include teh correct header */ /* include the correct header */
#ifdef WITH_MOZJS #ifdef WITH_MOZJS
#include "js/jsapi.h" #include "js/jsapi.h"
#else #else
@ -155,8 +155,10 @@ JS_NewCompartmentAndGlobalObject(JSContext *cx,
#define JSAPI_GCMARK(thing) JS_MarkGCThing(cx, thing, "object", arg) #define JSAPI_GCMARK(thing) JS_MarkGCThing(cx, thing, "object", arg)
/* Macros for manipulating GC root */ #define JSAPI_MARKOP_RETURN(value) return value
/* Macros for manipulating GC root */
#define JSAPI_ADD_OBJECT_ROOT(cx, obj) JS_AddRoot(cx, obj) #define JSAPI_ADD_OBJECT_ROOT(cx, obj) JS_AddRoot(cx, obj)
#define JSAPI_REMOVE_OBJECT_ROOT(cx, obj) JS_RemoveRoot(cx, obj) #define JSAPI_REMOVE_OBJECT_ROOT(cx, obj) JS_RemoveRoot(cx, obj)
@ -270,6 +272,8 @@ JS_NewCompartmentAndGlobalObject(JSContext *cx,
#define JSAPI_GCMARK(thing) JS_CallTracer(trc, thing, JSTRACE_OBJECT); #define JSAPI_GCMARK(thing) JS_CallTracer(trc, thing, JSTRACE_OBJECT);
#define JSAPI_MARKOP_RETURN(value) return value
/* Macros for manipulating GC root */ /* Macros for manipulating GC root */
#define JSAPI_ADD_OBJECT_ROOT(cx, obj) JS_AddRoot(cx, obj) #define JSAPI_ADD_OBJECT_ROOT(cx, obj) JS_AddRoot(cx, obj)
#define JSAPI_REMOVE_OBJECT_ROOT(cx, obj) JS_RemoveRoot(cx, obj) #define JSAPI_REMOVE_OBJECT_ROOT(cx, obj) JS_RemoveRoot(cx, obj)
@ -360,21 +364,24 @@ JS_NewCompartmentAndGlobalObject(JSContext *cx,
/* GC marking */ /* GC marking */
#ifdef JSCLASS_MARK_IS_TRACE #ifdef JSCLASS_MARK_IS_TRACE
/* mark requires casting */ /* mark function pointer requires casting */
#define JSAPI_JSCLASS_MARK_IS_TRACE JSCLASS_MARK_IS_TRACE #define JSAPI_JSCLASS_MARK_IS_TRACE JSCLASS_MARK_IS_TRACE
#define JSAPI_JSCLASS_MARKOP(x) ((JSMarkOp)x) #define JSAPI_JSCLASS_MARKOP(x) ((JSMarkOp)x)
#else #else
/* mark does not require casting */ /* mark function pointer does not require casting */
#define JSAPI_JSCLASS_MARK_IS_TRACE 0 #define JSAPI_JSCLASS_MARK_IS_TRACE 0
#define JSAPI_JSCLASS_MARKOP(x) (x) #define JSAPI_JSCLASS_MARKOP(x) (x)
#endif #endif
#define JSAPI_MARKOP(name) JSBool name(JSTracer *trc, JSObject *obj) #define JSAPI_MARKOP(name) void name(JSTracer *trc, JSObject *obj)
#define JSAPI_MARKCX trc->context #define JSAPI_MARKCX trc->context
#define JSAPI_GCMARK(thing) JS_CallTracer(trc, thing, JSTRACE_OBJECT); #define JSAPI_GCMARK(thing) JS_CallTracer(trc, thing, JSTRACE_OBJECT);
#define JSAPI_MARKOP_RETURN(value)
/* Macros for manipulating GC root */ /* Macros for manipulating GC root */
#define JSAPI_ADD_OBJECT_ROOT(cx, obj) JS_AddObjectRoot(cx, obj) #define JSAPI_ADD_OBJECT_ROOT(cx, obj) JS_AddObjectRoot(cx, obj)
#define JSAPI_REMOVE_OBJECT_ROOT(cx, obj) JS_RemoveObjectRoot(cx, obj) #define JSAPI_REMOVE_OBJECT_ROOT(cx, obj) JS_RemoveObjectRoot(cx, obj)

View File

@ -60,6 +60,7 @@ binding document {
} }
api finalise %{ api finalise %{
LOG(("jscontext:%p jsobject:%p private:%p", cx, obj, private));
if (private != NULL) { if (private != NULL) {
JSLOG("dom_document %p in content %p", JSLOG("dom_document %p in content %p",
private->node, private->htmlc); private->node, private->htmlc);

View File

@ -11,6 +11,7 @@
webidlfile "html.idl"; webidlfile "html.idl";
webidlfile "dom.idl"; webidlfile "dom.idl";
webidlfile "console.idl";
hdrcomment "Copyright 2012 Vincent Sanders <vince@netsurf-browser.org>"; hdrcomment "Copyright 2012 Vincent Sanders <vince@netsurf-browser.org>";
hdrcomment "This file is part of NetSurf, http://www.netsurf-browser.org/"; hdrcomment "This file is part of NetSurf, http://www.netsurf-browser.org/";
@ -61,6 +62,72 @@ struct browser_window *jsapi_get_browser_window(JSContext *cx)
return NULL; return NULL;
} }
static bool
init_user_prototypes(JSContext *cx,
struct jsclass_private *private,
JSObject *parent)
{
/* Initialises all the user javascript classes to make their
* prototypes available.
*/
/** @todo should we be managing these prototype objects ourselves */
private->prototype_Document = jsapi_InitClass_Document(cx, parent);
if (private->prototype_Document == NULL) {
return false;
}
private->prototype_Navigator = jsapi_InitClass_Navigator(cx, parent);
if (private->prototype_Navigator == NULL) {
return false;
}
private->prototype_Location = jsapi_InitClass_Location(cx, parent);
if (private->prototype_Location == NULL) {
return false;
}
private->prototype_Console = jsapi_InitClass_Console(cx, parent);
if (private->prototype_Console == NULL) {
return false;
}
private->prototype_HTMLElement = jsapi_InitClass_HTMLElement(cx, parent);
if (private->prototype_HTMLElement == NULL) {
return false;
}
private->prototype_HTMLCollection = jsapi_InitClass_HTMLCollection(cx, parent);
if (private->prototype_HTMLCollection == NULL) {
return false;
}
private->prototype_NodeList = jsapi_InitClass_NodeList(cx, parent);
if (private->prototype_NodeList == NULL) {
return false;
}
private->prototype_Text = jsapi_InitClass_Text(cx, parent);
if (private->prototype_Text == NULL) {
return false;
}
private->prototype_Comment = jsapi_InitClass_Comment(cx, parent);
if (private->prototype_Comment == NULL) {
return false;
}
private->prototype_Node = jsapi_InitClass_Node(cx, parent);
if (private->prototype_Node == NULL) {
return false;
}
private->prototype_Event = jsapi_InitClass_Event(cx, parent);
if (private->prototype_Event == NULL) {
return false;
}
return true;
}
%} %}
binding window { binding window {
@ -71,23 +138,82 @@ binding window {
private "struct browser_window *" bw; private "struct browser_window *" bw;
private "struct html_content *" htmlc; private "struct html_content *" htmlc;
internal "JSObject *" document; /* prototypes held in this object */
internal "JSObject *" navigator; internal "JSObject *" prototype_Document;
internal "JSObject *" console; internal "JSObject *" prototype_Navigator;
internal "JSObject *" prototype_Location;
internal "JSObject *" prototype_Console;
internal "JSObject *" prototype_HTMLElement;
internal "JSObject *" prototype_HTMLCollection;
internal "JSObject *" prototype_NodeList;
internal "JSObject *" prototype_Text;
internal "JSObject *" prototype_Comment;
internal "JSObject *" prototype_Node;
internal "JSObject *" prototype_Event;
/** document instantiated on first use */
property unshared document;
/** navigator instantiated on first use */
property unshared navigator;
/** console instantiated on first use */
property unshared console;
/** location is unshared */
property unshared location;
/** @todo instantiate forms, history etc. attributes */
/* events through a single interface */
property unshared type EventHandler; property unshared type EventHandler;
} }
api mark %{ api mark %{
if (private != NULL) { if (private != NULL) {
if (private->document != NULL) { if (private->prototype_Document != NULL) {
JSAPI_GCMARK(private->document); JSAPI_GCMARK(private->prototype_Document);
} }
if (private->navigator != NULL) {
JSAPI_GCMARK(private->navigator); if (private->prototype_Navigator != NULL) {
JSAPI_GCMARK(private->prototype_Navigator);
} }
if (private->console != NULL) {
JSAPI_GCMARK(private->console); if (private->prototype_Location != NULL) {
JSAPI_GCMARK(private->prototype_Location);
}
if (private->prototype_Console != NULL) {
JSAPI_GCMARK(private->prototype_Console);
}
if (private->prototype_HTMLElement != NULL) {
JSAPI_GCMARK(private->prototype_HTMLElement);
}
if (private->prototype_HTMLCollection != NULL) {
JSAPI_GCMARK(private->prototype_HTMLCollection);
}
if (private->prototype_NodeList != NULL) {
JSAPI_GCMARK(private->prototype_NodeList);
}
if (private->prototype_Text != NULL) {
JSAPI_GCMARK(private->prototype_Text);
}
if (private->prototype_Comment != NULL) {
JSAPI_GCMARK(private->prototype_Comment);
}
if (private->prototype_Node != NULL) {
JSAPI_GCMARK(private->prototype_Node);
}
if (private->prototype_Event != NULL) {
JSAPI_GCMARK(private->prototype_Event);
} }
} }
%} %}
@ -96,8 +222,6 @@ api global %{
%} %}
api init %{ api init %{
JSObject *user_proto;
prototype = JS_NewCompartmentAndGlobalObject(cx, &JSClass_Window, NULL); prototype = JS_NewCompartmentAndGlobalObject(cx, &JSClass_Window, NULL);
if (prototype == NULL) { if (prototype == NULL) {
return NULL; return NULL;
@ -128,65 +252,8 @@ api init %{
if (!JS_DefineProperties(cx, prototype, jsclass_properties)) if (!JS_DefineProperties(cx, prototype, jsclass_properties))
return NULL; return NULL;
/* Initialises all the user javascript classes to make their /* as the global just got changed, force a GC run */
* prototypes available. JS_GC(cx);
*/
/** @todo should we be managing these prototype objects ourselves */
user_proto = jsapi_InitClass_Document(cx, prototype);
if (user_proto == NULL) {
return NULL;
}
user_proto = jsapi_InitClass_Navigator(cx, prototype);
if (user_proto == NULL) {
return NULL;
}
user_proto = jsapi_InitClass_Location(cx, prototype);
if (user_proto == NULL) {
return NULL;
}
user_proto = jsapi_InitClass_Console(cx, prototype);
if (user_proto == NULL) {
return NULL;
}
user_proto = jsapi_InitClass_HTMLElement(cx, prototype);
if (user_proto == NULL) {
return NULL;
}
user_proto = jsapi_InitClass_HTMLCollection(cx, prototype);
if (user_proto == NULL) {
return NULL;
}
user_proto = jsapi_InitClass_NodeList(cx, prototype);
if (user_proto == NULL) {
return NULL;
}
user_proto = jsapi_InitClass_Text(cx, prototype);
if (user_proto == NULL) {
return NULL;
}
user_proto = jsapi_InitClass_Comment(cx, prototype);
if (user_proto == NULL) {
return NULL;
}
user_proto = jsapi_InitClass_Node(cx, prototype);
if (user_proto == NULL) {
return NULL;
}
user_proto = jsapi_InitClass_Event(cx, prototype);
if (user_proto == NULL) {
return NULL;
}
%} %}
api new %{ api new %{
@ -196,34 +263,47 @@ api new %{
/* the window object is the global so its prototype *is* the instance */ /* the window object is the global so its prototype *is* the instance */
newobject = prototype; newobject = prototype;
/* instantiate the subclasses off the window global */ if (init_user_prototypes(cx, private, prototype) == false) {
private->document = jsapi_new_Document(cx, /* prototype initialisation failed */
NULL,
newobject,
(dom_document *)dom_node_ref(htmlc->document),
htmlc);
if (private->document == NULL) {
free(private); free(private);
return NULL; return NULL;
} }
private->navigator = jsapi_new_Navigator(cx, NULL, newobject);
if (private->navigator == NULL) {
free(private);
return NULL;
}
private->console = jsapi_new_Console(cx, NULL, newobject);
if (private->console == NULL) {
free(private);
return NULL;
}
/** @todo forms, history */
LOG(("Created new window object %p", newobject)); LOG(("Created new window object %p", newobject));
%} %}
getter document %{
if (!JSVAL_IS_VOID(JSAPI_PROP_RVAL(cx, vp))) {
/* already created - return it */
return JS_TRUE;
}
/* instantiate the subclasses off the window global */
jsret = jsapi_new_Document(cx,
NULL,
NULL,
(dom_document *)dom_node_ref(private->htmlc->document),
private->htmlc);
%}
getter navigator %{
if (!JSVAL_IS_VOID(JSAPI_PROP_RVAL(cx, vp))) {
/* already created - return it */
return JS_TRUE;
}
jsret = jsapi_new_Navigator(cx, NULL, NULL);
%}
getter console %{
if (!JSVAL_IS_VOID(JSAPI_PROP_RVAL(cx, vp))) {
/* already created - return it */
return JS_TRUE;
}
jsret = jsapi_new_Console(cx, NULL, NULL);
%}
operation confirm %{ operation confirm %{
warn_user(message, NULL); warn_user(message, NULL);
%} %}
@ -273,9 +353,21 @@ operation dispatchEvent %{
%} %}
getter location %{ getter location %{
if (!JSVAL_IS_VOID(JSAPI_PROP_RVAL(cx, vp))) {
/* already created - return it */
return JS_TRUE;
}
/* should get the docuemnts location
jsval loc; jsval loc;
JS_GetProperty(cx, private->document, "location", &loc); JS_GetProperty(cx, private->document, "location", &loc);
jsret = JSVAL_TO_OBJECT(loc); jsret = JSVAL_TO_OBJECT(loc);
*/
jsret = jsapi_new_Location(cx,
NULL,
NULL,
llcache_handle_get_url(private->htmlc->base.llcache));
%} %}
getter window %{ getter window %{

View File

@ -142,9 +142,9 @@ main(int argc, char **argv)
die("Options failed to initialise"); die("Options failed to initialise");
} }
options = filepath_find(respaths, "Choices"); options = filepath_find(respaths, "Choices");
nsoption_read(options, NULL); nsoption_read(options, nsoptions);
free(options); free(options);
nsoption_commandline(&argc, argv, NULL); nsoption_commandline(&argc, argv, nsoptions);
/* common initialisation */ /* common initialisation */
messages = filepath_find(respaths, "Messages"); messages = filepath_find(respaths, "Messages");
@ -173,5 +173,9 @@ main(int argc, char **argv)
netsurf_exit(); netsurf_exit();
fprintf(stdout, "GENERIC FINISHED\n"); fprintf(stdout, "GENERIC FINISHED\n");
/* finalise options */
nsoption_finalise(nsoptions, nsoptions_default);
return 0; return 0;
} }

View File

@ -54,7 +54,8 @@ struct nsoption_s *nsoptions_default = NULL;
#define NSOPTION_COLOUR(NAME, DEFAULT) \ #define NSOPTION_COLOUR(NAME, DEFAULT) \
{ #NAME, sizeof(#NAME) - 1, OPTION_COLOUR, { .c = DEFAULT } }, { #NAME, sizeof(#NAME) - 1, OPTION_COLOUR, { .c = DEFAULT } },
struct nsoption_s defaults[] = { /** The table of compiled in default options */
static struct nsoption_s defaults[] = {
#include "desktop/options.h" #include "desktop/options.h"
#if defined(riscos) #if defined(riscos)
@ -160,11 +161,11 @@ static void nsoption_validate(struct nsoption_s *opts, struct nsoption_s *defs)
/* to aid migration from old, broken, configuration files this /* to aid migration from old, broken, configuration files this
* checks to see if all the system colours are set to black * checks to see if all the system colours are set to black
* and returns them to defaults instead * and returns them to defaults instead
*/ */
for (cloop = NSOPTION_SYS_COLOUR_START; for (cloop = NSOPTION_SYS_COLOUR_START;
cloop <= NSOPTION_SYS_COLOUR_END; cloop <= NSOPTION_SYS_COLOUR_END;
cloop++) { cloop++) {
if (opts[cloop].value.c != 0) { if (opts[cloop].value.c != 0) {
black = false; black = false;
@ -172,18 +173,26 @@ static void nsoption_validate(struct nsoption_s *opts, struct nsoption_s *defs)
} }
} }
if (black == true) { if (black == true) {
for (cloop = NSOPTION_SYS_COLOUR_START; for (cloop = NSOPTION_SYS_COLOUR_START;
cloop <= NSOPTION_SYS_COLOUR_END; cloop <= NSOPTION_SYS_COLOUR_END;
cloop++) { cloop++) {
opts[cloop].value.c = defs[cloop].value.c; opts[cloop].value.c = defs[cloop].value.c;
} }
} }
} }
static bool /**
nsoption_is_set(struct nsoption_s *opts, * Determines if an option is different between two option tables.
struct nsoption_s *defs, *
enum nsoption_e entry) * @param opts The first table to compare.
* @param defs The second table to compare.
* @param entry The option to compare.
* @return true if the option differs false if not.
*/
static bool
nsoption_is_set(const struct nsoption_s *opts,
const struct nsoption_s *defs,
const enum nsoption_e entry)
{ {
bool ret = false; bool ret = false;
@ -232,11 +241,12 @@ nsoption_is_set(struct nsoption_s *opts,
return ret; return ret;
} }
/** Output choices to file stream /**
* Output choices to file stream
* *
* @param fp the file stream to write to * @param fp The file stream to write to.
* @param opts The options table to write * @param opts The options table to write.
* @param defs the default value table to compare with. * @param defs The default value table to compare with.
* @param all Output all entries not just ones changed from defaults * @param all Output all entries not just ones changed from defaults
*/ */
static nserror static nserror
@ -245,14 +255,12 @@ nsoption_output(FILE *fp,
struct nsoption_s *defs, struct nsoption_s *defs,
bool all) bool all)
{ {
unsigned int entry; unsigned int entry; /* index to option being output */
bool show;
colour rgbcolour; /* RRGGBB */ colour rgbcolour; /* RRGGBB */
for (entry = 0; entry < NSOPTION_LISTEND; entry++) { for (entry = 0; entry < NSOPTION_LISTEND; entry++) {
show = all || nsoption_is_set(opts, defs, entry); if ((all == false) &&
(nsoption_is_set(opts, defs, entry) == false)) {
if (show == false) {
continue; continue;
} }
@ -302,11 +310,11 @@ nsoption_output(FILE *fp,
/** /**
* Output an option value into a string, in HTML format. * Output an option value into a string, in HTML format.
* *
* \param option The option to output the value of. * @param option The option to output the value of.
* \param size The size of the string buffer. * @param size The size of the string buffer.
* \param pos The current position in string * @param pos The current position in string
* \param string The string in which to output the value. * @param string The string in which to output the value.
* \return The number of bytes written to string or -1 on error * @return The number of bytes written to string or -1 on error
*/ */
static size_t static size_t
nsoption_output_value_html(struct nsoption_s *option, nsoption_output_value_html(struct nsoption_s *option,
@ -372,11 +380,11 @@ nsoption_output_value_html(struct nsoption_s *option,
/** /**
* Output an option value into a string, in plain text format. * Output an option value into a string, in plain text format.
* *
* \param option The option to output the value of. * @param option The option to output the value of.
* \param size The size of the string buffer. * @param size The size of the string buffer.
* \param pos The current position in string * @param pos The current position in string
* \param string The string in which to output the value. * @param string The string in which to output the value.
* \return The number of bytes written to string or -1 on error * @return The number of bytes written to string or -1 on error
*/ */
static size_t static size_t
nsoption_output_value_text(struct nsoption_s *option, nsoption_output_value_text(struct nsoption_s *option,
@ -429,6 +437,69 @@ nsoption_output_value_text(struct nsoption_s *option,
return slen; return slen;
} }
/**
* Duplicates an option table.
*
* Allocates a new option table and copies an existing one into it.
*
* @param src The source table to copy
*/
static nserror
nsoption_dup(struct nsoption_s *src, struct nsoption_s **pdst)
{
struct nsoption_s *dst;
dst = malloc(sizeof(defaults));
if (dst == NULL) {
return NSERROR_NOMEM;
}
*pdst = dst;
/* copy the source table into the destination table */
memcpy(dst, src, sizeof(defaults));
while (src->key != NULL) {
if ((src->type == OPTION_STRING) &&
(src->value.s != NULL)) {
dst->value.s = strdup(src->value.s);
}
src++;
dst++;
}
return NSERROR_OK;
}
/**
* frees an option table.
*
* Iterates through an option table a freeing resources as required
* finally freeing the option table itself.
*
* @param opts The option table to free.
*/
static nserror
nsoption_free(struct nsoption_s *opts)
{
struct nsoption_s *cur; /* option being freed */
if (opts == NULL) {
return NSERROR_BAD_PARAMETER;
}
cur = opts;
while (cur->key != NULL) {
if ((cur->type == OPTION_STRING) && (cur->value.s != NULL)) {
free(cur->value.s);
}
cur++;
}
free(opts);
return NSERROR_OK;
}
/* exported interface documented in utils/nsoption.h */ /* exported interface documented in utils/nsoption.h */
nserror nserror
nsoption_init(nsoption_set_default_t *set_defaults, nsoption_init(nsoption_set_default_t *set_defaults,
@ -436,38 +507,37 @@ nsoption_init(nsoption_set_default_t *set_defaults,
struct nsoption_s **pdefs) struct nsoption_s **pdefs)
{ {
nserror ret; nserror ret;
struct nsoption_s *src; struct nsoption_s *defs;
struct nsoption_s *dst;
struct nsoption_s *opts; struct nsoption_s *opts;
ret = nsoption_dup(&defaults[0], &defs);
if (ret != NSERROR_OK) {
return ret;
}
/* update the default table */ /* update the default table */
if (set_defaults != NULL) { if (set_defaults != NULL) {
nsoptions = &defaults[0]; /** @todo it would be better if the frontends actually
ret = set_defaults(&defaults[0]); * set values in the passed in table instead of
* assuming the global one.
*/
opts = nsoptions;
nsoptions = defs;
ret = set_defaults(defs);
if (ret != NSERROR_OK) { if (ret != NSERROR_OK) {
nsoptions = NULL; nsoptions = opts;
nsoption_free(defs);
return ret; return ret;
} }
} }
opts = malloc(sizeof(defaults));
if (opts == NULL) {
return NSERROR_NOMEM;
}
/* copy the default values into the working set */ /* copy the default values into the working set */
src = &defaults[0]; ret = nsoption_dup(defs, &opts);
dst = opts; if (ret != NSERROR_OK) {
nsoption_free(defs);
memcpy(dst, src, sizeof(defaults)); return ret;
while (src->key != NULL) {
if ((src->type == OPTION_STRING) && (src->value.s != NULL)) {
dst->value.s = strdup(src->value.s);
}
src++;
dst++;
} }
/* return values if wanted */ /* return values if wanted */
@ -478,13 +548,33 @@ nsoption_init(nsoption_set_default_t *set_defaults,
} }
if (pdefs != NULL) { if (pdefs != NULL) {
*pdefs = &defaults[0]; *pdefs = defs;
} else {
nsoptions_default = defs;
} }
return NSERROR_OK; return NSERROR_OK;
} }
/* exported interface documented in utils/nsoption.h */
nserror nsoption_finalise(struct nsoption_s *opts, struct nsoption_s *defs)
{
/* check to see if global table selected */
if (opts == NULL) {
opts = nsoptions;
}
nsoption_free(opts);
/* check to see if global table selected */
if (defs == NULL) {
defs = nsoptions_default;
}
nsoption_free(defs);
return NSERROR_OK;
}
/* exported interface documented in utils/nsoption.h */ /* exported interface documented in utils/nsoption.h */
nserror nserror
@ -503,8 +593,8 @@ nsoption_read(const char *path, struct nsoption_s *opts)
opts = nsoptions; opts = nsoptions;
} }
/* @todo is this and API bug not being a parameter */ /** @todo is this and API bug not being a parameter */
defs = nsoptions_default; defs = nsoptions_default;
fp = fopen(path, "r"); fp = fopen(path, "r");
if (!fp) { if (!fp) {
@ -569,7 +659,7 @@ nsoption_write(const char *path,
/* check to see if global table selected */ /* check to see if global table selected */
if (defs == NULL) { if (defs == NULL) {
defs = &defaults[0]; defs = nsoptions_default;
} }
fp = fopen(path, "w"); fp = fopen(path, "w");
@ -699,8 +789,8 @@ nsoption_snoptionf(char *string,
break; break;
case 'p': case 'p':
if (nsoption_is_set(nsoptions, if (nsoption_is_set(nsoptions,
nsoptions_default, nsoptions_default,
option_idx)) { option_idx)) {
slen += snprintf(string + slen, slen += snprintf(string + slen,
size - slen, size - slen,
@ -774,3 +864,33 @@ nsoption_snoptionf(char *string,
return slen; return slen;
} }
/* exported interface documented in options.h */
nserror
nsoption_set_tbl_charp(struct nsoption_s *opts,
enum nsoption_e option_idx,
char *s)
{
struct nsoption_s *option;
option = &opts[option_idx];
/* ensure it is a string option */
if (option->type != OPTION_STRING) {
return NSERROR_BAD_PARAMETER;
}
/* free any existing string */
if (option->value.s != NULL) {
free(option->value.s);
}
option->value.s = s;
/* check for empty string */
if ((option->value.s != NULL) && (*option->value.s == 0)) {
free(option->value.s);
option->value.s = NULL;
}
return NSERROR_OK;
}

View File

@ -34,7 +34,7 @@
* pointer to the active options table and be implemented as functions * pointer to the active options table and be implemented as functions
* within nsoptions.c * within nsoptions.c
* *
* Indirect acees would have an impact on performance of NetSurf as * Indirect access would have an impact on performance of NetSurf as
* the expected option lookup cost is currently that of a simple * the expected option lookup cost is currently that of a simple
* dereference (which this current implementation keeps). * dereference (which this current implementation keeps).
*/ */
@ -91,15 +91,17 @@ enum { OPTION_HTTP_PROXY_AUTH_NONE = 0,
#define DEFAULT_EXPORT_SCALE 0.7 #define DEFAULT_EXPORT_SCALE 0.7
#ifndef DEFAULT_REFLOW_PERIOD #ifndef DEFAULT_REFLOW_PERIOD
#define DEFAULT_REFLOW_PERIOD 25 /* time in cs */ /** Default reflow time in cs */
#define DEFAULT_REFLOW_PERIOD 25
#endif #endif
/** The options type. */
enum nsoption_type_e { enum nsoption_type_e {
OPTION_BOOL, OPTION_BOOL, /**< Option is a boolean. */
OPTION_INTEGER, OPTION_INTEGER, /**< Option is an integer. */
OPTION_UINT, OPTION_UINT, /**< Option is an unsigned integer */
OPTION_STRING, OPTION_STRING, /**< option is a heap allocated string. */
OPTION_COLOUR OPTION_COLOUR /**< Option is a netsurf colour. */
}; };
struct nsoption_s { struct nsoption_s {
@ -149,17 +151,24 @@ enum nsoption_e {
#undef NSOPTION_UINT #undef NSOPTION_UINT
#undef NSOPTION_COLOUR #undef NSOPTION_COLOUR
/* global option table */ /**
* global active option table.
*/
extern struct nsoption_s *nsoptions; extern struct nsoption_s *nsoptions;
/* global default option table */ /**
* global default option table.
*/
extern struct nsoption_s *nsoptions_default; extern struct nsoption_s *nsoptions_default;
/* default setting callback */ /**
* default setting callback.
*/
typedef nserror(nsoption_set_default_t)(struct nsoption_s *defaults); typedef nserror(nsoption_set_default_t)(struct nsoption_s *defaults);
/** Initialise option system. /**
* Initialise option system.
* *
* @param set_default callback to allow the customisation of the default * @param set_default callback to allow the customisation of the default
* options. * options.
@ -170,7 +179,20 @@ typedef nserror(nsoption_set_default_t)(struct nsoption_s *defaults);
nserror nsoption_init(nsoption_set_default_t *set_default, struct nsoption_s **popts, struct nsoption_s **pdefs); nserror nsoption_init(nsoption_set_default_t *set_default, struct nsoption_s **popts, struct nsoption_s **pdefs);
/** Read choices file and set them in the passed table /**
* Finalise option system
*
* Releases all resources allocated in the initialisation.
*
* @param opts the options table or NULL to use global table.
* @param defs the default options table to use or NULL to use global table
* return The error status
*/
nserror nsoption_finalise(struct nsoption_s *opts, struct nsoption_s *defs);
/**
* Read choices file and set them in the passed table
* *
* @param path The path to read the file from * @param path The path to read the file from
* @param opts The options table to enerate values from or NULL to use global * @param opts The options table to enerate values from or NULL to use global
@ -179,7 +201,8 @@ nserror nsoption_init(nsoption_set_default_t *set_default, struct nsoption_s **p
nserror nsoption_read(const char *path, struct nsoption_s *opts); nserror nsoption_read(const char *path, struct nsoption_s *opts);
/** Write options that have changed from the defaults to a file. /**
* Write options that have changed from the defaults to a file.
* *
* The \a nsoption_dump can be used to output all entries not just * The \a nsoption_dump can be used to output all entries not just
* changed ones. * changed ones.
@ -201,6 +224,7 @@ nserror nsoption_write(const char *path, struct nsoption_s *opts, struct nsoptio
*/ */
nserror nsoption_dump(FILE *outf, struct nsoption_s *opts); nserror nsoption_dump(FILE *outf, struct nsoption_s *opts);
/** /**
* Process commandline and set options approriately. * Process commandline and set options approriately.
* *
@ -211,6 +235,7 @@ nserror nsoption_dump(FILE *outf, struct nsoption_s *opts);
*/ */
nserror nsoption_commandline(int *pargc, char **argv, struct nsoption_s *opts); nserror nsoption_commandline(int *pargc, char **argv, struct nsoption_s *opts);
/** /**
* Fill a buffer with an option using a format. * Fill a buffer with an option using a format.
* *
@ -231,44 +256,88 @@ nserror nsoption_commandline(int *pargc, char **argv, struct nsoption_s *opts);
int nsoption_snoptionf(char *string, size_t size, enum nsoption_e option, const char *fmt); int nsoption_snoptionf(char *string, size_t size, enum nsoption_e option, const char *fmt);
/**
* Get the value of a boolean option.
/* value acessors - caution should be taken with type as this is not verified */ *
* Gets the value of an option assuming it is a boolean type.
* @note option type is unchecked so care must be taken in caller.
*/
#define nsoption_bool(OPTION) (nsoptions[NSOPTION_##OPTION].value.b) #define nsoption_bool(OPTION) (nsoptions[NSOPTION_##OPTION].value.b)
/**
* Get the value of an integer option.
*
* Gets the value of an option assuming it is a integer type.
* @note option type is unchecked so care must be taken in caller.
*/
#define nsoption_int(OPTION) (nsoptions[NSOPTION_##OPTION].value.i) #define nsoption_int(OPTION) (nsoptions[NSOPTION_##OPTION].value.i)
/**
* Get the value of an unsigned integer option.
*
* Gets the value of an option assuming it is a integer type.
* @note option type is unchecked so care must be taken in caller.
*/
#define nsoption_uint(OPTION) (nsoptions[NSOPTION_##OPTION].value.u) #define nsoption_uint(OPTION) (nsoptions[NSOPTION_##OPTION].value.u)
/**
* Get the value of a string option.
*
* Gets the value of an option assuming it is a string type.
* @note option type is unchecked so care must be taken in caller.
*/
#define nsoption_charp(OPTION) (nsoptions[NSOPTION_##OPTION].value.s) #define nsoption_charp(OPTION) (nsoptions[NSOPTION_##OPTION].value.s)
/**
* Get the value of a netsurf colour option.
*
* Gets the value of an option assuming it is a colour type.
* @note option type is unchecked so care must be taken in caller.
*/
#define nsoption_colour(OPTION) (nsoptions[NSOPTION_##OPTION].value.c) #define nsoption_colour(OPTION) (nsoptions[NSOPTION_##OPTION].value.c)
#define nsoption_set_bool(OPTION, VALUE) nsoptions[NSOPTION_##OPTION].value.b = VALUE
#define nsoption_set_int(OPTION, VALUE) nsoptions[NSOPTION_##OPTION].value.i = VALUE
#define nsoption_set_colour(OPTION, VALUE) nsoptions[NSOPTION_##OPTION].value.c = VALUE
#define nsoption_set_charp(OPTION, VALUE) \
do { \
if (nsoptions[NSOPTION_##OPTION].value.s != NULL) { \
free(nsoptions[NSOPTION_##OPTION].value.s); \
} \
nsoptions[NSOPTION_##OPTION].value.s = VALUE; \
if ((nsoptions[NSOPTION_##OPTION].value.s != NULL) && \
(*nsoptions[NSOPTION_##OPTION].value.s == 0)) { \
free(nsoptions[NSOPTION_##OPTION].value.s); \
nsoptions[NSOPTION_##OPTION].value.s = NULL; \
} \
} while (0)
/* if a string option is unset set it otherwise leave it set */ /** set a boolean option in the default table */
#define nsoption_set_bool(OPTION, VALUE) nsoptions[NSOPTION_##OPTION].value.b = VALUE
/** set an integer option in the default table */
#define nsoption_set_int(OPTION, VALUE) nsoptions[NSOPTION_##OPTION].value.i = VALUE
/** set a colour option in the default table */
#define nsoption_set_colour(OPTION, VALUE) nsoptions[NSOPTION_##OPTION].value.c = VALUE
/**
* Set string option in specified table.
*
* Sets the string option to the value given freeing any resources
* currently allocated to the option. If the passed string is empty it
* is converted to the NULL value.
*
* @param opts The table to set option in
* @param option_idx The option
* @param s The string to set. This is used directly and not copied.
*/
nserror nsoption_set_tbl_charp(struct nsoption_s *opts, enum nsoption_e option_idx, char *s);
/** set string option in default table */
#define nsoption_set_charp(OPTION, VALUE) \
nsoption_set_tbl_charp(nsoptions, NSOPTION_##OPTION, VALUE)
/** set string option in default table if currently unset */
#define nsoption_setnull_charp(OPTION, VALUE) \ #define nsoption_setnull_charp(OPTION, VALUE) \
do { \ do { \
if (nsoptions[NSOPTION_##OPTION].value.s == NULL) { \ if (nsoptions[NSOPTION_##OPTION].value.s == NULL) { \
nsoptions[NSOPTION_##OPTION].value.s = VALUE; \ nsoption_set_tbl_charp(nsoptions, NSOPTION_##OPTION, VALUE); \
if (*nsoptions[NSOPTION_##OPTION].value.s == 0) { \
free(nsoptions[NSOPTION_##OPTION].value.s); \
nsoptions[NSOPTION_##OPTION].value.s = NULL; \
} \
} else { \ } else { \
free(VALUE); \ free(VALUE); \
} \ } \
} while (0) } while (0)
#endif #endif