diff options
Diffstat (limited to 'frontends/framebuffer')
30 files changed, 1281 insertions, 515 deletions
diff --git a/frontends/framebuffer/Makefile b/frontends/framebuffer/Makefile index 6d2acb079..bdedd903b 100644 --- a/frontends/framebuffer/Makefile +++ b/frontends/framebuffer/Makefile @@ -130,10 +130,12 @@ define convert_font S_FONTS += $(2) -$(2): $(1) $(TOOLROOT)/convert_font +$(2) $(3): $(1) $(TOOLROOT)/convert_font $(VQ)echo " FONT: $(1) ($(4))" $(Q)$(TOOLROOT)/convert_font -H $(3) $(1) $(2) +frontends/framebuffer/font_internal.c: $(2) + endef S_FONTS := @@ -146,7 +148,7 @@ $(eval $(foreach V,$(filter FB_FONT_$(NETSURF_FB_FONTLIB)_%,$(.VARIABLES)),$(cal # S_FRONTEND are sources purely for the framebuffer build S_FRONTEND := gui.c framebuffer.c schedule.c bitmap.c fetch.c \ - findfile.c localhistory.c clipboard.c + findfile.c corewindow.c local_history.c clipboard.c # toolkit sources S_FRAMEBUFFER_FBTK := fbtk.c event.c fill.c bitmap.c user.c window.c \ @@ -168,14 +170,15 @@ EXETARGET := nsfb NETSURF_FRAMEBUFFER_RESOURCE_LIST := adblock.css credits.html \ default.css internal.css licence.html \ - netsurf.png quirks.css welcome.html maps.html Messages + netsurf.png quirks.css welcome.html maps.html install-framebuffer: $(Q)$(MKDIR) -p $(DESTDIR)$(NETSURF_FRAMEBUFFER_BIN) $(Q)$(MKDIR) -p $(DESTDIR)$(NETSURF_FRAMEBUFFER_RESOURCES) $(Q)cp -v $(EXETARGET) $(DESTDIR)/$(NETSURF_FRAMEBUFFER_BIN)netsurf-fb $(Q)for F in $(NETSURF_FRAMEBUFFER_RESOURCE_LIST); do cp -vL $(FRONTEND_RESOURCES_DIR)/$$F $(DESTDIR)/$(NETSURF_FRAMEBUFFER_RESOURCES); done - $(Q)$(SPLIT_MESSAGES) -l en -p fb -f messages resources/FatMessages | gzip -9n > $(DESTDIR)$(NETSURF_FRAMEBUFFER_RESOURCES)messages + $(Q)$(RM) $(DESTDIR)$(NETSURF_FRAMEBUFFER_RESOURCES)messages + $(Q)$(SPLIT_MESSAGES) -l en -p fb -f messages -o $(DESTDIR)$(NETSURF_FRAMEBUFFER_RESOURCES)messages -z resources/FatMessages # ---------------------------------------------------------------------------- # Package target diff --git a/frontends/framebuffer/bitmap.c b/frontends/framebuffer/bitmap.c index 027e0122b..1fc9f46a2 100644 --- a/frontends/framebuffer/bitmap.c +++ b/frontends/framebuffer/bitmap.c @@ -51,7 +51,8 @@ static void *bitmap_create(int width, int height, unsigned int state) { nsfb_t *bm; - LOG("width %d, height %d, state %u", width, height, state); + NSLOG(netsurf, INFO, "width %d, height %d, state %u", width, height, + state); bm = nsfb_new(NSFB_SURFACE_RAM); if (bm == NULL) { @@ -69,7 +70,7 @@ static void *bitmap_create(int width, int height, unsigned int state) return NULL; } - LOG("bitmap %p", bm); + NSLOG(netsurf, INFO, "bitmap %p", bm); return bm; } @@ -197,11 +198,11 @@ static bool bitmap_test_opaque(void *bitmap) while (tst-- > 0) { if (bmpptr[(tst << 2) + 3] != 0xff) { - LOG("bitmap %p has transparency", bm); + NSLOG(netsurf, INFO, "bitmap %p has transparency", bm); return false; } } - LOG("bitmap %p is opaque", bm); + NSLOG(netsurf, INFO, "bitmap %p is opaque", bm); return true; } @@ -282,14 +283,14 @@ bitmap_render(struct bitmap *bitmap, nsfb_get_geometry(tbm, &width, &height, NULL); - LOG("width %d, height %d", width, height); + NSLOG(netsurf, INFO, "width %d, height %d", width, height); /* Calculate size of buffer to render the content into */ - /* We get the width from the content width, unless it exceeds 1024, - * in which case we use 1024. This means we never create excessively - * large render buffers for huge contents, which would eat memory and - * cripple performance. */ - cwidth = min(content_get_width(content), 1024); + /* We get the width from the largest of the bitmap width and the content + * width, unless it exceeds 1024, in which case we use 1024. This means + * we never create excessively large render buffers for huge contents, + * which would eat memory and cripple performance. */ + cwidth = max(width, min(content_get_width(content), 1024)); /* The height is set in proportion with the width, according to the * aspect ratio of the required thumbnail. */ cheight = ((cwidth * height) + (width / 2)) / width; diff --git a/frontends/framebuffer/clipboard.c b/frontends/framebuffer/clipboard.c index 1254c36f3..20a00e038 100644 --- a/frontends/framebuffer/clipboard.c +++ b/frontends/framebuffer/clipboard.c @@ -53,8 +53,8 @@ static void gui_get_clipboard(char **buffer, size_t *length) if (gui_clipboard.length > 0) { assert(gui_clipboard.buffer != NULL); - LOG("Pasting %zd bytes: \"%s\"\n", - gui_clipboard.length, gui_clipboard.buffer); + NSLOG(netsurf, INFO, "Pasting %zd bytes: \"%s\"\n", + gui_clipboard.length, gui_clipboard.buffer); *buffer = malloc(gui_clipboard.length); diff --git a/frontends/framebuffer/corewindow.c b/frontends/framebuffer/corewindow.c new file mode 100644 index 000000000..93f88ff61 --- /dev/null +++ b/frontends/framebuffer/corewindow.c @@ -0,0 +1,262 @@ +/* + * Copyright 2017 Vincent Sanders <vince@netsurf-browser.org> + * + * This file is part of NetSurf, http://www.netsurf-browser.org/ + * + * NetSurf is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * NetSurf is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +/** + * \file + * framebuffer generic core window interface. + * + * Provides interface for core renderers to the framebufefr toolkit + * drawable area. + * + * This module is an object that must be encapsulated. Client users + * should embed a struct fb_corewindow at the beginning of their + * context for this display surface, fill in relevant data and then + * call fb_corewindow_init() + * + * The fb core window structure requires the callback for draw, key and + * mouse operations. + */ + +#include <assert.h> +#include <stdbool.h> +#include <stdlib.h> +#include <limits.h> + +#include <libnsfb.h> +#include <libnsfb_plot.h> +#include <libnsfb_event.h> + +#include "utils/log.h" +#include "utils/utils.h" +#include "utils/messages.h" +#include "utils/utf8.h" +#include "utils/nsoption.h" +#include "netsurf/keypress.h" +#include "netsurf/mouse.h" +#include "netsurf/plot_style.h" + +#include "framebuffer/gui.h" +#include "framebuffer/fbtk.h" +#include "framebuffer/corewindow.h" + + +/* toolkit event handlers that do generic things and call internal callbacks */ + + +static int +fb_cw_mouse_press_event(fbtk_widget_t *widget, fbtk_callback_info *cbi) +{ + struct fb_corewindow *fb_cw = (struct fb_corewindow *)cbi->context; + browser_mouse_state state; + + /** \todo frambuffer corewindow mouse event handling needs improving */ + if (cbi->event->type != NSFB_EVENT_KEY_UP) { + state = BROWSER_MOUSE_HOVER; + } else { + state = BROWSER_MOUSE_PRESS_1; + } + + fb_cw->mouse(fb_cw, state, cbi->x, cbi->y); + + return 1; +} + +/* +static bool +fb_cw_input_event(toolkit_widget *widget, void *ctx) +{ + struct fb_corewindow *fb_cw = (struct fb_corewindow *)ctx; + + fb_cw->key(fb_cw, keycode); + + return true; +} +*/ + +/** + * handler for toolkit window redraw event + */ +static int fb_cw_draw_event(fbtk_widget_t *widget, fbtk_callback_info *cbi) +{ + struct fb_corewindow *fb_cw; + nsfb_bbox_t rbox; + struct rect clip; + + fb_cw = (struct fb_corewindow *)cbi->context; + + rbox.x0 = fbtk_get_absx(widget); + rbox.y0 = fbtk_get_absy(widget); + + rbox.x1 = rbox.x0 + fbtk_get_width(widget); + rbox.y1 = rbox.y0 + fbtk_get_height(widget); + + nsfb_claim(fbtk_get_nsfb(widget), &rbox); + + clip.x0 = fb_cw->scrollx; + clip.y0 = fb_cw->scrolly; + clip.x1 = fbtk_get_width(widget) + fb_cw->scrollx; + clip.y1 = fbtk_get_height(widget) + fb_cw->scrolly; + + fb_cw->draw(fb_cw, &clip); + + nsfb_update(fbtk_get_nsfb(widget), &rbox); + + return 0; +} + + +/** + * callback from core to request a redraw + */ +static nserror +fb_cw_invalidate(struct core_window *cw, const struct rect *r) +{ +/* struct fb_corewindow *fb_cw = (struct fb_corewindow *)cw; + + toolkit_widget_queue_draw_area(fb_cw->widget, + r->x0, r->y0, + r->x1 - r->x0, r->y1 - r->y0); +*/ + return NSERROR_OK; +} + + +static void +fb_cw_update_size(struct core_window *cw, int width, int height) +{ +/* struct fb_corewindow *fb_cw = (struct fb_corewindow *)cw; + + toolkit_widget_set_size_request(FB_WIDGET(fb_cw->drawing_area), + width, height); +*/ +} + + +static void +fb_cw_scroll_visible(struct core_window *cw, const struct rect *r) +{ +/* struct fb_corewindow *fb_cw = (struct fb_corewindow *)cw; + + toolkit_scroll_widget(fb_cw->widget, r); +*/ +} + + +static void +fb_cw_get_window_dimensions(struct core_window *cw, int *width, int *height) +{ + struct fb_corewindow *fb_cw = (struct fb_corewindow *)cw; + + *width = fbtk_get_width(fb_cw->drawable); + *height = fbtk_get_height(fb_cw->drawable); +} + + +static void +fb_cw_drag_status(struct core_window *cw, core_window_drag_status ds) +{ + struct fb_corewindow *fb_cw = (struct fb_corewindow *)cw; + fb_cw->drag_status = ds; +} + + +struct core_window_callback_table fb_cw_cb_table = { + .invalidate = fb_cw_invalidate, + .update_size = fb_cw_update_size, + .scroll_visible = fb_cw_scroll_visible, + .get_window_dimensions = fb_cw_get_window_dimensions, + .drag_status = fb_cw_drag_status +}; + +/* exported function documented fb/corewindow.h */ +nserror fb_corewindow_init(fbtk_widget_t *parent, struct fb_corewindow *fb_cw) +{ + int furniture_width; + + furniture_width = nsoption_int(fb_furniture_size); + + /* setup the core window callback table */ + fb_cw->cb_table = &fb_cw_cb_table; + fb_cw->drag_status = CORE_WINDOW_DRAG_NONE; + + /* container window */ + fb_cw->wnd = fbtk_create_window(parent, 0, 0, 0, 0, 0); + + fb_cw->drawable = fbtk_create_user(fb_cw->wnd, + 0, 0, + -furniture_width, -furniture_width, + fb_cw); + + fbtk_set_handler(fb_cw->drawable, + FBTK_CBT_REDRAW, + fb_cw_draw_event, + fb_cw); + + fbtk_set_handler(fb_cw->drawable, + FBTK_CBT_CLICK, + fb_cw_mouse_press_event, + fb_cw); +/* + fbtk_set_handler(fb_cw->drawable, + FBTK_CBT_INPUT, + fb_cw_input_event, + fb_cw); + + fbtk_set_handler(fb_cw->drawable, + FBTK_CBT_POINTERMOVE, + fb_cw_move_event, + fb_cw); +*/ + + /* create horizontal scrollbar */ + fb_cw->hscroll = fbtk_create_hscroll(fb_cw->wnd, + 0, + fbtk_get_height(fb_cw->wnd) - furniture_width, + fbtk_get_width(fb_cw->wnd) - furniture_width, + furniture_width, + FB_SCROLL_COLOUR, + FB_FRAME_COLOUR, + NULL, + NULL); + + fb_cw->vscroll = fbtk_create_vscroll(fb_cw->wnd, + fbtk_get_width(fb_cw->wnd) - furniture_width, + 0, + furniture_width, + fbtk_get_height(fb_cw->wnd) - furniture_width, + FB_SCROLL_COLOUR, + FB_FRAME_COLOUR, + NULL, + NULL); + + fbtk_create_fill(fb_cw->wnd, + fbtk_get_width(fb_cw->wnd) - furniture_width, + fbtk_get_height(fb_cw->wnd) - furniture_width, + furniture_width, + furniture_width, + FB_FRAME_COLOUR); + + + return NSERROR_OK; +} + +/* exported interface documented in fb/corewindow.h */ +nserror fb_corewindow_fini(struct fb_corewindow *fb_cw) +{ + return NSERROR_OK; +} diff --git a/frontends/framebuffer/corewindow.h b/frontends/framebuffer/corewindow.h new file mode 100644 index 000000000..5546c09b6 --- /dev/null +++ b/frontends/framebuffer/corewindow.h @@ -0,0 +1,107 @@ +/* + * Copyright 2017 Vincent Sanders <vince@netsurf-browser.org> + * + * This file is part of NetSurf, http://www.netsurf-browser.org/ + * + * NetSurf is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * NetSurf is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef FB_COREWINDOW_H +#define FB_COREWINDOW_H + +#include "netsurf/core_window.h" + +/** + * fb core window state + */ +struct fb_corewindow { + + /** + * framebuffer toolkit window. + */ + struct fbtk_widget_s *wnd; + /** + * framebuffer toolkit horizontal scrollbar. + */ + struct fbtk_widget_s *hscroll; + /** + * framebuffer toolkit vertical scrollbar. + */ + struct fbtk_widget_s *vscroll; + /** + * framebuffer toolkit user drawable widget. + */ + struct fbtk_widget_s *drawable; + + int scrollx, scrolly; /**< scroll offsets. */ + + + /** drag status set by core */ + core_window_drag_status drag_status; + + /** table of callbacks for core window operations */ + struct core_window_callback_table *cb_table; + + /** + * callback to draw on drawable area of fb core window + * + * \param fb_cw The fb core window structure. + * \param r The rectangle of the window that needs updating. + * \return NSERROR_OK on success otherwise apropriate error code + */ + nserror (*draw)(struct fb_corewindow *fb_cw, struct rect *r); + + /** + * callback for keypress on fb core window + * + * \param fb_cw The fb core window structure. + * \param nskey The netsurf key code. + * \return NSERROR_OK if key processed, + * NSERROR_NOT_IMPLEMENTED if key not processed + * otherwise apropriate error code + */ + nserror (*key)(struct fb_corewindow *fb_cw, uint32_t nskey); + + /** + * callback for mouse event on fb core window + * + * \param fb_cw The fb core window structure. + * \param mouse_state mouse state + * \param x location of event + * \param y location of event + * \return NSERROR_OK on sucess otherwise apropriate error code. + */ + nserror (*mouse)(struct fb_corewindow *fb_cw, browser_mouse_state mouse_state, int x, int y); +}; + + +/** + * initialise elements of fb core window. + * + * As a pre-requisite the draw, key and mouse callbacks must be defined + * + * \param fb_cw A fb core window structure to initialise + * \return NSERROR_OK on successful initialisation otherwise error code. + */ +nserror fb_corewindow_init(fbtk_widget_t *parent, struct fb_corewindow *fb_cw); + + +/** + * finalise elements of fb core window. + * + * \param fb_cw A fb core window structure to initialise + * \return NSERROR_OK on successful finalisation otherwise error code. + */ +nserror fb_corewindow_fini(struct fb_corewindow *fb_cw); + +#endif diff --git a/frontends/framebuffer/fbtk.h b/frontends/framebuffer/fbtk.h index 3cc326cef..86bdc864b 100644 --- a/frontends/framebuffer/fbtk.h +++ b/frontends/framebuffer/fbtk.h @@ -21,12 +21,6 @@ #include "netsurf/types.h" -#ifdef FBTK_LOGGING -#define FBTK_LOG(x) LOG(x) -#else -#define FBTK_LOG(x) -#endif - #define FB_SCROLL_COLOUR 0xFFAAAAAA #define FB_FRAME_COLOUR 0xFFDDDDDD #define FB_COLOUR_BLACK 0xFF000000 diff --git a/frontends/framebuffer/fbtk/event.c b/frontends/framebuffer/fbtk/event.c index a48e63809..84c6c3791 100644 --- a/frontends/framebuffer/fbtk/event.c +++ b/frontends/framebuffer/fbtk/event.c @@ -51,7 +51,7 @@ fbtk_input(fbtk_widget_t *root, nsfb_event_t *event) /* obtain widget with input focus */ input = root->u.root.input; if (input == NULL) { - LOG("No widget has input focus."); + NSLOG(netsurf, INFO, "No widget has input focus."); return; /* no widget with input */ } @@ -84,7 +84,7 @@ fbtk_click(fbtk_widget_t *widget, nsfb_event_t *event) x = fbtk_get_absx(clicked); y = fbtk_get_absy(clicked); - LOG("clicked %p at %d,%d", clicked, x, y); + NSLOG(netsurf, INFO, "clicked %p at %d,%d", clicked, x, y); /* post the click */ fbtk_post_callback(clicked, FBTK_CBT_CLICK, event, cloc.x0 - x, cloc.y0 - y); diff --git a/frontends/framebuffer/fbtk/fbtk.c b/frontends/framebuffer/fbtk/fbtk.c index c63a6d8c9..91f6e2570 100644 --- a/frontends/framebuffer/fbtk/fbtk.c +++ b/frontends/framebuffer/fbtk/fbtk.c @@ -53,7 +53,7 @@ dump_tk_tree(fbtk_widget_t *widget) int indent = 0; while (widget != NULL) { - LOG("%*s%p", indent, "", widget); + NSLOG(fbtk, DEBUG, "%*s%p", indent, "", widget); if (widget->first_child != NULL) { widget = widget->first_child; indent += 6; @@ -100,9 +100,13 @@ fbtk_request_redraw(fbtk_widget_t *widget) widget->redraw.width = widget->width; widget->redraw.height = widget->height; -#ifdef FBTK_LOGGING - LOG("redrawing %p %d,%d %d,%d", widget, widget->redraw.x, widget->redraw.y, widget->redraw.width, widget->redraw.height); -#endif + NSLOG(fbtk, DEBUG, + "redrawing %p %d,%d %d,%d", + widget, + widget->redraw.x, + widget->redraw.y, + widget->redraw.width, + widget->redraw.height); cwidget = widget->last_child; while (cwidget != NULL) { @@ -122,7 +126,7 @@ fbtk_request_redraw(fbtk_widget_t *widget) int fbtk_set_mapping(fbtk_widget_t *widget, bool map) { - LOG("setting mapping on %p to %d", widget, map); + NSLOG(netsurf, INFO, "setting mapping on %p to %d", widget, map); widget->mapped = map; if (map) { fbtk_request_redraw(widget); @@ -132,9 +136,11 @@ fbtk_set_mapping(fbtk_widget_t *widget, bool map) return 0; } -/** swap the widget given with the next sibling. - * + +/** * Swap a sibling widget with the next deepest in the hierachy + * + * \param lw The widget to swap */ static void swap_siblings(fbtk_widget_t *lw) @@ -145,7 +151,7 @@ swap_siblings(fbtk_widget_t *lw) assert(rw != NULL); - LOG("Swapping %p with %p", lw, rw); + NSLOG(netsurf, INFO, "Swapping %p with %p", lw, rw); before = lw->prev; after = rw->next; @@ -401,7 +407,6 @@ fbtk_set_ptr(fbtk_widget_t *widget, fbtk_callback_info *cbi) } - /* internally exported function documented in widget.h */ fbtk_widget_t * fbtk_get_root_widget(fbtk_widget_t *widget) @@ -411,7 +416,8 @@ fbtk_get_root_widget(fbtk_widget_t *widget) /* check root widget was found */ if (widget->type != FB_WIDGET_TYPE_ROOT) { - LOG("Widget with null parent that is not the root widget!"); + NSLOG(netsurf, INFO, + "Widget with null parent that is not the root widget!"); return NULL; } @@ -433,6 +439,7 @@ fbtk_get_absx(fbtk_widget_t *widget) return x; } + /* exported function documented in fbtk.h */ int fbtk_get_absy(fbtk_widget_t *widget) @@ -447,6 +454,7 @@ fbtk_get_absy(fbtk_widget_t *widget) return y; } + /* exported function documented in fbtk.h */ int fbtk_get_height(fbtk_widget_t *widget) @@ -551,9 +559,7 @@ fbtk_widget_new(fbtk_widget_t *parent, if (neww == NULL) return NULL; -#ifdef FBTK_LOGGING - LOG("creating %p %d,%d %d,%d", neww, x, y, width, height); -#endif + NSLOG(fbtk, DEBUG, "creating %p %d,%d %d,%d", neww, x, y, width, height); /* make new window fit inside parent */ if (width == 0) { @@ -574,9 +580,8 @@ fbtk_widget_new(fbtk_widget_t *parent, height = parent->height - y; } -#ifdef FBTK_LOGGING - LOG("using %p %d,%d %d,%d", neww, x, y, width, height); -#endif + NSLOG(fbtk, DEBUG, "using %p %d,%d %d,%d", neww, x, y, width, height); + /* set values */ neww->type = type; neww->x = x; @@ -634,9 +639,12 @@ do_redraw(nsfb_t *nsfb, fbtk_widget_t *widget) plot_ctx.x1 = plot_ctx.x0 + widget->redraw.width; plot_ctx.y1 = plot_ctx.y0 + widget->redraw.height; -#ifdef FBTK_LOGGING - LOG("clipping %p %d,%d %d,%d", widget, plot_ctx.x0, plot_ctx.y0, plot_ctx.x1, plot_ctx.y1); -#endif + NSLOG(fbtk, DEBUG, + "clipping %p %d,%d %d,%d", + widget, + plot_ctx.x0, plot_ctx.y0, + plot_ctx.x1, plot_ctx.y1); + if (nsfb_plot_set_clip(nsfb, &plot_ctx) == true) { fbtk_post_callback(widget, FBTK_CBT_REDRAW); } diff --git a/frontends/framebuffer/fbtk/scroll.c b/frontends/framebuffer/fbtk/scroll.c index cc98fb2dd..b056ac81f 100644 --- a/frontends/framebuffer/fbtk/scroll.c +++ b/frontends/framebuffer/fbtk/scroll.c @@ -334,7 +334,7 @@ hscroll_redraw(fbtk_widget_t *widget, fbtk_callback_info *cbi) hpos = 0; } - LOG("hscroll %d", hscroll); + NSLOG(netsurf, INFO, "hscroll %d", hscroll); rect.x0 = bbox.x0 + 3 + hpos; rect.y0 = bbox.y0 + 5; @@ -362,7 +362,7 @@ hscrolll_click(fbtk_widget_t *widget, fbtk_callback_info *cbi) newpos = scrollw->u.scroll.minimum; if (newpos == scrollw->u.scroll.position) { - LOG("horiz scroll was the same %d", newpos); + NSLOG(netsurf, INFO, "horiz scroll was the same %d", newpos); return 0; } diff --git a/frontends/framebuffer/fbtk/text.c b/frontends/framebuffer/fbtk/text.c index 00dcba491..9c96dcef4 100644 --- a/frontends/framebuffer/fbtk/text.c +++ b/frontends/framebuffer/fbtk/text.c @@ -71,7 +71,7 @@ fb_text_font_style(fbtk_widget_t *widget, int *font_height, int *padding, #endif font_style->family = PLOT_FONT_FAMILY_SANS_SERIF; - font_style->size = px_to_pt(*font_height * FONT_SIZE_SCALE); + font_style->size = px_to_pt(*font_height * PLOT_STYLE_SCALE); font_style->weight = 400; font_style->flags = FONTF_NONE; font_style->background = widget->bg; @@ -98,6 +98,11 @@ fb_redraw_text(fbtk_widget_t *widget, fbtk_callback_info *cbi ) int padding; int scroll = 0; bool caret = false; + struct redraw_context ctx = { + .interactive = true, + .background_images = true, + .plot = &fb_plotters + }; fb_text_font_style(widget, &fh, &padding, &font_style); @@ -142,8 +147,11 @@ fb_redraw_text(fbtk_widget_t *widget, fbtk_callback_info *cbi ) } /* Call the fb text plotting, baseline is 3/4 down the font */ - fb_plotters.text(x, y, widget->u.text.text, - widget->u.text.len, &font_style); + ctx.plot->text(&ctx, + &font_style, + x, y, + widget->u.text.text, + widget->u.text.len); } if (caret) { @@ -209,6 +217,11 @@ fb_redraw_text_button(fbtk_widget_t *widget, fbtk_callback_info *cbi ) int fh; int border; fbtk_widget_t *root = fbtk_get_root_widget(widget); + struct redraw_context ctx = { + .interactive = true, + .background_images = true, + .plot = &fb_plotters + }; fb_text_font_style(widget, &fh, &border, &font_style); @@ -256,11 +269,12 @@ fb_redraw_text_button(fbtk_widget_t *widget, fbtk_callback_info *cbi ) if (widget->u.text.text != NULL) { /* Call the fb text plotting, baseline is 3/4 down the font */ - fb_plotters.text(bbox.x0 + border, - bbox.y0 + ((fh * 3) / 4) + border, - widget->u.text.text, - widget->u.text.len, - &font_style); + ctx.plot->text(&ctx, + &font_style, + bbox.x0 + border, + bbox.y0 + ((fh * 3) / 4) + border, + widget->u.text.text, + widget->u.text.len); } nsfb_update(root->u.root.fb, &bbox); @@ -374,6 +388,22 @@ text_input(fbtk_widget_t *widget, fbtk_callback_info *cbi) } break; + case NSFB_KEY_HOME: + if (widget->u.text.idx > 0) { + widget->u.text.idx = 0; + + caret_moved = true; + } + break; + + case NSFB_KEY_END: + if (widget->u.text.idx < widget->u.text.len) { + widget->u.text.idx = widget->u.text.len; + + caret_moved = true; + } + break; + case NSFB_KEY_PAGEUP: case NSFB_KEY_PAGEDOWN: case NSFB_KEY_UP: diff --git a/frontends/framebuffer/fetch.c b/frontends/framebuffer/fetch.c index 801b87a74..23cbb4f21 100644 --- a/frontends/framebuffer/fetch.c +++ b/frontends/framebuffer/fetch.c @@ -65,7 +65,7 @@ static nsurl *get_resource_url(const char *path) static const char *fetch_filetype(const char *unix_path) { int l; - LOG("unix path %s", unix_path); + NSLOG(netsurf, INFO, "unix path %s", unix_path); l = strlen(unix_path); if (2 < l && strcasecmp(unix_path + l - 3, "css") == 0) return "text/css"; diff --git a/frontends/framebuffer/font_freetype.c b/frontends/framebuffer/font_freetype.c index e7c07f5ff..744ac6281 100644 --- a/frontends/framebuffer/font_freetype.c +++ b/frontends/framebuffer/font_freetype.c @@ -90,12 +90,13 @@ ft_face_requester(FTC_FaceID face_id, error = FT_New_Face(library, fb_face->fontfile, fb_face->index, face); if (error) { - LOG("Could not find font (code %d)", error); + NSLOG(netsurf, INFO, "Could not find font (code %d)", error); } else { error = FT_Select_Charmap(*face, FT_ENCODING_UNICODE); if (error) { - LOG("Could not select charmap (code %d)", error); + NSLOG(netsurf, INFO, + "Could not select charmap (code %d)", error); } else { for (cidx = 0; cidx < (*face)->num_charmaps; cidx++) { if ((*face)->charmap == (*face)->charmaps[cidx]) { @@ -105,7 +106,7 @@ ft_face_requester(FTC_FaceID face_id, } } } - LOG("Loaded face from %s", fb_face->fontfile); + NSLOG(netsurf, INFO, "Loaded face from %s", fb_face->fontfile); return error; } @@ -132,7 +133,8 @@ fb_new_face(const char *option, const char *resname, const char *fontname) error = FTC_Manager_LookupFace(ft_cmanager, (FTC_FaceID)newf, &aface); if (error) { - LOG("Could not find font face %s (code %d)", fontname, error); + NSLOG(netsurf, INFO, "Could not find font face %s (code %d)", + fontname, error); free(newf->fontfile); free(newf); newf = NULL; @@ -152,7 +154,8 @@ bool fb_font_init(void) /* freetype library initialise */ error = FT_Init_FreeType( &library ); if (error) { - LOG("Freetype could not initialised (code %d)", error); + NSLOG(netsurf, INFO, + "Freetype could not initialised (code %d)", error); return false; } @@ -172,7 +175,9 @@ bool fb_font_init(void) NULL, &ft_cmanager); if (error) { - LOG("Freetype could not initialise cache manager (code %d)", error); + NSLOG(netsurf, INFO, + "Freetype could not initialise cache manager (code %d)", + error); FT_Done_FreeType(library); return false; } @@ -189,7 +194,7 @@ bool fb_font_init(void) NETSURF_FB_FONT_SANS_SERIF); if (fb_face == NULL) { /* The sans serif font is the default and must be found. */ - LOG("Could not find the default font"); + NSLOG(netsurf, INFO, "Could not find the default font"); FTC_Manager_Done(ft_cmanager); FT_Done_FreeType(library); return false; @@ -387,7 +392,7 @@ static void fb_fill_scalar(const plot_font_style_t *fstyle, FTC_Scaler srec) srec->face_id = (FTC_FaceID)fb_faces[selected_face]; - srec->width = srec->height = (fstyle->size * 64) / FONT_SIZE_SCALE; + srec->width = srec->height = (fstyle->size * 64) / PLOT_STYLE_SCALE; srec->pixel = 0; srec->x_res = srec->y_res = browser_get_dpi(); diff --git a/frontends/framebuffer/font_internal.c b/frontends/framebuffer/font_internal.c index 3b8a1c43f..d755681c6 100644 --- a/frontends/framebuffer/font_internal.c +++ b/frontends/framebuffer/font_internal.c @@ -212,7 +212,7 @@ fb_get_font_size(const plot_font_style_t *fstyle) { int size = fstyle->size * 10 / (((nsoption_int(font_min_size) * 3 + - nsoption_int(font_size)) / 4) * FONT_SIZE_SCALE); + nsoption_int(font_size)) / 4) * PLOT_STYLE_SCALE); if (size > 2) size = 2; else if (size <= 0) @@ -270,6 +270,7 @@ fb_get_glyph(uint32_t ucs4, enum fb_font_style style, int scale) break; } } + /* Fall through. */ case FB_BOLD: section = fb_bold_section_table[ucs4 / 256]; if (section != 0 || ucs4 / 256 == 0) { @@ -280,6 +281,7 @@ fb_get_glyph(uint32_t ucs4, enum fb_font_style style, int scale) break; } } + /* Fall through. */ case FB_ITALIC: section = fb_italic_section_table[ucs4 / 256]; if (section != 0 || ucs4 / 256 == 0) { @@ -290,6 +292,7 @@ fb_get_glyph(uint32_t ucs4, enum fb_font_style style, int scale) break; } } + /* Fall through. */ case FB_REGULAR: section = fb_regular_section_table[ucs4 / 256]; if (section != 0 || ucs4 / 256 == 0) { @@ -300,6 +303,7 @@ fb_get_glyph(uint32_t ucs4, enum fb_font_style style, int scale) break; } } + /* Fall through. */ default: glyph_data = get_codepoint(ucs4, style & FB_ITALIC); break; diff --git a/frontends/framebuffer/framebuffer.c b/frontends/framebuffer/framebuffer.c index 74c72fe71..52afdbf5d 100644 --- a/frontends/framebuffer/framebuffer.c +++ b/frontends/framebuffer/framebuffer.c @@ -45,139 +45,274 @@ static nsfb_t *nsfb; -static bool -framebuffer_plot_disc(int x, int y, int radius, const plot_style_t *style) +/** + * \brief Sets a clip rectangle for subsequent plot operations. + * + * \param ctx The current redraw context. + * \param clip The rectangle to limit all subsequent plot + * operations within. + * \return NSERROR_OK on success else error code. + */ +static nserror +framebuffer_plot_clip(const struct redraw_context *ctx, const struct rect *clip) { - nsfb_bbox_t ellipse; - ellipse.x0 = x - radius; - ellipse.y0 = y - radius; - ellipse.x1 = x + radius; - ellipse.y1 = y + radius; - - if (style->fill_type != PLOT_OP_TYPE_NONE) { - nsfb_plot_ellipse_fill(nsfb, &ellipse, style->fill_colour); - } - - if (style->stroke_type != PLOT_OP_TYPE_NONE) { - nsfb_plot_ellipse(nsfb, &ellipse, style->stroke_colour); - } - return true; + nsfb_bbox_t nsfb_clip; + nsfb_clip.x0 = clip->x0; + nsfb_clip.y0 = clip->y0; + nsfb_clip.x1 = clip->x1; + nsfb_clip.y1 = clip->y1; + + if (!nsfb_plot_set_clip(nsfb, &nsfb_clip)) { + return NSERROR_INVALID; + } + return NSERROR_OK; } -static bool -framebuffer_plot_arc(int x, int y, int radius, int angle1, int angle2, const plot_style_t *style) + +/** + * Plots an arc + * + * plot an arc segment around (x,y), anticlockwise from angle1 + * to angle2. Angles are measured anticlockwise from + * horizontal, in degrees. + * + * \param ctx The current redraw context. + * \param style Style controlling the arc plot. + * \param x The x coordinate of the arc. + * \param y The y coordinate of the arc. + * \param radius The radius of the arc. + * \param angle1 The start angle of the arc. + * \param angle2 The finish angle of the arc. + * \return NSERROR_OK on success else error code. + */ +static nserror +framebuffer_plot_arc(const struct redraw_context *ctx, + const plot_style_t *style, + int x, int y, int radius, int angle1, int angle2) { - return nsfb_plot_arc(nsfb, x, y, radius, angle1, angle2, style->fill_colour); + if (!nsfb_plot_arc(nsfb, x, y, radius, angle1, angle2, style->fill_colour)) { + return NSERROR_INVALID; + } + return NSERROR_OK; } -static bool -framebuffer_plot_polygon(const int *p, unsigned int n, const plot_style_t *style) + +/** + * Plots a circle + * + * Plot a circle centered on (x,y), which is optionally filled. + * + * \param ctx The current redraw context. + * \param style Style controlling the circle plot. + * \param x x coordinate of circle centre. + * \param y y coordinate of circle centre. + * \param radius circle radius. + * \return NSERROR_OK on success else error code. + */ +static nserror +framebuffer_plot_disc(const struct redraw_context *ctx, + const plot_style_t *style, + int x, int y, int radius) { - return nsfb_plot_polygon(nsfb, p, n, style->fill_colour); + nsfb_bbox_t ellipse; + ellipse.x0 = x - radius; + ellipse.y0 = y - radius; + ellipse.x1 = x + radius; + ellipse.y1 = y + radius; + + if (style->fill_type != PLOT_OP_TYPE_NONE) { + nsfb_plot_ellipse_fill(nsfb, &ellipse, style->fill_colour); + } + + if (style->stroke_type != PLOT_OP_TYPE_NONE) { + nsfb_plot_ellipse(nsfb, &ellipse, style->stroke_colour); + } + return NSERROR_OK; } -#ifdef FB_USE_FREETYPE -static bool -framebuffer_plot_text(int x, int y, const char *text, size_t length, - const plot_font_style_t *fstyle) +/** + * Plots a line + * + * plot a line from (x0,y0) to (x1,y1). Coordinates are at + * centre of line width/thickness. + * + * \param ctx The current redraw context. + * \param style Style controlling the line plot. + * \param line A rectangle defining the line to be drawn + * \return NSERROR_OK on success else error code. + */ +static nserror +framebuffer_plot_line(const struct redraw_context *ctx, + const plot_style_t *style, + const struct rect *line) { - uint32_t ucs4; - size_t nxtchr = 0; - FT_Glyph glyph; - FT_BitmapGlyph bglyph; - nsfb_bbox_t loc; - - while (nxtchr < length) { - ucs4 = utf8_to_ucs4(text + nxtchr, length - nxtchr); - nxtchr = utf8_next(text, length, nxtchr); - - glyph = fb_getglyph(fstyle, ucs4); - if (glyph == NULL) - continue; - - if (glyph->format == FT_GLYPH_FORMAT_BITMAP) { - bglyph = (FT_BitmapGlyph)glyph; - - loc.x0 = x + bglyph->left; - loc.y0 = y - bglyph->top; - loc.x1 = loc.x0 + bglyph->bitmap.width; - loc.y1 = loc.y0 + bglyph->bitmap.rows; - - /* now, draw to our target surface */ - if (bglyph->bitmap.pixel_mode == FT_PIXEL_MODE_MONO) { - nsfb_plot_glyph1(nsfb, - &loc, - bglyph->bitmap.buffer, - bglyph->bitmap.pitch, - fstyle->foreground); - } else { - nsfb_plot_glyph8(nsfb, - &loc, - bglyph->bitmap.buffer, - bglyph->bitmap.pitch, - fstyle->foreground); - } - } - x += glyph->advance.x >> 16; - - } - return true; + nsfb_bbox_t rect; + nsfb_plot_pen_t pen; + + rect.x0 = line->x0; + rect.y0 = line->y0; + rect.x1 = line->x1; + rect.y1 = line->y1; + + if (style->stroke_type != PLOT_OP_TYPE_NONE) { + + if (style->stroke_type == PLOT_OP_TYPE_DOT) { + pen.stroke_type = NFSB_PLOT_OPTYPE_PATTERN; + pen.stroke_pattern = 0xAAAAAAAA; + } else if (style->stroke_type == PLOT_OP_TYPE_DASH) { + pen.stroke_type = NFSB_PLOT_OPTYPE_PATTERN; + pen.stroke_pattern = 0xF0F0F0F0; + } else { + pen.stroke_type = NFSB_PLOT_OPTYPE_SOLID; + } + + pen.stroke_colour = style->stroke_colour; + pen.stroke_width = plot_style_fixed_to_int(style->stroke_width); + nsfb_plot_line(nsfb, &rect, &pen); + } + return NSERROR_OK; } -#else -static bool framebuffer_plot_text(int x, int y, const char *text, size_t length, - const plot_font_style_t *fstyle) + + +/** + * Plots a rectangle. + * + * The rectangle can be filled an outline or both controlled + * by the plot style The line can be solid, dotted or + * dashed. Top left corner at (x0,y0) and rectangle has given + * width and height. + * + * \param ctx The current redraw context. + * \param style Style controlling the rectangle plot. + * \param nsrect A rectangle defining the line to be drawn + * \return NSERROR_OK on success else error code. + */ +static nserror +framebuffer_plot_rectangle(const struct redraw_context *ctx, + const plot_style_t *style, + const struct rect *nsrect) { - enum fb_font_style style = fb_get_font_style(fstyle); - int size = fb_get_font_size(fstyle); - const uint8_t *chrp; - size_t nxtchr = 0; - nsfb_bbox_t loc; - uint32_t ucs4; - int p = FB_FONT_PITCH * size; - int w = FB_FONT_WIDTH * size; - int h = FB_FONT_HEIGHT * size; + nsfb_bbox_t rect; + bool dotted = false; + bool dashed = false; - y -= ((h * 3) / 4); - /* the coord is the bottom-left of the pixels offset by 1 to make - * it work since fb coords are the top-left of pixels */ - y += 1; + rect.x0 = nsrect->x0; + rect.y0 = nsrect->y0; + rect.x1 = nsrect->x1; + rect.y1 = nsrect->y1; - while (nxtchr < length) { - ucs4 = utf8_to_ucs4(text + nxtchr, length - nxtchr); - nxtchr = utf8_next(text, length, nxtchr); + if (style->fill_type != PLOT_OP_TYPE_NONE) { + nsfb_plot_rectangle_fill(nsfb, &rect, style->fill_colour); + } - if (!codepoint_displayable(ucs4)) - continue; + if (style->stroke_type != PLOT_OP_TYPE_NONE) { + if (style->stroke_type == PLOT_OP_TYPE_DOT) { + dotted = true; + } - loc.x0 = x; - loc.y0 = y; - loc.x1 = loc.x0 + w; - loc.y1 = loc.y0 + h; + if (style->stroke_type == PLOT_OP_TYPE_DASH) { + dashed = true; + } - chrp = fb_get_glyph(ucs4, style, size); - nsfb_plot_glyph1(nsfb, &loc, chrp, p, fstyle->foreground); + nsfb_plot_rectangle(nsfb, &rect, + plot_style_fixed_to_int(style->stroke_width), + style->stroke_colour, dotted, dashed); + } + return NSERROR_OK; +} - x += w; - } +/** + * Plot a polygon + * + * Plots a filled polygon with straight lines between + * points. The lines around the edge of the ploygon are not + * plotted. The polygon is filled with the non-zero winding + * rule. + * + * \param ctx The current redraw context. + * \param style Style controlling the polygon plot. + * \param p verticies of polygon + * \param n number of verticies. + * \return NSERROR_OK on success else error code. + */ +static nserror +framebuffer_plot_polygon(const struct redraw_context *ctx, + const plot_style_t *style, + const int *p, + unsigned int n) +{ + if (!nsfb_plot_polygon(nsfb, p, n, style->fill_colour)) { + return NSERROR_INVALID; + } + return NSERROR_OK; +} - return true; + +/** + * Plots a path. + * + * Path plot consisting of cubic Bezier curves. Line and fill colour is + * controlled by the plot style. + * + * \param ctx The current redraw context. + * \param pstyle Style controlling the path plot. + * \param p elements of path + * \param n nunber of elements on path + * \param transform A transform to apply to the path. + * \return NSERROR_OK on success else error code. + */ +static nserror +framebuffer_plot_path(const struct redraw_context *ctx, + const plot_style_t *pstyle, + const float *p, + unsigned int n, + const float transform[6]) +{ + NSLOG(netsurf, INFO, "path unimplemented"); + return NSERROR_OK; } -#endif -static bool -framebuffer_plot_bitmap(int x, int y, - int width, int height, - struct bitmap *bitmap, colour bg, - bitmap_flags_t flags) +/** + * Plot a bitmap + * + * Tiled plot of a bitmap image. (x,y) gives the top left + * coordinate of an explicitly placed tile. From this tile the + * image can repeat in all four directions -- up, down, left + * and right -- to the extents given by the current clip + * rectangle. + * + * The bitmap_flags say whether to tile in the x and y + * directions. If not tiling in x or y directions, the single + * image is plotted. The width and height give the dimensions + * the image is to be scaled to. + * + * \param ctx The current redraw context. + * \param bitmap The bitmap to plot + * \param x The x coordinate to plot the bitmap + * \param y The y coordiante to plot the bitmap + * \param width The width of area to plot the bitmap into + * \param height The height of area to plot the bitmap into + * \param bg the background colour to alpha blend into + * \param flags the flags controlling the type of plot operation + * \return NSERROR_OK on success else error code. + */ +static nserror +framebuffer_plot_bitmap(const struct redraw_context *ctx, + struct bitmap *bitmap, + int x, int y, + int width, + int height, + colour bg, + bitmap_flags_t flags) { - nsfb_bbox_t loc; - nsfb_bbox_t clipbox; - bool repeat_x = (flags & BITMAPF_REPEAT_X); - bool repeat_y = (flags & BITMAPF_REPEAT_Y); + nsfb_bbox_t loc; + nsfb_bbox_t clipbox; + bool repeat_x = (flags & BITMAPF_REPEAT_X); + bool repeat_y = (flags & BITMAPF_REPEAT_Y); int bmwidth; int bmheight; int bmstride; @@ -193,15 +328,18 @@ framebuffer_plot_bitmap(int x, int y, if (!(repeat_x || repeat_y)) { /* Not repeating at all, so just plot it */ - loc.x0 = x; - loc.y0 = y; - loc.x1 = loc.x0 + width; - loc.y1 = loc.y0 + height; + loc.x0 = x; + loc.y0 = y; + loc.x1 = loc.x0 + width; + loc.y1 = loc.y0 + height; - return nsfb_plot_copy(bm, NULL, nsfb, &loc); + if (!nsfb_plot_copy(bm, NULL, nsfb, &loc)) { + return NSERROR_INVALID; + } + return NSERROR_OK; } - nsfb_plot_get_clip(nsfb, &clipbox); + nsfb_plot_get_clip(nsfb, &clipbox); nsfb_get_geometry(bm, &bmwidth, &bmheight, &bmformat); nsfb_get_buffer(bm, &bmptr, &bmstride); @@ -209,8 +347,11 @@ framebuffer_plot_bitmap(int x, int y, * of the area. Can only be done when image is fully opaque. */ if ((bmwidth == 1) && (bmheight == 1)) { if ((*(nsfb_colour_t *)bmptr & 0xff000000) != 0) { - return nsfb_plot_rectangle_fill(nsfb, &clipbox, - *(nsfb_colour_t *)bmptr); + if (!nsfb_plot_rectangle_fill(nsfb, &clipbox, + *(nsfb_colour_t *)bmptr)) { + return NSERROR_INVALID; + } + return NSERROR_OK; } } @@ -221,24 +362,29 @@ framebuffer_plot_bitmap(int x, int y, if (framebuffer_bitmap_get_opaque(bm)) { /** TODO: Currently using top left pixel. Maybe centre * pixel or average value would be better. */ - return nsfb_plot_rectangle_fill(nsfb, &clipbox, - *(nsfb_colour_t *)bmptr); + if (!nsfb_plot_rectangle_fill(nsfb, &clipbox, + *(nsfb_colour_t *)bmptr)) { + return NSERROR_INVALID; + } + return NSERROR_OK; } } /* get left most tile position */ - if (repeat_x) + if (repeat_x) { for (; x > clipbox.x0; x -= width); + } /* get top most tile position */ - if (repeat_y) + if (repeat_y) { for (; y > clipbox.y0; y -= height); + } /* set up top left tile location */ - loc.x0 = x; - loc.y0 = y; - loc.x1 = loc.x0 + width; - loc.y1 = loc.y0 + height; + loc.x0 = x; + loc.y0 = y; + loc.x1 = loc.x0 + width; + loc.y1 = loc.y0 + height; /* plot tiling across and down to extents */ nsfb_plot_bitmap_tiles(nsfb, &loc, @@ -247,94 +393,135 @@ framebuffer_plot_bitmap(int x, int y, (nsfb_colour_t *)bmptr, bmwidth, bmheight, bmstride * 8 / 32, bmformat == NSFB_FMT_ABGR8888); - return true; + return NSERROR_OK; } -static bool -framebuffer_plot_rectangle(int x0, int y0, int x1, int y1, const plot_style_t *style) -{ - nsfb_bbox_t rect; - bool dotted = false; - bool dashed = false; - - rect.x0 = x0; - rect.y0 = y0; - rect.x1 = x1; - rect.y1 = y1; - if (style->fill_type != PLOT_OP_TYPE_NONE) { - nsfb_plot_rectangle_fill(nsfb, &rect, style->fill_colour); - } - - if (style->stroke_type != PLOT_OP_TYPE_NONE) { - if (style->stroke_type == PLOT_OP_TYPE_DOT) - dotted = true; - - if (style->stroke_type == PLOT_OP_TYPE_DASH) - dashed = true; +#ifdef FB_USE_FREETYPE +/** + * Text plotting. + * + * \param ctx The current redraw context. + * \param fstyle plot style for this text + * \param x x coordinate + * \param y y coordinate + * \param text UTF-8 string to plot + * \param length length of string, in bytes + * \return NSERROR_OK on success else error code. + */ +static nserror +framebuffer_plot_text(const struct redraw_context *ctx, + const struct plot_font_style *fstyle, + int x, + int y, + const char *text, + size_t length) +{ + uint32_t ucs4; + size_t nxtchr = 0; + FT_Glyph glyph; + FT_BitmapGlyph bglyph; + nsfb_bbox_t loc; + + while (nxtchr < length) { + ucs4 = utf8_to_ucs4(text + nxtchr, length - nxtchr); + nxtchr = utf8_next(text, length, nxtchr); + + glyph = fb_getglyph(fstyle, ucs4); + if (glyph == NULL) + continue; + + if (glyph->format == FT_GLYPH_FORMAT_BITMAP) { + bglyph = (FT_BitmapGlyph)glyph; + + loc.x0 = x + bglyph->left; + loc.y0 = y - bglyph->top; + loc.x1 = loc.x0 + bglyph->bitmap.width; + loc.y1 = loc.y0 + bglyph->bitmap.rows; + + /* now, draw to our target surface */ + if (bglyph->bitmap.pixel_mode == FT_PIXEL_MODE_MONO) { + nsfb_plot_glyph1(nsfb, + &loc, + bglyph->bitmap.buffer, + bglyph->bitmap.pitch, + fstyle->foreground); + } else { + nsfb_plot_glyph8(nsfb, + &loc, + bglyph->bitmap.buffer, + bglyph->bitmap.pitch, + fstyle->foreground); + } + } + x += glyph->advance.x >> 16; - nsfb_plot_rectangle(nsfb, &rect, style->stroke_width, style->stroke_colour, dotted, dashed); } + return NSERROR_OK; - return true; } -static bool -framebuffer_plot_line(int x0, int y0, int x1, int y1, const plot_style_t *style) +#else + +/** + * Text plotting. + * + * \param ctx The current redraw context. + * \param fstyle plot style for this text + * \param x x coordinate + * \param y y coordinate + * \param text UTF-8 string to plot + * \param length length of string, in bytes + * \return NSERROR_OK on success else error code. + */ +static nserror +framebuffer_plot_text(const struct redraw_context *ctx, + const struct plot_font_style *fstyle, + int x, + int y, + const char *text, + size_t length) { - nsfb_bbox_t rect; - nsfb_plot_pen_t pen; + enum fb_font_style style = fb_get_font_style(fstyle); + int size = fb_get_font_size(fstyle); + const uint8_t *chrp; + size_t nxtchr = 0; + nsfb_bbox_t loc; + uint32_t ucs4; + int p = FB_FONT_PITCH * size; + int w = FB_FONT_WIDTH * size; + int h = FB_FONT_HEIGHT * size; - rect.x0 = x0; - rect.y0 = y0; - rect.x1 = x1; - rect.y1 = y1; - - if (style->stroke_type != PLOT_OP_TYPE_NONE) { + y -= ((h * 3) / 4); + /* the coord is the bottom-left of the pixels offset by 1 to make + * it work since fb coords are the top-left of pixels */ + y += 1; - if (style->stroke_type == PLOT_OP_TYPE_DOT) { - pen.stroke_type = NFSB_PLOT_OPTYPE_PATTERN; - pen.stroke_pattern = 0xAAAAAAAA; - } else if (style->stroke_type == PLOT_OP_TYPE_DASH) { - pen.stroke_type = NFSB_PLOT_OPTYPE_PATTERN; - pen.stroke_pattern = 0xF0F0F0F0; - } else { - pen.stroke_type = NFSB_PLOT_OPTYPE_SOLID; - } + while (nxtchr < length) { + ucs4 = utf8_to_ucs4(text + nxtchr, length - nxtchr); + nxtchr = utf8_next(text, length, nxtchr); - pen.stroke_colour = style->stroke_colour; - pen.stroke_width = style->stroke_width; - nsfb_plot_line(nsfb, &rect, &pen); - } + if (!codepoint_displayable(ucs4)) + continue; - return true; -} + loc.x0 = x; + loc.y0 = y; + loc.x1 = loc.x0 + w; + loc.y1 = loc.y0 + h; + chrp = fb_get_glyph(ucs4, style, size); + nsfb_plot_glyph1(nsfb, &loc, chrp, p, fstyle->foreground); -static bool -framebuffer_plot_path(const float *p, - unsigned int n, - colour fill, - float width, - colour c, - const float transform[6]) -{ - LOG("path unimplemented"); - return true; -} + x += w; -static bool -framebuffer_plot_clip(const struct rect *clip) -{ - nsfb_bbox_t nsfb_clip; - nsfb_clip.x0 = clip->x0; - nsfb_clip.y0 = clip->y0; - nsfb_clip.x1 = clip->x1; - nsfb_clip.y1 = clip->y1; + } - return nsfb_plot_set_clip(nsfb, &nsfb_clip); + return NSERROR_OK; } +#endif + +/** framebuffer plot operation table */ const struct plotter_table fb_plotters = { .clip = framebuffer_plot_clip, .arc = framebuffer_plot_arc, @@ -345,7 +532,7 @@ const struct plotter_table fb_plotters = { .path = framebuffer_plot_path, .bitmap = framebuffer_plot_bitmap, .text = framebuffer_plot_text, - .option_knockout = true, + .option_knockout = true, }; @@ -377,7 +564,7 @@ static bool framebuffer_format_from_bpp(int bpp, enum nsfb_format_e *fmt) break; default: - LOG("Bad bits per pixel (%d)\n", bpp); + NSLOG(netsurf, INFO, "Bad bits per pixel (%d)\n", bpp); return false; } @@ -394,33 +581,34 @@ framebuffer_initialise(const char *fename, int width, int height, int bpp) /* bpp is a proxy for the framebuffer format */ if (framebuffer_format_from_bpp(bpp, &fbfmt) == false) { - return NULL; + return NULL; } fbtype = nsfb_type_from_name(fename); if (fbtype == NSFB_SURFACE_NONE) { - LOG("The %s surface is not available from libnsfb\n", fename); - return NULL; + NSLOG(netsurf, INFO, + "The %s surface is not available from libnsfb\n", fename); + return NULL; } nsfb = nsfb_new(fbtype); if (nsfb == NULL) { - LOG("Unable to create %s fb surface\n", fename); - return NULL; + NSLOG(netsurf, INFO, "Unable to create %s fb surface\n", fename); + return NULL; } - + if (nsfb_set_geometry(nsfb, width, height, fbfmt) == -1) { - LOG("Unable to set surface geometry\n"); - nsfb_free(nsfb); - return NULL; + NSLOG(netsurf, INFO, "Unable to set surface geometry\n"); + nsfb_free(nsfb); + return NULL; } nsfb_cursor_init(nsfb); - + if (nsfb_init(nsfb) == -1) { - LOG("Unable to initialise nsfb surface\n"); - nsfb_free(nsfb); - return NULL; + NSLOG(netsurf, INFO, "Unable to initialise nsfb surface\n"); + nsfb_free(nsfb); + return NULL; } return nsfb; @@ -434,12 +622,12 @@ framebuffer_resize(nsfb_t *nsfb, int width, int height, int bpp) /* bpp is a proxy for the framebuffer format */ if (framebuffer_format_from_bpp(bpp, &fbfmt) == false) { - return false; + return false; } if (nsfb_set_geometry(nsfb, width, height, fbfmt) == -1) { - LOG("Unable to change surface geometry\n"); - return false; + NSLOG(netsurf, INFO, "Unable to change surface geometry\n"); + return false; } return true; @@ -449,14 +637,14 @@ framebuffer_resize(nsfb_t *nsfb, int width, int height, int bpp) void framebuffer_finalise(void) { - nsfb_free(nsfb); + nsfb_free(nsfb); } bool framebuffer_set_cursor(struct fbtk_bitmap *bm) { return nsfb_cursor_set(nsfb, (nsfb_colour_t *)bm->pixdata, bm->width, bm->height, bm->width, bm->hot_x, bm->hot_y); -} +} nsfb_t *framebuffer_set_surface(nsfb_t *new_nsfb) { diff --git a/frontends/framebuffer/gui.c b/frontends/framebuffer/gui.c index 4d4c7334f..1e27dafb6 100644 --- a/frontends/framebuffer/gui.c +++ b/frontends/framebuffer/gui.c @@ -54,6 +54,7 @@ #include "framebuffer/clipboard.h" #include "framebuffer/fetch.h" #include "framebuffer/bitmap.h" +#include "framebuffer/local_history.h" #define NSFB_TOOLBAR_DEFAULT_LAYOUT "blfsrutc" @@ -119,7 +120,7 @@ static void die(const char *error) */ static nserror fb_warn_user(const char *warning, const char *detail) { - LOG("%s %s", warning, detail); + NSLOG(netsurf, INFO, "%s %s", warning, detail); return NSERROR_OK; } @@ -152,7 +153,7 @@ widget_scroll_y(struct gui_window *gw, int y, bool abs) int content_width, content_height; int height; - LOG("window scroll"); + NSLOG(netsurf, INFO, "window scroll"); if (abs) { bwidget->pany = y - bwidget->scrolly; } else { @@ -236,7 +237,7 @@ fb_pan(fbtk_widget_t *widget, height = fbtk_get_height(widget); width = fbtk_get_width(widget); - LOG("panning %d, %d", bwidget->panx, bwidget->pany); + NSLOG(netsurf, INFO, "panning %d, %d", bwidget->panx, bwidget->pany); x = fbtk_get_absx(widget); y = fbtk_get_absy(widget); @@ -412,7 +413,8 @@ fb_browser_window_redraw(fbtk_widget_t *widget, fbtk_callback_info *cbi) bwidget = fbtk_get_userpw(widget); if (bwidget == NULL) { - LOG("browser widget from widget %p was null", widget); + NSLOG(netsurf, INFO, + "browser widget from widget %p was null", widget); return -1; } @@ -464,7 +466,7 @@ process_cmdline(int argc, char** argv) {0, 0, 0, 0 } }; /* no long options */ - LOG("argc %d, argv %p", argc, argv); + NSLOG(netsurf, INFO, "argc %d, argv %p", argc, argv); fename = "sdl"; febpp = 32; @@ -533,7 +535,7 @@ static nserror set_defaults(struct nsoption_s *defaults) if (nsoption_charp(cookie_file) == NULL || nsoption_charp(cookie_jar) == NULL) { - LOG("Failed initialising cookie options"); + NSLOG(netsurf, INFO, "Failed initialising cookie options"); return NSERROR_BAD_PARAMETER; } @@ -611,7 +613,7 @@ static void framebuffer_run(void) static void gui_quit(void) { - LOG("gui_quit"); + NSLOG(netsurf, INFO, "gui_quit"); urldb_save_cookies(nsoption_charp(cookie_jar)); @@ -638,7 +640,8 @@ fb_browser_window_click(fbtk_widget_t *widget, fbtk_callback_info *cbi) cbi->event->type != NSFB_EVENT_KEY_UP) return 0; - LOG("browser window clicked at %d,%d", cbi->x, cbi->y); + NSLOG(netsurf, INFO, "browser window clicked at %d,%d", cbi->x, + cbi->y); switch (cbi->event->type) { case NSFB_EVENT_KEY_DOWN: @@ -823,7 +826,7 @@ fb_browser_window_input(fbtk_widget_t *widget, fbtk_callback_info *cbi) static fbtk_modifier_type modifier = FBTK_MOD_CLEAR; int ucs4 = -1; - LOG("got value %d", cbi->event->value.keycode); + NSLOG(netsurf, INFO, "got value %d", cbi->event->value.keycode); switch (cbi->event->type) { case NSFB_EVENT_KEY_DOWN: @@ -948,8 +951,8 @@ fb_browser_window_input(fbtk_widget_t *widget, fbtk_callback_info *cbi) browser_window_key_press(gw->bw, NS_KEY_REDO); break; } - /* Z or Y pressed but not undo or redo; - * Fall through to default handling */ + /* Z or Y pressed but not undo or redo; */ + /* Fall through */ default: ucs4 = fbtk_keycode_to_ucs4(cbi->event->value.keycode, @@ -1150,7 +1153,7 @@ fb_localhistory_btn_clik(fbtk_widget_t *widget, fbtk_callback_info *cbi) if (cbi->event->type != NSFB_EVENT_KEY_UP) return 0; - fb_localhistory_map(gw->localhistory); + fb_local_history_present(fbtk, gw->bw); return 0; } @@ -1199,7 +1202,7 @@ create_toolbar(struct gui_window *gw, toolbar_layout = NSFB_TOOLBAR_DEFAULT_LAYOUT; } - LOG("Using toolbar layout %s", toolbar_layout); + NSLOG(netsurf, INFO, "Using toolbar layout %s", toolbar_layout); itmtype = toolbar_layout; @@ -1233,7 +1236,7 @@ create_toolbar(struct gui_window *gw, (*itmtype != 0) && (xdir !=0)) { - LOG("toolbar adding %c", *itmtype); + NSLOG(netsurf, INFO, "toolbar adding %c", *itmtype); switch (*itmtype) { @@ -1375,7 +1378,9 @@ create_toolbar(struct gui_window *gw, default: widget = NULL; xdir = 0; - LOG("Unknown element %c in toolbar layout", *itmtype); + NSLOG(netsurf, INFO, + "Unknown element %c in toolbar layout", + *itmtype); break; } @@ -1384,7 +1389,7 @@ create_toolbar(struct gui_window *gw, xpos += (xdir * (fbtk_get_width(widget) + padding)); } - LOG("xpos is %d", xpos); + NSLOG(netsurf, INFO, "xpos is %d", xpos); itmtype += xdir; } @@ -1583,7 +1588,7 @@ resize_browser_widget(struct gui_window *gw, int x, int y, int width, int height) { fbtk_set_pos_and_size(gw->browser, x, y, width, height); - browser_window_reformat(gw->bw, false, width, height); + browser_window_schedule_reformat(gw->bw); } static void @@ -1594,7 +1599,7 @@ create_normal_browser_window(struct gui_window *gw, int furniture_width) int statusbar_width = 0; int toolbar_height = nsoption_int(fb_toolbar_size); - LOG("Normal window"); + NSLOG(netsurf, INFO, "Normal window"); gw->window = fbtk_create_window(fbtk, 0, 0, 0, 0, 0); @@ -1625,7 +1630,8 @@ create_normal_browser_window(struct gui_window *gw, int furniture_width) false); fbtk_set_handler(gw->status, FBTK_CBT_POINTERENTER, set_ptr_default_move, NULL); - LOG("status bar %p at %d,%d", gw->status, fbtk_get_absx(gw->status), fbtk_get_absy(gw->status)); + NSLOG(netsurf, INFO, "status bar %p at %d,%d", gw->status, + fbtk_get_absx(gw->status), fbtk_get_absy(gw->status)); /* create horizontal scrollbar */ gw->hscroll = fbtk_create_hscroll(gw->window, @@ -1782,7 +1788,6 @@ gui_window_create(struct browser_window *bw, gw->bw = bw; create_normal_browser_window(gw, nsoption_int(fb_furniture_size)); - gw->localhistory = fb_create_localhistory(bw, fbtk, nsoption_int(fb_furniture_size)); /* map and request redraw of gui window */ fbtk_set_mapping(gw->window, true); @@ -1803,21 +1808,33 @@ gui_window_destroy(struct gui_window *gw) free(gw); } -static void -gui_window_redraw_window(struct gui_window *g) -{ - fb_queue_redraw(g->browser, 0, 0, fbtk_get_width(g->browser), fbtk_get_height(g->browser) ); -} -static void -gui_window_update_box(struct gui_window *g, const struct rect *rect) +/** + * Invalidates an area of a framebuffer browser window + * + * \param g The netsurf window being invalidated. + * \param rect area to redraw or NULL for the entire window area + * \return NSERROR_OK on success or appropriate error code + */ +static nserror +fb_window_invalidate_area(struct gui_window *g, const struct rect *rect) { struct browser_widget_s *bwidget = fbtk_get_userpw(g->browser); - fb_queue_redraw(g->browser, - rect->x0 - bwidget->scrollx, - rect->y0 - bwidget->scrolly, - rect->x1 - bwidget->scrollx, - rect->y1 - bwidget->scrolly); + + if (rect != NULL) { + fb_queue_redraw(g->browser, + rect->x0 - bwidget->scrollx, + rect->y0 - bwidget->scrolly, + rect->x1 - bwidget->scrollx, + rect->y1 - bwidget->scrolly); + } else { + fb_queue_redraw(g->browser, + 0, + 0, + fbtk_get_width(g->browser), + fbtk_get_height(g->browser)); + } + return NSERROR_OK; } static bool @@ -1832,34 +1849,56 @@ gui_window_get_scroll(struct gui_window *g, int *sx, int *sy) return true; } -static void -gui_window_set_scroll(struct gui_window *gw, int sx, int sy) +/** + * Set the scroll position of a framebuffer browser window. + * + * Scrolls the viewport to ensure the specified rectangle of the + * content is shown. The framebuffer implementation scrolls the contents so + * the specified point in the content is at the top of the viewport. + * + * \param gw gui_window to scroll + * \param rect The rectangle to ensure is shown. + * \return NSERROR_OK on success or apropriate error code. + */ +static nserror +gui_window_set_scroll(struct gui_window *gw, const struct rect *rect) { struct browser_widget_s *bwidget = fbtk_get_userpw(gw->browser); float scale = browser_window_get_scale(gw->bw); assert(bwidget); - widget_scroll_x(gw, sx * scale, true); - widget_scroll_y(gw, sy * scale, true); + widget_scroll_x(gw, rect->x0 * scale, true); + widget_scroll_y(gw, rect->y0 * scale, true); + + return NSERROR_OK; } -static void -gui_window_get_dimensions(struct gui_window *g, +/** + * Find the current dimensions of a framebuffer browser window content area. + * + * \param gw The gui window to measure content area of. + * \param width receives width of window + * \param height receives height of window + * \param scaled whether to return scaled values + * \return NSERROR_OK on sucess and width and height updated. + */ +static nserror +gui_window_get_dimensions(struct gui_window *gw, int *width, int *height, bool scaled) { - float scale = browser_window_get_scale(g->bw); - - *width = fbtk_get_width(g->browser); - *height = fbtk_get_height(g->browser); + *width = fbtk_get_width(gw->browser); + *height = fbtk_get_height(gw->browser); if (scaled) { + float scale = browser_window_get_scale(gw->bw); *width /= scale; *height /= scale; } + return NSERROR_OK; } static void @@ -2038,26 +2077,15 @@ gui_window_remove_caret(struct gui_window *g) } } -static void framebuffer_window_reformat(struct gui_window *gw) -{ - /** @todo if we ever do zooming reformat should be implemented */ - LOG("window:%p", gw); - - /* - browser_window_reformat(gw->bw, false, width, height); - */ -} static struct gui_window_table framebuffer_window_table = { .create = gui_window_create, .destroy = gui_window_destroy, - .redraw = gui_window_redraw_window, - .update = gui_window_update_box, + .invalidate = fb_window_invalidate_area, .get_scroll = gui_window_get_scroll, .set_scroll = gui_window_set_scroll, .get_dimensions = gui_window_get_dimensions, .update_extent = gui_window_update_extent, - .reformat = framebuffer_window_reformat, .set_url = gui_window_set_url, .set_status = gui_window_set_status, @@ -2160,7 +2188,7 @@ main(int argc, char** argv) /* create an initial browser window */ - LOG("calling browser_window_create"); + NSLOG(netsurf, INFO, "calling browser_window_create"); ret = nsurl_create(feurl, &url); if (ret == NSERROR_OK) { @@ -2182,11 +2210,14 @@ main(int argc, char** argv) netsurf_exit(); if (fb_font_finalise() == false) - LOG("Font finalisation failed."); + NSLOG(netsurf, INFO, "Font finalisation failed."); /* finalise options */ nsoption_finalise(nsoptions, nsoptions_default); + /* finalise logging */ + nslog_finalise(); + return 0; } diff --git a/frontends/framebuffer/gui.h b/frontends/framebuffer/gui.h index 0de1add69..abb27c4bb 100644 --- a/frontends/framebuffer/gui.h +++ b/frontends/framebuffer/gui.h @@ -27,17 +27,6 @@ typedef struct fb_cursor_s fb_cursor_t; /* bounding box */ typedef struct nsfb_bbox_s bbox_t; -struct gui_localhistory { - struct browser_window *bw; - - struct fbtk_widget_s *window; - struct fbtk_widget_s *hscroll; - struct fbtk_widget_s *vscroll; - struct fbtk_widget_s *history; - - int scrollx, scrolly; /**< scroll offsets. */ -}; - struct gui_window { struct browser_window *bw; @@ -59,8 +48,6 @@ struct gui_window { int throbber_index; - struct gui_localhistory *localhistory; - struct gui_window *next; struct gui_window *prev; }; @@ -68,13 +55,8 @@ struct gui_window { extern struct gui_window *window_list; -struct gui_localhistory *fb_create_localhistory(struct browser_window *bw, - struct fbtk_widget_s *parent, int furniture_width); -void fb_localhistory_map(struct gui_localhistory * glh); - void gui_resize(struct fbtk_widget_s *root, int width, int height); - #endif /* NETSURF_FB_GUI_H */ /* diff --git a/frontends/framebuffer/local_history.c b/frontends/framebuffer/local_history.c new file mode 100644 index 000000000..cc45b1f29 --- /dev/null +++ b/frontends/framebuffer/local_history.c @@ -0,0 +1,248 @@ +/* + * Copyright 2017 Vincent Sanders <vince@netsurf-browser.org> + * + * This file is part of NetSurf, http://www.netsurf-browser.org/ + * + * NetSurf is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * NetSurf is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +/** + * \file + * Implementation of framebuffer local history manager. + */ + +#include <stdint.h> +#include <stdbool.h> +#include <stdlib.h> +#include <limits.h> + +#include <libnsfb.h> +#include <libnsfb_plot.h> +#include <libnsfb_event.h> + +#include "utils/log.h" +#include "netsurf/keypress.h" +#include "netsurf/plotters.h" +#include "desktop/local_history.h" + +#include "framebuffer/gui.h" +#include "framebuffer/fbtk.h" +#include "framebuffer/framebuffer.h" +#include "framebuffer/corewindow.h" +#include "framebuffer/local_history.h" + +struct fb_local_history_window { + struct fb_corewindow core; + + struct local_history_session *session; +}; + +static struct fb_local_history_window *local_history_window = NULL; + + +/** + * callback for mouse action on local history window + * + * \param fb_cw The fb core window structure. + * \param mouse_state netsurf mouse state on event + * \param x location of event + * \param y location of event + * \return NSERROR_OK on success otherwise apropriate error code + */ +static nserror +fb_local_history_mouse(struct fb_corewindow *fb_cw, + browser_mouse_state mouse_state, + int x, int y) +{ + struct fb_local_history_window *lhw; + /* technically degenerate container of */ + lhw = (struct fb_local_history_window *)fb_cw; + + local_history_mouse_action(lhw->session, mouse_state, x, y); + + if (mouse_state != BROWSER_MOUSE_HOVER) { + fbtk_set_mapping(lhw->core.wnd, false); + } + + return NSERROR_OK; +} + + +/** + * callback for keypress on local history window + * + * \param fb_cw The fb core window structure. + * \param nskey The netsurf key code + * \return NSERROR_OK on success otherwise apropriate error code + */ +static nserror +fb_local_history_key(struct fb_corewindow *fb_cw, uint32_t nskey) +{ + struct fb_local_history_window *lhw; + /* technically degenerate container of */ + lhw = (struct fb_local_history_window *)fb_cw; + + if (local_history_keypress(lhw->session, nskey)) { + return NSERROR_OK; + } + return NSERROR_NOT_IMPLEMENTED; +} + + +/** + * callback on draw event for local history window + * + * \param fb_cw The fb core window structure. + * \param r The rectangle of the window that needs updating. + * \return NSERROR_OK on success otherwise apropriate error code + */ +static nserror +fb_local_history_draw(struct fb_corewindow *fb_cw, struct rect *r) +{ + struct redraw_context ctx = { + .interactive = true, + .background_images = true, + .plot = &fb_plotters + }; + struct fb_local_history_window *lhw; + + /* technically degenerate container of */ + lhw = (struct fb_local_history_window *)fb_cw; + + local_history_redraw(lhw->session, 0, 0, r, &ctx); + + return NSERROR_OK; +} + +/** + * Creates the window for the local history view. + * + * \return NSERROR_OK on success else appropriate error code on faliure. + */ +static nserror +fb_local_history_init(fbtk_widget_t *parent, + struct browser_window *bw, + struct fb_local_history_window **win_out) +{ + struct fb_local_history_window *ncwin; + nserror res; + + /* memoise window so it can be represented when necessary + * instead of recreating every time. + */ + if ((*win_out) != NULL) { + res = local_history_set((*win_out)->session, bw); + return res; + } + + ncwin = calloc(1, sizeof(*ncwin)); + if (ncwin == NULL) { + return NSERROR_NOMEM; + } + + ncwin->core.draw = fb_local_history_draw; + ncwin->core.key = fb_local_history_key; + ncwin->core.mouse = fb_local_history_mouse; + + res = fb_corewindow_init(parent, &ncwin->core); + if (res != NSERROR_OK) { + free(ncwin); + return res; + } + + res = local_history_init(ncwin->core.cb_table, + (struct core_window *)ncwin, + bw, + &ncwin->session); + if (res != NSERROR_OK) { + free(ncwin); + return res; + } + + *win_out = ncwin; + + return NSERROR_OK; +} + + +/* exported function documented gtk/history.h */ +nserror fb_local_history_present(fbtk_widget_t *parent, + struct browser_window *bw) +{ + nserror res; + int prnt_width, prnt_height; + int width, height; + + res = fb_local_history_init(parent, bw, &local_history_window); + if (res == NSERROR_OK) { + + prnt_width = fbtk_get_width(parent); + prnt_height = fbtk_get_height(parent); + + /* resize history widget ensureing the drawing area is + * no larger than parent window + */ + res = local_history_get_size(local_history_window->session, + &width, + &height); + if (width > prnt_width) { + width = prnt_width; + } + if (height > prnt_height) { + height = prnt_height; + } + /* should update scroll area with contents */ + + fbtk_set_zorder(local_history_window->core.wnd, INT_MIN); + fbtk_set_mapping(local_history_window->core.wnd, true); + } + + return res; +} + + +/* exported function documented gtk/history.h */ +nserror fb_local_history_hide(void) +{ + nserror res = NSERROR_OK; + + if (local_history_window != NULL) { + fbtk_set_mapping(local_history_window->core.wnd, false); + + res = local_history_set(local_history_window->session, NULL); + } + + return res; +} + + +/* exported function documented gtk/history.h */ +nserror fb_local_history_destroy(void) +{ + nserror res; + + if (local_history_window == NULL) { + return NSERROR_OK; + } + + res = local_history_fini(local_history_window->session); + if (res == NSERROR_OK) { + res = fb_corewindow_fini(&local_history_window->core); + //gtk_widget_destroy(GTK_WIDGET(local_history_window->wnd)); + free(local_history_window); + local_history_window = NULL; + } + + return res; + +} diff --git a/frontends/framebuffer/local_history.h b/frontends/framebuffer/local_history.h new file mode 100644 index 000000000..929eeacd8 --- /dev/null +++ b/frontends/framebuffer/local_history.h @@ -0,0 +1,49 @@ +/* + * Copyright 2017 Vincent Sanders <vince@netsurf-browser.org> + * + * This file is part of NetSurf, http://www.netsurf-browser.org/ + * + * NetSurf is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * NetSurf is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +/** + * \file + * Interface to framebuffer local history manager + */ + +#ifndef FB_LOCAL_HISTORY_H +#define FB_LOCAL_HISTORY_H + +struct browser_window; + +/** + * make the local history window visible. + * + * \return NSERROR_OK on success else appropriate error code on faliure. + */ +nserror fb_local_history_present(fbtk_widget_t *parent, struct browser_window *bw); + +/** + * hide the local history window from being visible. + * + * \return NSERROR_OK on success else appropriate error code on faliure. + */ +nserror fb_local_history_hide(void); + +/** + * Destroys the local history window and performs any other necessary cleanup + * actions. + */ +nserror fb_local_history_destroy(void); + +#endif diff --git a/frontends/framebuffer/localhistory.c b/frontends/framebuffer/localhistory.c deleted file mode 100644 index 3192f0747..000000000 --- a/frontends/framebuffer/localhistory.c +++ /dev/null @@ -1,144 +0,0 @@ -/* - * Copyright 2010 Vincent Sanders <vince@simtec.co.uk> - * - * This file is part of NetSurf, http://www.netsurf-browser.org/ - * - * NetSurf is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * NetSurf is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - */ - -#include <stdbool.h> -#include <stdlib.h> -#include <limits.h> - -#include <libnsfb.h> -#include <libnsfb_plot.h> -#include <libnsfb_event.h> - -#include "desktop/browser_history.h" -#include "netsurf/plotters.h" - -#include "framebuffer/gui.h" -#include "framebuffer/fbtk.h" -#include "framebuffer/framebuffer.h" - -static int -localhistory_redraw(fbtk_widget_t *widget, fbtk_callback_info *cbi) -{ - struct gui_localhistory *glh = cbi->context; - nsfb_bbox_t rbox; - - struct redraw_context ctx = { - .interactive = true, - .background_images = true, - .plot = &fb_plotters - }; - - rbox.x0 = fbtk_get_absx(widget); - rbox.y0 = fbtk_get_absy(widget); - - rbox.x1 = rbox.x0 + fbtk_get_width(widget); - rbox.y1 = rbox.y0 + fbtk_get_height(widget); - - nsfb_claim(fbtk_get_nsfb(widget), &rbox); - - nsfb_plot_rectangle_fill(fbtk_get_nsfb(widget), &rbox, 0xffffffff); - - browser_window_history_redraw_rectangle(glh->bw, - glh->scrollx, - glh->scrolly, - fbtk_get_width(widget) + glh->scrollx, - fbtk_get_height(widget) + glh->scrolly, - 0, 0, &ctx); - - nsfb_update(fbtk_get_nsfb(widget), &rbox); - - return 0; -} - -static int -localhistory_click(fbtk_widget_t *widget, fbtk_callback_info *cbi) -{ - struct gui_localhistory *glh = cbi->context; - - if (cbi->event->type != NSFB_EVENT_KEY_UP) - return 0; - - browser_window_history_click(glh->bw, cbi->x, cbi->y, false); - - fbtk_set_mapping(glh->window, false); - - return 1; -} - -struct gui_localhistory * -fb_create_localhistory(struct browser_window *bw, - fbtk_widget_t *parent, - int furniture_width) -{ - struct gui_localhistory *glh; - glh = calloc(1, sizeof(struct gui_localhistory)); - - if (glh == NULL) - return NULL; - - glh->bw = bw; - - /* container window */ - glh->window = fbtk_create_window(parent, 0, 0, 0, 0, 0); - - glh->history = fbtk_create_user(glh->window, 0, 0, -furniture_width, -furniture_width, glh); - - fbtk_set_handler(glh->history, FBTK_CBT_REDRAW, localhistory_redraw, glh); - fbtk_set_handler(glh->history, FBTK_CBT_CLICK, localhistory_click, glh); - /* - fbtk_set_handler(gw->localhistory, FBTK_CBT_INPUT, fb_browser_window_input, gw); - fbtk_set_handler(gw->localhistory, FBTK_CBT_POINTERMOVE, fb_browser_window_move, bw); - */ - - /* create horizontal scrollbar */ - glh->hscroll = fbtk_create_hscroll(glh->window, - 0, - fbtk_get_height(glh->window) - furniture_width, - fbtk_get_width(glh->window) - furniture_width, - furniture_width, - FB_SCROLL_COLOUR, - FB_FRAME_COLOUR, - NULL, - NULL); - - glh->vscroll = fbtk_create_vscroll(glh->window, - fbtk_get_width(glh->window) - furniture_width, - 0, - furniture_width, - fbtk_get_height(glh->window) - furniture_width, - FB_SCROLL_COLOUR, - FB_FRAME_COLOUR, - NULL, - NULL); - - fbtk_create_fill(glh->window, - fbtk_get_width(glh->window) - furniture_width, - fbtk_get_height(glh->window) - furniture_width, - furniture_width, - furniture_width, - FB_FRAME_COLOUR); - - return glh; -} - -void -fb_localhistory_map(struct gui_localhistory * glh) -{ - fbtk_set_zorder(glh->window, INT_MIN); - fbtk_set_mapping(glh->window, true); -} diff --git a/frontends/framebuffer/res/Messages b/frontends/framebuffer/res/Messages deleted file mode 120000 index 72c9eff90..000000000 --- a/frontends/framebuffer/res/Messages +++ /dev/null @@ -1 +0,0 @@ -../../../!NetSurf/Resources/en/Messages
\ No newline at end of file diff --git a/frontends/framebuffer/res/adblock.css b/frontends/framebuffer/res/adblock.css index ff2485622..0d12aaa7c 120000 --- a/frontends/framebuffer/res/adblock.css +++ b/frontends/framebuffer/res/adblock.css @@ -1 +1 @@ -../../../!NetSurf/Resources/AdBlock,f79
\ No newline at end of file +../../../resources/adblock.css
\ No newline at end of file diff --git a/frontends/framebuffer/res/credits.html b/frontends/framebuffer/res/credits.html index 1ba17392b..b43a1a06c 120000 --- a/frontends/framebuffer/res/credits.html +++ b/frontends/framebuffer/res/credits.html @@ -1 +1 @@ -../../../!NetSurf/Resources/en/credits.html,faf
\ No newline at end of file +../../../resources/en/credits.html
\ No newline at end of file diff --git a/frontends/framebuffer/res/default.css b/frontends/framebuffer/res/default.css index a8579eb7c..fa3ae6c26 120000 --- a/frontends/framebuffer/res/default.css +++ b/frontends/framebuffer/res/default.css @@ -1 +1 @@ -../../../!NetSurf/Resources/CSS,f79
\ No newline at end of file +../../../resources/default.css
\ No newline at end of file diff --git a/frontends/framebuffer/res/internal.css b/frontends/framebuffer/res/internal.css index 17f9f1504..5583a9811 120000 --- a/frontends/framebuffer/res/internal.css +++ b/frontends/framebuffer/res/internal.css @@ -1 +1 @@ -../../../!NetSurf/Resources/internal.css,f79
\ No newline at end of file +../../../resources/internal.css
\ No newline at end of file diff --git a/frontends/framebuffer/res/licence.html b/frontends/framebuffer/res/licence.html index 147dd6db2..c0c1e6630 120000 --- a/frontends/framebuffer/res/licence.html +++ b/frontends/framebuffer/res/licence.html @@ -1 +1 @@ -../../../!NetSurf/Resources/en/licence.html,faf
\ No newline at end of file +../../../resources/en/licence.html
\ No newline at end of file diff --git a/frontends/framebuffer/res/maps.html b/frontends/framebuffer/res/maps.html index 28362130a..05bcdc42e 120000 --- a/frontends/framebuffer/res/maps.html +++ b/frontends/framebuffer/res/maps.html @@ -1 +1 @@ -../../../!NetSurf/Resources/en/welcome.html,faf
\ No newline at end of file +../../../resources/en/maps.html
\ No newline at end of file diff --git a/frontends/framebuffer/res/netsurf.png b/frontends/framebuffer/res/netsurf.png index 905512c25..d0ab72a5e 120000 --- a/frontends/framebuffer/res/netsurf.png +++ b/frontends/framebuffer/res/netsurf.png @@ -1 +1 @@ -../../../!NetSurf/Resources/netsurf.png,b60
\ No newline at end of file +../../../resources/netsurf.png
\ No newline at end of file diff --git a/frontends/framebuffer/res/quirks.css b/frontends/framebuffer/res/quirks.css index 88aabe48c..1e752cb9e 120000 --- a/frontends/framebuffer/res/quirks.css +++ b/frontends/framebuffer/res/quirks.css @@ -1 +1 @@ -../../../!NetSurf/Resources/Quirks,f79
\ No newline at end of file +../../../resources/quirks.css
\ No newline at end of file diff --git a/frontends/framebuffer/res/welcome.html b/frontends/framebuffer/res/welcome.html index 28362130a..d5220f90a 120000 --- a/frontends/framebuffer/res/welcome.html +++ b/frontends/framebuffer/res/welcome.html @@ -1 +1 @@ -../../../!NetSurf/Resources/en/welcome.html,faf
\ No newline at end of file +../../../resources/en/welcome.html
\ No newline at end of file diff --git a/frontends/framebuffer/schedule.c b/frontends/framebuffer/schedule.c index 581ad72f1..6d1711236 100644 --- a/frontends/framebuffer/schedule.c +++ b/frontends/framebuffer/schedule.c @@ -24,12 +24,6 @@ #include "framebuffer/schedule.h" -#ifdef DEBUG_SCHEDULER -#define SRLOG(x...) LOG(x) -#else -#define SRLOG(x...) ((void) 0) -#endif - /* linked list of scheduled callbacks */ static struct nscallback *schedule_list = NULL; @@ -63,7 +57,7 @@ static nserror schedule_remove(void (*callback)(void *p), void *p) return NSERROR_OK; } - SRLOG("removing %p, %p", callback, p); + NSLOG(schedule, DEBUG, "removing %p, %p", callback, p); cur_nscb = schedule_list; prev_nscb = NULL; @@ -73,7 +67,8 @@ static nserror schedule_remove(void (*callback)(void *p), void *p) (cur_nscb->p == p)) { /* item to remove */ - SRLOG("callback entry %p removing %p(%p)", + NSLOG(schedule, DEBUG, + "callback entry %p removing %p(%p)", cur_nscb, cur_nscb->callback, cur_nscb->p); /* remove callback */ @@ -109,7 +104,7 @@ nserror framebuffer_schedule(int tival, void (*callback)(void *p), void *p) return ret; } - SRLOG("Adding %p(%p) in %d", callback, p, tival); + NSLOG(schedule, DEBUG, "Adding %p(%p) in %d", callback, p, tival); tv.tv_sec = tival / 1000; /* miliseconds to seconds */ tv.tv_usec = (tival % 1000) * 1000; /* remainder to microseconds */ @@ -190,7 +185,9 @@ int schedule_run(void) /* make rettime relative to now */ timersub(&nexttime, &tv, &rettime); - SRLOG("returning time to next event as %ldms",(rettime.tv_sec * 1000) + (rettime.tv_usec / 1000)); + NSLOG(schedule, DEBUG, + "returning time to next event as %ldms", + (rettime.tv_sec * 1000) + (rettime.tv_usec / 1000)); /* return next event time in milliseconds (24days max wait) */ return (rettime.tv_sec * 1000) + (rettime.tv_usec / 1000); @@ -203,12 +200,14 @@ void list_schedule(void) gettimeofday(&tv, NULL); - LOG("schedule list at %ld:%ld", tv.tv_sec, tv.tv_usec); + NSLOG(netsurf, INFO, "schedule list at %ld:%ld", tv.tv_sec, + tv.tv_usec); cur_nscb = schedule_list; while (cur_nscb != NULL) { - LOG("Schedule %p at %ld:%ld", cur_nscb, cur_nscb->tv.tv_sec, cur_nscb->tv.tv_usec); + NSLOG(netsurf, INFO, "Schedule %p at %ld:%ld", cur_nscb, + cur_nscb->tv.tv_sec, cur_nscb->tv.tv_usec); cur_nscb = cur_nscb->next; } } |