From 132be1eed23315c8fbd72acaa06ccdec62363c73 Mon Sep 17 00:00:00 2001 From: Chris Young Date: Sat, 16 Jan 2016 19:37:39 +0000 Subject: OS3 build fixes --- amiga/Makefile.target | 2 +- amiga/font.c | 2 +- amiga/font_cache.c | 2 +- amiga/gui.c | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/amiga/Makefile.target b/amiga/Makefile.target index 8c850d1db..9172ce0b0 100644 --- a/amiga/Makefile.target +++ b/amiga/Makefile.target @@ -7,7 +7,7 @@ CFLAGS += -std=c99 -Dnsamiga ifneq ($(SUBTARGET),os3) CFLAGS += -O2 -finline-functions -U__STRICT_ANSI__ -D__USE_INLINE__ -D__USE_BASETYPE__ else - CFLAGS += -m68020-60 -O0 -DPATH_MAX=1024 -D__m68k__ + CFLAGS += -msoft-float -m68020-60 -O0 -DPATH_MAX=1024 -D__m68k__ endif NETSURF_FEATURE_ROSPRITE_CFLAGS := -DWITH_NSSPRITE diff --git a/amiga/font.c b/amiga/font.c index ac5fd129f..b7e31cea8 100644 --- a/amiga/font.c +++ b/amiga/font.c @@ -41,7 +41,7 @@ void ami_font_setdevicedpi(int id) if(nsoption_bool(bitmap_fonts) == true) { LOG("WARNING: Using diskfont.library for text. Forcing DPI to 72."); - nsoption_int(screen_ydpi) = 72; + nsoption_set_int(screen_ydpi, 72); } browser_set_dpi(nsoption_int(screen_ydpi)); diff --git a/amiga/font_cache.c b/amiga/font_cache.c index b036f6334..e3f107dd8 100644 --- a/amiga/font_cache.c +++ b/amiga/font_cache.c @@ -171,7 +171,7 @@ void ami_font_cache_insert(struct ami_font_cache_node *nodedata, const char *fon #ifndef __amigaos4__ struct nsObject *node = AddObject(ami_font_cache_list, AMINS_FONT); if(node) { - ObjectCallback(ami_font_bullet_close); + ObjectCallback(node, ami_font_bullet_close); node->objstruct = nodedata; node->dtz_Node.ln_Name = strdup(font); } diff --git a/amiga/gui.c b/amiga/gui.c index 837063639..e0f370f6e 100644 --- a/amiga/gui.c +++ b/amiga/gui.c @@ -562,7 +562,7 @@ static nserror ami_set_options(struct nsoption_s *defaults) nsoption_set_bool(font_antialiasing, false); nsoption_set_bool(truecolour_mouse_pointers, false); nsoption_set_bool(use_openurl_lib, true); - nsoption_set_bool(use_diskfont, true); + nsoption_set_bool(bitmap_fonts, true); #endif if((!nsoption_charp(accept_language)) || -- cgit v1.2.3 From b3aa313e8421a26489719ecb4626cc6837e0079c Mon Sep 17 00:00:00 2001 From: Chris Young Date: Sun, 17 Jan 2016 23:40:50 +0000 Subject: misc amiga fixes re font plotting --- amiga/font.c | 4 ++-- amiga/font.h | 2 -- amiga/font_bullet.c | 6 +++--- amiga/plotters.c | 11 +++++------ 4 files changed, 10 insertions(+), 13 deletions(-) diff --git a/amiga/font.c b/amiga/font.c index b7e31cea8..27ea62d6e 100644 --- a/amiga/font.c +++ b/amiga/font.c @@ -36,14 +36,14 @@ void ami_font_setdevicedpi(int id) { DisplayInfoHandle dih; struct DisplayInfo dinfo; - ULONG ydpi = nsoption_int(screen_ydpi); - ULONG xdpi = nsoption_int(screen_ydpi); if(nsoption_bool(bitmap_fonts) == true) { LOG("WARNING: Using diskfont.library for text. Forcing DPI to 72."); nsoption_set_int(screen_ydpi, 72); } + ULONG ydpi = nsoption_int(screen_ydpi); + ULONG xdpi = nsoption_int(screen_ydpi); browser_set_dpi(nsoption_int(screen_ydpi)); if(id && (nsoption_int(monitor_aspect_x) != 0) && (nsoption_int(monitor_aspect_y) != 0)) diff --git a/amiga/font.h b/amiga/font.h index 416609a8d..e0799ea05 100755 --- a/amiga/font.h +++ b/amiga/font.h @@ -23,8 +23,6 @@ #include #include -struct ami_font_cache_node; - void ami_font_setdevicedpi(int id); void ami_font_init(void); void ami_font_fini(void); diff --git a/amiga/font_bullet.c b/amiga/font_bullet.c index 2800533a0..69757e5a3 100644 --- a/amiga/font_bullet.c +++ b/amiga/font_bullet.c @@ -155,7 +155,7 @@ static inline uint32 amiga_nsfont_decode_surrogate(const uint16 *char1) } } -static inline bool amiga_nsfont_width(const plot_font_style_t *fstyle, +static bool amiga_nsfont_width(const plot_font_style_t *fstyle, const char *string, size_t length, int *width) { @@ -178,7 +178,7 @@ static inline bool amiga_nsfont_width(const plot_font_style_t *fstyle, * \return true on success, false on error and error reported */ -static inline bool amiga_nsfont_position_in_string(const plot_font_style_t *fstyle, +static bool amiga_nsfont_position_in_string(const plot_font_style_t *fstyle, const char *string, size_t length, int x, size_t *char_offset, int *actual_x) { @@ -261,7 +261,7 @@ static inline bool amiga_nsfont_position_in_string(const plot_font_style_t *fsty * Returning char_offset == length means no split possible */ -static inline bool amiga_nsfont_split(const plot_font_style_t *fstyle, +static bool amiga_nsfont_split(const plot_font_style_t *fstyle, const char *string, size_t length, int x, size_t *char_offset, int *actual_x) { diff --git a/amiga/plotters.c b/amiga/plotters.c index b459dcc7e..d241dd408 100644 --- a/amiga/plotters.c +++ b/amiga/plotters.c @@ -94,7 +94,7 @@ void ami_init_layers(struct gui_globals *gg, ULONG width, ULONG height) * Height is set to screen width to give enough space for thumbnails * * Also applies to the further gfx/layers functions and memory below */ - ULONG depth = 32; + int depth = 32; struct BitMap *friend = NULL; depth = GetBitMapAttr(scrn->RastPort.BitMap, BMA_DEPTH); @@ -112,6 +112,8 @@ void ami_init_layers(struct gui_globals *gg, ULONG width, ULONG height) if(depth > 8) depth = 8; #endif + if(palette_mapped == true) nsoption_set_bool(font_antialiasing, false); + if(!width) width = nsoption_int(redraw_tile_size_x); if(!height) height = nsoption_int(redraw_tile_size_y); gg->width = width; @@ -429,13 +431,10 @@ static bool ami_text(int x, int y, const char *text, size_t length, LOG("[ami_plotter] Entered ami_text()"); #endif - bool aa = true; - - if((nsoption_bool(font_antialiasing) == false) || (palette_mapped == true)) - aa = false; + if(__builtin_expect(ami_nsfont == NULL, 0)) return false; ami_plot_setapen(glob->rp, fstyle->foreground); - ami_nsfont->text(glob->rp, text, length, fstyle, x, y, aa); + ami_nsfont->text(glob->rp, text, length, fstyle, x, y, nsoption_bool(font_antialiasing)); return true; } -- cgit v1.2.3 From 9c62993efd45bcd685c579d51be013a1ae4f2770 Mon Sep 17 00:00:00 2001 From: Chris Young Date: Mon, 18 Jan 2016 00:02:52 +0000 Subject: Don't expose the DPI-related variables --- amiga/font.c | 13 +++++++++++++ amiga/font.h | 9 +++++---- amiga/font_bullet.c | 4 ++-- amiga/gui.c | 6 +++++- 4 files changed, 25 insertions(+), 7 deletions(-) diff --git a/amiga/font.c b/amiga/font.c index 27ea62d6e..39cb38602 100644 --- a/amiga/font.c +++ b/amiga/font.c @@ -32,6 +32,19 @@ #include "amiga/font_diskfont.h" #include "amiga/font_scan.h" +static ULONG ami_devicedpi = 72; +static ULONG ami_xdpi = 72; + +ULONG ami_font_dpi_get_devicedpi(void) +{ + return ami_devicedpi; +} + +ULONG ami_font_dpi_get_xdpi(void) +{ + return ami_xdpi; +} + void ami_font_setdevicedpi(int id) { DisplayInfoHandle dih; diff --git a/amiga/font.h b/amiga/font.h index e0799ea05..da23b5989 100755 --- a/amiga/font.h +++ b/amiga/font.h @@ -23,10 +23,14 @@ #include #include -void ami_font_setdevicedpi(int id); void ami_font_init(void); void ami_font_fini(void); +/* DPI stuff */ +void ami_font_setdevicedpi(int id); +ULONG ami_font_dpi_get_devicedpi(void); +ULONG ami_font_dpi_get_xdpi(void); + /* Simple diskfont functions for graphics.library use (not page rendering) */ struct TextFont *ami_font_open_disk_font(struct TextAttr *tattr); void ami_font_close_disk_font(struct TextFont *tfont); @@ -50,9 +54,6 @@ struct ami_font_functions { ULONG x, ULONG y, bool aa); }; -ULONG ami_devicedpi; -ULONG ami_xdpi; - const struct ami_font_functions *ami_nsfont; #endif diff --git a/amiga/font_bullet.c b/amiga/font_bullet.c index 69757e5a3..f63455257 100644 --- a/amiga/font_bullet.c +++ b/amiga/font_bullet.c @@ -55,7 +55,7 @@ #define NSA_VALUE_SHEARSIN (1 << 14) #define NSA_VALUE_SHEARCOS (1 << 16) -#define NSA_FONT_EMWIDTH(s) (s / FONT_SIZE_SCALE) * (ami_xdpi / 72.0) +#define NSA_FONT_EMWIDTH(s) (s / FONT_SIZE_SCALE) * (ami_font_dpi_get_xdpi() / 72.0) const uint16 sc_table[] = { 0x0061, 0x1D00, /* a */ @@ -510,7 +510,7 @@ static struct OutlineFont *ami_open_outline_font(const plot_font_style_t *fstyle #endif if(ESetInfo(AMI_OFONT_ENGINE, - OT_DeviceDPI, ami_devicedpi, + OT_DeviceDPI, ami_font_dpi_get_devicedpi(), OT_PointHeight, ysize, OT_EmboldenX, emboldenx, OT_EmboldenY, emboldeny, diff --git a/amiga/gui.c b/amiga/gui.c index e0f370f6e..768b4062a 100644 --- a/amiga/gui.c +++ b/amiga/gui.c @@ -5589,8 +5589,12 @@ int main(int argc, char** argv) #ifdef __amigaos4__ amiga_plugin_hack_init(); -#endif + + /* DataTypes loader needs datatypes.library v45, + * but for some reason that's not in OS3.9. + * Skip it to ensure it isn't causing other problems. */ ret = amiga_datatypes_init(); +#endif /* user options setup */ ret = nsoption_init(ami_set_options, &nsoptions, &nsoptions_default); -- cgit v1.2.3 From 59ea187b74cb8ec2295c189356321390cea43ab3 Mon Sep 17 00:00:00 2001 From: Chris Young Date: Mon, 18 Jan 2016 00:20:45 +0000 Subject: Ensure the textattr flags field is clear This fixes problems with inconsistent layouting on OS3 --- amiga/font_diskfont.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/amiga/font_diskfont.c b/amiga/font_diskfont.c index 61f777355..7b8819969 100644 --- a/amiga/font_diskfont.c +++ b/amiga/font_diskfont.c @@ -43,6 +43,8 @@ static struct TextFont *ami_font_bm_open(struct RastPort *rp, const plot_font_st if(rp == NULL) return NULL; + tattr.ta_Flags = 0; + switch(fstyle->family) { case PLOT_FONT_FAMILY_SANS_SERIF: -- cgit v1.2.3 From f266eb1c5d0423679438a77834b3ee2e669e63a4 Mon Sep 17 00:00:00 2001 From: Vincent Sanders Date: Tue, 19 Jan 2016 13:51:54 +0000 Subject: make search engines resource common between gtk and beos --- beos/Makefile.target | 4 +--- beos/res/SearchEngines | 1 + gtk/res/SearchEngines | 21 +-------------------- resources/SearchEngines | 20 ++++++++++++++++++++ 4 files changed, 23 insertions(+), 23 deletions(-) create mode 120000 beos/res/SearchEngines mode change 100644 => 120000 gtk/res/SearchEngines create mode 100644 resources/SearchEngines diff --git a/beos/Makefile.target b/beos/Makefile.target index 8759d08bd..e8745d876 100644 --- a/beos/Makefile.target +++ b/beos/Makefile.target @@ -137,17 +137,15 @@ $(RSRC_BEOS): $(RDEF_BEOS) $(RDEF_IMP_BEOS) # ---------------------------------------------------------------------------- install-beos: -# TODO:HAIKU -- not sure if throbber is needed. being left out for now. mkdir -p $(DESTDIR)$(NETSURF_BEOS_BIN) mkdir -p $(DESTDIR)$(NETSURF_BEOS_RESOURCES) -# mkdir -p $(DESTDIR)$(NETSURF_BEOS_RESOURCES)throbber @copyattr -d $(EXETARGET) $(DESTDIR)$(NETSURF_BEOS_BIN)NetSurf @cp -vRL beos/res/adblock.css $(DESTDIR)$(NETSURF_BEOS_RESOURCES) @cp -vRL beos/res/ca-bundle.txt $(DESTDIR)$(NETSURF_BEOS_RESOURCES) @cp -vRL beos/res/default.css $(DESTDIR)$(NETSURF_BEOS_RESOURCES) @cp -vRL beos/res/beosdefault.css $(DESTDIR)$(NETSURF_BEOS_RESOURCES) @cp -vRL gtk/res/license $(DESTDIR)$(NETSURF_BEOS_RESOURCES) -# @cp -vRL beos/res/throbber/*.png $(DESTDIR)$(NETSURF_BEOS_RESOURCES)throbber + @cp -vRL beos/res/SearchEngines $(DESTDIR)$(NETSURF_BEOS_RESOURCES) # ---------------------------------------------------------------------------- # Package target diff --git a/beos/res/SearchEngines b/beos/res/SearchEngines new file mode 120000 index 000000000..df5252e07 --- /dev/null +++ b/beos/res/SearchEngines @@ -0,0 +1 @@ +../../resources/SearchEngines \ No newline at end of file diff --git a/gtk/res/SearchEngines b/gtk/res/SearchEngines deleted file mode 100644 index 38e77957b..000000000 --- a/gtk/res/SearchEngines +++ /dev/null @@ -1,20 +0,0 @@ -Google|www.google.com|http://www.google.com/search?q=%s|http://www.google.com/favicon.ico| -Yahoo|search.yahoo.com|http://search.yahoo.com/search?p=%s|http://www.yahoo.com/favicon.ico| -Bing|www.bing.com|http://www.bing.com/search?q=%s|http://www.bing.com/favicon.ico| -Business.com|www.business.com|http://www.business.com/search/rslt_default.asp?query=%s|http://www.business.com/favicon.ico| -Omgili|www.omgili.com|http://www.omgili.com/AAAAA/%s.html|http://omgili.com/public/images/favicon.ico| -BBC News|search.bbc.co.uk|http://search.bbc.co.uk/search?q=%s&tab=ns|http://www.bbc.co.uk/favicon.ico| -Ubuntu Packages|packages.ubuntu.com|http://packages.ubuntu.com/search?keywords=%s|http://packages.ubuntu.com/favicon.ico| -Creative Commons|creativecommons.org|http://creativecommons.org/?s=%s|http://creativecommons.org/favicon.ico|fixme:favicon does not work as it is served as x-icon and is a png -Ask.com|www.ask.com|http://www.ask.com/web?q=%s|http://sp.uk.ask.com/sh/i/a14/favicon/favicon.ico|fixme:favicon is served as text/plain -Dictionary.com|dictionary.reference.com|http://dictionary.reference.com/browse/%s?jss=0|http://dictionary.reference.com/favicon.ico| -Youtube|www.youtube.com|http://www.youtube.com/results?search_query=%s|http://www.youtube.com/favicon.ico| -AOL|search.aol.com|http://search.aol.com/aol/search?query=%s|http://www.aol.com/favicon.ico| -Baidu|www.baidu.com|http://www.baidu.com/s?wd=%s|http://www.baidu.com/favicon.ico| -Amazon|www.amazon.com|http://www.amazon.com/s/ref=nb_ss_gw?field-keywords=%s|http://www.amazon.com/favicon.ico| -Ebay|shop.ebay.com|http://shop.ebay.com/items/%s|http://www.ebay.com/favicon.ico| -IMDB|www.imdb.com|http://www.imdb.com/find?q=%s|http://www.imdb.com/favicon.ico| -ESPN|search.espn.go.com|http://search.espn.go.com/%s/|http://www.espn.go.com/favicon.ico| -Wikipedia|en.wikipedia.org|http://en.wikipedia.org/w/index.php?title=Special%%3ASearch&search=%s|http://en.wikipedia.org/favicon.ico| -DuckDuckGo|www.duckduckgo.com|http://www.duckduckgo.com/html/?q=%s|http://www.duckduckgo.com/favicon.ico|fixme:Their ico upsets the current implementation -Seeks|www.seeks-project.info|https://www.seeks-project.info/search.php/search?q=%s|http://www.seeks-project.info/search.php/public/images/seek_icon_32x32_transparent.png|fixme:they have no icon diff --git a/gtk/res/SearchEngines b/gtk/res/SearchEngines new file mode 120000 index 000000000..df5252e07 --- /dev/null +++ b/gtk/res/SearchEngines @@ -0,0 +1 @@ +../../resources/SearchEngines \ No newline at end of file diff --git a/resources/SearchEngines b/resources/SearchEngines new file mode 100644 index 000000000..38e77957b --- /dev/null +++ b/resources/SearchEngines @@ -0,0 +1,20 @@ +Google|www.google.com|http://www.google.com/search?q=%s|http://www.google.com/favicon.ico| +Yahoo|search.yahoo.com|http://search.yahoo.com/search?p=%s|http://www.yahoo.com/favicon.ico| +Bing|www.bing.com|http://www.bing.com/search?q=%s|http://www.bing.com/favicon.ico| +Business.com|www.business.com|http://www.business.com/search/rslt_default.asp?query=%s|http://www.business.com/favicon.ico| +Omgili|www.omgili.com|http://www.omgili.com/AAAAA/%s.html|http://omgili.com/public/images/favicon.ico| +BBC News|search.bbc.co.uk|http://search.bbc.co.uk/search?q=%s&tab=ns|http://www.bbc.co.uk/favicon.ico| +Ubuntu Packages|packages.ubuntu.com|http://packages.ubuntu.com/search?keywords=%s|http://packages.ubuntu.com/favicon.ico| +Creative Commons|creativecommons.org|http://creativecommons.org/?s=%s|http://creativecommons.org/favicon.ico|fixme:favicon does not work as it is served as x-icon and is a png +Ask.com|www.ask.com|http://www.ask.com/web?q=%s|http://sp.uk.ask.com/sh/i/a14/favicon/favicon.ico|fixme:favicon is served as text/plain +Dictionary.com|dictionary.reference.com|http://dictionary.reference.com/browse/%s?jss=0|http://dictionary.reference.com/favicon.ico| +Youtube|www.youtube.com|http://www.youtube.com/results?search_query=%s|http://www.youtube.com/favicon.ico| +AOL|search.aol.com|http://search.aol.com/aol/search?query=%s|http://www.aol.com/favicon.ico| +Baidu|www.baidu.com|http://www.baidu.com/s?wd=%s|http://www.baidu.com/favicon.ico| +Amazon|www.amazon.com|http://www.amazon.com/s/ref=nb_ss_gw?field-keywords=%s|http://www.amazon.com/favicon.ico| +Ebay|shop.ebay.com|http://shop.ebay.com/items/%s|http://www.ebay.com/favicon.ico| +IMDB|www.imdb.com|http://www.imdb.com/find?q=%s|http://www.imdb.com/favicon.ico| +ESPN|search.espn.go.com|http://search.espn.go.com/%s/|http://www.espn.go.com/favicon.ico| +Wikipedia|en.wikipedia.org|http://en.wikipedia.org/w/index.php?title=Special%%3ASearch&search=%s|http://en.wikipedia.org/favicon.ico| +DuckDuckGo|www.duckduckgo.com|http://www.duckduckgo.com/html/?q=%s|http://www.duckduckgo.com/favicon.ico|fixme:Their ico upsets the current implementation +Seeks|www.seeks-project.info|https://www.seeks-project.info/search.php/search?q=%s|http://www.seeks-project.info/search.php/public/images/seek_icon_32x32_transparent.png|fixme:they have no icon -- cgit v1.2.3 From 9a64e9302ee53dfbdda7a5fa8210877c030ed01d Mon Sep 17 00:00:00 2001 From: Adrián Arroyo Calle Date: Tue, 19 Jan 2016 14:03:18 +0000 Subject: Add web search bar to haiku frontend --- beos/Makefile.target | 2 +- beos/gui.cpp | 4 +++- beos/gui.h | 2 ++ beos/scaffolding.cpp | 58 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 64 insertions(+), 2 deletions(-) diff --git a/beos/Makefile.target b/beos/Makefile.target index e8745d876..a3f857ec1 100644 --- a/beos/Makefile.target +++ b/beos/Makefile.target @@ -99,7 +99,7 @@ RDEF_IMP_BEOS := $(addprefix $(OBJROOT)/,$(subst /,_,$(RDEF_IMP_BEOS))) RDEP_BEOS := \ adblock.css beosdefault.css default.css internal.css quirks.css \ netsurf.png favicon.png ca-bundle.txt \ - credits.html licence.html welcome.html maps.html + credits.html licence.html welcome.html maps.html SearchEngines RDEP_BEOS := $(addprefix beos/res/,$(RDEP_BEOS)) \ $(wildcard beos/res/icons/*.png) \ $(wildcard beos/res/??/*) \ diff --git a/beos/gui.cpp b/beos/gui.cpp index cfd026b66..1e653a0fe 100644 --- a/beos/gui.cpp +++ b/beos/gui.cpp @@ -1,4 +1,5 @@ /* + * Copyright 2015 Adrián Arroyo Calle * Copyright 2008 François Revol * Copyright 2005 James Bursa * @@ -137,6 +138,7 @@ NSBrowserApplication::MessageReceived(BMessage *message) case 'home': case 'urlc': case 'urle': + case 'sear': case 'menu': // NetPositive messages case B_NETPOSITIVE_OPEN_URL: @@ -254,7 +256,7 @@ image_id nsbeos_find_app_path(char *path) * \param def default to return if file not found * \return path to resource. */ -static char *find_resource(char *buf, const char *filename, const char *def) +char *find_resource(char *buf, const char *filename, const char *def) { const char *cdir = NULL; status_t err; diff --git a/beos/gui.h b/beos/gui.h index 215cda8b1..b9f560e8d 100644 --- a/beos/gui.h +++ b/beos/gui.h @@ -1,4 +1,5 @@ /* + * Copyright 2015 Adrián Arroyo Calle * Copyright 2008 François Revol * Copyright 2005 James Bursa * @@ -65,6 +66,7 @@ void nsbeos_pipe_message_top(BMessage *message, BWindow *_this, struct beos_scaf void nsbeos_gui_view_source(struct hlcache_handle *content); image_id nsbeos_find_app_path(char *path); +char *find_resource(char *buf, const char *filename, const char *def); void nsbeos_update_system_ui_colors(void); diff --git a/beos/scaffolding.cpp b/beos/scaffolding.cpp index 2c5d4e961..a1c46978d 100644 --- a/beos/scaffolding.cpp +++ b/beos/scaffolding.cpp @@ -1,4 +1,5 @@ /* + * Copyright 2015 Adrián Arroyo Calle * Copyright 2008 François Revol * Copyright 2006 Rob Kendrick * @@ -56,6 +57,8 @@ extern "C" { #include "desktop/browser.h" #include "desktop/netsurf.h" #include "desktop/version.h" +#include "desktop/searchweb.h" +#include "desktop/search.h" #include "desktop/plotters.h" #include "utils/nsoption.h" #include "desktop/textinput.h" @@ -111,6 +114,7 @@ struct beos_scaffolding { BControl *home_button; NSIconTextControl *url_bar; + NSIconTextControl *search_bar; //BMenuField *url_bar_completion; NSThrobber *throbber; @@ -478,6 +482,7 @@ NSBaseView::MessageReceived(BMessage *message) case 'home': case 'urlc': case 'urle': + case 'sear': case 'menu': case NO_ACTION: case HELP_OPEN_CONTENTS: @@ -653,6 +658,7 @@ NSBaseView::AllAttached() g->home_button->SetTarget(this); g->url_bar->SetTarget(this); + g->search_bar->SetTarget(this); rgb_color c = ui_color(B_PANEL_BACKGROUND_COLOR); SetViewColor(c); @@ -669,6 +675,7 @@ NSBaseView::AllAttached() g->home_button->SetViewColor(c); g->home_button->SetLowColor(c); g->url_bar->SetViewColor(c); + g->search_bar->SetViewColor(c); g->throbber->SetViewColor(c); g->scroll_view->SetViewColor(c); @@ -806,6 +813,7 @@ static void nsbeos_scaffolding_update_colors(nsbeos_scaffolding *g) g->reload_button->SetViewColor(c); g->home_button->SetViewColor(c); g->url_bar->SetViewColor(c); + g->search_bar->SetViewColor(c); g->throbber->SetViewColor(c); g->scroll_view->SetViewColor(c); @@ -1073,6 +1081,41 @@ void nsbeos_scaffolding_dispatch_event(nsbeos_scaffolding *scaffold, BMessage *m //nsbeos_completion_update(text.String()); break; } + case 'sear': + { + nserror ret; + nsurl* url; + BString text; + if (!scaffold->search_bar->LockLooper()) + break; + text = scaffold->search_bar->Text(); + scaffold->search_bar->UnlockLooper(); + + char t[PATH_MAX]; + find_resource(t,"SearchEngines","./beos/res/SearchEngines"); + + search_web_init(); + + ret = search_web_omni(text.String(),SEARCH_WEB_OMNI_SEARCHONLY + ,&url); + if (ret == NSERROR_OK) { + ret = browser_window_create( + (browser_window_create_flags)(BW_CREATE_HISTORY | BW_CREATE_TAB), + url, + NULL, + bw, + NULL); + nsurl_unref(url); + } + + if (ret != NSERROR_OK) { + warn_user(messages_get_errorcode(ret), 0); + } + + search_web_finalise(); + + break; + } /* case 'menu': { @@ -2113,6 +2156,21 @@ nsbeos_scaffolding *nsbeos_new_scaffolding(struct gui_window *toplevel) g->url_bar->TextView()->SetTextRect(rect); g->tool_bar->AddChild(g->url_bar); + // search bar + + rect = g->tool_bar->Bounds(); + rect.left += TOOLBAR_HEIGHT * nButtons + (g->url_bar->Bounds().right - g->url_bar->Bounds().left); + rect.right -= TOOLBAR_HEIGHT * 1; + rect.InsetBy(5,5); + message = new BMessage('sear'); + message->AddPointer("scaffolding", g); + g->search_bar = new NSIconTextControl(rect,"search_bar","","Search...",message, + B_FOLLOW_RIGHT); + g->search_bar->SetDivider(0); + rect = g->search_bar->TextView()->TextRect(); + rect.left += 0; + g->search_bar->TextView()->TextRect(); + g->tool_bar->AddChild(g->search_bar); // throbber rect.Set(0, 0, 24, 24); -- cgit v1.2.3 From 0a5f63abf145c05ed9994566289316516310a603 Mon Sep 17 00:00:00 2001 From: Adrián Arroyo Calle Date: Tue, 19 Jan 2016 14:07:57 +0000 Subject: Add cookie management for Haiku frontend --- beos/Makefile.target | 5 +- beos/cookies.cpp | 416 +++++++++++++++++++++++++++++++++++++++++++++++++++ beos/cookies.h | 24 +++ beos/scaffolding.cpp | 20 ++- 4 files changed, 452 insertions(+), 13 deletions(-) create mode 100644 beos/cookies.cpp create mode 100644 beos/cookies.h diff --git a/beos/Makefile.target b/beos/Makefile.target index a3f857ec1..38ec27919 100644 --- a/beos/Makefile.target +++ b/beos/Makefile.target @@ -57,7 +57,7 @@ else NETLDFLAGS := -lnetwork endif -LDFLAGS += -lbe -ltranslation -ltracker $(NETLDFLAGS) +LDFLAGS += -lbe -ltranslation -ltracker -lcolumnlistview $(NETLDFLAGS) ifeq ($(CC_MAJOR),2) LDFLAGS += -lstdc++.r4 else @@ -85,7 +85,8 @@ endif # ---------------------------------------------------------------------------- # S_BEOS are sources purely for the BeOS build -S_BEOS := about.cpp bitmap.cpp download.cpp fetch_rsrc.cpp filetype.cpp \ +S_BEOS := about.cpp bitmap.cpp cookies.cpp \ + download.cpp fetch_rsrc.cpp filetype.cpp \ font.cpp gui.cpp login.cpp gui_options.cpp plotters.cpp \ scaffolding.cpp search.cpp schedule.cpp throbber.cpp window.cpp S_BEOS := $(addprefix beos/,$(S_BEOS)) diff --git a/beos/cookies.cpp b/beos/cookies.cpp new file mode 100644 index 000000000..acd0ac14d --- /dev/null +++ b/beos/cookies.cpp @@ -0,0 +1,416 @@ +/* + * Copyright 2015 Adrián Arroyo Calle + * + * 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 . + */ + +#define __STDBOOL_H__ 1 +#include +#include +#include +extern "C" { +#include "desktop/mouse.h" +#include "utils/log.h" +#include "desktop/cookie_manager.h" +#include "desktop/plotters.h" +#include "desktop/tree.h" +#include "desktop/textinput.h" +#include "content/urldb.h" +} +#include "beos/cookies.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +static std::vector cookieJar; + +class CookieWindow : public BWindow { +public: + CookieWindow(BRect frame); + virtual void MessageReceived(BMessage* message); + virtual void Show(); + virtual bool QuitRequested(); + +private: + void _BuildDomainList(); + BStringItem* _AddDomain(BString domain, bool fake); + void _ShowCookiesForDomain(BString domain); + void _DeleteCookies(); + +private: + BOutlineListView* fDomains; + BColumnListView* fCookies; + BStringView* fHeaderView; +}; + +enum { + COOKIE_IMPORT = 'cimp', + COOKIE_EXPORT = 'cexp', + COOKIE_DELETE = 'cdel', + COOKIE_REFRESH = 'rfsh', + + DOMAIN_SELECTED = 'dmsl' +}; + + +class CookieDateColumn: public BDateColumn +{ +public: + CookieDateColumn(const char* title, float width) + : + BDateColumn(title, width, width / 2, width * 2) + { + } + + void DrawField(BField* field, BRect rect, BView* parent) { + BDateField* dateField = (BDateField*)field; + if (dateField->UnixTime() == -1) { + DrawString("Session cookie", parent, rect); + } else { + BDateColumn::DrawField(field, rect, parent); + } + } +}; + + +class CookieRow: public BRow +{ +public: + CookieRow(BColumnListView* list, struct cookie_data& cookie) + : + BRow(), + fCookie(cookie) + { + list->AddRow(this); + SetField(new BStringField(cookie.name), 0); + SetField(new BStringField(cookie.path), 1); + time_t expiration = cookie.expires; + SetField(new BDateField(&expiration), 2); + SetField(new BStringField(cookie.value), 3); + + BString flags; + if (cookie.secure) + flags = "https "; + if (cookie.http_only) + flags = "http "; + + SetField(new BStringField(flags.String()), 4); + } + +public: + struct cookie_data fCookie; +}; + + +class DomainItem: public BStringItem +{ +public: + DomainItem(BString text, bool empty) + : + BStringItem(text), + fEmpty(empty) + { + } + +public: + bool fEmpty; +}; + + +CookieWindow::CookieWindow(BRect frame) + : + BWindow(frame,"Cookie manager", B_TITLED_WINDOW, + B_NORMAL_WINDOW_FEEL, + B_AUTO_UPDATE_SIZE_LIMITS | B_ASYNCHRONOUS_CONTROLS | B_NOT_ZOOMABLE) +{ + BGroupLayout* root = new BGroupLayout(B_HORIZONTAL, 0.0); + SetLayout(root); + + fDomains = new BOutlineListView("domain list"); + root->AddView(new BScrollView("scroll", fDomains, 0, false, true), 1); + + fHeaderView = new BStringView("label","The cookie jar is empty!"); + fCookies = new BColumnListView("cookie list", B_WILL_DRAW, B_FANCY_BORDER, + false); + + float em = fCookies->StringWidth("M"); + float flagsLength = fCookies->StringWidth("Mhttps hostOnly" B_UTF8_ELLIPSIS); + + fCookies->AddColumn(new BStringColumn("Name", + 20 * em, 10 * em, 50 * em, 0), 0); + fCookies->AddColumn(new BStringColumn("Path", + 10 * em, 10 * em, 50 * em, 0), 1); + fCookies->AddColumn(new CookieDateColumn("Expiration", + fCookies->StringWidth("88/88/8888 88:88:88 AM")), 2); + fCookies->AddColumn(new BStringColumn("Value", + 20 * em, 10 * em, 50 * em, 0), 3); + fCookies->AddColumn(new BStringColumn("Flags", + flagsLength, flagsLength, flagsLength, 0), 4); + + root->AddItem(BGroupLayoutBuilder(B_VERTICAL, B_USE_DEFAULT_SPACING) + .SetInsets(5, 5, 5, 5) + .AddGroup(B_HORIZONTAL, B_USE_DEFAULT_SPACING) + .Add(fHeaderView) + .AddGlue() + .End() + .Add(fCookies) + .AddGroup(B_HORIZONTAL, B_USE_DEFAULT_SPACING) + .SetInsets(5, 5, 5, 5) + .AddGlue() + .Add(new BButton("delete", "Delete", + new BMessage(COOKIE_DELETE))), 3); + + fDomains->SetSelectionMessage(new BMessage(DOMAIN_SELECTED)); +} + + +void +CookieWindow::MessageReceived(BMessage* message) +{ + switch(message->what) { + case DOMAIN_SELECTED: + { + int32 index = message->FindInt32("index"); + BStringItem* item = (BStringItem*)fDomains->ItemAt(index); + if (item != NULL) { + BString domain = item->Text(); + _ShowCookiesForDomain(domain); + } + return; + } + + case COOKIE_REFRESH: + _BuildDomainList(); + return; + + case COOKIE_DELETE: + _DeleteCookies(); + return; + } + BWindow::MessageReceived(message); +} + + +void +CookieWindow::Show() +{ + BWindow::Show(); + if (IsHidden()) + return; + + PostMessage(COOKIE_REFRESH); +} + + +bool +CookieWindow::QuitRequested() +{ + if (!IsHidden()) + Hide(); + cookieJar.clear(); + return false; +} + + +void +CookieWindow::_BuildDomainList() +{ + // Empty the domain list (TODO should we do this when hiding instead?) + for (int i = fDomains->FullListCountItems() - 1; i >= 1; i--) { + delete fDomains->FullListItemAt(i); + } + fDomains->MakeEmpty(); + + // BOutlineListView does not handle parent = NULL in many methods, so let's + // make sure everything always has a parent. + DomainItem* rootItem = new DomainItem("", true); + fDomains->AddItem(rootItem); + + // Populate the domain list - TODO USE STL VECTOR + + + for(std::vector::iterator it = cookieJar.begin(); it != cookieJar.end(); ++it) { + _AddDomain((*it)->domain, false); + } + + int i = 1; + while (i < fDomains->FullListCountItems()) + { + DomainItem* item = (DomainItem*)fDomains->FullListItemAt(i); + // Detach items from the fake root + item->SetOutlineLevel(item->OutlineLevel() - 1); + i++; + } + fDomains->RemoveItem(rootItem); + delete rootItem; + + i = 0; + int firstNotEmpty = i; + // Collapse empty items to keep the list short + while (i < fDomains->FullListCountItems()) + { + DomainItem* item = (DomainItem*)fDomains->FullListItemAt(i); + if (item->fEmpty == true) { + if (fDomains->CountItemsUnder(item, true) == 1) { + // The item has no cookies, and only a single child. We can + // remove it and move its child one level up in the tree. + + int count = fDomains->CountItemsUnder(item, false); + int index = fDomains->FullListIndexOf(item) + 1; + for (int j = 0; j < count; j++) { + BListItem* child = fDomains->FullListItemAt(index + j); + child->SetOutlineLevel(child->OutlineLevel() - 1); + } + + fDomains->RemoveItem(item); + delete item; + + // The moved child is at the same index the removed item was. + // We continue the loop without incrementing i to process it. + continue; + } else { + // The item has no cookies, but has multiple children. Mark it + // as disabled so it is not selectable. + item->SetEnabled(false); + if (i == firstNotEmpty) + firstNotEmpty++; + } + } + + i++; + } + + fDomains->Select(firstNotEmpty); +} + + +BStringItem* +CookieWindow::_AddDomain(BString domain, bool fake) +{ + BStringItem* parent = NULL; + int firstDot = domain.FindFirst('.'); + if (firstDot >= 0) { + BString parentDomain(domain); + parentDomain.Remove(0, firstDot + 1); + parent = _AddDomain(parentDomain, true); + } else { + parent = (BStringItem*)fDomains->FullListItemAt(0); + } + + BListItem* existing; + int i = 0; + // check that we aren't already there + while ((existing = fDomains->ItemUnderAt(parent, true, i++)) != NULL) { + DomainItem* stringItem = (DomainItem*)existing; + if (stringItem->Text() == domain) { + if (fake == false) + stringItem->fEmpty = false; + return stringItem; + } + } + + // Insert the new item, keeping the list alphabetically sorted + BStringItem* domainItem = new DomainItem(domain, fake); + domainItem->SetOutlineLevel(parent->OutlineLevel() + 1); + BStringItem* sibling = NULL; + int siblingCount = fDomains->CountItemsUnder(parent, true); + for (i = 0; i < siblingCount; i++) { + sibling = (BStringItem*)fDomains->ItemUnderAt(parent, true, i); + if (strcmp(sibling->Text(), domainItem->Text()) > 0) { + fDomains->AddItem(domainItem, fDomains->FullListIndexOf(sibling)); + return domainItem; + } + } + + if (sibling) { + // There were siblings, but all smaller than what we try to insert. + // Insert after the last one (and its subitems) + fDomains->AddItem(domainItem, fDomains->FullListIndexOf(sibling) + + fDomains->CountItemsUnder(sibling, false) + 1); + } else { + // There were no siblings, insert right after the parent + fDomains->AddItem(domainItem, fDomains->FullListIndexOf(parent) + 1); + } + + return domainItem; +} + + +void +CookieWindow::_ShowCookiesForDomain(BString domain) +{ + BString label; + label.SetToFormat("Cookies for %s", domain.String()); + fHeaderView->SetText(label); + + // Empty the cookie list + fCookies->Clear(); + + // Populate the domain list + + for(std::vector::iterator it = cookieJar.begin(); it != cookieJar.end(); ++it) { + if((*it)->domain == domain) { + new CookieRow(fCookies,**it); + } + } +} + +static bool nsbeos_cookie_parser(const struct cookie_data* data) +{ + cookieJar.push_back((struct cookie_data*)data); + return true; +} + +void +CookieWindow::_DeleteCookies() +{ + // TODO shall we handle multiple selection here? + CookieRow* row = (CookieRow*)fCookies->CurrentSelection(); + if (row == NULL) { + // TODO see if a domain is selected in the domain list, and delete all + // cookies for that domain + return; + } + + fCookies->RemoveRow(row); + + urldb_delete_cookie(row->fCookie.domain, row->fCookie.path, row->fCookie.name); + cookieJar.clear(); + urldb_iterate_cookies(&nsbeos_cookie_parser); + + delete row; +} + +/** + * Creates the Cookie Manager + */ +void nsbeos_cookies_init(void) +{ + CookieWindow* cookWin=new CookieWindow(BRect(100,100,400,400)); + cookWin->Show(); + urldb_iterate_cookies(&nsbeos_cookie_parser); +} diff --git a/beos/cookies.h b/beos/cookies.h new file mode 100644 index 000000000..977ccd232 --- /dev/null +++ b/beos/cookies.h @@ -0,0 +1,24 @@ +/* + * Copyright 2015 Adrián Arroyo Calle + * + * 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 . + */ + +#ifndef __BEOS_COOKIES_H__ +#define __BEOS_COOKIES_H__ + +void nsbeos_cookies_init(); + +#endif /* __BEOS_ABOUT_H__ */ diff --git a/beos/scaffolding.cpp b/beos/scaffolding.cpp index a1c46978d..3205866f8 100644 --- a/beos/scaffolding.cpp +++ b/beos/scaffolding.cpp @@ -81,6 +81,7 @@ extern "C" { #include "beos/window.h" #include "beos/schedule.h" //#include "beos/download.h" +#include "beos/cookies.h" #define TOOLBAR_HEIGHT 32 #define DRAGGER_WIDTH 8 @@ -1191,9 +1192,15 @@ void nsbeos_scaffolding_dispatch_event(nsbeos_scaffolding *scaffold, BMessage *m case HOTLIST_SHOW: break; case COOKIES_SHOW: + { + nsbeos_cookie_init(); break; + } case COOKIES_DELETE: + { + nsbeos_cookie_init(); break; + } case BROWSER_PAGE: break; case BROWSER_PAGE_INFO: @@ -1976,18 +1983,9 @@ nsbeos_scaffolding *nsbeos_new_scaffolding(struct gui_window *toplevel) item = make_menu_item("HistGlobal", message); submenu->AddItem(item); - - submenu = new BMenu(messages_get("Cookies")); - menu->AddItem(submenu); - message = new BMessage(COOKIES_SHOW); - item = make_menu_item("ShowCookies", message); - submenu->AddItem(item); - - message = new BMessage(COOKIES_DELETE); - item = make_menu_item("DeleteCookies", message); - submenu->AddItem(item); - + item = make_menu_item("Cookie manager", message, true); + menu->AddItem(item); message = new BMessage(BROWSER_FIND_TEXT); item = make_menu_item("FindText", message); -- cgit v1.2.3 From 65bdef55ab12bf07aa52fb9c184c073cbf562e3b Mon Sep 17 00:00:00 2001 From: Vincent Sanders Date: Tue, 19 Jan 2016 15:10:29 +0000 Subject: move the container code to gtk directory as its only ever used there. --- gtk/Makefile.target | 5 +- gtk/scaffolding.c | 2 +- gtk/theme.c | 2 +- gtk/theme.h | 3 - gtk/theme_container.c | 765 ++++++++++++++++++++++++++++++++++++++++++++++++++ gtk/theme_container.h | 53 ++++ utils/container.c | 763 ------------------------------------------------- utils/container.h | 53 ---- 8 files changed, 822 insertions(+), 824 deletions(-) create mode 100644 gtk/theme_container.c create mode 100644 gtk/theme_container.h delete mode 100644 utils/container.c delete mode 100644 utils/container.h diff --git a/gtk/Makefile.target b/gtk/Makefile.target index 5efe65fd8..50d2a77fd 100644 --- a/gtk/Makefile.target +++ b/gtk/Makefile.target @@ -179,12 +179,11 @@ endif S_GTK := font_pango.c bitmap.c gui.c schedule.c plotters.c \ treeview.c scaffolding.c gdk.c completion.c login.c throbber.c \ selection.c history.c window.c fetch.c download.c menu.c \ - print.c search.c tabs.c theme.c toolbar.c gettext.c \ + print.c search.c tabs.c theme.c theme_container.c toolbar.c gettext.c \ compat.c cookies.c hotlist.c viewdata.c viewsource.c \ preferences.c about.c ssl_cert.c resources.c -S_GTK := $(addprefix gtk/,$(S_GTK)) $(addprefix utils/,container.c) -# code in utils/container.ch is non-universal it seems +S_GTK := $(addprefix gtk/,$(S_GTK)) # This is the final source build list # Note this is deliberately *not* expanded here as common and image diff --git a/gtk/scaffolding.c b/gtk/scaffolding.c index 19d5b2e15..a9a3d0589 100644 --- a/gtk/scaffolding.c +++ b/gtk/scaffolding.c @@ -62,12 +62,12 @@ #include "gtk/plotters.h" #include "gtk/print.h" #include "gtk/search.h" -#include "gtk/theme.h" #include "gtk/throbber.h" #include "gtk/toolbar.h" #include "gtk/window.h" #include "gtk/gdk.h" #include "gtk/scaffolding.h" +#include "gtk/theme.h" #include "gtk/tabs.h" #include "gtk/schedule.h" #include "gtk/viewdata.h" diff --git a/gtk/theme.c b/gtk/theme.c index eb43fc588..9baab13ed 100644 --- a/gtk/theme.c +++ b/gtk/theme.c @@ -24,7 +24,6 @@ #include "utils/config.h" #include "utils/nsoption.h" -#include "utils/container.h" #include "utils/log.h" #include "utils/messages.h" #include "utils/utils.h" @@ -39,6 +38,7 @@ #include "gtk/scaffolding.h" #include "gtk/menu.h" #include "gtk/theme.h" +#include "gtk/theme_container.h" #include "gtk/window.h" #include "gtk/preferences.h" diff --git a/gtk/theme.h b/gtk/theme.h index b3059ee93..32a7ffcdb 100644 --- a/gtk/theme.h +++ b/gtk/theme.h @@ -19,9 +19,6 @@ #ifndef _NETSURF_GTK_THEME_H_ #define _NETSURF_GTK_THEME_H_ -#include -#include "gtk/scaffolding.h" - typedef enum search_buttons { SEARCH_BACK_BUTTON = 0, SEARCH_FORWARD_BUTTON, diff --git a/gtk/theme_container.c b/gtk/theme_container.c new file mode 100644 index 000000000..3a86ea9d4 --- /dev/null +++ b/gtk/theme_container.c @@ -0,0 +1,765 @@ +/* + * Copyright 2006 Rob Kendrick + * + * 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 . + */ + +/* To build a stand-alone command-line utility to create and dismantal + * these theme files, build this thusly: + * + * gcc -I../ -DNSTHEME -o themetool container.c + * + * [needs a c99 compiler] + * + * then for instance to create a theme file called mythemefilename + * ./themetool --verbose --create -n"My theme name" mythemefilename\ + * --author "Myname" /path/to/directory/containing/theme/files/ + */ + +/** \file + * Container format handling for themes etc. */ + +#include +#include +#include +#include +#include +#include +#include + +#include "utils/config.h" +#include "utils/log.h" +#include "utils/messages.h" +#include "utils/utils.h" + +#include "gtk/theme_container.h" + +#ifdef WITH_MMAP +#include +#endif + +#ifdef NSTHEME +bool verbose_log = true; +#endif + +struct container_dirent { + unsigned char filename[64]; + u_int32_t startoffset; + u_int32_t len; + u_int32_t flags1; + u_int32_t flags2; +}; + +struct container_header { + u_int32_t magic; /* 0x4d54534e little endian */ + u_int32_t parser; + unsigned char name[32]; + unsigned char author[64]; + u_int32_t diroffset; +}; + +struct container_ctx { + FILE *fh; + bool creating; + bool processed; + struct container_header header; + unsigned int entries; + unsigned char *data; + struct container_dirent *directory; +}; + +inline static size_t container_filelen(FILE *fd) +{ + long o; + long a; + + o = ftell(fd); + if (o == -1) { + LOG("Could not get current stream position"); + return 0; + } + + if (fseek(fd, 0, SEEK_END) != 0) { + LOG("Could not get seek to end of file"); + return 0; + } + a = ftell(fd); + + if (fseek(fd, o, SEEK_SET) != 0) { + LOG("Could not reset seek position in file"); + return 0; + } + if (a == -1) { + LOG("could not ascertain size of file in theme container; omitting"); + return 0; + } + if (((unsigned long) a) > SIZE_MAX) { + LOG("overlarge file in theme container; possible truncation"); + return SIZE_MAX; + } + return (size_t) a; +} + +static void container_add_to_dir(struct container_ctx *ctx, + const unsigned char *entryname, + const u_int32_t offset, + const u_int32_t length) +{ + struct container_dirent *temp; + temp = realloc(ctx->directory, ctx->entries * + sizeof(struct container_dirent)); + if (temp == NULL) { + printf("error adding entry for %s to theme container\n", entryname); + return; + } + ctx->entries += 1; + ctx->directory = temp; + + snprintf((char*)ctx->directory[ctx->entries - 1].filename, + sizeof(ctx->directory[ctx->entries - 1].filename), + "%s", (char *)entryname); + + ctx->directory[ctx->entries - 1].startoffset = offset; + ctx->directory[ctx->entries - 1].len = length; + ctx->directory[ctx->entries - 1].flags1 = 0; + ctx->directory[ctx->entries - 1].flags2 = 0; +} + +struct container_ctx *container_open(const char *filename) +{ + size_t val; + struct container_ctx *ctx = calloc(sizeof(struct container_ctx), 1); + + ctx->fh = fopen(filename, "rb"); + + if (ctx->fh == NULL) { + free(ctx); + return NULL; + } + + /* we don't actually load any of the data (including directory) + * until we need to, such that _get_name and _get_author are as quick + * as possible. When we have, this gets set to true. + */ + ctx->processed = false; + + val = fread(&ctx->header.magic, 4, 1, ctx->fh); + if (val == 0) + LOG("empty read magic"); + ctx->header.magic = ntohl(ctx->header.magic); + + val = fread(&ctx->header.parser, 4, 1, ctx->fh); + if (val == 0) + LOG("empty read parser"); + ctx->header.parser = ntohl(ctx->header.parser); + + val = fread(ctx->header.name, 32, 1, ctx->fh); + if (val == 0) + LOG("empty read name"); + val = fread(ctx->header.author, 64, 1, ctx->fh); + if (val == 0) + LOG("empty read author"); + + val = fread(&ctx->header.diroffset, 4, 1, ctx->fh); + if (val == 0) + LOG("empty read diroffset"); + ctx->header.diroffset = ntohl(ctx->header.diroffset); + + if (ctx->header.magic != 0x4e53544d || ctx->header.parser != 3) { + fclose(ctx->fh); + free(ctx); + return NULL; + } + + return ctx; +} + +static void container_process(struct container_ctx *ctx) +{ + size_t val; + unsigned char filename[64]; + u_int32_t start, len, flags1, flags2; + +#ifdef WITH_MMAP + ctx->data = mmap(NULL, ctx->header.diroffset, PROT_READ, MAP_PRIVATE, + fileno(ctx->fh), 0); +#else + ctx->data = malloc(ctx->header.diroffset); + if (fseek(ctx->fh, 0, SEEK_SET) != 0) { + return; + } + val = fread(ctx->data, ctx->header.diroffset, 1, ctx->fh); + if (val == 0) + LOG("empty read diroffset"); +#endif + if (fseek(ctx->fh, ctx->header.diroffset, SEEK_SET) != 0) { + return; + } + /* now work through the directory structure taking it apart into + * our structure */ +#define BEREAD(x) do { val = fread(&(x), 4, 1, ctx->fh); if (val == 0)\ + LOG("empty read");(x) = ntohl((x)); } while (0) + do { + val = fread(filename, 64, 1, ctx->fh); + if (val == 0) + LOG("empty read filename"); + BEREAD(start); + BEREAD(len); + BEREAD(flags1); + BEREAD(flags2); + if (filename[0] != '\0') + container_add_to_dir(ctx, filename, start, len); + } while (filename[0] != '\0'); +#undef BEREAD + ctx->processed = true; +} + +static const struct container_dirent *container_lookup( + struct container_ctx *ctx, + const unsigned char *entryname) +{ + unsigned int i; + + for (i = 1; i <= ctx->entries; i++) { + struct container_dirent *e = ctx->directory + i - 1; + if (strcmp((char *)e->filename, (char *)entryname) == 0) + return e; + } + + return NULL; +} + +const unsigned char *container_get(struct container_ctx *ctx, + const unsigned char *entryname, + u_int32_t *size) +{ + const struct container_dirent *e; + + if (ctx->processed == false) + container_process(ctx); + + e = container_lookup(ctx, entryname); + + if (e == NULL) + return NULL; + + *size = e->len; + + return &ctx->data[e->startoffset]; +} + +const unsigned char *container_iterate(struct container_ctx *ctx, int *state) +{ + struct container_dirent *e; + unsigned char *r; + + if (ctx->processed == false) + container_process(ctx); + + e = ctx->directory + *state; + + r = e->filename; + + if (r == NULL || r[0] == '\0') + r = NULL; + + *state += 1; + + return r; +} + +const unsigned char *container_get_name(struct container_ctx *ctx) +{ + return ctx->header.name; +} + +const unsigned char *container_get_author(struct container_ctx *ctx) +{ + return ctx->header.author; +} + + +static void container_write_dir(struct container_ctx *ctx) +{ + size_t val; + unsigned int i; + u_int32_t tmp; +#define BEWRITE(x) do {tmp = htonl((x)); val = fwrite(&tmp, 4, 1, ctx->fh);\ + if (val == 0) LOG("empty write"); } while(0) + for (i = 1; i <= ctx->entries; i++) { + struct container_dirent *e = ctx->directory + i - 1; + val = fwrite(e->filename, 64, 1, ctx->fh); + if (val == 0) + LOG("empty write filename"); + BEWRITE(e->startoffset); + BEWRITE(e->len); + BEWRITE(e->flags1); + BEWRITE(e->flags2); + } +#undef BEWRITE + /* empty entry signifies end of directory */ + tmp = 0; + val = fwrite(&tmp, 4, 8, ctx->fh); + if (val == 0) + LOG("empty write end"); +} + +struct container_ctx *container_create(const char *filename, + const unsigned char *name, + const unsigned char *author) +{ + size_t val; + struct container_ctx *ctx = calloc(sizeof(struct container_ctx), 1); + + ctx->fh = fopen(filename, "wb"); + + if (ctx->fh == NULL) { + free(ctx); + return NULL; + } + + ctx->creating = true; + ctx->entries = 0; + ctx->directory = NULL; + ctx->header.parser = htonl(3); + + snprintf((char *)ctx->header.name, + sizeof(ctx->header.name), + "%s", (char *)name); + + snprintf((char *)ctx->header.author, + sizeof(ctx->header.author), + "%s", (char *)author); + + val = fwrite("NSTM", 4, 1, ctx->fh); + if (val == 0) + LOG("empty write NSTM"); + val = fwrite(&ctx->header.parser, 4, 1, ctx->fh); + if (val == 0) + LOG("empty write parser"); + val = fwrite(ctx->header.name, 32, 1, ctx->fh); + if (val == 0) + LOG("empty write name"); + val = fwrite(ctx->header.author, 64, 1, ctx->fh); + if (val == 0) + LOG("empty write author"); + + ctx->header.diroffset = 108; + + /* skip over the directory offset for now, and fill it in later. + * we don't know where it'll be yet! + */ + + if (fseek(ctx->fh, 108, SEEK_SET) == -1) { + LOG("directory offset seek failed"); + free(ctx); + return NULL; + } + + return ctx; +} + +void container_add(struct container_ctx *ctx, const unsigned char *entryname, + const unsigned char *data, + const u_int32_t datalen) +{ + size_t val; + container_add_to_dir(ctx, entryname, ftell(ctx->fh), datalen); + val = fwrite(data, datalen, 1, ctx->fh); + if (val == 0) + LOG("empty write add file"); +} + +void container_close(struct container_ctx *ctx) +{ + if (ctx->creating == true) { + size_t flen, nflen, val; + + /* discover where the directory's going to go. */ + flen = container_filelen(ctx->fh); + flen = (flen + 3) & (~3); /* round up to nearest 4 bytes */ + + /* write this location to the header */ + if (fseek(ctx->fh, 104, SEEK_SET) == 0) { + nflen = htonl(flen); + val = fwrite(&nflen, 4, 1, ctx->fh); + if (val == 0) + LOG("empty write directory location"); + + /* seek to where the directory will be, and write it */ + if (fseek(ctx->fh, flen, SEEK_SET) == 0) { + container_write_dir(ctx); + } + } + + } else if (ctx->processed) { +#ifdef WITH_MMAP + munmap(ctx->data, ctx->header.diroffset); +#else + free(ctx->data); +#endif + } + + fclose(ctx->fh); + free(ctx); +} + +#ifdef WITH_THEME_INSTALL + +/** + * install theme from container + * \param themefile a file containing the containerized theme + * \param dirbasename a directory basename including trailing path sep; the + * full path of the theme is then a subdirectory of that + * caller owns reference to returned string, NULL for error + */ + +char *container_extract_theme(const char *themefile, const char *dirbasename) +{ + struct stat statbuf; + struct container_ctx *cctx; + FILE *fh; + size_t val; + const unsigned char *e, *d; + char *themename, *dirname; + char path[PATH_MAX]; + int state = 0; + unsigned int i; + u_int32_t flen; + + cctx = container_open(themefile); + if (cctx == NULL) { + warn_user("FileOpenError", themefile); + return NULL; + } + themename = strdup((const char *)container_get_name(cctx)); + if (themename == NULL) { + warn_user("NoMemory", 0); + container_close(cctx); + return NULL; + } + LOG("theme name: %s", themename); + LOG("theme author: %s", container_get_author(cctx)); + + dirname = malloc(strlen(dirbasename) + strlen(themename) + 2); + if (dirname == NULL) { + warn_user(messages_get("NoMemory"), 0); + free(themename); + container_close(cctx); + return NULL; + } + strcpy(dirname, dirbasename); + strcat(dirname, themename); + if (stat(dirname, &statbuf) != -1) { + /* directory exists */ + warn_user("DirectoryError", dirname); + container_close(cctx); + free(dirname); + free(themename); + return NULL; + } + if (mkdir(dirname, S_IRWXU) != 0) { + warn_user("DirectoryError", dirname); + container_close(cctx); + free(dirname); + free(themename); + return NULL; + } + + for (e = container_iterate(cctx, &state), i = 0; i < cctx->entries; + e = container_iterate(cctx, &state), i++) { + LOG("extracting %s", e); + snprintf(path, PATH_MAX, "%s/%s", dirname, e); + fh = fopen(path, "wb"); + if (fh == NULL) { + warn_user("FileOpenError", (char *)e); + } else { + d = container_get(cctx, e, &flen); + val = fwrite(d, flen, 1, fh); + if (val == 0) + LOG("empty write"); + fclose(fh); + } + } + LOG("theme container unpacked"); + container_close(cctx); + free(dirname); + return themename; + +} + +#endif + +#ifdef TEST_RIG +int main(int argc, char *argv[]) +{ + struct container_ctx *ctx = container_create("test.theme", "Test theme", + "Rob Kendrick"); + u_int32_t size; + int state = 0; + char *n; + + container_add(ctx, "CHEESE", "This is a test of some cheese.", sizeof("This is a test of some cheese.")); + container_add(ctx, "FOO", "This is a test of some cheese.", sizeof("This is a test of some cheese.")); + + container_close(ctx); + + ctx = container_open("test.theme"); + + printf("Theme name: %s\n", container_get_name(ctx)); + printf("Theme author: %s\n", container_get_author(ctx)); + + printf("Test string: %s\n", container_get(ctx, "CHEESE", &size)); + printf("Length of text: %d\n", size); + + while ( (n = container_iterate(ctx, &state)) ) { + printf("%s\n", n); + } + + container_close(ctx); + + exit(0); +} +#endif + +#ifdef NSTHEME + /* code to implement a simple container creator/extractor */ +#include +#include +#include +#include + +static bool verbose = false; + +static void show_usage(const char *argv0) +{ + fprintf(stderr, "%s [options] \n", argv0); + fprintf(stderr, " --help This text\n"); + fprintf(stderr, " --create Create theme file from directory\n"); + fprintf(stderr, " --extract Extract theme file into directory\n"); + fprintf(stderr, " --name x Set theme's name when creating\n"); + fprintf(stderr, " --author x Set theme's author when creating\n"); + fprintf(stderr, " --verbose Print progress information\n"); + fprintf(stderr, "\nOne and only one of --create or --extract must be specified.\n"); +} + +static void extract_theme(const char *themefile, const char *dirname) +{ + struct stat statbuf; + struct container_ctx *cctx; + FILE *fh; + const unsigned char *e, *d; + char path[PATH_MAX]; + int i, state = 0; + u_int32_t flen; + + + if (stat(dirname, &statbuf) != -1) { + fprintf(stderr, "error: directory '%s' already exists.\n", + dirname); + exit(1); + } + + mkdir(dirname, S_IRWXU); + + cctx = container_open(themefile); + if (cctx == NULL) { + fprintf(stderr, "error: unable to open theme file '%s'\n", + themefile); + exit(1); + } + + if (verbose == true) { + printf("theme name: %s\n", container_get_name(cctx)); + printf("theme author: %s\n", container_get_author(cctx)); + } + + for (e = container_iterate(cctx, &state), i = 0; i < cctx->entries; + e = container_iterate(cctx, &state), i++) { + if (verbose == true) + printf("extracting %s\n", e); + snprintf(path, PATH_MAX, "%s/%s", dirname, e); + fh = fopen(path, "wb"); + if (fh == NULL) { + perror("warning: unable to open file for output"); + } else { + d = container_get(cctx, e, &flen); + fwrite(d, flen, 1, fh); + fclose(fh); + } + } + + container_close(cctx); + +} + +static void create_theme(const char *themefile, const char *dirname, + const unsigned char *name, + const unsigned char *author) +{ + DIR *dir = opendir(dirname); + FILE *fh; + struct dirent *e; + struct stat statbuf; + struct container_ctx *cctx; + unsigned char *data; + char path[PATH_MAX]; + size_t flen; + int t; + + if (dir == NULL) { + perror("error: unable to open directory"); + exit(1); + } + + cctx = container_create(themefile, name, author); + + errno = 0; /* to distinguish between end of dir and err */ + + while ((e = readdir(dir)) != NULL) { + if (strcmp(e->d_name, ".") != 0 && + strcmp(e->d_name, "..") != 0) { + /* not the metadirs, so we want to process this. */ + if (verbose == true) + printf("adding %s\n", e->d_name); + if (strlen(e->d_name) > 63) { + fprintf(stderr, + "warning: name truncated to length 63.\n"); + } + + snprintf(path, PATH_MAX, "%s/%s", dirname, e->d_name); + + stat(path, &statbuf); + if (S_ISDIR(statbuf.st_mode)) { + fprintf(stderr, + "warning: skipping directory '%s'\n", + e->d_name); + continue; + } + + fh = fopen(path, "rb"); + if (fh == NULL) { + fprintf(stderr, + "warning: unable to open, skipping."); + } else { + flen = statbuf.st_size; + data = malloc(flen); + t = fread(data, flen, 1, fh); + fclose(fh); + container_add(cctx, (unsigned char *)e->d_name, + data, flen); + free(data); + } + } + errno = 0; + } + + if (errno != 0) { + perror("error: couldn't enumerate directory"); + closedir(dir); + container_close(cctx); + exit(1); + } + + closedir(dir); + container_close(cctx); +} + +int main(int argc, char *argv[]) +{ + static struct option l_opts[] = { + { "help", 0, 0, 'h' }, + { "create", 0, 0, 'c' }, + { "extract", 0, 0, 'x' }, + { "name", 1, 0, 'n' }, + { "author", 1, 0, 'a' }, + { "verbose", 0, 0, 'v' }, + + { NULL, 0, 0, 0 } + }; + + static char *s_opts = "hcxn:a:v"; + int optch, optidx; + bool creating = false, extracting = false; + unsigned char name[32] = { '\0' }, author[64] = { '\0' }; + char *themefile, *dirname; + + while ((optch = getopt_long(argc, argv, s_opts, l_opts, &optidx)) != -1) + switch (optch) { + case 'h': + show_usage(argv[0]); + exit(0); + break; + case 'c': + creating = true; + break; + case 'x': + extracting = true; + break; + case 'n': + strncpy((char *)name, optarg, 31); + if (strlen(optarg) > 32) + fprintf(stderr, "warning: theme name truncated to 32 characters.\n"); + break; + case 'a': + strncpy((char *)author, optarg, 63); + if (strlen(optarg) > 64) + fprintf(stderr, "warning: theme author truncated to 64 characters.\n"); + break; + case 'v': + verbose = true; + break; + default: + show_usage(argv[0]); + exit(1); + break; + } + + if (creating == extracting) { + show_usage(argv[0]); + exit(1); + } + + if ((argc - optind) < 2) { + show_usage(argv[0]); + exit(1); + } + + if (creating == true && + (strlen((char *)name) == 0 || strlen((char *)author) == 0)) { + fprintf(stderr, "No theme name and/or author specified.\n"); + show_usage(argv[0]); + exit(1); + } + + themefile = strdup(argv[optind]); + dirname = strdup(argv[optind + 1]); + + if (verbose == true) + printf("%s '%s' %s directory '%s'\n", + creating ? "creating" : "extracting", themefile, + creating ? "from" : "to", dirname); + + if (creating) { + if (verbose == true) + printf("name = %s, author = %s\n", name, author); + create_theme(themefile, dirname, name, author); + } else { + extract_theme(themefile, dirname); + } + + return 0; +} +#endif diff --git a/gtk/theme_container.h b/gtk/theme_container.h new file mode 100644 index 000000000..de880ecd5 --- /dev/null +++ b/gtk/theme_container.h @@ -0,0 +1,53 @@ +/* + * Copyright 2006 Rob Kendrick + * + * 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 . + */ + +/** \file + * Container format handling for themes etc. */ + +#ifndef __CONTAINER_H__ +#define __CONTAINER_H__ + +#include + +struct container_ctx; + +/* reading interface */ +struct container_ctx *container_open(const char *filename); +const unsigned char *container_get(struct container_ctx *ctx, + const unsigned char *entryname, + u_int32_t *size); +const unsigned char *container_get_name(struct container_ctx *ctx); +const unsigned char *container_get_author(struct container_ctx *ctx); +const unsigned char *container_iterate(struct container_ctx *ctx, + int *state); + +/* creating interface */ +struct container_ctx *container_create(const char *filename, + const unsigned char *name, + const unsigned char *author); +void container_add(struct container_ctx *ctx, const unsigned char *entryname, + const unsigned char *data, + const u_int32_t datalen); + +/* common interface */ +void container_close(struct container_ctx *ctx); + +#ifdef WITH_THEME_INSTALL +char *container_extract_theme(const char *themefile, const char *dirbasename); +#endif +#endif /* __CONTAINER_H__ */ diff --git a/utils/container.c b/utils/container.c deleted file mode 100644 index 68ea32211..000000000 --- a/utils/container.c +++ /dev/null @@ -1,763 +0,0 @@ -/* - * Copyright 2006 Rob Kendrick - * - * 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 . - */ - -/* To build a stand-alone command-line utility to create and dismantal - * these theme files, build this thusly: - * - * gcc -I../ -DNSTHEME -o themetool container.c - * - * [needs a c99 compiler] - * - * then for instance to create a theme file called mythemefilename - * ./themetool --verbose --create -n"My theme name" mythemefilename\ - * --author "Myname" /path/to/directory/containing/theme/files/ - */ - -/** \file - * Container format handling for themes etc. */ - -#include -#include -#include -#include -#include -#include -#include -#include "utils/config.h" -#include "utils/container.h" -#include "utils/log.h" -#include "utils/messages.h" -#include "utils/utils.h" - -#ifdef WITH_MMAP -#include -#endif - -#ifdef NSTHEME -bool verbose_log = true; -#endif - -struct container_dirent { - unsigned char filename[64]; - u_int32_t startoffset; - u_int32_t len; - u_int32_t flags1; - u_int32_t flags2; -}; - -struct container_header { - u_int32_t magic; /* 0x4d54534e little endian */ - u_int32_t parser; - unsigned char name[32]; - unsigned char author[64]; - u_int32_t diroffset; -}; - -struct container_ctx { - FILE *fh; - bool creating; - bool processed; - struct container_header header; - unsigned int entries; - unsigned char *data; - struct container_dirent *directory; -}; - -inline static size_t container_filelen(FILE *fd) -{ - long o; - long a; - - o = ftell(fd); - if (o == -1) { - LOG("Could not get current stream position"); - return 0; - } - - if (fseek(fd, 0, SEEK_END) != 0) { - LOG("Could not get seek to end of file"); - return 0; - } - a = ftell(fd); - - if (fseek(fd, o, SEEK_SET) != 0) { - LOG("Could not reset seek position in file"); - return 0; - } - if (a == -1) { - LOG("could not ascertain size of file in theme container; omitting"); - return 0; - } - if (((unsigned long) a) > SIZE_MAX) { - LOG("overlarge file in theme container; possible truncation"); - return SIZE_MAX; - } - return (size_t) a; -} - -static void container_add_to_dir(struct container_ctx *ctx, - const unsigned char *entryname, - const u_int32_t offset, - const u_int32_t length) -{ - struct container_dirent *temp; - temp = realloc(ctx->directory, ctx->entries * - sizeof(struct container_dirent)); - if (temp == NULL) { - printf("error adding entry for %s to theme container\n", entryname); - return; - } - ctx->entries += 1; - ctx->directory = temp; - - snprintf((char*)ctx->directory[ctx->entries - 1].filename, - sizeof(ctx->directory[ctx->entries - 1].filename), - "%s", (char *)entryname); - - ctx->directory[ctx->entries - 1].startoffset = offset; - ctx->directory[ctx->entries - 1].len = length; - ctx->directory[ctx->entries - 1].flags1 = 0; - ctx->directory[ctx->entries - 1].flags2 = 0; -} - -struct container_ctx *container_open(const char *filename) -{ - size_t val; - struct container_ctx *ctx = calloc(sizeof(struct container_ctx), 1); - - ctx->fh = fopen(filename, "rb"); - - if (ctx->fh == NULL) { - free(ctx); - return NULL; - } - - /* we don't actually load any of the data (including directory) - * until we need to, such that _get_name and _get_author are as quick - * as possible. When we have, this gets set to true. - */ - ctx->processed = false; - - val = fread(&ctx->header.magic, 4, 1, ctx->fh); - if (val == 0) - LOG("empty read magic"); - ctx->header.magic = ntohl(ctx->header.magic); - - val = fread(&ctx->header.parser, 4, 1, ctx->fh); - if (val == 0) - LOG("empty read parser"); - ctx->header.parser = ntohl(ctx->header.parser); - - val = fread(ctx->header.name, 32, 1, ctx->fh); - if (val == 0) - LOG("empty read name"); - val = fread(ctx->header.author, 64, 1, ctx->fh); - if (val == 0) - LOG("empty read author"); - - val = fread(&ctx->header.diroffset, 4, 1, ctx->fh); - if (val == 0) - LOG("empty read diroffset"); - ctx->header.diroffset = ntohl(ctx->header.diroffset); - - if (ctx->header.magic != 0x4e53544d || ctx->header.parser != 3) { - fclose(ctx->fh); - free(ctx); - return NULL; - } - - return ctx; -} - -static void container_process(struct container_ctx *ctx) -{ - size_t val; - unsigned char filename[64]; - u_int32_t start, len, flags1, flags2; - -#ifdef WITH_MMAP - ctx->data = mmap(NULL, ctx->header.diroffset, PROT_READ, MAP_PRIVATE, - fileno(ctx->fh), 0); -#else - ctx->data = malloc(ctx->header.diroffset); - if (fseek(ctx->fh, 0, SEEK_SET) != 0) { - return; - } - val = fread(ctx->data, ctx->header.diroffset, 1, ctx->fh); - if (val == 0) - LOG("empty read diroffset"); -#endif - if (fseek(ctx->fh, ctx->header.diroffset, SEEK_SET) != 0) { - return; - } - /* now work through the directory structure taking it apart into - * our structure */ -#define BEREAD(x) do { val = fread(&(x), 4, 1, ctx->fh); if (val == 0)\ - LOG("empty read");(x) = ntohl((x)); } while (0) - do { - val = fread(filename, 64, 1, ctx->fh); - if (val == 0) - LOG("empty read filename"); - BEREAD(start); - BEREAD(len); - BEREAD(flags1); - BEREAD(flags2); - if (filename[0] != '\0') - container_add_to_dir(ctx, filename, start, len); - } while (filename[0] != '\0'); -#undef BEREAD - ctx->processed = true; -} - -static const struct container_dirent *container_lookup( - struct container_ctx *ctx, - const unsigned char *entryname) -{ - unsigned int i; - - for (i = 1; i <= ctx->entries; i++) { - struct container_dirent *e = ctx->directory + i - 1; - if (strcmp((char *)e->filename, (char *)entryname) == 0) - return e; - } - - return NULL; -} - -const unsigned char *container_get(struct container_ctx *ctx, - const unsigned char *entryname, - u_int32_t *size) -{ - const struct container_dirent *e; - - if (ctx->processed == false) - container_process(ctx); - - e = container_lookup(ctx, entryname); - - if (e == NULL) - return NULL; - - *size = e->len; - - return &ctx->data[e->startoffset]; -} - -const unsigned char *container_iterate(struct container_ctx *ctx, int *state) -{ - struct container_dirent *e; - unsigned char *r; - - if (ctx->processed == false) - container_process(ctx); - - e = ctx->directory + *state; - - r = e->filename; - - if (r == NULL || r[0] == '\0') - r = NULL; - - *state += 1; - - return r; -} - -const unsigned char *container_get_name(struct container_ctx *ctx) -{ - return ctx->header.name; -} - -const unsigned char *container_get_author(struct container_ctx *ctx) -{ - return ctx->header.author; -} - - -static void container_write_dir(struct container_ctx *ctx) -{ - size_t val; - unsigned int i; - u_int32_t tmp; -#define BEWRITE(x) do {tmp = htonl((x)); val = fwrite(&tmp, 4, 1, ctx->fh);\ - if (val == 0) LOG("empty write"); } while(0) - for (i = 1; i <= ctx->entries; i++) { - struct container_dirent *e = ctx->directory + i - 1; - val = fwrite(e->filename, 64, 1, ctx->fh); - if (val == 0) - LOG("empty write filename"); - BEWRITE(e->startoffset); - BEWRITE(e->len); - BEWRITE(e->flags1); - BEWRITE(e->flags2); - } -#undef BEWRITE - /* empty entry signifies end of directory */ - tmp = 0; - val = fwrite(&tmp, 4, 8, ctx->fh); - if (val == 0) - LOG("empty write end"); -} - -struct container_ctx *container_create(const char *filename, - const unsigned char *name, - const unsigned char *author) -{ - size_t val; - struct container_ctx *ctx = calloc(sizeof(struct container_ctx), 1); - - ctx->fh = fopen(filename, "wb"); - - if (ctx->fh == NULL) { - free(ctx); - return NULL; - } - - ctx->creating = true; - ctx->entries = 0; - ctx->directory = NULL; - ctx->header.parser = htonl(3); - - snprintf((char *)ctx->header.name, - sizeof(ctx->header.name), - "%s", (char *)name); - - snprintf((char *)ctx->header.author, - sizeof(ctx->header.author), - "%s", (char *)author); - - val = fwrite("NSTM", 4, 1, ctx->fh); - if (val == 0) - LOG("empty write NSTM"); - val = fwrite(&ctx->header.parser, 4, 1, ctx->fh); - if (val == 0) - LOG("empty write parser"); - val = fwrite(ctx->header.name, 32, 1, ctx->fh); - if (val == 0) - LOG("empty write name"); - val = fwrite(ctx->header.author, 64, 1, ctx->fh); - if (val == 0) - LOG("empty write author"); - - ctx->header.diroffset = 108; - - /* skip over the directory offset for now, and fill it in later. - * we don't know where it'll be yet! - */ - - if (fseek(ctx->fh, 108, SEEK_SET) == -1) { - LOG("directory offset seek failed"); - free(ctx); - return NULL; - } - - return ctx; -} - -void container_add(struct container_ctx *ctx, const unsigned char *entryname, - const unsigned char *data, - const u_int32_t datalen) -{ - size_t val; - container_add_to_dir(ctx, entryname, ftell(ctx->fh), datalen); - val = fwrite(data, datalen, 1, ctx->fh); - if (val == 0) - LOG("empty write add file"); -} - -void container_close(struct container_ctx *ctx) -{ - if (ctx->creating == true) { - size_t flen, nflen, val; - - /* discover where the directory's going to go. */ - flen = container_filelen(ctx->fh); - flen = (flen + 3) & (~3); /* round up to nearest 4 bytes */ - - /* write this location to the header */ - if (fseek(ctx->fh, 104, SEEK_SET) == 0) { - nflen = htonl(flen); - val = fwrite(&nflen, 4, 1, ctx->fh); - if (val == 0) - LOG("empty write directory location"); - - /* seek to where the directory will be, and write it */ - if (fseek(ctx->fh, flen, SEEK_SET) == 0) { - container_write_dir(ctx); - } - } - - } else if (ctx->processed) { -#ifdef WITH_MMAP - munmap(ctx->data, ctx->header.diroffset); -#else - free(ctx->data); -#endif - } - - fclose(ctx->fh); - free(ctx); -} - -#ifdef WITH_THEME_INSTALL - -/** - * install theme from container - * \param themefile a file containing the containerized theme - * \param dirbasename a directory basename including trailing path sep; the - * full path of the theme is then a subdirectory of that - * caller owns reference to returned string, NULL for error - */ - -char *container_extract_theme(const char *themefile, const char *dirbasename) -{ - struct stat statbuf; - struct container_ctx *cctx; - FILE *fh; - size_t val; - const unsigned char *e, *d; - char *themename, *dirname; - char path[PATH_MAX]; - int state = 0; - unsigned int i; - u_int32_t flen; - - cctx = container_open(themefile); - if (cctx == NULL) { - warn_user("FileOpenError", themefile); - return NULL; - } - themename = strdup((const char *)container_get_name(cctx)); - if (themename == NULL) { - warn_user("NoMemory", 0); - container_close(cctx); - return NULL; - } - LOG("theme name: %s", themename); - LOG("theme author: %s", container_get_author(cctx)); - - dirname = malloc(strlen(dirbasename) + strlen(themename) + 2); - if (dirname == NULL) { - warn_user(messages_get("NoMemory"), 0); - free(themename); - container_close(cctx); - return NULL; - } - strcpy(dirname, dirbasename); - strcat(dirname, themename); - if (stat(dirname, &statbuf) != -1) { - /* directory exists */ - warn_user("DirectoryError", dirname); - container_close(cctx); - free(dirname); - free(themename); - return NULL; - } - if (mkdir(dirname, S_IRWXU) != 0) { - warn_user("DirectoryError", dirname); - container_close(cctx); - free(dirname); - free(themename); - return NULL; - } - - for (e = container_iterate(cctx, &state), i = 0; i < cctx->entries; - e = container_iterate(cctx, &state), i++) { - LOG("extracting %s", e); - snprintf(path, PATH_MAX, "%s/%s", dirname, e); - fh = fopen(path, "wb"); - if (fh == NULL) { - warn_user("FileOpenError", (char *)e); - } else { - d = container_get(cctx, e, &flen); - val = fwrite(d, flen, 1, fh); - if (val == 0) - LOG("empty write"); - fclose(fh); - } - } - LOG("theme container unpacked"); - container_close(cctx); - free(dirname); - return themename; - -} - -#endif - -#ifdef TEST_RIG -int main(int argc, char *argv[]) -{ - struct container_ctx *ctx = container_create("test.theme", "Test theme", - "Rob Kendrick"); - u_int32_t size; - int state = 0; - char *n; - - container_add(ctx, "CHEESE", "This is a test of some cheese.", sizeof("This is a test of some cheese.")); - container_add(ctx, "FOO", "This is a test of some cheese.", sizeof("This is a test of some cheese.")); - - container_close(ctx); - - ctx = container_open("test.theme"); - - printf("Theme name: %s\n", container_get_name(ctx)); - printf("Theme author: %s\n", container_get_author(ctx)); - - printf("Test string: %s\n", container_get(ctx, "CHEESE", &size)); - printf("Length of text: %d\n", size); - - while ( (n = container_iterate(ctx, &state)) ) { - printf("%s\n", n); - } - - container_close(ctx); - - exit(0); -} -#endif - -#ifdef NSTHEME - /* code to implement a simple container creator/extractor */ -#include -#include -#include -#include - -static bool verbose = false; - -static void show_usage(const char *argv0) -{ - fprintf(stderr, "%s [options] \n", argv0); - fprintf(stderr, " --help This text\n"); - fprintf(stderr, " --create Create theme file from directory\n"); - fprintf(stderr, " --extract Extract theme file into directory\n"); - fprintf(stderr, " --name x Set theme's name when creating\n"); - fprintf(stderr, " --author x Set theme's author when creating\n"); - fprintf(stderr, " --verbose Print progress information\n"); - fprintf(stderr, "\nOne and only one of --create or --extract must be specified.\n"); -} - -static void extract_theme(const char *themefile, const char *dirname) -{ - struct stat statbuf; - struct container_ctx *cctx; - FILE *fh; - const unsigned char *e, *d; - char path[PATH_MAX]; - int i, state = 0; - u_int32_t flen; - - - if (stat(dirname, &statbuf) != -1) { - fprintf(stderr, "error: directory '%s' already exists.\n", - dirname); - exit(1); - } - - mkdir(dirname, S_IRWXU); - - cctx = container_open(themefile); - if (cctx == NULL) { - fprintf(stderr, "error: unable to open theme file '%s'\n", - themefile); - exit(1); - } - - if (verbose == true) { - printf("theme name: %s\n", container_get_name(cctx)); - printf("theme author: %s\n", container_get_author(cctx)); - } - - for (e = container_iterate(cctx, &state), i = 0; i < cctx->entries; - e = container_iterate(cctx, &state), i++) { - if (verbose == true) - printf("extracting %s\n", e); - snprintf(path, PATH_MAX, "%s/%s", dirname, e); - fh = fopen(path, "wb"); - if (fh == NULL) { - perror("warning: unable to open file for output"); - } else { - d = container_get(cctx, e, &flen); - fwrite(d, flen, 1, fh); - fclose(fh); - } - } - - container_close(cctx); - -} - -static void create_theme(const char *themefile, const char *dirname, - const unsigned char *name, - const unsigned char *author) -{ - DIR *dir = opendir(dirname); - FILE *fh; - struct dirent *e; - struct stat statbuf; - struct container_ctx *cctx; - unsigned char *data; - char path[PATH_MAX]; - size_t flen; - int t; - - if (dir == NULL) { - perror("error: unable to open directory"); - exit(1); - } - - cctx = container_create(themefile, name, author); - - errno = 0; /* to distinguish between end of dir and err */ - - while ((e = readdir(dir)) != NULL) { - if (strcmp(e->d_name, ".") != 0 && - strcmp(e->d_name, "..") != 0) { - /* not the metadirs, so we want to process this. */ - if (verbose == true) - printf("adding %s\n", e->d_name); - if (strlen(e->d_name) > 63) { - fprintf(stderr, - "warning: name truncated to length 63.\n"); - } - - snprintf(path, PATH_MAX, "%s/%s", dirname, e->d_name); - - stat(path, &statbuf); - if (S_ISDIR(statbuf.st_mode)) { - fprintf(stderr, - "warning: skipping directory '%s'\n", - e->d_name); - continue; - } - - fh = fopen(path, "rb"); - if (fh == NULL) { - fprintf(stderr, - "warning: unable to open, skipping."); - } else { - flen = statbuf.st_size; - data = malloc(flen); - t = fread(data, flen, 1, fh); - fclose(fh); - container_add(cctx, (unsigned char *)e->d_name, - data, flen); - free(data); - } - } - errno = 0; - } - - if (errno != 0) { - perror("error: couldn't enumerate directory"); - closedir(dir); - container_close(cctx); - exit(1); - } - - closedir(dir); - container_close(cctx); -} - -int main(int argc, char *argv[]) -{ - static struct option l_opts[] = { - { "help", 0, 0, 'h' }, - { "create", 0, 0, 'c' }, - { "extract", 0, 0, 'x' }, - { "name", 1, 0, 'n' }, - { "author", 1, 0, 'a' }, - { "verbose", 0, 0, 'v' }, - - { NULL, 0, 0, 0 } - }; - - static char *s_opts = "hcxn:a:v"; - int optch, optidx; - bool creating = false, extracting = false; - unsigned char name[32] = { '\0' }, author[64] = { '\0' }; - char *themefile, *dirname; - - while ((optch = getopt_long(argc, argv, s_opts, l_opts, &optidx)) != -1) - switch (optch) { - case 'h': - show_usage(argv[0]); - exit(0); - break; - case 'c': - creating = true; - break; - case 'x': - extracting = true; - break; - case 'n': - strncpy((char *)name, optarg, 31); - if (strlen(optarg) > 32) - fprintf(stderr, "warning: theme name truncated to 32 characters.\n"); - break; - case 'a': - strncpy((char *)author, optarg, 63); - if (strlen(optarg) > 64) - fprintf(stderr, "warning: theme author truncated to 64 characters.\n"); - break; - case 'v': - verbose = true; - break; - default: - show_usage(argv[0]); - exit(1); - break; - } - - if (creating == extracting) { - show_usage(argv[0]); - exit(1); - } - - if ((argc - optind) < 2) { - show_usage(argv[0]); - exit(1); - } - - if (creating == true && - (strlen((char *)name) == 0 || strlen((char *)author) == 0)) { - fprintf(stderr, "No theme name and/or author specified.\n"); - show_usage(argv[0]); - exit(1); - } - - themefile = strdup(argv[optind]); - dirname = strdup(argv[optind + 1]); - - if (verbose == true) - printf("%s '%s' %s directory '%s'\n", - creating ? "creating" : "extracting", themefile, - creating ? "from" : "to", dirname); - - if (creating) { - if (verbose == true) - printf("name = %s, author = %s\n", name, author); - create_theme(themefile, dirname, name, author); - } else { - extract_theme(themefile, dirname); - } - - return 0; -} -#endif diff --git a/utils/container.h b/utils/container.h deleted file mode 100644 index de880ecd5..000000000 --- a/utils/container.h +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright 2006 Rob Kendrick - * - * 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 . - */ - -/** \file - * Container format handling for themes etc. */ - -#ifndef __CONTAINER_H__ -#define __CONTAINER_H__ - -#include - -struct container_ctx; - -/* reading interface */ -struct container_ctx *container_open(const char *filename); -const unsigned char *container_get(struct container_ctx *ctx, - const unsigned char *entryname, - u_int32_t *size); -const unsigned char *container_get_name(struct container_ctx *ctx); -const unsigned char *container_get_author(struct container_ctx *ctx); -const unsigned char *container_iterate(struct container_ctx *ctx, - int *state); - -/* creating interface */ -struct container_ctx *container_create(const char *filename, - const unsigned char *name, - const unsigned char *author); -void container_add(struct container_ctx *ctx, const unsigned char *entryname, - const unsigned char *data, - const u_int32_t datalen); - -/* common interface */ -void container_close(struct container_ctx *ctx); - -#ifdef WITH_THEME_INSTALL -char *container_extract_theme(const char *themefile, const char *dirbasename); -#endif -#endif /* __CONTAINER_H__ */ -- cgit v1.2.3 From 7caaa86d75b308a100daa68184367dba581cc34b Mon Sep 17 00:00:00 2001 From: Vincent Sanders Date: Tue, 19 Jan 2016 15:16:32 +0000 Subject: fix haiku web search bar initalisation --- beos/scaffolding.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/beos/scaffolding.cpp b/beos/scaffolding.cpp index 3205866f8..f3f49c62c 100644 --- a/beos/scaffolding.cpp +++ b/beos/scaffolding.cpp @@ -1095,7 +1095,7 @@ void nsbeos_scaffolding_dispatch_event(nsbeos_scaffolding *scaffold, BMessage *m char t[PATH_MAX]; find_resource(t,"SearchEngines","./beos/res/SearchEngines"); - search_web_init(); + search_web_init(&t[0]); ret = search_web_omni(text.String(),SEARCH_WEB_OMNI_SEARCHONLY ,&url); -- cgit v1.2.3 From 54c153246ca76bdd3acb7667fe1106f04a0a9856 Mon Sep 17 00:00:00 2001 From: Vincent Sanders Date: Tue, 19 Jan 2016 15:31:56 +0000 Subject: fix call to cookie manager initialisation for haiku --- beos/scaffolding.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/beos/scaffolding.cpp b/beos/scaffolding.cpp index f3f49c62c..42e10b5df 100644 --- a/beos/scaffolding.cpp +++ b/beos/scaffolding.cpp @@ -1193,12 +1193,12 @@ void nsbeos_scaffolding_dispatch_event(nsbeos_scaffolding *scaffold, BMessage *m break; case COOKIES_SHOW: { - nsbeos_cookie_init(); + nsbeos_cookies_init(); break; } case COOKIES_DELETE: { - nsbeos_cookie_init(); + nsbeos_cookies_init(); break; } case BROWSER_PAGE: -- cgit v1.2.3 From 018adc2f5e332609dfbd71b4c29951dd80f9f67e Mon Sep 17 00:00:00 2001 From: Michael Drake Date: Wed, 20 Jan 2016 18:27:15 +0000 Subject: Remove redundant condition in white hot path. --- render/layout.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/render/layout.c b/render/layout.c index 7905eabb7..008be2426 100644 --- a/render/layout.c +++ b/render/layout.c @@ -2071,7 +2071,7 @@ void find_sides(struct box *fl, int y0, int y1, *x0 = fx1; *left = fl; } - } else if (fl->type == BOX_FLOAT_RIGHT) { + } else { fx0 = fl->x; if (fx0 < *x1) { *x1 = fx0; -- cgit v1.2.3 From 38e6fd1b74f2bc6677398d5167aff68bf163a286 Mon Sep 17 00:00:00 2001 From: Michael Drake Date: Wed, 20 Jan 2016 18:38:04 +0000 Subject: Split adding float to a container out into separate function. --- render/layout.c | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/render/layout.c b/render/layout.c index 008be2426..4381f296c 100644 --- a/render/layout.c +++ b/render/layout.c @@ -2087,6 +2087,19 @@ void find_sides(struct box *fl, int y0, int y1, } +/** + * Insert a float into a container. + * + * \param cont block formatting context block, used to contain float + * \param b box to add to float + */ +static void add_float_to_container(struct box *cont, struct box *b) +{ + b->next_float = cont->float_children; + cont->float_children = b; +} + + /** * Layout lines of text or inline boxes with floats. * @@ -2787,16 +2800,7 @@ bool layout_line(struct box *first, int *width, int *y, else right = b; } - if (cont->float_children == b) { -#ifdef LAYOUT_DEBUG - LOG("float %p already placed", b); -#endif - - box_dump(stderr, cont, 0, true); - assert(0); - } - b->next_float = cont->float_children; - cont->float_children = b; + add_float_to_container(cont, b); split_box = 0; } -- cgit v1.2.3 From 948a93041dba3ec95dbb04bee523a9bbd4ca9918 Mon Sep 17 00:00:00 2001 From: Michael Drake Date: Wed, 20 Jan 2016 18:40:38 +0000 Subject: Sort float_children of containers by their bottom edge. --- render/layout.c | 29 +++++++++++++++++++++++++++-- 1 file changed, 27 insertions(+), 2 deletions(-) diff --git a/render/layout.c b/render/layout.c index 4381f296c..f1e321e7f 100644 --- a/render/layout.c +++ b/render/layout.c @@ -2092,11 +2092,36 @@ void find_sides(struct box *fl, int y0, int y1, * * \param cont block formatting context block, used to contain float * \param b box to add to float + * + * This sorts floats in order of descending bottom edges. */ static void add_float_to_container(struct box *cont, struct box *b) { - b->next_float = cont->float_children; - cont->float_children = b; + struct box *box = cont->float_children; + int b_bottom = b->y + b->height; + + assert(b->type == BOX_FLOAT_LEFT || b->type == BOX_FLOAT_RIGHT); + + if (box == NULL) { + /* No other float children */ + b->next_float = NULL; + cont->float_children = b; + return; + } else if (b_bottom >= box->y + box->height) { + /* Goes at start of list */ + b->next_float = cont->float_children; + cont->float_children = b; + } else { + struct box *prev = NULL; + while (box != NULL && b_bottom < box->y + box->height) { + prev = box; + box = box->next_float; + } + if (prev != NULL) { + b->next_float = prev->next_float; + prev->next_float = b; + } + } } -- cgit v1.2.3 From c13080d96c41f42ce58b063a7883cac191d6c64b Mon Sep 17 00:00:00 2001 From: Michael Drake Date: Wed, 20 Jan 2016 18:42:30 +0000 Subject: Optimise white hot find_sides to take advantage of sorted float_children. Now we have an early exit when we get to the floats above the area we're interested in. --- render/layout.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/render/layout.c b/render/layout.c index f1e321e7f..95f3681aa 100644 --- a/render/layout.c +++ b/render/layout.c @@ -2062,8 +2062,14 @@ void find_sides(struct box *fl, int y0, int y1, *left = *right = 0; for (; fl; fl = fl->next_float) { - fy0 = fl->y; fy1 = fl->y + fl->height; + if (fy1 < y0) { + /* Floats are sorted in order of decreasing bottom pos. + * Past here, all floats will be too high to concern us. + */ + return; + } + fy0 = fl->y; if (y0 < fy1 && fy0 <= y1) { if (fl->type == BOX_FLOAT_LEFT) { fx1 = fl->x + fl->width; -- cgit v1.2.3 From 0bbc03c5776fdcf6006bb0447341f82967d2b5d1 Mon Sep 17 00:00:00 2001 From: Michael Drake Date: Wed, 20 Jan 2016 19:24:12 +0000 Subject: Cache place below level, to avoid pointless calls to find_sides. --- render/box.c | 1 + render/box.h | 3 +++ render/layout.c | 9 ++++++++- 3 files changed, 12 insertions(+), 1 deletion(-) diff --git a/render/box.c b/render/box.c index 0d92b594c..7111f1a6e 100644 --- a/render/box.c +++ b/render/box.c @@ -156,6 +156,7 @@ struct box * box_create(css_select_results *styles, css_computed_style *style, box->float_children = NULL; box->float_container = NULL; box->next_float = NULL; + box->cached_place_below_level = 0; box->list_marker = NULL; box->col = NULL; box->gadget = NULL; diff --git a/render/box.h b/render/box.h index 8e5aef8f5..5501f88c8 100644 --- a/render/box.h +++ b/render/box.h @@ -244,6 +244,9 @@ struct box { * This is used only for boxes with float_children */ int clear_level; + /* Level below which floats have been placed. */ + int cached_place_below_level; + /** List marker box if this is a list-item, or 0. */ struct box *list_marker; diff --git a/render/layout.c b/render/layout.c index 95f3681aa..f069cd665 100644 --- a/render/layout.c +++ b/render/layout.c @@ -227,6 +227,7 @@ bool layout_block_context(struct box *block, int viewport_height, assert(block->width != AUTO); block->float_children = NULL; + block->cached_place_below_level = 0; block->clear_level = 0; /* special case if the block contains an object */ @@ -2737,6 +2738,7 @@ bool layout_line(struct box *first, int *width, int *y, d = b->children; d->float_children = 0; + d->cached_place_below_level = 0; b->float_container = d->float_container = cont; if (!layout_float(d, *width, content)) @@ -3439,10 +3441,13 @@ bool layout_float(struct box *b, int width, html_content *content) void place_float_below(struct box *c, int width, int cx, int y, struct box *cont) { - int x0, x1, yy = y; + int x0, x1, yy; struct box *left; struct box *right; + yy = y > cont->cached_place_below_level ? + y : cont->cached_place_below_level; + #ifdef LAYOUT_DEBUG LOG("c %p, width %i, cx %i, y %i, cont %p", c, width, cx, y, cont); #endif @@ -3471,6 +3476,7 @@ void place_float_below(struct box *c, int width, int cx, int y, c->x = x1 - c->width; } c->y = y; + cont->cached_place_below_level = y; } @@ -3864,6 +3870,7 @@ bool layout_table(struct box *table, int available_width, c->padding[RIGHT] - c->border[RIGHT].width; c->float_children = 0; + c->cached_place_below_level = 0; c->height = AUTO; if (!layout_block_context(c, -1, content)) { -- cgit v1.2.3 From a774e9473df785f77e86e69a7d450324a2aa03a3 Mon Sep 17 00:00:00 2001 From: Michael Drake Date: Wed, 20 Jan 2016 22:37:22 +0000 Subject: Make use of cached place float below value earlier. --- render/layout.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/render/layout.c b/render/layout.c index f069cd665..b7d9e2034 100644 --- a/render/layout.c +++ b/render/layout.c @@ -2775,7 +2775,8 @@ bool layout_line(struct box *first, int *width, int *y, left == 0 && right == 0)) && (!place_below || (left == 0 && right == 0 && x == 0)) && - cy >= cont->clear_level) { + cy >= cont->clear_level && + cy >= cont->cached_place_below_level) { /* + not cleared or, * cleared and there are no floats to clear * + fits without needing to be placed below or, @@ -2800,6 +2801,9 @@ bool layout_line(struct box *first, int *width, int *y, /* place below into next available space */ int fcy = (cy > cont->clear_level) ? cy : cont->clear_level; + fcy = (fcy > cont->cached_place_below_level) ? + fcy : + cont->cached_place_below_level; fy = (fy > fcy) ? fy : fcy; fy = (fy == cy) ? fy + height : fy; -- cgit v1.2.3 From 750677795ba1ca41627edd68a4de24e0d6c07a20 Mon Sep 17 00:00:00 2001 From: Chris Young Date: Wed, 20 Jan 2016 22:51:05 +0000 Subject: Alloc font name on the stack --- amiga/font_diskfont.c | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/amiga/font_diskfont.c b/amiga/font_diskfont.c index 7b8819969..bd1e1f9d0 100644 --- a/amiga/font_diskfont.c +++ b/amiga/font_diskfont.c @@ -35,11 +35,14 @@ #include "amiga/gui.h" #include "amiga/utf8.h" +#define MAX_FONT_NAME_SIZE 33 + static struct TextFont *ami_font_bm_open(struct RastPort *rp, const plot_font_style_t *fstyle) { struct TextFont *bmfont = NULL; struct TextAttr tattr; - char *fontname, *font; + char *fontname; + char font[MAX_FONT_NAME_SIZE]; if(rp == NULL) return NULL; @@ -78,14 +81,12 @@ static struct TextFont *ami_font_bm_open(struct RastPort *rp, const plot_font_st if (fstyle->weight >= 700) tattr.ta_Style |= FSF_BOLD; - if((font = ASPrintf("%s.font", fontname))) { - tattr.ta_Name = font; - tattr.ta_YSize = fstyle->size / FONT_SIZE_SCALE; - LOG("font: %s/%d", tattr.ta_Name, tattr.ta_YSize); - if((bmfont = OpenDiskFont(&tattr))) { - SetRPAttrs(rp, RPTAG_Font, bmfont, TAG_DONE); - } - FreeVec(font); + snprintf(font, MAX_FONT_NAME_SIZE, "%s.font", fontname); + tattr.ta_Name = font; + tattr.ta_YSize = fstyle->size / FONT_SIZE_SCALE; + LOG("font: %s/%d", tattr.ta_Name, tattr.ta_YSize); + if((bmfont = OpenDiskFont(&tattr))) { + SetRPAttrs(rp, RPTAG_Font, bmfont, TAG_DONE); } return bmfont; -- cgit v1.2.3