summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn Mark Bell <jmb@netsurf-browser.org>2010-07-07 18:08:17 +0000
committerJohn Mark Bell <jmb@netsurf-browser.org>2010-07-07 18:08:17 +0000
commit5bebf2f2fc27a31c8b2efa7a837baef63c1b0a97 (patch)
tree65d353a907c3496eb638bbff780ff4d0f1437313
parentf6faa20a37f38643d505ba41baa8a88e3dfa545a (diff)
downloadnetsurf-5bebf2f2fc27a31c8b2efa7a837baef63c1b0a97.tar.gz
netsurf-5bebf2f2fc27a31c8b2efa7a837baef63c1b0a97.tar.bz2
Merge branches/vince/netsurf-fbtk-rework to trunk.
svn path=/trunk/netsurf/; revision=10605
-rw-r--r--Makefile.resources2
-rw-r--r--Makefile.sources10
-rw-r--r--desktop/plot_style.h4
-rw-r--r--framebuffer/fbtk.c1209
-rw-r--r--framebuffer/fbtk.h358
-rw-r--r--framebuffer/fbtk/bitmap.c137
-rw-r--r--framebuffer/fbtk/event.c273
-rw-r--r--framebuffer/fbtk/fbtk.c726
-rw-r--r--framebuffer/fbtk/fill.c81
-rw-r--r--framebuffer/fbtk/osk.c202
-rw-r--r--framebuffer/fbtk/scroll.c543
-rw-r--r--framebuffer/fbtk/text.c421
-rw-r--r--framebuffer/fbtk/user.c64
-rw-r--r--framebuffer/fbtk/widget.h246
-rw-r--r--framebuffer/fbtk/window.c91
-rw-r--r--framebuffer/fbtk_widget.h109
-rw-r--r--framebuffer/fbtk_widget_scroll.c305
-rw-r--r--framebuffer/framebuffer.c6
-rw-r--r--framebuffer/gui.c1503
-rw-r--r--framebuffer/gui.h45
-rw-r--r--framebuffer/image_data.h3
-rw-r--r--framebuffer/localhistory.c162
-rw-r--r--framebuffer/options.h54
-rw-r--r--framebuffer/res/icons/history.pngbin0 -> 884 bytes
-rw-r--r--framebuffer/res/icons/history_g.pngbin0 -> 798 bytes
-rw-r--r--framebuffer/thumbnail.c13
26 files changed, 4130 insertions, 2437 deletions
diff --git a/Makefile.resources b/Makefile.resources
index 2a5493226..285275367 100644
--- a/Makefile.resources
+++ b/Makefile.resources
@@ -18,11 +18,13 @@ FB_IMAGE_left_arrow := framebuffer/res/icons/back.png
FB_IMAGE_right_arrow := framebuffer/res/icons/forward.png
FB_IMAGE_reload := framebuffer/res/icons/reload.png
FB_IMAGE_stop_image := framebuffer/res/icons/stop.png
+FB_IMAGE_history_image := framebuffer/res/icons/history.png
FB_IMAGE_left_arrow_g := framebuffer/res/icons/back_g.png
FB_IMAGE_right_arrow_g := framebuffer/res/icons/forward_g.png
FB_IMAGE_reload_g := framebuffer/res/icons/reload_g.png
FB_IMAGE_stop_image_g := framebuffer/res/icons/stop_g.png
+FB_IMAGE_history_image_g := framebuffer/res/icons/history_g.png
FB_IMAGE_scrolll := framebuffer/res/icons/scrolll.png
FB_IMAGE_scrollr := framebuffer/res/icons/scrollr.png
diff --git a/Makefile.sources b/Makefile.sources
index ed3c6751f..e5ff9183d 100644
--- a/Makefile.sources
+++ b/Makefile.sources
@@ -99,10 +99,14 @@ S_AMIGA := compat.c gui.c tree.c history.c hotlist.c schedule.c \
stringview/stringview.c stringview/urlhistory.c
S_AMIGA := $(addprefix amiga/,$(S_AMIGA))
+
# S_FRAMEBUFFER are sources purely for the framebuffer build
S_FRAMEBUFFER := gui.c framebuffer.c tree.c history.c hotlist.c \
save.c schedule.c thumbnail.c misc.c bitmap.c filetype.c \
- login.c findfile.c fbtk.c fbtk_widget_scroll.c
+ login.c findfile.c localhistory.c
+
+S_FRAMEBUFFER_FBTK := fbtk.c event.c fill.c bitmap.c user.c window.c \
+ text.c scroll.c osk.c
S_FRAMEBUFFER += font_$(NETSURF_FB_FONTLIB).c
@@ -111,8 +115,8 @@ S_FRAMEBUFFER += nsfont_regular.c nsfont_italic.c nsfont_bold.c \
nsfont_italic_bold.c
endif
+S_FRAMEBUFFER := $(addprefix framebuffer/,$(S_FRAMEBUFFER)) $(addprefix framebuffer/fbtk/,$(S_FRAMEBUFFER_FBTK))
-S_FRAMEBUFFER := $(addprefix framebuffer/,$(S_FRAMEBUFFER))
# Some extra rules for building the transliteration table.
ifeq ($(HOST),riscos)
@@ -162,7 +166,7 @@ endif
ifeq ($(TARGET),amiga)
SOURCES := $(S_COMMON) $(S_IMAGE) $(S_BROWSER) $(S_AMIGA) $(S_PDF)
-EXETARGET := NetSurf$(SUBTARGET)
+EXETARGET := NetSurf
endif
ifeq ($(TARGET),framebuffer)
diff --git a/desktop/plot_style.h b/desktop/plot_style.h
index a3b3f0103..1271e138b 100644
--- a/desktop/plot_style.h
+++ b/desktop/plot_style.h
@@ -31,13 +31,13 @@
/* Darken a colour by taking three quarters of each channel's intensity */
#define darken_colour(c1) \
- ((((3 * (c1 >> 16)) >> 2) << 16) | \
+ ((((3 * ((c1 >> 16) & 0xff)) >> 2) << 16) | \
(((3 * ((c1 >> 8) & 0xff)) >> 2) << 8) | \
(((3 * (c1 & 0xff)) >> 2) << 0))
/* Darken a colour by taking nine sixteenths of each channel's intensity */
#define double_darken_colour(c1) \
- ((((9 * (c1 >> 16)) >> 4) << 16) | \
+ ((((9 * ((c1 >> 16) & 0xff)) >> 4) << 16) | \
(((9 * ((c1 >> 8) & 0xff)) >> 4) << 8) | \
(((9 * (c1 & 0xff)) >> 4) << 0))
diff --git a/framebuffer/fbtk.c b/framebuffer/fbtk.c
deleted file mode 100644
index 56215bdd5..000000000
--- a/framebuffer/fbtk.c
+++ /dev/null
@@ -1,1209 +0,0 @@
-/*
- * Copyright 2008 Vincent Sanders <vince@simtec.co.uk>
- *
- * Framebuffer windowing toolkit
- *
- * 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 <sys/types.h>
-#include <stdint.h>
-#include <string.h>
-#include <stdbool.h>
-
-#include <libnsfb.h>
-#include <libnsfb_plot.h>
-#include <libnsfb_plot_util.h>
-#include <libnsfb_event.h>
-#include <libnsfb_cursor.h>
-
-#include "utils/utils.h"
-#include "utils/log.h"
-#include "css/css.h"
-#include "desktop/browser.h"
-#include "desktop/plotters.h"
-
-#include "framebuffer/gui.h"
-#include "framebuffer/fbtk.h"
-#include "framebuffer/fbtk_widget.h"
-#include "framebuffer/bitmap.h"
-#include "framebuffer/image_data.h"
-
-static plot_font_style_t root_style = {
- .family = PLOT_FONT_FAMILY_SANS_SERIF,
- .size = 11 * FONT_SIZE_SCALE,
- .weight = 400,
- .flags = FONTF_NONE,
-};
-
-
-/* widget list */
-struct fbtk_widget_list_s {
- struct fbtk_widget_list_s *next;
- struct fbtk_widget_list_s *prev;
- fbtk_widget_t *widget;
-} ;
-
-enum {
- POINT_LEFTOF_REGION = 1,
- POINT_RIGHTOF_REGION = 2,
- POINT_ABOVE_REGION = 4,
- POINT_BELOW_REGION = 8,
-};
-
-#define REGION(x,y,cx1,cx2,cy1,cy2) \
- (( (y) > (cy2) ? POINT_BELOW_REGION : 0) | \
- ( (y) < (cy1) ? POINT_ABOVE_REGION : 0) | \
- ( (x) > (cx2) ? POINT_RIGHTOF_REGION : 0) | \
- ( (x) < (cx1) ? POINT_LEFTOF_REGION : 0) )
-
-#define SWAP(a, b) do { int t; t=(a); (a)=(b); (b)=t; } while(0)
-
-/* clip a rectangle to another rectangle */
-bool fbtk_clip_rect(const bbox_t * restrict clip, bbox_t * restrict box)
-{
- uint8_t region1;
- uint8_t region2;
-
- if (box->x1 < box->x0) SWAP(box->x0, box->x1);
- if (box->y1 < box->y0) SWAP(box->y0, box->y1);
-
- region1 = REGION(box->x0, box->y0, clip->x0, clip->x1 - 1, clip->y0, clip->y1 - 1);
- region2 = REGION(box->x1, box->y1, clip->x0, clip->x1 - 1, clip->y0, clip->y1 - 1);
-
- /* area lies entirely outside the clipping rectangle */
- if ((region1 | region2) && (region1 & region2))
- return false;
-
- if (box->x0 < clip->x0)
- box->x0 = clip->x0;
- if (box->x0 > clip->x1)
- box->x0 = clip->x1;
-
- if (box->x1 < clip->x0)
- box->x1 = clip->x0;
- if (box->x1 > clip->x1)
- box->x1 = clip->x1;
-
- if (box->y0 < clip->y0)
- box->y0 = clip->y0;
- if (box->y0 > clip->y1)
- box->y0 = clip->y1;
-
- if (box->y1 < clip->y0)
- box->y1 = clip->y0;
- if (box->y1 > clip->y1)
- box->y1 = clip->y1;
-
- return true;
-}
-
-/* clip a rectangle to a widgets area rectangle */
-bool fbtk_clip_to_widget(fbtk_widget_t *widget, bbox_t * restrict box)
-{
- bbox_t wbox;
- wbox.x0 = 0;
- wbox.y0 = 0;
- wbox.x1 = widget->width;
- wbox.y1 = widget->height;
- return fbtk_clip_rect(&wbox, box);
-}
-
-
-/* creates a new widget of a given type */
-fbtk_widget_t *
-new_widget(enum fbtk_widgettype_e type)
-{
- fbtk_widget_t *neww;
- neww = calloc(1, sizeof(fbtk_widget_t));
- neww->type = type;
- return neww;
-}
-
-
-/* find the root widget from any widget in the toolkits hierarchy */
-fbtk_widget_t *
-get_root_widget(fbtk_widget_t *widget)
-{
- while (widget->parent != NULL)
- widget = widget->parent;
-
- /* check root widget was found */
- if (widget->type != FB_WIDGET_TYPE_ROOT) {
- LOG(("Widget with null parent that is not the root widget!"));
- return NULL;
- }
-
- return widget;
-}
-
-
-/* set widget to be redrawn */
-void
-fbtk_request_redraw(fbtk_widget_t *widget)
-{
- widget->redraw_required = true;
-
- if (widget->type == FB_WIDGET_TYPE_WINDOW) {
- fbtk_widget_list_t *lent = widget->u.window.widgets;
-
- while (lent != NULL) {
- lent->widget->redraw_required = true;
- lent = lent->next;
- }
- }
-
- while (widget->parent != NULL) {
- widget = widget->parent;
- widget->redraw_required = true;
- }
-}
-
-fbtk_widget_t *
-add_widget_to_window(fbtk_widget_t *window, fbtk_widget_t *widget)
-{
- fbtk_widget_list_t *newent;
- fbtk_widget_list_t **nextent;
- fbtk_widget_list_t *prevent; /* previous entry pointer */
-
- if (window->type == FB_WIDGET_TYPE_WINDOW) {
- /* caller attached widget to a window */
-
- nextent = &window->u.window.widgets;
- prevent = NULL;
- while (*nextent != NULL) {
- prevent = (*nextent);
- nextent = &(prevent->next);
- }
-
- newent = calloc(1, sizeof(struct fbtk_widget_list_s));
-
- newent->widget = widget;
- newent->next = NULL;
- newent->prev = prevent;
-
- *nextent = newent;
-
- window->u.window.widgets_end = newent;
- }
- widget->parent = window;
-
- fbtk_request_redraw(widget);
-
- return widget;
-}
-
-static void
-remove_widget_from_window(fbtk_widget_t *window, fbtk_widget_t *widget)
-{
- fbtk_widget_list_t *lent = window->u.window.widgets;
-
- while ((lent != NULL) && (lent->widget != widget)) {
- lent = lent->next;
- }
-
- if (lent != NULL) {
- if (lent->prev == NULL) {
- window->u.window.widgets = lent->next;
- } else {
- lent->prev->next = lent->next;
- }
- if (lent->next == NULL) {
- window->u.window.widgets_end = lent->prev;
- } else {
- lent->next->prev = lent->prev;
- }
- free(lent);
- }
-}
-
-static void
-fbtk_redraw_widget(fbtk_widget_t *widget)
-{
- nsfb_bbox_t saved_plot_ctx;
- nsfb_bbox_t plot_ctx;
- fbtk_widget_t *root = get_root_widget(widget);
-
- //LOG(("widget %p type %d", widget, widget->type));
- if (widget->redraw_required == false)
- return;
-
- widget->redraw_required = false;
-
- /* ensure there is a redraw handler */
- if (fbtk_get_handler(widget, FBTK_CBT_REDRAW) == NULL)
- return;
-
- /* get the current clipping rectangle */
- nsfb_plot_get_clip(root->u.root.fb, &saved_plot_ctx);
-
- plot_ctx.x0 = fbtk_get_x(widget);
- plot_ctx.y0 = fbtk_get_y(widget);
- plot_ctx.x1 = plot_ctx.x0 + widget->width;
- plot_ctx.y1 = plot_ctx.y0 + widget->height;
-
- /* clip widget to the current area and redraw if its exposed */
- if (nsfb_plot_clip(&saved_plot_ctx, &plot_ctx )) {
-
- nsfb_plot_set_clip(root->u.root.fb, &plot_ctx);
-
- fbtk_post_callback(widget, FBTK_CBT_REDRAW);
-
- /* restore clipping rectangle */
- nsfb_plot_set_clip(root->u.root.fb, &saved_plot_ctx);
-
- //LOG(("OS redrawing %d,%d %d,%d", fb_plot_ctx.x0, fb_plot_ctx.y0, fb_plot_ctx.x1, fb_plot_ctx.y1));
- }
-
-}
-
-/*************** redraw widgets **************/
-
-static int
-fb_redraw_fill(fbtk_widget_t *widget, fbtk_callback_info *cbi)
-{
- nsfb_bbox_t bbox;
- fbtk_widget_t *root = get_root_widget(widget);
-
- fbtk_get_bbox(widget, &bbox);
-
- nsfb_claim(root->u.root.fb, &bbox);
-
- /* clear background */
- if ((widget->bg & 0xFF000000) != 0) {
- /* transparent polygon filling isnt working so fake it */
- nsfb_plot_rectangle_fill(root->u.root.fb, &bbox, widget->bg);
- }
-
- nsfb_update(root->u.root.fb, &bbox);
- return 0;
-}
-
-
-
-static int
-fb_redraw_bitmap(fbtk_widget_t *widget, fbtk_callback_info *cbi)
-{
- nsfb_bbox_t bbox;
- nsfb_bbox_t rect;
- fbtk_widget_t *root = get_root_widget(widget);
-
- fbtk_get_bbox(widget, &bbox);
-
- rect = bbox;
-
- nsfb_claim(root->u.root.fb, &bbox);
-
- /* clear background */
- if ((widget->bg & 0xFF000000) != 0) {
- /* transparent polygon filling isnt working so fake it */
- nsfb_plot_rectangle_fill(root->u.root.fb, &bbox, widget->bg);
- }
-
- /* plot the image */
- nsfb_plot_bitmap(root->u.root.fb,
- &rect,
- (nsfb_colour_t *)widget->u.bitmap.bitmap->pixdata,
- widget->u.bitmap.bitmap->width,
- widget->u.bitmap.bitmap->height,
- widget->u.bitmap.bitmap->width,
- !widget->u.bitmap.bitmap->opaque);
-
- nsfb_update(root->u.root.fb, &bbox);
-
- return 0;
-}
-
-static int
-fbtk_window_default_redraw(fbtk_widget_t *window, fbtk_callback_info *cbi)
-{
- fbtk_widget_list_t *lent;
- int res = 0;
-
- /* get the list of widgets */
- lent = window->u.window.widgets;
-
- while (lent != NULL) {
- fbtk_redraw_widget(lent->widget);
- lent = lent->next;
- }
- return res;
-}
-
-static int
-fbtk_window_default_move(fbtk_widget_t *window, fbtk_callback_info *cbi)
-{
- fbtk_widget_list_t *lent;
- fbtk_widget_t *widget;
- int res = 0;
-
- /* get the list of widgets */
- lent = window->u.window.widgets_end;
-
- while (lent != NULL) {
- widget = lent->widget;
-
- if ((cbi->x > widget->x) &&
- (cbi->y > widget->y) &&
- (cbi->x < widget->x + widget->width) &&
- (cbi->y < widget->y + widget->height)) {
- res = fbtk_post_callback(widget,
- FBTK_CBT_POINTERMOVE,
- cbi->x - widget->x,
- cbi->y - widget->y);
- break;
- }
- lent = lent->prev;
- }
- return res;
-}
-
-static int
-fbtk_window_default_click(fbtk_widget_t *window, fbtk_callback_info *cbi)
-{
- fbtk_widget_list_t *lent;
- fbtk_widget_t *widget;
- int res = 0;
-
- /* get the list of widgets */
- lent = window->u.window.widgets;
-
- while (lent != NULL) {
- widget = lent->widget;
-
- if ((cbi->x > widget->x) &&
- (cbi->y > widget->y) &&
- (cbi->x < widget->x + widget->width) &&
- (cbi->y < widget->y + widget->height)) {
- if (fbtk_get_handler(widget, FBTK_CBT_INPUT) != NULL) {
- fbtk_widget_t *root = get_root_widget(widget);
- root->u.root.input = widget;
- }
-
- res = fbtk_post_callback(widget,
- FBTK_CBT_CLICK,
- cbi->event,
- cbi->x - widget->x,
- cbi->y - widget->y);
- if (res != 0)
- break;
-
- }
- lent = lent->next;
- }
- return res;
-}
-
-static int
-fb_redraw_text(fbtk_widget_t *widget, fbtk_callback_info *cbi )
-{
- nsfb_bbox_t bbox;
- nsfb_bbox_t rect;
- fbtk_widget_t *root = get_root_widget(widget);
-
- fbtk_get_bbox(widget, &bbox);
-
- rect = bbox;
-
- nsfb_claim(root->u.root.fb, &bbox);
-
- /* clear background */
- if ((widget->bg & 0xFF000000) != 0) {
- /* transparent polygon filling isnt working so fake it */
- nsfb_plot_rectangle_fill(root->u.root.fb, &bbox, widget->bg);
- }
-
-
- if (widget->u.text.outline) {
- rect.x1--;
- rect.y1--;
- nsfb_plot_rectangle(root->u.root.fb, &rect, 1, 0x00000000, false, false);
- }
-
- if (widget->u.text.text != NULL) {
- root_style.background = widget->bg;
- root_style.foreground = widget->fg;
-
- plot.text(bbox.x0 + 3,
- bbox.y0 + 17,
- widget->u.text.text,
- strlen(widget->u.text.text),
- &root_style);
- }
-
- nsfb_update(root->u.root.fb, &bbox);
-
- return 0;
-}
-
-
-
-
-static int
-text_input(fbtk_widget_t *widget, fbtk_callback_info *cbi)
-{
- int value;
- if (cbi->event == NULL) {
- /* gain focus */
- if (widget->u.text.text == NULL)
- widget->u.text.text = calloc(1,1);
- widget->u.text.idx = strlen(widget->u.text.text);
-
- fbtk_request_redraw(widget);
-
- return 0;
- }
-
- if (cbi->event->type != NSFB_EVENT_KEY_DOWN)
- return 0;
-
- value = cbi->event->value.keycode;
- switch (value) {
- case NSFB_KEY_BACKSPACE:
- if (widget->u.text.idx <= 0)
- break;
- widget->u.text.idx--;
- widget->u.text.text[widget->u.text.idx] = 0;
- break;
-
- case NSFB_KEY_RETURN:
- widget->u.text.enter(widget->u.text.pw, widget->u.text.text);
- break;
-
- case NSFB_KEY_PAGEUP:
- case NSFB_KEY_PAGEDOWN:
- case NSFB_KEY_RIGHT:
- case NSFB_KEY_LEFT:
- case NSFB_KEY_UP:
- case NSFB_KEY_DOWN:
- case NSFB_KEY_RSHIFT:
- case NSFB_KEY_LSHIFT:
- /* Not handling any of these correctly yet, but avoid putting
- * charcters in the text widget when they're pressed. */
- break;
-
- default:
- /* allow for new character and null */
- {
- char *temp = realloc(widget->u.text.text,
- widget->u.text.idx + 2);
- if (temp != NULL) {
- widget->u.text.text = temp;
- widget->u.text.text[widget->u.text.idx] = value;
- widget->u.text.text[widget->u.text.idx + 1] = '\0';
- widget->u.text.idx++;
- }
- }
- break;
- }
-
- fbtk_request_redraw(widget);
-
- return 0;
-}
-
-/* sets the enter action on a writable icon */
-void
-fbtk_writable_text(fbtk_widget_t *widget, fbtk_enter_t enter, void *pw)
-{
- widget->u.text.enter = enter;
- widget->u.text.pw = pw;
-
- fbtk_set_handler(widget, FBTK_CBT_INPUT, text_input, widget);
-}
-
-
-/********** acessors ***********/
-int
-fbtk_get_height(fbtk_widget_t *widget)
-{
- return widget->height;
-}
-
-int
-fbtk_get_width(fbtk_widget_t *widget)
-{
- return widget->width;
-}
-
-int
-fbtk_get_x(fbtk_widget_t *widget)
-{
- int x = widget->x;
-
- while (widget->parent != NULL) {
- widget = widget->parent;
- x += widget->x;
- }
-
- return x;
-}
-
-int
-fbtk_get_y(fbtk_widget_t *widget)
-{
- int y = widget->y;
-
- while (widget->parent != NULL) {
- widget = widget->parent;
- y += widget->y;
- }
-
- return y;
-}
-
-/* get widgets bounding box in screen co-ordinates */
-bool
-fbtk_get_bbox(fbtk_widget_t *widget, nsfb_bbox_t *bbox)
-{
- bbox->x0 = widget->x;
- bbox->y0 = widget->y;
- bbox->x1 = widget->x + widget->width;
- bbox->y1 = widget->y + widget->height;
-
- while (widget->parent != NULL) {
- widget = widget->parent;
- bbox->x0 += widget->x;
- bbox->y0 += widget->y;
- bbox->x1 += widget->x;
- bbox->y1 += widget->y;
- }
-
- return true;
-}
-
-fbtk_callback
-fbtk_get_handler(fbtk_widget_t *widget, fbtk_callback_type cbt)
-{
- if ((cbt <= FBTK_CBT_START) || (cbt >= FBTK_CBT_END)) {
- /* type out of range, no way to report error so return NULL */
- return NULL;
- }
-
- return widget->callback[cbt];
-}
-
-fbtk_callback
-fbtk_set_handler(fbtk_widget_t *widget,
- fbtk_callback_type cbt,
- fbtk_callback cb,
- void *context)
-{
- fbtk_callback prevcb;
-
- if ((cbt <= FBTK_CBT_START) || (cbt >= FBTK_CBT_END)) {
- /* type out of range, no way to report error so return NULL */
- return NULL;
- }
-
- prevcb = widget->callback[cbt];
-
- widget->callback[cbt] = cb;
- widget->callback_context[cbt] = context;
-
- return prevcb;
-}
-
-
-void *
-fbtk_get_userpw(fbtk_widget_t *widget)
-{
- if ((widget == NULL) || (widget->type != FB_WIDGET_TYPE_USER))
- return NULL;
-
- return widget->u.user.pw;
-}
-
-void
-fbtk_set_text(fbtk_widget_t *widget, const char *text)
-{
- if ((widget == NULL) || (widget->type != FB_WIDGET_TYPE_TEXT))
- return;
- if (widget->u.text.text != NULL) {
- if (strcmp(widget->u.text.text, text) == 0)
- return; /* text is being set to the same thing */
- free(widget->u.text.text);
- }
- widget->u.text.text = strdup(text);
- widget->u.text.idx = strlen(text);
-
- fbtk_request_redraw(widget);
-}
-
-
-void
-fbtk_set_bitmap(fbtk_widget_t *widget, struct bitmap *image)
-{
- if ((widget == NULL) || (widget->type != FB_WIDGET_TYPE_BITMAP))
- return;
-
- widget->u.bitmap.bitmap = image;
-
- fbtk_request_redraw(widget);
-}
-
-void
-fbtk_set_pos_and_size(fbtk_widget_t *widget, int x, int y, int width, int height)
-{
- if ((widget->x != x) ||
- (widget->y != y) ||
- (widget->width != width) ||
- (widget->height != height)) {
- widget->x = x;
- widget->y = y;
- widget->width = width;
- widget->height = height;
- fbtk_request_redraw(widget);
- LOG(("%d,%d %d,%d",x,y,width,height));
- }
-}
-
-int
-fbtk_count_children(fbtk_widget_t *widget)
-{
- int count = 0;
- fbtk_widget_list_t *lent;
-
- if (widget->type != FB_WIDGET_TYPE_WINDOW) {
- if (widget->type != FB_WIDGET_TYPE_ROOT)
- return -1;
- widget = widget->u.root.rootw;
- }
-
- lent = widget->u.window.widgets;
-
- while (lent != NULL) {
- count++;
- lent = lent->next;
- }
-
- return count;
-}
-
-
-void
-fbtk_input(fbtk_widget_t *root, nsfb_event_t *event)
-{
- fbtk_widget_t *input;
-
- root = get_root_widget(root);
-
- /* obtain widget with input focus */
- input = root->u.root.input;
- if (input == NULL)
- return; /* no widget with input */
-
- fbtk_post_callback(input, FBTK_CBT_INPUT, event);
-}
-
-void
-fbtk_click(fbtk_widget_t *widget, nsfb_event_t *event)
-{
- fbtk_widget_t *root;
- nsfb_bbox_t cloc;
-
- /* ensure we have the root widget */
- root = get_root_widget(widget);
-
- nsfb_cursor_loc_get(root->u.root.fb, &cloc);
-
-
- /* post the click */
- fbtk_post_callback(root->u.root.rootw, FBTK_CBT_CLICK, event, cloc.x0, cloc.y0);
-}
-
-
-
-void
-fbtk_move_pointer(fbtk_widget_t *widget, int x, int y, bool relative)
-{
- fbtk_widget_t *root;
- nsfb_bbox_t cloc;
-
- /* ensure we have the root widget */
- root = get_root_widget(widget);
-
- if (relative) {
- nsfb_cursor_loc_get(root->u.root.fb, &cloc);
- cloc.x0 += x;
- cloc.y0 += y;
- } else {
- cloc.x0 = x;
- cloc.y0 = y;
- }
-
- root->redraw_required = true;
-
- /* update the pointer cursor */
- nsfb_cursor_loc_set(root->u.root.fb, &cloc);
-
- /* post the movement */
- fbtk_post_callback(root->u.root.rootw, FBTK_CBT_POINTERMOVE, cloc.x0, cloc.y0);
-
-}
-
-bool
-fbtk_redraw_pending(fbtk_widget_t *widget)
-{
- fbtk_widget_t *root;
-
- /* ensure we have the root widget */
- root = get_root_widget(widget);
-
- return root->redraw_required;
-}
-
-int
-fbtk_redraw(fbtk_widget_t *widget)
-{
- fbtk_widget_t *root;
-
- /* ensure we have the root widget */
- root = get_root_widget(widget);
-
- if (!root->redraw_required)
- return 0;
-
- fbtk_post_callback(root->u.root.rootw, FBTK_CBT_REDRAW);
-
- widget->redraw_required = false;
-
- return 1;
-}
-
-/****** widget destruction ********/
-int fbtk_destroy_widget(fbtk_widget_t *widget)
-{
- if (widget->type == FB_WIDGET_TYPE_WINDOW) {
- /* TODO: walk child widgets and destroy them */
- }
-
- remove_widget_from_window(widget->parent, widget);
- free(widget);
-
- return 0;
-}
-
-
-/************** Widget creation *************/
-fbtk_widget_t *
-fbtk_create_text(fbtk_widget_t *window,
- int x, int y,
- int width, int height,
- colour bg, colour fg,
- bool outline)
-{
- fbtk_widget_t *newt = new_widget(FB_WIDGET_TYPE_TEXT);
-
- newt->x = x;
- newt->y = y;
- newt->width = width;
- newt->height = height;
- newt->u.text.outline = outline;
-
- newt->fg = fg;
- newt->bg = bg;
-
- fbtk_set_handler(newt, FBTK_CBT_REDRAW, fb_redraw_text, NULL);
-
- return add_widget_to_window(window, newt);
-}
-
-fbtk_widget_t *
-fbtk_create_bitmap(fbtk_widget_t *window, int x, int y, colour c, struct bitmap *image)
-{
- fbtk_widget_t *newb = new_widget(FB_WIDGET_TYPE_BITMAP);
-
- newb->x = x;
- newb->y = y;
- newb->width = image->width;
- newb->height = image->height;
- newb->bg = c;
-
- newb->u.bitmap.bitmap = image;
-
- fbtk_set_handler(newb, FBTK_CBT_REDRAW, fb_redraw_bitmap, NULL);
-
- return add_widget_to_window(window, newb);
-}
-
-static void
-fbtk_width_height(fbtk_widget_t *parent, int x, int y, int *width, int *height)
-{
- /* make widget fit inside parent */
- if (*width == 0) {
- *width = parent->width - x;
- } else if (*width < 0) {
- *width = parent->width + *width;
- }
- if ((*width + x) > parent->width) {
- *width = parent->width - x;
- }
-
- if (*height == 0) {
- *height = parent->height - y;
- } else if (*height < 0) {
- *height = parent->height + *height;
- }
- if ((*height + y) > parent->height) {
- *height = parent->height - y;
- }
-}
-
-fbtk_widget_t *
-fbtk_create_fill(fbtk_widget_t *window, int x, int y, int width, int height, colour c)
-{
- fbtk_widget_t *neww = new_widget(FB_WIDGET_TYPE_FILL);
-
- neww->x = x;
- neww->y = y;
- neww->width = width;
- neww->height = height;
-
- fbtk_width_height(window, x, y, &neww->width, &neww->height);
-
- neww->bg = c;
-
- fbtk_set_handler(neww, FBTK_CBT_REDRAW, fb_redraw_fill, NULL);
-
- return add_widget_to_window(window, neww);
-}
-
-/* set pointer to bitmap in context on cursor move */
-static int
-fbtk_set_ptr_move(fbtk_widget_t *widget, fbtk_callback_info *cbi)
-{
- fbtk_widget_t *root = get_root_widget(widget);
- struct bitmap *bm = cbi->context;
-
- nsfb_cursor_set(root->u.root.fb,
- (nsfb_colour_t *)bm->pixdata,
- bm->width,
- bm->height,
- bm->width);
-
- return 0;
-}
-
-fbtk_widget_t *
-fbtk_create_button(fbtk_widget_t *window,
- int x, int y,
- colour c,
- struct bitmap *image,
- fbtk_callback click,
- void *pw)
-{
- fbtk_widget_t *newb = fbtk_create_bitmap(window, x, y, c, image);
-
- fbtk_set_handler(newb, FBTK_CBT_CLICK, click, pw);
- fbtk_set_handler(newb, FBTK_CBT_POINTERMOVE, fbtk_set_ptr_move, &hand_image);
-
- return newb;
-}
-
-fbtk_widget_t *
-fbtk_create_writable_text(fbtk_widget_t *window,
- int x, int y,
- int width, int height,
- colour bg, colour fg,
- bool outline,
- fbtk_enter_t enter, void *pw)
-{
- fbtk_widget_t *newt = fbtk_create_text(window, x, y, width, height, bg,fg,outline);
- newt->u.text.enter = enter;
- newt->u.text.pw = pw;
-
- fbtk_set_handler(newt, FBTK_CBT_INPUT, text_input, newt);
-
- return newt;
-}
-
-/* create user widget
- *
- * @param x coord relative to parent
- */
-fbtk_widget_t *
-fbtk_create_user(fbtk_widget_t *window,
- int x, int y,
- int width, int height,
- void *pw)
-{
- fbtk_widget_t *newu = new_widget(FB_WIDGET_TYPE_USER);
-
-
- /* make new window fit inside parent */
- if (width == 0) {
- width = window->width - x;
- } else if (width < 0) {
- width = window->width + width;
- }
- if ((width + x) > window->width) {
- width = window->width - x;
- }
-
- if (height == 0) {
- height = window->height - y;
- } else if (height < 0) {
- height = window->height + height;
- }
- if ((height + y) > window->height) {
- height = window->height - y;
- }
-
- newu->x = x;
- newu->y = y;
- newu->width = width;
- newu->height = height;
-
- newu->u.user.pw = pw;
-
- return add_widget_to_window(window, newu);
-}
-
-
-/* create new window
- *
- * @param x coord relative to parent
- */
-fbtk_widget_t *
-fbtk_create_window(fbtk_widget_t *parent,
- int x, int y, int width, int height)
-{
- fbtk_widget_t *newwin;
-
- LOG(("Creating window %p %d,%d %d,%d",parent,x,y,width,height));
- if (parent == NULL)
- return NULL;
-
- if ((parent->type == FB_WIDGET_TYPE_ROOT) &&
- (parent->u.root.rootw != NULL)) {
- LOG(("Using root window"));
- parent = parent->u.root.rootw;
- }
-
- newwin = new_widget(FB_WIDGET_TYPE_WINDOW);
-
- /* make new window fit inside parent */
- if (width == 0) {
- width = parent->width - x;
- } else if (width < 0) {
- width = parent->width + width;
- }
- if ((width + x) > parent->width) {
- width = parent->width - x;
- }
-
- if (height == 0) {
- height = parent->height - y;
- } else if (height < 0) {
- height = parent->height + height;
- }
- if ((height + y) > parent->height) {
- height = parent->height - y;
- }
-
- newwin->x = x;
- newwin->y = y;
- newwin->width = width;
- newwin->height = height;
-
- fbtk_set_handler(newwin, FBTK_CBT_REDRAW, fbtk_window_default_redraw, NULL);
- fbtk_set_handler(newwin, FBTK_CBT_POINTERMOVE, fbtk_window_default_move, NULL);
- fbtk_set_handler(newwin, FBTK_CBT_CLICK, fbtk_window_default_click, NULL);
- LOG(("Created window %p %d,%d %d,%d",newwin,x,y,width,height));
-
- return add_widget_to_window(parent, newwin);
-}
-
-int
-fbtk_post_callback(fbtk_widget_t *widget, fbtk_callback_type cbt, ...)
-{
- fbtk_callback_info cbi;
- int ret = 0;
- va_list ap;
-
- if (widget->callback[cbt] != NULL) {
- cbi.type = cbt;
- cbi.context = widget->callback_context[cbt];
-
- va_start(ap, cbt);
-
- switch (cbt) {
- case FBTK_CBT_SCROLLX:
- cbi.x = va_arg(ap,int);
- break;
-
- case FBTK_CBT_SCROLLY:
- cbi.y = va_arg(ap,int);
- break;
-
- case FBTK_CBT_CLICK:
- cbi.event = va_arg(ap, void *);
- cbi.x = va_arg(ap, int);
- cbi.y = va_arg(ap, int);
- break;
-
- case FBTK_CBT_INPUT:
- cbi.event = va_arg(ap, void *);
- break;
-
- case FBTK_CBT_POINTERMOVE:
- cbi.x = va_arg(ap, int);
- cbi.y = va_arg(ap, int);
- break;
-
- case FBTK_CBT_REDRAW:
- break;
-
- case FBTK_CBT_USER:
- break;
-
- default:
- break;
- }
- va_end(ap);
-
- ret = (widget->callback[cbt])(widget, &cbi);
- }
-
- return ret;
-}
-
-bool fbtk_event(fbtk_widget_t *root, nsfb_event_t *event, int timeout)
-{
- bool unused = false; /* is the event available */
-
- /* ensure we have the root widget */
- root = get_root_widget(root);
-
- //LOG(("Reading event with timeout %d",timeout));
-
- if (nsfb_event(root->u.root.fb, event, timeout) == false)
- return false;
-
- switch (event->type) {
- case NSFB_EVENT_KEY_DOWN:
- case NSFB_EVENT_KEY_UP:
- if ((event->value.controlcode >= NSFB_KEY_MOUSE_1) &&
- (event->value.controlcode <= NSFB_KEY_MOUSE_5)) {
- fbtk_click(root, event);
- } else {
- fbtk_input(root, event);
- }
- break;
-
- case NSFB_EVENT_CONTROL:
- unused = true;
- break;
-
- case NSFB_EVENT_MOVE_RELATIVE:
- fbtk_move_pointer(root, event->value.vector.x, event->value.vector.y, true);
- break;
-
- case NSFB_EVENT_MOVE_ABSOLUTE:
- fbtk_move_pointer(root, event->value.vector.x, event->value.vector.y, false);
- break;
-
- default:
- break;
-
- }
- return unused;
-}
-
-
-nsfb_t *
-fbtk_get_nsfb(fbtk_widget_t *widget)
-{
- fbtk_widget_t *root;
-
- /* ensure we have the root widget */
- root = get_root_widget(widget);
-
- return root->u.root.fb;
-}
-
-/* Initialise toolkit for use */
-fbtk_widget_t *
-fbtk_init(nsfb_t *fb)
-{
- fbtk_widget_t *root = new_widget(FB_WIDGET_TYPE_ROOT);
-
- nsfb_get_geometry(fb, &root->width, &root->height, NULL);
-
- LOG(("width %d height %d",root->width, root->height));
- root->u.root.fb = fb;
- root->x = 0;
- root->y = 0;
- root->u.root.rootw = fbtk_create_window(root, 0, 0, 0, 0);
-
- return root;
-}
-
-static int keymap[] = {
- /* 0 1 2 3 4 5 6 7 8 9 */
- -1, -1, -1, -1, -1, -1, -1, -1, 8, 9, /* 0 - 9 */
- -1, -1, -1, 13, -1, -1, -1, -1, -1, -1, /* 10 - 19 */
- -1, -1, -1, -1, -1, -1, -1, 27, -1, -1, /* 20 - 29 */
- -1, -1, ' ', '!', '"', '#', '$', -1, '&','\'', /* 30 - 39 */
- '(', ')', '*', '+', ',', '-', '.', '/', '0', '1', /* 40 - 49 */
- '2', '3', '4', '5', '6', '7', '8', '9', ':', ';', /* 50 - 59 */
- '<', '=', '>', '?', '@', -1, -1, -1, -1, -1, /* 60 - 69 */
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 70 - 79 */
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 80 - 89 */
- -1, '[','\\', ']', '~', '_', '`', 'a', 'b', 'c', /* 90 - 99 */
- 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', /* 100 - 109 */
- 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', /* 110 - 119 */
- 'x', 'y', 'z', -1, -1, -1, -1, -1, -1, -1, /* 120 - 129 */
-};
-
-static int sh_keymap[] = {
- /* 0 1 2 3 4 5 6 7 8 9 */
- -1, -1, -1, -1, -1, -1, -1, -1, 8, 9, /* 0 - 9 */
- -1, -1, -1, 13, -1, -1, -1, -1, -1, -1, /* 10 - 19 */
- -1, -1, -1, -1, -1, -1, -1, 27, -1, -1, /* 20 - 29 */
- -1, -1, ' ', '!', '"', '~', '$', -1, '&', '@', /* 30 - 39 */
- '(', ')', '*', '+', '<', '_', '>', '?', ')', '!', /* 40 - 49 */
- '"', 243, '$', '%', '^', '&', '*', '(', ';', ':', /* 50 - 59 */
- '<', '+', '>', '?', '@', -1, -1, -1, -1, -1, /* 60 - 69 */
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 70 - 79 */
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 80 - 89 */
- -1, '{', '|', '}', '~', '_', 254, 'A', 'B', 'C', /* 90 - 99 */
- 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', /* 100 - 109 */
- 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', /* 110 - 119 */
- 'X', 'Y', 'Z', -1, -1, -1, -1, -1, -1, -1, /* 120 - 129 */
-};
-
-
-/* performs character mapping */
-int fbtk_keycode_to_ucs4(int code, uint8_t mods)
-{
- int ucs4 = -1;
-
- if (mods) {
- if ((code >= 0) && (code < (int) NOF_ELEMENTS(sh_keymap)))
- ucs4 = sh_keymap[code];
- } else {
- if ((code >= 0) && (code < (int) NOF_ELEMENTS(keymap)))
- ucs4 = keymap[code];
- }
- return ucs4;
-}
-
-/*
- * Local Variables:
- * c-basic-offset:8
- * End:
- */
diff --git a/framebuffer/fbtk.h b/framebuffer/fbtk.h
index fd104452b..61050f46f 100644
--- a/framebuffer/fbtk.h
+++ b/framebuffer/fbtk.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2008 Vincent Sanders <vince@simtec.co.uk>
+ * Copyright 2008,2010 Vincent Sanders <vince@simtec.co.uk>
*
* This file is part of NetSurf, http://www.netsurf-browser.org/
*
@@ -27,6 +27,7 @@
typedef struct fbtk_widget_s fbtk_widget_t;
+/* Widget Callback handling */
typedef enum fbtk_callback_type {
FBTK_CBT_START = 0,
FBTK_CBT_SCROLLX,
@@ -34,7 +35,10 @@ typedef enum fbtk_callback_type {
FBTK_CBT_CLICK,
FBTK_CBT_INPUT,
FBTK_CBT_POINTERMOVE,
+ FBTK_CBT_POINTERLEAVE,
+ FBTK_CBT_POINTERENTER,
FBTK_CBT_REDRAW,
+ FBTK_CBT_DESTROY,
FBTK_CBT_USER,
FBTK_CBT_END,
} fbtk_callback_type;
@@ -51,29 +55,212 @@ typedef struct fbtk_callback_info {
typedef int (*fbtk_callback)(fbtk_widget_t *widget, fbtk_callback_info *cbi);
-
-/* user widget callback */
-typedef int (*fbtk_user_t)(fbtk_widget_t *widget, void *pw);
-
-
/* enter pressed on writable icon */
typedef int (*fbtk_enter_t)(void *pw, char *text);
-/* helper function to allow simple method to call callbacks */
-int fbtk_post_callback(fbtk_widget_t *widget, fbtk_callback_type cbt, ...);
+/************************ Core ****************************/
-/* Widget creation */
/** Initialise widget toolkit.
*
- * Initialises widget toolkit and creates root window against a framebuffer.
+ * Initialises widget toolkit against a framebuffer.
*
* @param fb The underlying framebuffer.
* @return The root widget handle.
*/
fbtk_widget_t *fbtk_init(nsfb_t *fb);
+/** Retrieve the framebuffer library handle from toolkit widget.
+ *
+ * @param widget A fbtk widget.
+ * @return The underlying framebuffer.
+ */
+nsfb_t *fbtk_get_nsfb(fbtk_widget_t *widget);
+
+/** Perform any pending widget redraws.
+ *
+ * @param widget A fbtk widget.
+ */
+int fbtk_redraw(fbtk_widget_t *widget);
+
+/** Determine if there are any redraws pending for a widget.
+ *
+ * Mainly used by clients on the root widget to determine if they need
+ * to call ::fbtk_redraw
+ *
+ * @param widget to check.
+ */
+bool fbtk_get_redraw_pending(fbtk_widget_t *widget);
+
+/** clip a bounding box to a widgets area.
+ */
+bool fbtk_clip_to_widget(fbtk_widget_t *widget, bbox_t * restrict box);
+
+/** clip one bounding box to another.
+ */
+bool fbtk_clip_rect(const bbox_t * restrict clip, bbox_t * restrict box);
+
+/***************** Callback processing ********************/
+
+/** Helper function to allow simple calling of callbacks with parameters.
+ *
+ * @param widget The fbtk widget to post the callback to.
+ * @param cbt The type of callback to post
+ * @param ... Parameters appropriate for the callback type.
+ */
+int fbtk_post_callback(fbtk_widget_t *widget, fbtk_callback_type cbt, ...);
+
+/** Set a callback handler.
+ *
+ * Set a callback handler and the pointer to pass for a widget.
+ *
+ * @param widget The widget to set the handler for.
+ * @param cbt The type of callback to set.
+ * @param cb The callback.
+ * @param pw The private pointer to pass when calling teh callback.
+ * @return The previous callback handler for the type or NULL.
+ */
+fbtk_callback fbtk_set_handler(fbtk_widget_t *widget, fbtk_callback_type cbt, fbtk_callback cb, void *pw);
+
+/** Get a callback handler.
+ */
+fbtk_callback fbtk_get_handler(fbtk_widget_t *widget, fbtk_callback_type cbt);
+
+
+/******************* Event processing **********************/
+
+/** Retrive events from the framebuffer input.
+ *
+ * Obtain events from the framebuffer input system with a
+ * timeout. Some events may be used by the toolkit instead of being
+ * returned to the caller.
+ *
+ * @param root An fbtk widget.
+ * @param event an event structure to update.
+ * @param timeout The number of miliseconds to wait for an event. 0
+ * means do not wait and -1 means wait foreevr.
+ * @return wether \a event has been updated.
+ */
+bool fbtk_event(fbtk_widget_t *root, nsfb_event_t *event, int timeout);
+
+/** Insert mouse button press into toolkit.
+ */
+void fbtk_click(fbtk_widget_t *widget, nsfb_event_t *event);
+
+/** Insert input into toolkit.
+ */
+void fbtk_input(fbtk_widget_t *widget, nsfb_event_t *event);
+
+/** Move pointer.
+ *
+ * Move the pointer cursor to a given location.
+ *
+ * @param widget any tookit widget.
+ * @parm x movement in horizontal plane.
+ * @parm y movement in vertical plane.
+ * @parm relative Wheter the /a x and /a y should be considered relative to
+ * current pointer position.
+ */
+void fbtk_warp_pointer(fbtk_widget_t *widget, int x, int y, bool relative);
+
+/** Toggle pointer grab.
+ *
+ * Toggles the movement grab for a widget.
+ *
+ * @param widget The widget trying to grab the movement.
+ * @return true if the grab was ok, false if the grab failed (already grabbed).
+ */
+bool fbtk_tgrab_pointer(fbtk_widget_t *widget);
+
+/** Convert a framebuffer keycode to ucs4.
+ *
+ * Character mapping between keycode with modifier state and ucs-4.
+ */
+int fbtk_keycode_to_ucs4(int code, uint8_t mods);
+
+
+/******************* Widget Information **********************/
+
+/** Obtain the widget at a point on screen.
+ *
+ * @param widget any tookit widget.
+ * @parm x location in horizontal plane.
+ * @parm y location in vertical plane.
+ * @return widget or NULL.
+ */
+fbtk_widget_t *fbtk_get_widget_at(fbtk_widget_t *widget, int x, int y);
+
+/** Get a widget's absolute horizontal screen co-ordinate.
+ *
+ * @param widget The widget to inspect.
+ * @return The absolute screen co-ordinate.
+ */
+int fbtk_get_absx(fbtk_widget_t *widget);
+
+/** Get a widget's absolute vertical screen co-ordinate.
+ *
+ * @param widget The widget to inspect.
+ * @return The absolute screen co-ordinate.
+ */
+int fbtk_get_absy(fbtk_widget_t *widget);
+
+/** Get a widget's width.
+ *
+ * @param widget The widget to inspect.
+ * @return The widget width.
+ */
+int fbtk_get_width(fbtk_widget_t *widget);
+
+/** Get a widget's height.
+ *
+ * @param widget The widget to inspect.
+ * @return The widget height.
+ */
+int fbtk_get_height(fbtk_widget_t *widget);
+
+/** Get a widget's bounding box in absolute screen co-ordinates.
+ *
+ * @param widget The widget to inspect.
+ * @param bbox The bounding box structure to update.
+ * @return If the \a bbox parameter has been updated.
+ */
+bool fbtk_get_bbox(fbtk_widget_t *widget, struct nsfb_bbox_s *bbox);
+
+
+/******************* Widget Manipulation **********************/
+
+/** Change the widget's position and size.
+ *
+ */
+bool fbtk_set_pos_and_size(fbtk_widget_t *widget, int x, int y, int width, int height);
+
+/** Map a widget and request it is redrawn.
+ */
+int fbtk_set_mapping(fbtk_widget_t *widget, bool mapped);
+
+/** Set the z order of a widget.
+ */
+int fbtk_set_zorder(fbtk_widget_t *widget, int z);
+
+/** Indicate a widget should be redrawn.
+ */
+void fbtk_request_redraw(fbtk_widget_t *widget);
+
+/** Destroy a widget and all its descendants.
+ *
+ * Removes a widget from the hierachy and frees it and all its children.
+ *
+ * @param widget The widget to destroy.
+ * @return 0 on success or -1 on error.
+ */
+int fbtk_destroy_widget(fbtk_widget_t *widget);
+
+
+
+/********************************* Widgets *********************************/
+
+
/** Create a window widget.
*
* @param parent The parent window or the root widget for a top level window.
@@ -88,23 +275,9 @@ fbtk_widget_t *fbtk_init(nsfb_t *fb);
* @param c The background colour.
* @return new window widget handle or NULL on error.
*/
-fbtk_widget_t *fbtk_create_window(fbtk_widget_t *parent, int x, int y, int width, int height);
+fbtk_widget_t *fbtk_create_window(fbtk_widget_t *parent, int x, int y, int width, int height, colour bg);
-/** Create a text widget.
- *
- * @param window The window to add the text widget to.
- * @return new widget handle or NULL on error.
- */
-fbtk_widget_t *fbtk_create_text(fbtk_widget_t *window, int x, int y, int width, int height, colour bg, colour fg, bool outline);
-/** Create a bitmap widget.
- *
- * Create a widget which shows a bitmap.
- *
- * @param window The window to add the bitmap widget to.
- * @return new widget handle or NULL on error.
- */
-fbtk_widget_t *fbtk_create_bitmap(fbtk_widget_t *window, int x, int y, colour c,struct bitmap *image);
/** Create a filled rectangle
*
@@ -116,6 +289,9 @@ fbtk_widget_t *fbtk_create_bitmap(fbtk_widget_t *window, int x, int y, colour c,
fbtk_widget_t *
fbtk_create_fill(fbtk_widget_t *window, int x, int y, int width, int height, colour c);
+
+
+
/** Create a horizontal scroll widget
*
* Create a horizontal scroll widget.
@@ -136,6 +312,14 @@ fbtk_create_hscroll(fbtk_widget_t *window, int x, int y, int width, int height,
fbtk_widget_t *
fbtk_create_vscroll(fbtk_widget_t *window, int x, int y, int width, int height, colour fg, colour bg, fbtk_callback callback, void *context);
+bool fbtk_set_scroll_parameters(fbtk_widget_t *widget, int min, int max, int thumb, int page);
+
+bool fbtk_set_scroll_position(fbtk_widget_t *widget, int pos);
+
+
+
+
+
/** Create a user widget.
*
* Create a widget which is to be handled entirely by the calling application.
@@ -146,6 +330,20 @@ fbtk_create_vscroll(fbtk_widget_t *window, int x, int y, int width, int height,
*/
fbtk_widget_t *fbtk_create_user(fbtk_widget_t *window, int x, int y, int width, int height, void *pw);
+void *fbtk_get_userpw(fbtk_widget_t *widget);
+
+
+
+/** Create a bitmap widget.
+ *
+ * Create a widget which shows a bitmap.
+ *
+ * @param window The window to add the bitmap widget to.
+ * @return new widget handle or NULL on error.
+ */
+fbtk_widget_t *fbtk_create_bitmap(fbtk_widget_t *window, int x, int y, int width, int height, colour c,struct bitmap *image);
+
+void fbtk_set_bitmap(fbtk_widget_t *widget, struct bitmap *image);
/** Create a button widget.
*
@@ -155,7 +353,25 @@ fbtk_widget_t *fbtk_create_user(fbtk_widget_t *window, int x, int y, int width,
* @param window The window to add the button widget to.
* @return new widget handle or NULL on error.
*/
-fbtk_widget_t *fbtk_create_button(fbtk_widget_t *window, int x, int y, colour c, struct bitmap *image, fbtk_callback click, void *pw);
+fbtk_widget_t *fbtk_create_button(fbtk_widget_t *window, int x, int y, int width, int height, colour c, struct bitmap *image, fbtk_callback click, void *pw);
+
+
+
+
+
+/** Create a text widget.
+ *
+ * @param window The window to add the text widget to.
+ * @return new widget handle or NULL on error.
+ */
+fbtk_widget_t *fbtk_create_text(fbtk_widget_t *window, int x, int y, int width, int height, colour bg, colour fg, bool outline);
+
+/** Create a button with text.
+ *
+ * @param window The window to add the text widget to.
+ * @return new widget handle or NULL on error.
+ */
+fbtk_widget_t *fbtk_create_text_button(fbtk_widget_t *window, int x, int y, int width, int height, colour bg, colour fg, fbtk_callback click, void *pw);
/** Create a writable text widget.
*
@@ -168,94 +384,28 @@ fbtk_widget_t *fbtk_create_button(fbtk_widget_t *window, int x, int y, colour c,
*/
fbtk_widget_t *fbtk_create_writable_text(fbtk_widget_t *window, int x, int y, int width, int height, colour bg, colour fg, bool outline, fbtk_enter_t enter, void *pw);
-
-/* Widget Destruction */
-
-/** Destroy and free a widget and all its children.
- *
- * @param widget The widget to destroy.
- * @return 0 on success or -1 on error.
- */
-int fbtk_destroy_widget(fbtk_widget_t *widget);
-
-/* Widget information */
-
-int fbtk_get_y(fbtk_widget_t *widget);
-int fbtk_get_x(fbtk_widget_t *widget);
-int fbtk_get_width(fbtk_widget_t *widget);
-int fbtk_get_height(fbtk_widget_t *widget);
-void *fbtk_get_userpw(fbtk_widget_t *widget);
-nsfb_t *fbtk_get_nsfb(fbtk_widget_t *widget);
-
-/* Set widget properties */
-
-void fbtk_set_text(fbtk_widget_t *widget, const char *text);
-void fbtk_set_bitmap(fbtk_widget_t *widget, struct bitmap *image);
-void fbtk_set_scroll(fbtk_widget_t *widget, int pct);
-void fbtk_set_scroll_pos(fbtk_widget_t *widget, int pos);
-void fbtk_set_pos_and_size(fbtk_widget_t *widget, int x, int y, int width, int height);
-;
-
-/** Set a callback handler */
-fbtk_callback fbtk_set_handler(fbtk_widget_t *widget, fbtk_callback_type cbt, fbtk_callback cb, void *pw);
-
-/** Get a callback handler */
-fbtk_callback fbtk_get_handler(fbtk_widget_t *widget, fbtk_callback_type cbt);
-
/** Alter a text widget to be writable.
+ *
+ * @param widget Text widget.
+ * @param enter The routine to call when enter is pressed.
+ * @param pw The context to pass to teh enter callback routine.
*/
void fbtk_writable_text(fbtk_widget_t *widget, fbtk_enter_t enter, void *pw);
-
-/* General routines */
-
-bool fbtk_clip_rect(const bbox_t * restrict clip, bbox_t * restrict box);
-
-/** Pointer movement.
- *
- * Pointer has been moved.
+/** Change the text of a text widget.
*
- * @param widget any tookit widget.
- * @parm x movement in horizontal plane.
- * @parm y movement in vertical plane.
- * @parm relative Wether the /a x and /a y should be considered relative to
- * current pointer position.
- */
-void fbtk_move_pointer(fbtk_widget_t *widget, int x, int y, bool relative);
-
-/** Mouse has been clicked
- */
-void fbtk_click(fbtk_widget_t *widget, nsfb_event_t *event);
-
-/** Input has been recived
+ * @param widget Text widget.
+ * @param text The new UTF-8 text to put in the widget.
*/
-void fbtk_input(fbtk_widget_t *widget, nsfb_event_t *event);
-
-/** Indicate a widget has to be redrawn
- */
-void fbtk_request_redraw(fbtk_widget_t *widget);
-
-/** Cause a redraw to happen.
- */
-int fbtk_redraw(fbtk_widget_t *widget);
+void fbtk_set_text(fbtk_widget_t *widget, const char *text);
-bool fbtk_redraw_pending(fbtk_widget_t *widget);
-int fbtk_count_children(fbtk_widget_t *widget);
-bool fbtk_get_bbox(fbtk_widget_t *widget, struct nsfb_bbox_s *bbox);
-bool fbtk_event(fbtk_widget_t *root, nsfb_event_t *event, int timeout);
+/** enable the on screen keyboard for input */
+void fbtk_enable_oskb(fbtk_widget_t *widget);
-/* keycode to ucs4 */
-int fbtk_keycode_to_ucs4(int code, uint8_t mods);
-
-/* clip a box to a widgets area */
-bool fbtk_clip_to_widget(fbtk_widget_t *widget, bbox_t * restrict box);
+/** show the osk. */
+void map_osk(void);
#endif
-
-
-
-
-
diff --git a/framebuffer/fbtk/bitmap.c b/framebuffer/fbtk/bitmap.c
new file mode 100644
index 000000000..af2311287
--- /dev/null
+++ b/framebuffer/fbtk/bitmap.c
@@ -0,0 +1,137 @@
+/*
+ * Copyright 2010 Vincent Sanders <vince@simtec.co.uk>
+ *
+ * Framebuffer windowing toolkit bitmaped image widget
+ *
+ * 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 <malloc.h>
+
+#include <libnsfb.h>
+#include <libnsfb_plot.h>
+
+#include "desktop/browser.h"
+
+#include "framebuffer/gui.h"
+#include "framebuffer/fbtk.h"
+#include "framebuffer/bitmap.h"
+#include "framebuffer/image_data.h"
+
+#include "widget.h"
+
+static int
+fb_redraw_bitmap(fbtk_widget_t *widget, fbtk_callback_info *cbi)
+{
+ nsfb_bbox_t bbox;
+ nsfb_bbox_t rect;
+ nsfb_t *nsfb;
+
+ nsfb = fbtk_get_nsfb(widget);
+
+ fbtk_get_bbox(widget, &bbox);
+
+ rect = bbox;
+
+ nsfb_claim(nsfb, &bbox);
+
+ /* clear background */
+ if ((widget->bg & 0xFF000000) != 0) {
+ /* transparent polygon filling isnt working so fake it */
+ nsfb_plot_rectangle_fill(nsfb, &bbox, widget->bg);
+ }
+
+ /* plot the image */
+ nsfb_plot_bitmap(nsfb,
+ &rect,
+ (nsfb_colour_t *)widget->u.bitmap.bitmap->pixdata,
+ widget->u.bitmap.bitmap->width,
+ widget->u.bitmap.bitmap->height,
+ widget->u.bitmap.bitmap->width,
+ !widget->u.bitmap.bitmap->opaque);
+
+ nsfb_update(nsfb, &bbox);
+
+ return 0;
+}
+
+/* exported function documented in fbtk.h */
+void
+fbtk_set_bitmap(fbtk_widget_t *widget, struct bitmap *image)
+{
+ if ((widget == NULL) || (widget->type != FB_WIDGET_TYPE_BITMAP))
+ return;
+
+ widget->u.bitmap.bitmap = image;
+
+ fbtk_request_redraw(widget);
+}
+
+/* exported function documented in fbtk.h */
+fbtk_widget_t *
+fbtk_create_bitmap(fbtk_widget_t *parent,
+ int x,
+ int y,
+ int width,
+ int height,
+ colour c,
+ struct bitmap *image)
+{
+ fbtk_widget_t *neww;
+
+ neww = fbtk_widget_new(parent, FB_WIDGET_TYPE_BITMAP, x, y, width, height);
+
+ neww->bg = c;
+ neww->mapped = true;
+ neww->u.bitmap.bitmap = image;
+
+ fbtk_set_handler(neww, FBTK_CBT_REDRAW, fb_redraw_bitmap, NULL);
+
+ return neww;
+}
+
+/* exported function documented in fbtk.h */
+fbtk_widget_t *
+fbtk_create_button(fbtk_widget_t *parent,
+ int x,
+ int y,
+ int width,
+ int height,
+ colour c,
+ struct bitmap *image,
+ fbtk_callback click,
+ void *pw)
+{
+ fbtk_widget_t *neww;
+
+ neww = fbtk_widget_new(parent, FB_WIDGET_TYPE_BITMAP, x, y, width, height);
+
+ neww->bg = c;
+ neww->mapped = true;
+ neww->u.bitmap.bitmap = image;
+
+ fbtk_set_handler(neww, FBTK_CBT_REDRAW, fb_redraw_bitmap, NULL);
+ fbtk_set_handler(neww, FBTK_CBT_CLICK, click, pw);
+ fbtk_set_handler(neww, FBTK_CBT_POINTERENTER, fbtk_set_ptr, &hand_image);
+
+ return neww;
+}
+
+/*
+ * Local Variables:
+ * c-basic-offset:8
+ * End:
+ */
diff --git a/framebuffer/fbtk/event.c b/framebuffer/fbtk/event.c
new file mode 100644
index 000000000..c1ddaeeb0
--- /dev/null
+++ b/framebuffer/fbtk/event.c
@@ -0,0 +1,273 @@
+/*
+ * Copyright 2010 Vincent Sanders <vince@simtec.co.uk>
+ *
+ * Framebuffer windowing toolkit event processing.
+ *
+ * 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 <sys/types.h>
+#include <stdint.h>
+#include <string.h>
+#include <stdbool.h>
+
+#include <libnsfb.h>
+#include <libnsfb_plot.h>
+#include <libnsfb_plot_util.h>
+#include <libnsfb_event.h>
+#include <libnsfb_cursor.h>
+
+#include "utils/utils.h"
+#include "utils/log.h"
+#include "css/css.h"
+#include "desktop/browser.h"
+#include "desktop/plotters.h"
+
+#include "framebuffer/gui.h"
+#include "framebuffer/fbtk.h"
+#include "framebuffer/bitmap.h"
+#include "framebuffer/image_data.h"
+
+#include "widget.h"
+
+/* exported function documented in fbtk.h */
+void
+fbtk_input(fbtk_widget_t *root, nsfb_event_t *event)
+{
+ fbtk_widget_t *input;
+
+ root = fbtk_get_root_widget(root);
+
+ /* obtain widget with input focus */
+ input = root->u.root.input;
+ if (input == NULL)
+ return; /* no widget with input */
+
+ fbtk_post_callback(input, FBTK_CBT_INPUT, event);
+}
+
+/* exported function documented in fbtk.h */
+void
+fbtk_click(fbtk_widget_t *widget, nsfb_event_t *event)
+{
+ fbtk_widget_t *root;
+ fbtk_widget_t *clicked;
+ nsfb_bbox_t cloc;
+ int x, y;
+
+ /* ensure we have the root widget */
+ root = fbtk_get_root_widget(widget);
+
+ nsfb_cursor_loc_get(root->u.root.fb, &cloc);
+
+ clicked = fbtk_get_widget_at(root, cloc.x0, cloc.y0);
+
+ if (clicked == NULL)
+ return;
+
+ if (fbtk_get_handler(clicked, FBTK_CBT_INPUT) != NULL) {
+ root->u.root.input = clicked;
+ }
+
+ x = fbtk_get_absx(clicked);
+ y = fbtk_get_absy(clicked);
+
+ LOG(("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);
+}
+
+/* exported function documented in fbtk.h */
+bool
+fbtk_tgrab_pointer(fbtk_widget_t *widget)
+{
+ fbtk_widget_t *root;
+
+ /* ensure we have the root widget */
+ root = fbtk_get_root_widget(widget);
+
+ if (root->u.root.grabbed == widget) {
+ /* release pointer grab */
+ root->u.root.grabbed = NULL;
+ return true;
+ } else if (root->u.root.grabbed == NULL) {
+ /* set pointer grab */
+ root->u.root.grabbed = widget;
+ return true;
+ }
+ /* pointer was already grabbed */
+ return false;
+}
+
+/* exported function documented in fbtk.h */
+void
+fbtk_warp_pointer(fbtk_widget_t *widget, int x, int y, bool relative)
+{
+ fbtk_widget_t *root;
+ fbtk_widget_t *moved;
+ nsfb_bbox_t cloc;
+
+ /* ensure we have the root widget */
+ root = fbtk_get_root_widget(widget);
+
+ if (relative) {
+ nsfb_cursor_loc_get(root->u.root.fb, &cloc);
+ cloc.x0 += x;
+ cloc.y0 += y;
+ } else {
+ cloc.x0 = x;
+ cloc.y0 = y;
+ }
+
+ if (root->u.root.grabbed == NULL) {
+ /* update the pointer cursor */
+ nsfb_cursor_loc_set(root->u.root.fb, &cloc);
+
+ moved = fbtk_get_widget_at(root, cloc.x0, cloc.y0);
+
+ x = fbtk_get_absx(moved);
+ y = fbtk_get_absy(moved);
+
+ /* post enter and leaving messages */
+ if (moved != root->u.root.prev) {
+ fbtk_post_callback(root->u.root.prev, FBTK_CBT_POINTERLEAVE);
+ root->u.root.prev = moved;
+ fbtk_post_callback(root->u.root.prev, FBTK_CBT_POINTERENTER);
+ }
+ } else {
+ /* pointer movement has been grabbed by a widget */
+ moved = root->u.root.grabbed;
+
+ /* ensure pointer remains within widget boundary */
+ x = fbtk_get_absx(moved);
+ y = fbtk_get_absy(moved);
+
+ if (cloc.x0 < x)
+ cloc.x0 = x;
+ if (cloc.y0 < y)
+ cloc.y0 = y;
+ if (cloc.x0 > (x + moved->width))
+ cloc.x0 = (x + moved->width);
+ if (cloc.y0 > (y + moved->height))
+ cloc.y0 = (y + moved->height);
+
+ /* update the pointer cursor */
+ nsfb_cursor_loc_set(root->u.root.fb, &cloc);
+ }
+
+ /* post the movement */
+ fbtk_post_callback(moved, FBTK_CBT_POINTERMOVE, cloc.x0 - x, cloc.y0 - y);
+
+}
+
+/* exported function documented in fbtk.h */
+bool
+fbtk_event(fbtk_widget_t *root, nsfb_event_t *event, int timeout)
+{
+ bool unused = false; /* is the event available */
+
+ /* ensure we have the root widget */
+ root = fbtk_get_root_widget(root);
+
+ if (nsfb_event(root->u.root.fb, event, timeout) == false)
+ return false;
+
+ switch (event->type) {
+ case NSFB_EVENT_KEY_DOWN:
+ case NSFB_EVENT_KEY_UP:
+ if ((event->value.controlcode >= NSFB_KEY_MOUSE_1) &&
+ (event->value.controlcode <= NSFB_KEY_MOUSE_5)) {
+ fbtk_click(root, event);
+ } else {
+ fbtk_input(root, event);
+ }
+ break;
+
+ case NSFB_EVENT_CONTROL:
+ unused = true;
+ break;
+
+ case NSFB_EVENT_MOVE_RELATIVE:
+ fbtk_warp_pointer(root, event->value.vector.x, event->value.vector.y, true);
+ break;
+
+ case NSFB_EVENT_MOVE_ABSOLUTE:
+ fbtk_warp_pointer(root, event->value.vector.x, event->value.vector.y, false);
+ break;
+
+ default:
+ break;
+
+ }
+ return unused;
+}
+
+static int keymap[] = {
+ /* 0 1 2 3 4 5 6 7 8 9 */
+ -1, -1, -1, -1, -1, -1, -1, -1, 8, 9, /* 0 - 9 */
+ -1, -1, -1, 13, -1, -1, -1, -1, -1, -1, /* 10 - 19 */
+ -1, -1, -1, -1, -1, -1, -1, 27, -1, -1, /* 20 - 29 */
+ -1, -1, ' ', '!', '"', '#', '$', -1, '&','\'', /* 30 - 39 */
+ '(', ')', '*', '+', ',', '-', '.', '/', '0', '1', /* 40 - 49 */
+ '2', '3', '4', '5', '6', '7', '8', '9', ':', ';', /* 50 - 59 */
+ '<', '=', '>', '?', '@', -1, -1, -1, -1, -1, /* 60 - 69 */
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 70 - 79 */
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 80 - 89 */
+ -1, '[','\\', ']', '~', '_', '`', 'a', 'b', 'c', /* 90 - 99 */
+ 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', /* 100 - 109 */
+ 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', /* 110 - 119 */
+ 'x', 'y', 'z', -1, -1, -1, -1, -1, -1, -1, /* 120 - 129 */
+};
+
+static int sh_keymap[] = {
+ /* 0 1 2 3 4 5 6 7 8 9 */
+ -1, -1, -1, -1, -1, -1, -1, -1, 8, 9, /* 0 - 9 */
+ -1, -1, -1, 13, -1, -1, -1, -1, -1, -1, /* 10 - 19 */
+ -1, -1, -1, -1, -1, -1, -1, 27, -1, -1, /* 20 - 29 */
+ -1, -1, ' ', '!', '"', '~', '$', -1, '&', '@', /* 30 - 39 */
+ '(', ')', '*', '+', '<', '_', '>', '?', ')', '!', /* 40 - 49 */
+ '"', 243, '$', '%', '^', '&', '*', '(', ';', ':', /* 50 - 59 */
+ '<', '+', '>', '?', '@', -1, -1, -1, -1, -1, /* 60 - 69 */
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 70 - 79 */
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 80 - 89 */
+ -1, '{', '|', '}', '~', '_', 254, 'A', 'B', 'C', /* 90 - 99 */
+ 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', /* 100 - 109 */
+ 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', /* 110 - 119 */
+ 'X', 'Y', 'Z', -1, -1, -1, -1, -1, -1, -1, /* 120 - 129 */
+};
+
+
+/* exported function documented in fbtk.h */
+int
+fbtk_keycode_to_ucs4(int code, uint8_t mods)
+{
+ int ucs4 = -1;
+
+ if (mods) {
+ if ((code >= 0) && (code < (int) NOF_ELEMENTS(sh_keymap)))
+ ucs4 = sh_keymap[code];
+ } else {
+ if ((code >= 0) && (code < (int) NOF_ELEMENTS(keymap)))
+ ucs4 = keymap[code];
+ }
+ return ucs4;
+}
+
+/*
+ * Local Variables:
+ * c-basic-offset:8
+ * End:
+ */
diff --git a/framebuffer/fbtk/fbtk.c b/framebuffer/fbtk/fbtk.c
new file mode 100644
index 000000000..f8b3d850c
--- /dev/null
+++ b/framebuffer/fbtk/fbtk.c
@@ -0,0 +1,726 @@
+/*
+ * Copyright 2008,2010 Vincent Sanders <vince@simtec.co.uk>
+ *
+ * Framebuffer windowing toolkit core.
+ *
+ * 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 <sys/types.h>
+#include <stdint.h>
+#include <string.h>
+#include <stdbool.h>
+
+#include <libnsfb.h>
+#include <libnsfb_plot.h>
+#include <libnsfb_plot_util.h>
+#include <libnsfb_event.h>
+#include <libnsfb_cursor.h>
+
+#include "utils/utils.h"
+#include "utils/log.h"
+#include "css/css.h"
+#include "desktop/browser.h"
+#include "desktop/plotters.h"
+
+#include "framebuffer/gui.h"
+#include "framebuffer/fbtk.h"
+#include "framebuffer/bitmap.h"
+#include "framebuffer/image_data.h"
+
+#include "widget.h"
+
+/* tree dump debug, also example of depth first tree walk */
+static void
+dump_tk_tree(fbtk_widget_t *widget)
+{
+ widget = fbtk_get_root_widget(widget);
+ int indent = 0;
+
+ while (widget != NULL) {
+ LOG(("%*s%p", indent, "", widget));
+ if (widget->first_child != NULL) {
+ widget = widget->first_child;
+ indent += 6;
+ } else if (widget->next != NULL) {
+ widget = widget->next;
+ } else {
+ while ((widget->parent != NULL) &&
+ (widget->parent->next == NULL)) {
+ widget = widget->parent;
+ indent -= 6;
+ }
+ if (widget->parent != NULL) {
+ indent -= 6;
+ widget = widget->parent->next;
+ } else {
+ widget = NULL;
+ }
+ }
+ }
+}
+
+/* exported function documented in fbtk.h */
+void
+fbtk_request_redraw(fbtk_widget_t *widget)
+{
+ fbtk_widget_t *cwidget;
+ fbtk_widget_t *pwidget;
+
+ /* if widget not mapped do not try to redraw it */
+ pwidget = widget;
+ while (pwidget != NULL) {
+ if (pwidget->mapped == false)
+ return;
+ pwidget = pwidget->parent;
+ }
+
+ widget->redraw.needed = true;
+ widget->redraw.x = 0;
+ widget->redraw.y = 0;
+ widget->redraw.width = widget->width;
+ widget->redraw.height = widget->height;
+
+ LOG(("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) {
+ fbtk_request_redraw(cwidget);
+ cwidget = cwidget->prev;
+ }
+
+ while (widget->parent != NULL) {
+ widget = widget->parent;
+ widget->redraw.child = true;
+ }
+}
+
+
+
+/* exported function documented in fbtk.h */
+int
+fbtk_set_mapping(fbtk_widget_t *widget, bool map)
+{
+ LOG(("setting mapping on %p to %d", widget, map));
+ widget->mapped = map;
+ if (map) {
+ fbtk_request_redraw(widget);
+ } else {
+ fbtk_request_redraw(widget->parent);
+ }
+ return 0;
+}
+
+/** swap the widget given with the next sibling.
+ *
+ * Swap a sibling widget with the next deepest in the hierachy
+ */
+static void
+swap_siblings(fbtk_widget_t *lw)
+{
+ fbtk_widget_t *rw; /* the widget to swap lw with */
+ fbtk_widget_t *before;
+ fbtk_widget_t *after;
+
+ rw = lw->next;
+ LOG(("Swapping %p with %p", lw, rw));
+ before = lw->prev;
+ after = rw->next;
+
+ if (before == NULL) {
+ /* left widget is currently the first child */
+ lw->parent->first_child = rw;
+ } else {
+ before->next = rw;
+ }
+ rw->prev = before;
+ rw->next = lw;
+
+ if (after == NULL) {
+ /* right widget is currently the last child */
+ rw->parent->last_child = lw;
+ } else {
+ after->prev = lw;
+ }
+ lw->next = after;
+ lw->prev = rw;
+}
+
+
+
+/* exported function documented in fbtk.h */
+int
+fbtk_set_zorder(fbtk_widget_t *widget, int z)
+{
+ while (z != 0) {
+ if (z < 0) {
+ if (widget->prev == NULL)
+ break; /* cannot go any shallower */
+
+ /* swap with previous entry */
+ swap_siblings(widget->prev);
+
+ z++;
+ } else {
+ if (widget->next == NULL)
+ break; /* cannot go any deeper */
+
+ /* swap with subsequent entry */
+ swap_siblings(widget);
+
+ z--;
+ }
+ }
+
+ return z;
+}
+
+
+/* exported function documented in fbtk.h */
+bool
+fbtk_set_pos_and_size(fbtk_widget_t *widget,
+ int x, int y,
+ int width, int height)
+{
+ if ((widget->x != x) ||
+ (widget->y != y) ||
+ (widget->width != width) ||
+ (widget->height != height)) {
+ widget->x = x;
+ widget->y = y;
+ widget->width = width;
+ widget->height = height;
+ /* @todo This should limit the redrawn area to the sum
+ * of the old and new widget dimensions, not redraw the lot.
+ */
+ fbtk_request_redraw(widget->parent);
+ return true;
+ }
+ return false;
+}
+
+/* exported function documented in fbtk.h */
+int
+fbtk_destroy_widget(fbtk_widget_t *widget)
+{
+ fbtk_widget_t *parent;
+ int ret = 0;
+
+ ret = fbtk_post_callback(widget, FBTK_CBT_DESTROY);
+
+ while (widget->first_child != NULL) {
+ fbtk_destroy_widget(widget->first_child);
+ }
+
+ parent = widget->parent;
+ if (parent != NULL) {
+
+ /* unlink from siblings */
+ if (widget->prev != NULL) {
+ widget->prev->next = widget->next;
+ } else {
+ /* must be the first widget, unlink from parent */
+ parent->first_child = widget->next;
+ }
+ if (widget->next != NULL) {
+ widget->next->prev = widget->prev;
+ } else {
+ /* must be the last widget, unlink from parent */
+ parent->last_child = widget->prev;
+ }
+
+ free(widget);
+ }
+
+ return ret;
+}
+
+/* region coverage flags. */
+enum {
+ POINT_LEFTOF_REGION = 1,
+ POINT_RIGHTOF_REGION = 2,
+ POINT_ABOVE_REGION = 4,
+ POINT_BELOW_REGION = 8,
+};
+
+/* Computes where a point lies in respect to an area. */
+#define REGION(x,y,cx1,cx2,cy1,cy2) \
+ (( (y) > (cy2) ? POINT_BELOW_REGION : 0) | \
+ ( (y) < (cy1) ? POINT_ABOVE_REGION : 0) | \
+ ( (x) > (cx2) ? POINT_RIGHTOF_REGION : 0) | \
+ ( (x) < (cx1) ? POINT_LEFTOF_REGION : 0) )
+
+/* swap two integers */
+#define SWAP(a, b) do { int t; t=(a); (a)=(b); (b)=t; } while(0)
+
+/* exported function documented in fbtk.h */
+bool
+fbtk_clip_rect(const bbox_t * restrict clip, bbox_t * restrict box)
+{
+ uint8_t region1;
+ uint8_t region2;
+
+ /* ensure co-ordinates are in ascending order */
+ if (box->x1 < box->x0)
+ SWAP(box->x0, box->x1);
+ if (box->y1 < box->y0)
+ SWAP(box->y0, box->y1);
+
+ region1 = REGION(box->x0, box->y0, clip->x0, clip->x1 - 1, clip->y0, clip->y1 - 1);
+ region2 = REGION(box->x1, box->y1, clip->x0, clip->x1 - 1, clip->y0, clip->y1 - 1);
+
+ /* area lies entirely outside the clipping rectangle */
+ if ((region1 | region2) && (region1 & region2))
+ return false;
+
+ if (box->x0 < clip->x0)
+ box->x0 = clip->x0;
+ if (box->x0 > clip->x1)
+ box->x0 = clip->x1;
+
+ if (box->x1 < clip->x0)
+ box->x1 = clip->x0;
+ if (box->x1 > clip->x1)
+ box->x1 = clip->x1;
+
+ if (box->y0 < clip->y0)
+ box->y0 = clip->y0;
+ if (box->y0 > clip->y1)
+ box->y0 = clip->y1;
+
+ if (box->y1 < clip->y0)
+ box->y1 = clip->y0;
+ if (box->y1 > clip->y1)
+ box->y1 = clip->y1;
+
+ return true;
+}
+
+/* exported function documented in fbtk.h */
+bool
+fbtk_clip_to_widget(fbtk_widget_t *widget, bbox_t * restrict box)
+{
+ bbox_t wbox;
+ wbox.x0 = 0;
+ wbox.y0 = 0;
+ wbox.x1 = widget->width;
+ wbox.y1 = widget->height;
+ return fbtk_clip_rect(&wbox, box);
+}
+
+
+
+/* internally exported function documented in widget.h */
+int
+fbtk_set_ptr(fbtk_widget_t *widget, fbtk_callback_info *cbi)
+{
+ fbtk_widget_t *root = fbtk_get_root_widget(widget);
+ struct bitmap *bm = cbi->context;
+
+ nsfb_cursor_set(root->u.root.fb,
+ (nsfb_colour_t *)bm->pixdata,
+ bm->width,
+ bm->height,
+ bm->width);
+
+ return 0;
+}
+
+
+
+/* internally exported function documented in widget.h */
+fbtk_widget_t *
+fbtk_get_root_widget(fbtk_widget_t *widget)
+{
+ while (widget->parent != NULL)
+ widget = widget->parent;
+
+ /* check root widget was found */
+ if (widget->type != FB_WIDGET_TYPE_ROOT) {
+ LOG(("Widget with null parent that is not the root widget!"));
+ return NULL;
+ }
+
+ return widget;
+}
+
+
+/* exported function documented in fbtk.h */
+int
+fbtk_get_absx(fbtk_widget_t *widget)
+{
+ int x = widget->x;
+
+ while (widget->parent != NULL) {
+ widget = widget->parent;
+ x += widget->x;
+ }
+
+ return x;
+}
+
+/* exported function documented in fbtk.h */
+int
+fbtk_get_absy(fbtk_widget_t *widget)
+{
+ int y = widget->y;
+
+ while (widget->parent != NULL) {
+ widget = widget->parent;
+ y += widget->y;
+ }
+
+ return y;
+}
+
+/* exported function documented in fbtk.h */
+int
+fbtk_get_height(fbtk_widget_t *widget)
+{
+ return widget->height;
+}
+
+/* exported function documented in fbtk.h */
+int
+fbtk_get_width(fbtk_widget_t *widget)
+{
+ return widget->width;
+}
+
+/* exported function documented in fbtk.h */
+bool
+fbtk_get_bbox(fbtk_widget_t *widget, nsfb_bbox_t *bbox)
+{
+ bbox->x0 = widget->x;
+ bbox->y0 = widget->y;
+ bbox->x1 = widget->x + widget->width;
+ bbox->y1 = widget->y + widget->height;
+
+ widget = widget->parent;
+ while (widget != NULL) {
+ bbox->x0 += widget->x;
+ bbox->y0 += widget->y;
+ bbox->x1 += widget->x;
+ bbox->y1 += widget->y;
+ widget = widget->parent;
+ }
+
+ return true;
+}
+
+/* exported function documented in fbtk.h */
+fbtk_widget_t *
+fbtk_get_widget_at(fbtk_widget_t *nwid, int x, int y)
+{
+ fbtk_widget_t *widget = NULL; /* found widget */
+
+ /* require the root widget to start */
+ nwid = fbtk_get_root_widget(nwid);
+
+ while (nwid != NULL) {
+ if ((nwid->mapped) &&
+ (x >= nwid->x) &&
+ (y >= nwid->y) &&
+ (x < (nwid->x + nwid->width)) &&
+ (y < (nwid->y + nwid->height))) {
+ widget = nwid;
+ x -= nwid->x;
+ y -= nwid->y;
+ nwid = nwid->first_child;
+ } else {
+ nwid = nwid->next;
+ }
+ }
+
+ return widget;
+}
+
+
+
+
+/* internally exported function documented in widget.h */
+fbtk_widget_t *
+fbtk_widget_new(fbtk_widget_t *parent,
+ enum fbtk_widgettype_e type,
+ int x,
+ int y,
+ int width,
+ int height)
+{
+ fbtk_widget_t *neww; /* new widget */
+
+ if (parent == NULL)
+ return NULL;
+
+ neww = calloc(1, sizeof(fbtk_widget_t));
+ if (neww == NULL)
+ return NULL;
+
+ LOG(("creating %p %d,%d %d,%d", neww, x, y, width, height));
+
+ /* make new window fit inside parent */
+ if (width == 0) {
+ width = parent->width - x;
+ } else if (width < 0) {
+ width = parent->width + width - x;
+ }
+ if ((width + x) > parent->width) {
+ width = parent->width - x;
+ }
+
+ if (height == 0) {
+ height = parent->height - y;
+ } else if (height < 0) {
+ height = parent->height + height - y;
+ }
+ if ((height + y) > parent->height) {
+ height = parent->height - y;
+ }
+
+
+ LOG(("using %p %d,%d %d,%d", neww, x, y, width, height));
+ /* set values */
+ neww->type = type;
+ neww->x = x;
+ neww->y = y;
+ neww->width = width;
+ neww->height = height;
+
+ /* insert into widget heiarchy */
+
+ neww->parent = parent;
+
+ if (parent->first_child == NULL) {
+ /* no child widgets yet */
+ parent->last_child = neww;
+ } else {
+ /* add new widget to front of sibling chain */
+ neww->next = parent->first_child;
+ neww->next->prev = neww;
+ }
+ parent->first_child = neww;
+
+ return neww;
+}
+
+/* exported function documented in fbtk.h */
+bool
+fbtk_get_redraw_pending(fbtk_widget_t *widget)
+{
+ fbtk_widget_t *root;
+
+ /* ensure we have the root widget */
+ root = fbtk_get_root_widget(widget);
+
+ return root->redraw.needed | root->redraw.child;
+}
+
+/** Perform a depth-first tree-walk, calling the redraw callback of the widgets in turn.
+ *
+ * This function makes no decisions of its own and simply walks the
+ * widget tree depth first calling widgets redraw callbacks if flagged
+ * to do so.
+ * The tree search is optimised with a flag to indicate wether the
+ * children of a node should be considered.
+ */
+static int
+do_redraw(nsfb_t *nsfb, fbtk_widget_t *widget)
+{
+ nsfb_bbox_t plot_ctx;
+ fbtk_widget_t *cwidget; /* child widget */
+
+ /* check if the widget requires redrawing */
+ if (widget->redraw.needed == true) {
+ plot_ctx.x0 = fbtk_get_absx(widget) + widget->redraw.x;
+ plot_ctx.y0 = fbtk_get_absy(widget) + widget->redraw.y;
+ plot_ctx.x1 = plot_ctx.x0 + widget->redraw.width;
+ plot_ctx.y1 = plot_ctx.y0 + widget->redraw.height;
+
+ LOG(("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);
+ }
+ widget->redraw.needed = false;
+ }
+
+ /* walk the widgets children if child flag is set */
+ if (widget->redraw.child) {
+ cwidget = widget->last_child;
+ while (cwidget != NULL) {
+ do_redraw(nsfb, cwidget);
+ cwidget = cwidget->prev;
+ }
+ widget->redraw.child = false;
+ }
+
+ return 1;
+}
+
+/* exported function documented in fbtk.h */
+int
+fbtk_redraw(fbtk_widget_t *widget)
+{
+ fbtk_widget_t *root;
+
+ /* ensure we have the root widget */
+ root = fbtk_get_root_widget(widget);
+
+ return do_redraw(root->u.root.fb, root);
+}
+
+/* exported function documented in fbtk.h */
+fbtk_callback
+fbtk_get_handler(fbtk_widget_t *widget, fbtk_callback_type cbt)
+{
+ if ((cbt <= FBTK_CBT_START) || (cbt >= FBTK_CBT_END)) {
+ /* type out of range, no way to report error so return NULL */
+ return NULL;
+ }
+
+ return widget->callback[cbt];
+}
+
+/* exported function documented in fbtk.h */
+fbtk_callback
+fbtk_set_handler(fbtk_widget_t *widget,
+ fbtk_callback_type cbt,
+ fbtk_callback cb,
+ void *context)
+{
+ fbtk_callback prevcb;
+
+ if ((cbt <= FBTK_CBT_START) || (cbt >= FBTK_CBT_END)) {
+ /* type out of range, no way to report error so return NULL */
+ return NULL;
+ }
+
+ prevcb = widget->callback[cbt];
+
+ widget->callback[cbt] = cb;
+ widget->callback_context[cbt] = context;
+
+ return prevcb;
+}
+
+/* exported function docuemnted in fbtk.h */
+int
+fbtk_post_callback(fbtk_widget_t *widget, fbtk_callback_type cbt, ...)
+{
+ fbtk_callback_info cbi;
+ int ret = 0;
+ va_list ap;
+
+ if (widget == NULL)
+ return -1;
+ /* if the widget is not mapped do not attempt to post any
+ * events to it
+ */
+ if (widget->mapped == false)
+ return ret;
+
+ if (widget->callback[cbt] != NULL) {
+ cbi.type = cbt;
+ cbi.context = widget->callback_context[cbt];
+
+ va_start(ap, cbt);
+
+ switch (cbt) {
+ case FBTK_CBT_SCROLLX:
+ cbi.x = va_arg(ap,int);
+ break;
+
+ case FBTK_CBT_SCROLLY:
+ cbi.y = va_arg(ap,int);
+ break;
+
+ case FBTK_CBT_CLICK:
+ cbi.event = va_arg(ap, void *);
+ cbi.x = va_arg(ap, int);
+ cbi.y = va_arg(ap, int);
+ break;
+
+ case FBTK_CBT_INPUT:
+ cbi.event = va_arg(ap, void *);
+ break;
+
+ case FBTK_CBT_POINTERMOVE:
+ cbi.x = va_arg(ap, int);
+ cbi.y = va_arg(ap, int);
+ break;
+
+ case FBTK_CBT_REDRAW:
+ break;
+
+ case FBTK_CBT_USER:
+ break;
+
+ default:
+ break;
+ }
+ va_end(ap);
+
+ ret = (widget->callback[cbt])(widget, &cbi);
+ }
+
+ return ret;
+}
+
+
+
+/* exported function docuemnted in fbtk.h */
+nsfb_t *
+fbtk_get_nsfb(fbtk_widget_t *widget)
+{
+ fbtk_widget_t *root;
+
+ /* ensure we have the root widget */
+ root = fbtk_get_root_widget(widget);
+
+ return root->u.root.fb;
+}
+
+/* exported function docuemnted in fbtk.h */
+fbtk_widget_t *
+fbtk_init(nsfb_t *fb)
+{
+ fbtk_widget_t *root;
+
+ /* create and configure root widget */
+ root = calloc(1, sizeof(fbtk_widget_t));
+ if (root == NULL)
+ return NULL;
+
+ root->type = FB_WIDGET_TYPE_ROOT;
+ root->u.root.fb = fb;
+
+ nsfb_get_geometry(fb, &root->width, &root->height, NULL);
+
+ root->mapped = true;
+
+ return root;
+}
+
+/*
+ * Local Variables:
+ * c-basic-offset:8
+ * End:
+ */
diff --git a/framebuffer/fbtk/fill.c b/framebuffer/fbtk/fill.c
new file mode 100644
index 000000000..ce16b5bcf
--- /dev/null
+++ b/framebuffer/fbtk/fill.c
@@ -0,0 +1,81 @@
+/*
+ * Copyright 2010 Vincent Sanders <vince@simtec.co.uk>
+ *
+ * Framebuffer windowing toolkit filled area widget
+ *
+ * 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 <malloc.h>
+
+#include <libnsfb.h>
+#include <libnsfb_plot.h>
+
+#include "desktop/browser.h"
+
+#include "framebuffer/gui.h"
+#include "framebuffer/fbtk.h"
+
+#include "widget.h"
+
+static int
+fb_redraw_fill(fbtk_widget_t *widget, fbtk_callback_info *cbi)
+{
+ nsfb_bbox_t bbox;
+ nsfb_t *nsfb;
+
+ nsfb = fbtk_get_nsfb(widget);
+
+ fbtk_get_bbox(widget, &bbox);
+
+ nsfb_claim(nsfb, &bbox);
+
+ /* clear background */
+ if ((widget->bg & 0xFF000000) != 0) {
+ /* transparent polygon filling isnt working so fake it */
+ nsfb_plot_rectangle_fill(nsfb, &bbox, widget->bg);
+ }
+
+ nsfb_update(nsfb, &bbox);
+
+ return 0;
+}
+
+/* exported function documented in fbtk.h */
+fbtk_widget_t *
+fbtk_create_fill(fbtk_widget_t *parent,
+ int x,
+ int y,
+ int width,
+ int height,
+ colour c)
+{
+ fbtk_widget_t *neww;
+
+ neww = fbtk_widget_new(parent, FB_WIDGET_TYPE_FILL, x, y, width, height);
+ neww->bg = c;
+ neww->mapped = true;
+
+ fbtk_set_handler(neww, FBTK_CBT_REDRAW, fb_redraw_fill, NULL);
+
+ return neww;
+}
+
+/*
+ * Local Variables:
+ * c-basic-offset:8
+ * End:
+ */
diff --git a/framebuffer/fbtk/osk.c b/framebuffer/fbtk/osk.c
new file mode 100644
index 000000000..36fb765d3
--- /dev/null
+++ b/framebuffer/fbtk/osk.c
@@ -0,0 +1,202 @@
+/*
+ * Copyright 2010 Vincent Sanders <vince@simtec.co.uk>
+ *
+ * Framebuffer windowing toolkit on screen keyboard.
+ *
+ * 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 <limits.h>
+
+#include <libnsfb.h>
+#include <libnsfb_plot.h>
+#include <libnsfb_event.h>
+#include <libnsfb_cursor.h>
+
+#include "utils/log.h"
+#include "desktop/browser.h"
+
+#include "framebuffer/gui.h"
+#include "framebuffer/fbtk.h"
+#include "framebuffer/bitmap.h"
+#include "framebuffer/image_data.h"
+
+#include "widget.h"
+
+struct kbd_button_s {
+ int x;
+ int y;
+ int w;
+ int h;
+ const char *t;
+ enum nsfb_key_code_e keycode;
+};
+
+#define KEYCOUNT 58
+
+static struct kbd_button_s kbdbase[KEYCOUNT] = {
+ { 0, 0, 20, 15, "`", NSFB_KEY_BACKQUOTE},
+ { 20, 0, 20, 15, "1", NSFB_KEY_1},
+ { 40, 0, 20, 15, "2", NSFB_KEY_2},
+ { 60, 0, 20, 15, "3", NSFB_KEY_3},
+ { 80, 0, 20, 15, "4", NSFB_KEY_4},
+ { 100, 0, 20, 15, "5", NSFB_KEY_5},
+ { 120, 0, 20, 15, "6", NSFB_KEY_6},
+ { 140, 0, 20, 15, "7", NSFB_KEY_7},
+ { 160, 0, 20, 15, "8", NSFB_KEY_8},
+ { 180, 0, 20, 15, "9", NSFB_KEY_9},
+ { 200, 0, 20, 15, "0", NSFB_KEY_0},
+ { 220, 0, 20, 15, "-", NSFB_KEY_MINUS},
+ { 240, 0, 20, 15, "=", NSFB_KEY_EQUALS},
+ { 260, 0, 40, 15, "\xe2\x8c\xab", NSFB_KEY_BACKSPACE},
+ { 0, 15, 30, 15, "\xe2\x86\xb9", NSFB_KEY_TAB},
+ { 30, 15, 20, 15, "q", NSFB_KEY_q},
+ { 50, 15, 20, 15, "w", NSFB_KEY_w},
+ { 70, 15, 20, 15, "e", NSFB_KEY_e},
+ { 90, 15, 20, 15, "r", NSFB_KEY_r},
+ { 110, 15, 20, 15, "t", NSFB_KEY_t},
+ { 130, 15, 20, 15, "y", NSFB_KEY_y},
+ { 150, 15, 20, 15, "u", NSFB_KEY_u},
+ { 170, 15, 20, 15, "i", NSFB_KEY_i},
+ { 190, 15, 20, 15, "o", NSFB_KEY_o},
+ { 210, 15, 20, 15, "p", NSFB_KEY_p},
+ { 230, 15, 20, 15, "[", NSFB_KEY_LEFTBRACKET},
+ { 250, 15, 20, 15, "]", NSFB_KEY_RIGHTBRACKET},
+ { 275, 15, 25, 30, "\xe2\x8f\x8e", NSFB_KEY_RETURN},
+ { 35, 30, 20, 15, "a", NSFB_KEY_a},
+ { 55, 30, 20, 15, "s", NSFB_KEY_s},
+ { 75, 30, 20, 15, "d", NSFB_KEY_d},
+ { 95, 30, 20, 15, "f", NSFB_KEY_f},
+ { 115, 30, 20, 15, "g", NSFB_KEY_g},
+ { 135, 30, 20, 15, "h", NSFB_KEY_h},
+ { 155, 30, 20, 15, "j", NSFB_KEY_j},
+ { 175, 30, 20, 15, "k", NSFB_KEY_k},
+ { 195, 30, 20, 15, "l", NSFB_KEY_l},
+ { 215, 30, 20, 15, ";", NSFB_KEY_SEMICOLON},
+ { 235, 30, 20, 15, "'", NSFB_KEY_l},
+ { 255, 30, 20, 15, "#", NSFB_KEY_HASH},
+ { 0, 45, 25, 15, "\xe2\x87\xa7", NSFB_KEY_LSHIFT},
+ { 25, 45, 20, 15, "\\", NSFB_KEY_SLASH},
+ { 45, 45, 20, 15, "z", NSFB_KEY_z},
+ { 65, 45, 20, 15, "x", NSFB_KEY_x},
+ { 85, 45, 20, 15, "c", NSFB_KEY_c},
+ { 105, 45, 20, 15, "v", NSFB_KEY_v},
+ { 125, 45, 20, 15, "b", NSFB_KEY_b},
+ { 145, 45, 20, 15, "n", NSFB_KEY_n},
+ { 165, 45, 20, 15, "m", NSFB_KEY_m},
+ { 185, 45, 20, 15, ",", NSFB_KEY_COMMA},
+ { 205, 45, 20, 15, ".", NSFB_KEY_PERIOD},
+ { 225, 45, 20, 15, "/", NSFB_KEY_BACKSLASH},
+ { 245, 45, 55, 15, "\xe2\x87\xa7", NSFB_KEY_RSHIFT},
+ { 40, 67, 185, 15, "", NSFB_KEY_SPACE},
+ { 250, 60, 20, 15, "\xe2\x96\xb2", NSFB_KEY_UP},
+ { 230, 67, 20, 15, "\xe2\x97\x80", NSFB_KEY_LEFT},
+ { 270, 67, 20, 15, "\xe2\x96\xb6", NSFB_KEY_RIGHT},
+ { 250, 75, 20, 15, "\xe2\x96\xbc", NSFB_KEY_DOWN},
+};
+
+static fbtk_widget_t *osk;
+
+static int
+osk_close(fbtk_widget_t *widget, fbtk_callback_info *cbi)
+{
+ if (cbi->event->type != NSFB_EVENT_KEY_DOWN)
+ return 0;
+
+ fbtk_set_mapping(osk, false);
+
+ return 0;
+}
+
+static int
+osk_click(fbtk_widget_t *widget, fbtk_callback_info *cbi)
+{
+ nsfb_event_t event;
+ struct kbd_button_s *kbd_button = cbi->context;
+
+ event.type = cbi->event->type;
+ event.value.keycode = kbd_button->keycode;
+ fbtk_input(widget, &event);
+
+ return 0;
+}
+
+/* exported function documented in fbtk.h */
+void
+fbtk_enable_oskb(fbtk_widget_t *fbtk)
+{
+ fbtk_widget_t *widget;
+ int kloop;
+ int maxx = 0;
+ int maxy = 0;
+ int ww;
+ int wh;
+ fbtk_widget_t *root = fbtk_get_root_widget(fbtk);
+ int furniture_width = 18;
+
+ for (kloop=0; kloop < KEYCOUNT; kloop++) {
+ if ((kbdbase[kloop].x + kbdbase[kloop].w) > maxx)
+ maxx=kbdbase[kloop].x + kbdbase[kloop].w;
+ if ((kbdbase[kloop].y + kbdbase[kloop].h) > maxy)
+ maxy=kbdbase[kloop].y + kbdbase[kloop].h;
+ }
+
+ ww = fbtk_get_width(root);
+
+ /* scale window height apropriately */
+ wh = (maxy * ww) / maxx;
+
+ osk = fbtk_create_window(root, 0, fbtk_get_height(root) - wh, 0, wh, 0xff202020);
+
+ for (kloop=0; kloop < KEYCOUNT; kloop++) {
+ widget = fbtk_create_text_button(osk,
+ (kbdbase[kloop].x * ww) / maxx,
+ (kbdbase[kloop].y * ww) / maxx,
+ (kbdbase[kloop].w * ww) / maxx,
+ (kbdbase[kloop].h *ww) / maxx,
+ FB_FRAME_COLOUR,
+ FB_COLOUR_BLACK,
+ osk_click,
+ &kbdbase[kloop]);
+ fbtk_set_text(widget, kbdbase[kloop].t);
+ }
+
+ widget = fbtk_create_text_button(osk,
+ fbtk_get_width(osk) - furniture_width,
+ fbtk_get_height(osk) - furniture_width,
+ furniture_width,
+ furniture_width,
+ FB_FRAME_COLOUR,
+ FB_COLOUR_BLACK,
+ osk_close,
+ NULL);
+ fbtk_set_text(widget, "\xe2\x8c\xa8");
+
+}
+
+/* exported function documented in fbtk.h */
+void
+map_osk(void)
+{
+ fbtk_set_zorder(osk, INT_MIN);
+ fbtk_set_mapping(osk, true);
+}
+
+/*
+ * Local Variables:
+ * c-basic-offset:8
+ * End:
+ */
diff --git a/framebuffer/fbtk/scroll.c b/framebuffer/fbtk/scroll.c
new file mode 100644
index 000000000..356fd11c7
--- /dev/null
+++ b/framebuffer/fbtk/scroll.c
@@ -0,0 +1,543 @@
+/*
+ * Copyright 2010 Vincent Sanders <vince@simtec.co.uk>
+ *
+ * Framebuffer windowing toolkit scrollbar widgets
+ *
+ * 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 <libnsfb.h>
+#include <libnsfb_plot.h>
+#include <libnsfb_event.h>
+#include <libnsfb_cursor.h>
+
+#include "utils/log.h"
+#include "desktop/browser.h"
+
+#include "framebuffer/gui.h"
+#include "framebuffer/fbtk.h"
+#include "framebuffer/bitmap.h"
+#include "framebuffer/image_data.h"
+
+#include "widget.h"
+
+/* Vertical scroll widget */
+
+static int
+vscroll_redraw(fbtk_widget_t *widget, fbtk_callback_info *cbi)
+{
+ int vscroll;
+ int vpos;
+
+ nsfb_bbox_t bbox;
+ nsfb_bbox_t rect;
+ fbtk_widget_t *root = fbtk_get_root_widget(widget);
+
+ fbtk_get_bbox(widget, &bbox);
+
+ nsfb_claim(root->u.root.fb, &bbox);
+
+ rect = bbox;
+
+ /* background */
+ nsfb_plot_rectangle_fill(root->u.root.fb, &rect, widget->bg);
+
+ /* scroll well */
+ rect.x0 = bbox.x0 + 2;
+ rect.y0 = bbox.y0 + 1;
+ rect.x1 = bbox.x1 - 3;
+ rect.y1 = bbox.y1 - 2;
+
+ nsfb_plot_rectangle_fill(root->u.root.fb, &rect, widget->fg);
+ nsfb_plot_rectangle(root->u.root.fb, &rect, 1, 0xFF999999, false, false);
+
+ /* scroll bar */
+ if ((widget->u.scroll.maximum - widget->u.scroll.minimum) > 0) {
+ vscroll = ((widget->height - 4) * widget->u.scroll.thumb) /
+ (widget->u.scroll.maximum - widget->u.scroll.minimum) ;
+ vpos = ((widget->height - 4) * widget->u.scroll.position) /
+ (widget->u.scroll.maximum - widget->u.scroll.minimum) ;
+ } else {
+ vscroll = (widget->height - 4);
+ vpos = 0;
+ }
+
+ rect.x0 = bbox.x0 + 5;
+ rect.y0 = bbox.y0 + 3 + vpos;
+ rect.x1 = bbox.x0 + widget->width - 5;
+ rect.y1 = bbox.y0 + vscroll + vpos;
+
+ nsfb_plot_rectangle_fill(root->u.root.fb, &rect, widget->bg);
+
+ nsfb_update(root->u.root.fb, &bbox);
+
+ return 0;
+}
+
+static int
+vscroll_drag(fbtk_widget_t *widget, fbtk_callback_info *cbi)
+{
+ int newpos;
+ fbtk_widget_t *scrollw = cbi->context;
+
+ newpos = ((widget->u.scroll.maximum - widget->u.scroll.minimum) /
+ (widget->height - 4)) * (cbi->y - widget->u.scroll.drag);
+
+ if (newpos < scrollw->u.scroll.minimum)
+ newpos = scrollw->u.scroll.minimum;
+
+ if (newpos > (scrollw->u.scroll.maximum - scrollw->u.scroll.thumb ))
+ newpos = (scrollw->u.scroll.maximum - scrollw->u.scroll.thumb);
+
+ if (newpos == scrollw->u.scroll.position)
+ return 0;
+
+ return fbtk_post_callback(widget, FBTK_CBT_SCROLLY, newpos);
+}
+
+static int
+vscrollu_click(fbtk_widget_t *widget, fbtk_callback_info *cbi)
+{
+ int newpos;
+ fbtk_widget_t *scrollw = cbi->context;
+
+ if (cbi->event->type != NSFB_EVENT_KEY_DOWN)
+ return 0;
+
+ newpos = scrollw->u.scroll.position - scrollw->u.scroll.page;
+ if (newpos < scrollw->u.scroll.minimum)
+ newpos = scrollw->u.scroll.minimum;
+
+ if (newpos == scrollw->u.scroll.position)
+ return 0;
+
+ return fbtk_post_callback(scrollw, FBTK_CBT_SCROLLY, newpos);
+}
+
+static int
+vscrolld_click(fbtk_widget_t *widget, fbtk_callback_info *cbi)
+{
+ int newpos;
+ fbtk_widget_t *scrollw = cbi->context;
+
+ if (cbi->event->type != NSFB_EVENT_KEY_DOWN)
+ return 0;
+
+ newpos = scrollw->u.scroll.position + scrollw->u.scroll.page;
+ if (newpos > (scrollw->u.scroll.maximum - scrollw->u.scroll.thumb ))
+ newpos = (scrollw->u.scroll.maximum - scrollw->u.scroll.thumb);
+
+ if (newpos == scrollw->u.scroll.position)
+ return 0;
+
+ return fbtk_post_callback(scrollw, FBTK_CBT_SCROLLY, newpos);
+}
+
+static int
+vscrollarea_click(fbtk_widget_t *widget, fbtk_callback_info *cbi)
+{
+ int vscroll;
+ int vpos;
+ int newpos;
+ int ret = 0;
+
+ if (cbi->event->type != NSFB_EVENT_KEY_DOWN) {
+ /* end all drags, just in case */
+ if (fbtk_set_handler(widget, FBTK_CBT_POINTERMOVE, NULL, NULL) != NULL)
+ fbtk_tgrab_pointer(widget);
+ return 0;
+ }
+
+ switch (cbi->event->value.keycode) {
+
+ case NSFB_KEY_MOUSE_4:
+ /* scroll up */
+ newpos = widget->u.scroll.position - widget->u.scroll.page;
+ if (newpos < widget->u.scroll.minimum)
+ newpos = widget->u.scroll.minimum;
+ ret = fbtk_post_callback(cbi->context, FBTK_CBT_SCROLLY, newpos);
+ break;
+
+ case NSFB_KEY_MOUSE_5:
+ /* scroll down */
+ newpos = widget->u.scroll.position + widget->u.scroll.page;
+ if (newpos > widget->u.scroll.maximum)
+ newpos = widget->u.scroll.maximum;
+ ret = fbtk_post_callback(cbi->context, FBTK_CBT_SCROLLY, newpos);
+ break;
+
+ default:
+
+ if ((widget->u.scroll.maximum - widget->u.scroll.minimum) > 0) {
+ vscroll = ((widget->height - 4) * widget->u.scroll.thumb) /
+ (widget->u.scroll.maximum - widget->u.scroll.minimum) ;
+ vpos = ((widget->height - 4) * widget->u.scroll.position) /
+ (widget->u.scroll.maximum - widget->u.scroll.minimum) ;
+ } else {
+ vscroll = (widget->height - 4);
+ vpos = 0;
+ }
+
+ if (cbi->y < vpos) {
+ /* above bar */
+ newpos = widget->u.scroll.position - widget->u.scroll.thumb;
+ if (newpos < widget->u.scroll.minimum)
+ newpos = widget->u.scroll.minimum;
+ ret = fbtk_post_callback(cbi->context, FBTK_CBT_SCROLLY, newpos);
+ } else if (cbi->y > (vpos + vscroll)) {
+ /* below bar */
+ newpos = widget->u.scroll.position + widget->u.scroll.thumb;
+ if (newpos > widget->u.scroll.maximum)
+ newpos = widget->u.scroll.maximum;
+ ret = fbtk_post_callback(cbi->context, FBTK_CBT_SCROLLY, newpos);
+ } else {
+ /* on bar - start drag */
+ widget->u.scroll.drag = cbi->y - vpos;
+ fbtk_set_handler(widget, FBTK_CBT_POINTERMOVE, vscroll_drag, widget);
+ fbtk_tgrab_pointer(widget);
+ }
+ }
+ return ret;
+}
+
+
+/* exported function documented in fbtk.h */
+fbtk_widget_t *
+fbtk_create_vscroll(fbtk_widget_t *parent,
+ int x,
+ int y,
+ int width,
+ int height,
+ colour fg,
+ colour bg,
+ fbtk_callback callback,
+ void *context)
+{
+ fbtk_widget_t *neww;
+
+ neww = fbtk_widget_new(parent,
+ FB_WIDGET_TYPE_VSCROLL,
+ x,
+ y + scrollu.height,
+ width,
+ height - scrollu.height - scrolld.height);
+
+ neww->fg = fg;
+ neww->bg = bg;
+ neww->mapped = true;
+
+ fbtk_set_handler(neww, FBTK_CBT_REDRAW, vscroll_redraw, NULL);
+
+ fbtk_set_handler(neww, FBTK_CBT_CLICK, vscrollarea_click, neww);
+
+ fbtk_set_handler(neww, FBTK_CBT_SCROLLY, callback, context);
+
+ neww->u.scroll.btnul = fbtk_create_button(parent,
+ x,
+ y,
+ width,
+ scrollu.height,
+ fg,
+ &scrollu,
+ vscrollu_click,
+ neww);
+
+ neww->u.scroll.btndr = fbtk_create_button(parent,
+ x,
+ y + height - scrolld.height,
+ width,
+ scrolld.height,
+ fg,
+ &scrolld,
+ vscrolld_click,
+ neww);
+
+
+ return neww;
+}
+
+/* Horizontal scroll widget */
+
+static int
+hscroll_redraw(fbtk_widget_t *widget, fbtk_callback_info *cbi)
+{
+ int hscroll;
+ int hpos;
+ nsfb_bbox_t bbox;
+ nsfb_bbox_t rect;
+ fbtk_widget_t *root = fbtk_get_root_widget(widget);
+
+ fbtk_get_bbox(widget, &bbox);
+
+ nsfb_claim(root->u.root.fb, &bbox);
+
+ rect = bbox;
+
+ /* background */
+ nsfb_plot_rectangle_fill(root->u.root.fb, &rect, widget->bg);
+
+ /* scroll well */
+ rect.x0 = bbox.x0 + 1;
+ rect.y0 = bbox.y0 + 2;
+ rect.x1 = bbox.x1 - 2;
+ rect.y1 = bbox.y1 - 3;
+ nsfb_plot_rectangle_fill(root->u.root.fb, &rect, widget->fg);
+
+ /* scroll well outline */
+ nsfb_plot_rectangle(root->u.root.fb, &rect, 1, 0xFF999999, false, false);
+
+ if ((widget->u.scroll.maximum - widget->u.scroll.minimum) > 0) {
+ hscroll = ((widget->width - 4) * widget->u.scroll.thumb) /
+ (widget->u.scroll.maximum - widget->u.scroll.minimum) ;
+ hpos = ((widget->width - 4) * widget->u.scroll.position) /
+ (widget->u.scroll.maximum - widget->u.scroll.minimum) ;
+ } else {
+ hscroll = (widget->width - 4);
+ hpos = 0;
+ }
+
+ LOG(("hscroll %d", hscroll));
+
+ rect.x0 = bbox.x0 + 3 + hpos;
+ rect.y0 = bbox.y0 + 5;
+ rect.x1 = bbox.x0 + hscroll + hpos;
+ rect.y1 = bbox.y0 + widget->height - 5;
+
+ nsfb_plot_rectangle_fill(root->u.root.fb, &rect, widget->bg);
+
+ nsfb_update(root->u.root.fb, &bbox);
+
+ return 0;
+}
+
+static int
+hscrolll_click(fbtk_widget_t *widget, fbtk_callback_info *cbi)
+{
+ int newpos;
+ fbtk_widget_t *scrollw = cbi->context;
+
+ if (cbi->event->type != NSFB_EVENT_KEY_DOWN)
+ return 0;
+
+ newpos = scrollw->u.scroll.position - scrollw->u.scroll.page;
+ if (newpos < scrollw->u.scroll.minimum)
+ newpos = scrollw->u.scroll.minimum;
+
+ if (newpos == scrollw->u.scroll.position) {
+ LOG(("horiz scroll was the same %d", newpos));
+ return 0;
+ }
+
+ return fbtk_post_callback(scrollw, FBTK_CBT_SCROLLX, newpos);
+}
+
+static int
+hscrollr_click(fbtk_widget_t *widget, fbtk_callback_info *cbi)
+{
+ int newpos;
+ fbtk_widget_t *scrollw = cbi->context;
+
+ if (cbi->event->type != NSFB_EVENT_KEY_DOWN)
+ return 0;
+
+ newpos = scrollw->u.scroll.position + scrollw->u.scroll.page;
+ if (newpos > (scrollw->u.scroll.maximum - scrollw->u.scroll.thumb ))
+ newpos = (scrollw->u.scroll.maximum - scrollw->u.scroll.thumb);
+
+ if (newpos == scrollw->u.scroll.position)
+ return 0;
+
+ return fbtk_post_callback(scrollw, FBTK_CBT_SCROLLX, newpos);
+}
+
+static int
+hscroll_drag(fbtk_widget_t *widget, fbtk_callback_info *cbi)
+{
+ int newpos;
+ fbtk_widget_t *scrollw = cbi->context;
+
+ newpos = ((widget->u.scroll.maximum - widget->u.scroll.minimum) /
+ (widget->width - 4)) * (cbi->x - widget->u.scroll.drag);
+
+ if (newpos < scrollw->u.scroll.minimum)
+ newpos = scrollw->u.scroll.minimum;
+
+ if (newpos > (scrollw->u.scroll.maximum - scrollw->u.scroll.thumb ))
+ newpos = (scrollw->u.scroll.maximum - scrollw->u.scroll.thumb);
+
+ if (newpos == scrollw->u.scroll.position)
+ return 0;
+
+ return fbtk_post_callback(widget, FBTK_CBT_SCROLLX, newpos);
+}
+
+static int
+hscrollarea_click(fbtk_widget_t *widget, fbtk_callback_info *cbi)
+{
+ int hscroll;
+ int hpos;
+ int newpos;
+ int ret = 0;
+
+ if (cbi->event->type != NSFB_EVENT_KEY_DOWN) {
+ /* end all drags, just in case */
+ if (fbtk_set_handler(widget, FBTK_CBT_POINTERMOVE, NULL, NULL) != NULL)
+ fbtk_tgrab_pointer(widget);
+ return 0;
+ }
+
+ if ((widget->u.scroll.maximum - widget->u.scroll.minimum) > 0) {
+ hscroll = ((widget->width - 4) * widget->u.scroll.thumb) /
+ (widget->u.scroll.maximum - widget->u.scroll.minimum) ;
+ hpos = ((widget->width - 4) * widget->u.scroll.position) /
+ (widget->u.scroll.maximum - widget->u.scroll.minimum) ;
+ } else {
+ hscroll = (widget->width - 4);
+ hpos = 0;
+ }
+
+ if (cbi->x < hpos) {
+ /* left of bar */
+ newpos = widget->u.scroll.position - widget->u.scroll.page;
+ if (newpos < widget->u.scroll.minimum)
+ newpos = widget->u.scroll.minimum;
+ ret = fbtk_post_callback(cbi->context, FBTK_CBT_SCROLLX, newpos);
+ } else if (cbi->x > (hpos + hscroll)) {
+ /* right of bar */
+ newpos = widget->u.scroll.position + widget->u.scroll.page;
+ if (newpos > widget->u.scroll.maximum)
+ newpos = widget->u.scroll.maximum;
+ ret = fbtk_post_callback(cbi->context, FBTK_CBT_SCROLLX, newpos);
+ } else {
+ /* on bar - start drag */
+ widget->u.scroll.drag = cbi->x - hpos;
+ fbtk_set_handler(widget, FBTK_CBT_POINTERMOVE, hscroll_drag, widget);
+ fbtk_tgrab_pointer(widget);
+ }
+ return ret;
+}
+
+/* exported function documented in fbtk.h */
+fbtk_widget_t *
+fbtk_create_hscroll(fbtk_widget_t *parent,
+ int x,
+ int y,
+ int width,
+ int height,
+ colour fg,
+ colour bg,
+ fbtk_callback callback,
+ void *context)
+{
+ fbtk_widget_t *neww;
+
+ neww = fbtk_widget_new(parent,
+ FB_WIDGET_TYPE_HSCROLL,
+ x + scrolll.width,
+ y,
+ width - scrolll.width - scrollr.width,
+ height);
+
+ neww->fg = fg;
+ neww->bg = bg;
+ neww->mapped = true;
+
+ fbtk_set_handler(neww, FBTK_CBT_REDRAW, hscroll_redraw, NULL);
+ fbtk_set_handler(neww, FBTK_CBT_CLICK, hscrollarea_click, neww);
+ fbtk_set_handler(neww, FBTK_CBT_SCROLLX, callback, context);
+
+ neww->u.scroll.btnul = fbtk_create_button(parent,
+ x,
+ y,
+ scrolll.width,
+ height,
+ fg,
+ &scrolll,
+ hscrolll_click,
+ neww);
+
+ neww->u.scroll.btndr = fbtk_create_button(parent,
+ x + width - scrollr.width,
+ y,
+ scrollr.width,
+ height,
+ fg,
+ &scrollr,
+ hscrollr_click,
+ neww);
+
+ return neww;
+}
+
+
+/* exported function documented in fbtk.h */
+bool
+fbtk_set_scroll_parameters(fbtk_widget_t *widget,
+ int min,
+ int max,
+ int thumb,
+ int page)
+{
+ if (widget == NULL)
+ return false;
+
+ if ((widget->type != FB_WIDGET_TYPE_HSCROLL) &&
+ (widget->type != FB_WIDGET_TYPE_VSCROLL))
+ return false;
+
+ widget->u.scroll.minimum = min;
+ widget->u.scroll.maximum = max;
+ widget->u.scroll.thumb = thumb;
+ widget->u.scroll.page = page;
+
+ if (widget->u.scroll.position > max)
+ widget->u.scroll.position = max;
+ if (widget->u.scroll.position < min)
+ widget->u.scroll.position = min;
+
+ fbtk_request_redraw(widget);
+
+ return true;
+}
+
+/* exported function documented in fbtk.h */
+bool
+fbtk_set_scroll_position(fbtk_widget_t *widget, int position)
+{
+ if (widget == NULL)
+ return false;
+
+ if ((widget->type != FB_WIDGET_TYPE_HSCROLL) &&
+ (widget->type != FB_WIDGET_TYPE_VSCROLL))
+ return false;
+
+ if ((position < widget->u.scroll.minimum) ||
+ (position > widget->u.scroll.maximum))
+ return false;
+
+ widget->u.scroll.position = position;
+
+ fbtk_request_redraw(widget);
+
+ return true;
+}
+
+/*
+ * Local Variables:
+ * c-basic-offset:8
+ * End:
+ */
diff --git a/framebuffer/fbtk/text.c b/framebuffer/fbtk/text.c
new file mode 100644
index 000000000..ed090fe36
--- /dev/null
+++ b/framebuffer/fbtk/text.c
@@ -0,0 +1,421 @@
+/*
+ * Copyright 2010 Vincent Sanders <vince@simtec.co.uk>
+ *
+ * Framebuffer windowing toolkit scrollbar widgets.
+ *
+ * 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 <malloc.h>
+#include <string.h>
+
+#include <libnsfb.h>
+#include <libnsfb_plot.h>
+#include <libnsfb_plot_util.h>
+#include <libnsfb_event.h>
+
+#include "utils/log.h"
+#include "desktop/browser.h"
+#include "desktop/plotters.h"
+
+#include "framebuffer/gui.h"
+#include "framebuffer/fbtk.h"
+#include "framebuffer/image_data.h"
+
+#include "widget.h"
+
+#define TEXT_WIDGET_BORDER 3 /**< The pixel border round a text widget. */
+
+/* Lighten a colour by taking seven eights of each channel's intensity
+ * and adding a full eighth
+ */
+#define brighten_colour(c1) \
+ (((((7 * ((c1 >> 16) & 0xff)) >> 3) + 32) << 16) | \
+ ((((7 * ((c1 >> 8) & 0xff)) >> 3) + 32) << 8) | \
+ ((((7 * (c1 & 0xff)) >> 3) + 32) << 0))
+
+/** Text redraw callback.
+ *
+ * Called when a text widget requires redrawing.
+ *
+ * @param widget The widget to be redrawn.
+ * @param cbi The callback parameters.
+ * @return The callback result.
+ */
+static int
+fb_redraw_text(fbtk_widget_t *widget, fbtk_callback_info *cbi )
+{
+ nsfb_bbox_t bbox;
+ nsfb_bbox_t rect;
+ fbtk_widget_t *root;
+ plot_font_style_t font_style;
+ int fh;
+ int border;
+
+ border = (widget->height * 10) / 90;
+
+ root = fbtk_get_root_widget(widget);
+
+ fbtk_get_bbox(widget, &bbox);
+
+ rect = bbox;
+
+ nsfb_claim(root->u.root.fb, &bbox);
+
+ /* clear background */
+ if ((widget->bg & 0xFF000000) != 0) {
+ /* transparent polygon filling isnt working so fake it */
+ nsfb_plot_rectangle_fill(root->u.root.fb, &bbox, widget->bg);
+ }
+
+ if (widget->u.text.outline) {
+ rect.x1--;
+ rect.y1--;
+ nsfb_plot_rectangle(root->u.root.fb, &rect, 1, 0x00000000, false, false);
+ border++;
+ }
+
+ if (widget->u.text.text != NULL) {
+ fh = widget->height - border - border;
+ font_style.family = PLOT_FONT_FAMILY_SANS_SERIF;
+ font_style.size = fh * FONT_SIZE_SCALE;
+ font_style.weight = 400;
+ font_style.flags = FONTF_NONE;
+ font_style.background = widget->bg;
+ font_style.foreground = widget->fg;
+
+ LOG(("plotting %p at %d,%d %d,%d w/h %d,%d font h %d border %d",
+ widget, bbox.x0, bbox.y0, bbox.x1, bbox.y1,
+ widget->width, widget->height, fh, border));
+ /* Call the fb text plotting, baseline is 3/4 down the
+ * font, somewhere along the way the co-ordinate
+ * system for the baseline is to the "higher value
+ * pixel co-ordinate" due to this the + 1 is neccessary.
+ */
+ plot.text(bbox.x0 + border,
+ bbox.y0 + (((fh * 3) + 3)/4) + border + 1,
+ widget->u.text.text,
+ strlen(widget->u.text.text),
+ &font_style);
+ }
+
+ nsfb_update(root->u.root.fb, &bbox);
+
+ return 0;
+}
+
+/** Text button redraw callback.
+ *
+ * Called when a text widget requires redrawing.
+ *
+ * @param widget The widget to be redrawn.
+ * @param cbi The callback parameters.
+ * @return The callback result.
+ */
+static int
+fb_redraw_text_button(fbtk_widget_t *widget, fbtk_callback_info *cbi )
+{
+ nsfb_bbox_t bbox;
+ nsfb_bbox_t rect;
+ nsfb_bbox_t line;
+ nsfb_plot_pen_t pen;
+ plot_font_style_t font_style;
+ int fh;
+ int border;
+ fbtk_widget_t *root = fbtk_get_root_widget(widget);
+
+ if (widget->height < 20) {
+ border = 0;
+ } else {
+ border = (widget->height * 10) / 90;
+ }
+
+ pen.stroke_type = NFSB_PLOT_OPTYPE_SOLID;
+ pen.stroke_width = 1;
+ pen.stroke_colour = brighten_colour(widget->bg);
+
+ fbtk_get_bbox(widget, &bbox);
+
+ rect = bbox;
+ rect.x1--;
+ rect.y1--;
+
+ nsfb_claim(root->u.root.fb, &bbox);
+
+ /* clear background */
+ if ((widget->bg & 0xFF000000) != 0) {
+ /* transparent polygon filling isnt working so fake it */
+ nsfb_plot_rectangle_fill(root->u.root.fb, &rect, widget->bg);
+ }
+
+ if (widget->u.text.outline) {
+ line.x0 = rect.x0;
+ line.y0 = rect.y0;
+ line.x1 = rect.x0;
+ line.y1 = rect.y1;
+ nsfb_plot_line(root->u.root.fb, &line, &pen);
+ line.x0 = rect.x0;
+ line.y0 = rect.y0;
+ line.x1 = rect.x1;
+ line.y1 = rect.y0;
+ nsfb_plot_line(root->u.root.fb, &line, &pen);
+ pen.stroke_colour = darken_colour(widget->bg);
+ line.x0 = rect.x0;
+ line.y0 = rect.y1;
+ line.x1 = rect.x1;
+ line.y1 = rect.y1;
+ nsfb_plot_line(root->u.root.fb, &line, &pen);
+ line.x0 = rect.x1;
+ line.y0 = rect.y0;
+ line.x1 = rect.x1;
+ line.y1 = rect.y1;
+ nsfb_plot_line(root->u.root.fb, &line, &pen);
+ border++;
+ }
+
+ if (widget->u.text.text != NULL) {
+ fh = widget->height - border - border;
+ font_style.family = PLOT_FONT_FAMILY_SANS_SERIF;
+ font_style.size = fh * FONT_SIZE_SCALE;
+ font_style.weight = 400;
+ font_style.flags = FONTF_NONE;
+ font_style.background = widget->bg;
+ font_style.foreground = widget->fg;
+
+ LOG(("plotting %p at %d,%d %d,%d w/h %d,%d font h %d border %d",
+ widget, bbox.x0, bbox.y0, bbox.x1, bbox.y1,
+ widget->width, widget->height, fh, border));
+ /* Call the fb text plotting, baseline is 3/4 down the
+ * font, somewhere along the way the co-ordinate
+ * system for the baseline is to the "higher value
+ * pixel co-ordinate" due to this the + 1 is neccessary.
+ */
+ plot.text(bbox.x0 + border,
+ bbox.y0 + (((fh * 3) + 3)/4) + border + 1,
+ widget->u.text.text,
+ strlen(widget->u.text.text),
+ &font_style);
+ }
+
+ nsfb_update(root->u.root.fb, &bbox);
+
+ return 0;
+}
+
+/** Routine called when text events occour in writeable widget.
+ *
+ * @param widget The widget reciving input events.
+ * @param cbi The callback parameters.
+ * @return The callback result.
+ */
+static int
+text_input(fbtk_widget_t *widget, fbtk_callback_info *cbi)
+{
+ int value;
+ static uint8_t modifier = 0;
+ char *temp;
+
+ if (cbi->event == NULL) {
+ /* gain focus */
+ if (widget->u.text.text == NULL)
+ widget->u.text.text = calloc(1,1);
+ widget->u.text.idx = strlen(widget->u.text.text);
+
+ fbtk_request_redraw(widget);
+
+ return 0;
+ }
+
+ value = cbi->event->value.keycode;
+
+ if (cbi->event->type != NSFB_EVENT_KEY_DOWN) {
+ switch (value) {
+ case NSFB_KEY_RSHIFT:
+ modifier &= ~1;
+ break;
+
+ case NSFB_KEY_LSHIFT:
+ modifier &= ~(1<<1);
+ break;
+
+ default:
+ break;
+ }
+ return 0;
+ }
+
+ switch (value) {
+ case NSFB_KEY_BACKSPACE:
+ if (widget->u.text.idx <= 0)
+ break;
+ widget->u.text.idx--;
+ widget->u.text.text[widget->u.text.idx] = 0;
+ break;
+
+ case NSFB_KEY_RETURN:
+ widget->u.text.enter(widget->u.text.pw, widget->u.text.text);
+ break;
+
+ case NSFB_KEY_PAGEUP:
+ case NSFB_KEY_PAGEDOWN:
+ case NSFB_KEY_RIGHT:
+ case NSFB_KEY_LEFT:
+ case NSFB_KEY_UP:
+ case NSFB_KEY_DOWN:
+ /* Not handling any of these correctly yet, but avoid putting
+ * charcters in the text widget when they're pressed. */
+ break;
+
+ case NSFB_KEY_RSHIFT:
+ modifier |= 1;
+ break;
+
+ case NSFB_KEY_LSHIFT:
+ modifier |= 1<<1;
+ break;
+
+ default:
+ /* allow for new character and null */
+ temp = realloc(widget->u.text.text, widget->u.text.idx + 2);
+ if (temp != NULL) {
+ widget->u.text.text = temp;
+ widget->u.text.text[widget->u.text.idx] = fbtk_keycode_to_ucs4(value, modifier);
+ widget->u.text.text[widget->u.text.idx + 1] = '\0';
+ widget->u.text.idx++;
+ }
+
+ break;
+ }
+
+ fbtk_request_redraw(widget);
+
+ return 0;
+}
+
+/* exported function documented in fbtk.h */
+void
+fbtk_writable_text(fbtk_widget_t *widget, fbtk_enter_t enter, void *pw)
+{
+ widget->u.text.enter = enter;
+ widget->u.text.pw = pw;
+
+ fbtk_set_handler(widget, FBTK_CBT_INPUT, text_input, widget);
+}
+
+/* exported function documented in fbtk.h */
+void
+fbtk_set_text(fbtk_widget_t *widget, const char *text)
+{
+ if ((widget == NULL) || (widget->type != FB_WIDGET_TYPE_TEXT))
+ return;
+ if (widget->u.text.text != NULL) {
+ if (strcmp(widget->u.text.text, text) == 0)
+ return; /* text is being set to the same thing */
+ free(widget->u.text.text);
+ }
+ widget->u.text.text = strdup(text);
+ widget->u.text.idx = strlen(text);
+
+ fbtk_request_redraw(widget);
+}
+
+/* exported function documented in fbtk.h */
+fbtk_widget_t *
+fbtk_create_text(fbtk_widget_t *parent,
+ int x,
+ int y,
+ int width,
+ int height,
+ colour bg,
+ colour fg,
+ bool outline)
+{
+ fbtk_widget_t *neww;
+
+ neww = fbtk_widget_new(parent, FB_WIDGET_TYPE_TEXT, x, y, width, height);
+ neww->fg = fg;
+ neww->bg = bg;
+ neww->mapped = true;
+ neww->u.text.outline = outline;
+
+ fbtk_set_handler(neww, FBTK_CBT_REDRAW, fb_redraw_text, NULL);
+
+ return neww;
+}
+
+/* exported function documented in fbtk.h */
+fbtk_widget_t *
+fbtk_create_writable_text(fbtk_widget_t *parent,
+ int x,
+ int y,
+ int width,
+ int height,
+ colour bg,
+ colour fg,
+ bool outline,
+ fbtk_enter_t enter,
+ void *pw)
+{
+ fbtk_widget_t *neww;
+
+ neww = fbtk_widget_new(parent, FB_WIDGET_TYPE_TEXT, x, y, width, height);
+ neww->fg = fg;
+ neww->bg = bg;
+ neww->mapped = true;
+
+ neww->u.text.outline = outline;
+ neww->u.text.enter = enter;
+ neww->u.text.pw = pw;
+
+ fbtk_set_handler(neww, FBTK_CBT_REDRAW, fb_redraw_text, NULL);
+ fbtk_set_handler(neww, FBTK_CBT_INPUT, text_input, neww);
+
+ return neww;
+}
+
+/* exported function documented in fbtk.h */
+fbtk_widget_t *
+fbtk_create_text_button(fbtk_widget_t *parent,
+ int x,
+ int y,
+ int width,
+ int height,
+ colour bg,
+ colour fg,
+ fbtk_callback click,
+ void *pw)
+{
+ fbtk_widget_t *neww;
+
+ neww = fbtk_widget_new(parent, FB_WIDGET_TYPE_TEXT, x, y, width, height);
+ neww->fg = fg;
+ neww->bg = bg;
+ neww->mapped = true;
+
+ neww->u.text.outline = true;
+
+ fbtk_set_handler(neww, FBTK_CBT_REDRAW, fb_redraw_text_button, NULL);
+ fbtk_set_handler(neww, FBTK_CBT_CLICK, click, pw);
+ fbtk_set_handler(neww, FBTK_CBT_POINTERENTER, fbtk_set_ptr, &hand_image);
+
+ return neww;
+}
+
+/*
+ * Local Variables:
+ * c-basic-offset:8
+ * End:
+ */
diff --git a/framebuffer/fbtk/user.c b/framebuffer/fbtk/user.c
new file mode 100644
index 000000000..7b0f36ef7
--- /dev/null
+++ b/framebuffer/fbtk/user.c
@@ -0,0 +1,64 @@
+/*
+ * Copyright 2010 Vincent Sanders <vince@simtec.co.uk>
+ *
+ * Framebuffer windowing toolkit user widget.
+ *
+ * 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 <malloc.h>
+
+#include <libnsfb.h>
+
+#include "desktop/plotters.h"
+#include "framebuffer/gui.h"
+#include "framebuffer/fbtk.h"
+
+#include "widget.h"
+
+/* exported function documented in fbtk.h */
+void *
+fbtk_get_userpw(fbtk_widget_t *widget)
+{
+ if ((widget == NULL) ||
+ (widget->type != FB_WIDGET_TYPE_USER))
+ return NULL;
+
+ return widget->u.user.pw;
+}
+
+/* exported function documented in fbtk.h */
+fbtk_widget_t *
+fbtk_create_user(fbtk_widget_t *parent,
+ int x,
+ int y,
+ int width,
+ int height,
+ void *pw)
+{
+ fbtk_widget_t *neww;
+
+ neww = fbtk_widget_new(parent, FB_WIDGET_TYPE_USER, x, y, width, height);
+ neww->u.user.pw = pw;
+ neww->mapped = true;
+
+ return neww;
+}
+
+/*
+ * Local Variables:
+ * c-basic-offset:8
+ * End:
+ */
diff --git a/framebuffer/fbtk/widget.h b/framebuffer/fbtk/widget.h
new file mode 100644
index 000000000..75a2a646d
--- /dev/null
+++ b/framebuffer/fbtk/widget.h
@@ -0,0 +1,246 @@
+/*
+ * 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/>.
+ */
+
+#ifndef NETSURF_FB_FBTK_WIDGET_H
+#define NETSURF_FB_FBTK_WIDGET_H
+
+#include <stdbool.h>
+
+enum fbtk_widgettype_e {
+ FB_WIDGET_TYPE_ROOT = 0,
+ FB_WIDGET_TYPE_WINDOW,
+ FB_WIDGET_TYPE_BITMAP,
+ FB_WIDGET_TYPE_FILL,
+ FB_WIDGET_TYPE_TEXT,
+ FB_WIDGET_TYPE_HSCROLL,
+ FB_WIDGET_TYPE_VSCROLL,
+ FB_WIDGET_TYPE_USER,
+};
+
+
+/** Widget description.
+ *
+ * A widget is an entry in a tree structure which represents a
+ * rectangular area with co-ordinates relative to its parent widget.
+ * This area has a distinct set of callback operations for handling
+ * events which occour within its boundries. A widget may have an
+ * arbitrary number of child widgets. The order within the tree
+ * determines a widgets z order.
+ *
+ * ---
+ * A
+ * |
+ * +----------+
+ * +--->| Button 3 |
+ * | +----------+
+ * | | A
+ * | V |
+ * | +----------+
+ * | | Button 2 |
+ * | +----------+
+ * | | A
+ * | V |
+ * | +----------+
+ * | | Button 1 |
+ * | +----------+
+ * | | A
+ * | V |
+ * --- | +----------+
+ * A | +->| Filled |
+ * | | | +----------+
+ * +----------+ | | |
+ * +---->| |-+ | V
+ * | | Window 1 | | --- ---
+ * | | |---+ A
+ * | +----------+ |
+ * | | A +----------+ ---
+ * | | | +--->| Button 2 | A
+ * | | | | +----------+ |
+ * | | | | | A +-------------+
+ * | | | | | | +--->| Button Up |
+ * | | | | | | | +-------------+
+ * | | | | | | | | A
+ * | | | | | | | V |
+ * | | | | | | | +-------------+
+ * | | | | | | | | Button Down |
+ * | | | | | | | +-------------+
+ * | | | | | | | | A
+ * | | | | | | | V |
+ * | | | | | | | +-------------+
+ * | | | | | | | +->| Scroller |
+ * | | | | V | | | +-------------+
+ * | | | | +----------+ | | |
+ * | | | | | |-+ | V
+ * | | | | | V Scroll | | ---
+ * | | | | | |---+
+ * | | | | +----------+
+ * | | | | | A
+ * | | | | V |
+ * | | | | +----------+
+ * | | | | +->| Button 1 |
+ * | | | | | +----------+
+ * | +----------+ | | |
+ * | | |-+ | V
+ * | | Window 2 | | ---
+ * | | |---+
+ * | +----------+
+ * | | A
+ * | V |
+ * | +------------+
+ * --- | | Background |
+ * A | +->| Bitmap |
+ * | | | +------------+
+ * +------+ | | |
+ * | |-+ | V
+ * | Root | | ---
+ * | |---+
+ * +------+
+ * |
+ * V
+ * ---
+ *
+ * Every widget is contained within this generic wrapper. The
+ * integrated union provides for data specific to a widget type.
+ */
+struct fbtk_widget_s {
+ struct fbtk_widget_s *next; /* next lower z ordered widget in tree */
+ struct fbtk_widget_s *prev; /* next higher z ordered widget in tree */
+
+ struct fbtk_widget_s *parent; /* parent widget */
+
+ struct fbtk_widget_s *first_child; /* first child widget */
+ struct fbtk_widget_s *last_child; /* last child widget */
+
+ /* flags */
+ bool mapped; /**< The widget is mapped/visible . */
+
+ /* Generic properties */
+ int x;
+ int y;
+ int width;
+ int height;
+ colour bg;
+ colour fg;
+
+ /* event callback handlers */
+ fbtk_callback callback[FBTK_CBT_END];
+ void *callback_context[FBTK_CBT_END];
+
+ /* widget redraw */
+ struct {
+ bool child; /* A child of this widget requires redrawing */
+ bool needed; /* the widget requires redrawing */
+ int x;
+ int y;
+ int width;
+ int height;
+ } redraw;
+
+ enum fbtk_widgettype_e type; /**< The type of the widget */
+
+
+ union {
+ /* toolkit base handle */
+ struct {
+ nsfb_t *fb;
+ struct fbtk_widget_s *prev; /* previous widget pointer wasin */
+ struct fbtk_widget_s *grabbed; /* widget that has grabbed pointer movement. */
+ struct fbtk_widget_s *input;
+ } root;
+
+ /* bitmap */
+ struct {
+ struct bitmap *bitmap;
+ } bitmap;
+
+ /* text */
+ struct {
+ char* text;
+ bool outline;
+ fbtk_enter_t enter;
+ void *pw;
+ int idx;
+ } text;
+
+ /* application driven widget */
+ struct {
+ void *pw; /* private data for user widget */
+ } user;
+
+ struct {
+ int minimum; /* lowest value of scrollbar */
+ int maximum; /* highest value of scrollbar */
+ int thumb; /* size of bar representing a page */
+ int page; /* amount to page document */
+ int position; /* position of bar */
+ int drag; /* offset to start of drag */
+ struct fbtk_widget_s *btnul; /* scroll button up/left */
+ struct fbtk_widget_s *btndr; /* scroll button down/right*/
+ } scroll;
+
+ } u;
+};
+
+
+/* These functions are not considered part of the public API but are
+ * not static as they are used by the higher level widget provision
+ * routines
+ */
+
+
+/** creates a new widget and insert it into to hierachy.
+ *
+ * The widget is set to defaults of false, 0 or NULL.
+ *
+ * @param parent The parent widget. The new widget will be added with
+ * the shallowest z order relative to its siblings.
+ * @param type The type of the widget.
+ * @param x The x co-ordinate relative to the parent widget.
+ * @param y The y co-ordinate relative to the parent widget.
+ * @param width the widgets width. This will be clipped to the parent, if
+ * the value is 0 the largest extent which can fit within the parent
+ * is used, if the value is negative the largest value that will fit
+ * within the parent less the value given will be used.
+ * @param height the widgets width. This will be clipped to the parent, if
+ * the value is 0 the largest extent which can fit within the parent
+ * is used, if the value is negative the largest value that will fit
+ * within the parent less the value given will be used.
+ */
+fbtk_widget_t *fbtk_widget_new(fbtk_widget_t *parent, enum fbtk_widgettype_e type, int x, int y, int width, int height);
+
+/** find the root widget from any widget in the toolkit hierarchy.
+ *
+ * @param widget Any widget.
+ * @return The root widget or NULL if \a widget was not valid.
+ */
+fbtk_widget_t *fbtk_get_root_widget(fbtk_widget_t *widget);
+
+/** set pointer to bitmap in context.
+ *
+ * widget helper callback to set cursor image to the bitmap passed in
+ * the callbacks private data.
+ */
+int fbtk_set_ptr(fbtk_widget_t *widget, fbtk_callback_info *cbi);
+
+#endif
+
+/*
+ * Local Variables:
+ * c-basic-offset:8
+ * End:
+ */
diff --git a/framebuffer/fbtk/window.c b/framebuffer/fbtk/window.c
new file mode 100644
index 000000000..a2c9227e6
--- /dev/null
+++ b/framebuffer/fbtk/window.c
@@ -0,0 +1,91 @@
+/*
+ * Copyright 2010 Vincent Sanders <vince@simtec.co.uk>
+ *
+ * Framebuffer windowing toolkit window widget.
+ *
+ * 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 <malloc.h>
+
+#include <libnsfb.h>
+#include <libnsfb_plot.h>
+
+#include "desktop/browser.h"
+
+#include "framebuffer/gui.h"
+#include "framebuffer/fbtk.h"
+
+#include "widget.h"
+
+/** Window redraw callback.
+ *
+ * Called when a window requires redrawing.
+ *
+ * @param widget The widget to be redrawn.
+ * @param cbi The callback parameters.
+ * @return The callback result.
+ */
+static int
+fb_redraw_window(fbtk_widget_t *widget, fbtk_callback_info *cbi)
+{
+ nsfb_bbox_t bbox;
+ nsfb_t *nsfb;
+
+ if ((widget->bg & 0xFF000000) == 0)
+ return 0;
+
+ nsfb = fbtk_get_nsfb(widget);
+
+ fbtk_get_bbox(widget, &bbox);
+
+ nsfb_claim(nsfb, &bbox);
+
+ nsfb_plot_rectangle_fill(nsfb, &bbox, widget->bg);
+
+ nsfb_update(nsfb, &bbox);
+
+ return 0;
+}
+
+/* exported function documented in fbtk.h */
+fbtk_widget_t *
+fbtk_create_window(fbtk_widget_t *parent,
+ int x,
+ int y,
+ int width,
+ int height,
+ colour bg)
+{
+ fbtk_widget_t *neww;
+
+ if (parent == NULL)
+ return NULL;
+
+ neww = fbtk_widget_new(parent, FB_WIDGET_TYPE_WINDOW, x, y, width, height);
+
+ neww->bg = bg;
+
+ fbtk_set_handler(neww, FBTK_CBT_REDRAW, fb_redraw_window, NULL);
+
+ return neww;
+}
+
+/*
+ * Local Variables:
+ * c-basic-offset:8
+ * End:
+ */
diff --git a/framebuffer/fbtk_widget.h b/framebuffer/fbtk_widget.h
deleted file mode 100644
index c542c2012..000000000
--- a/framebuffer/fbtk_widget.h
+++ /dev/null
@@ -1,109 +0,0 @@
-/*
- * Copyright 2008 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/>.
- */
-
-#ifndef NETSURF_FB_FBTK_WIDGET_H
-#define NETSURF_FB_FBTK_WIDGET_H
-
-enum fbtk_widgettype_e {
- FB_WIDGET_TYPE_ROOT = 0,
- FB_WIDGET_TYPE_WINDOW,
- FB_WIDGET_TYPE_BITMAP,
- FB_WIDGET_TYPE_FILL,
- FB_WIDGET_TYPE_TEXT,
- FB_WIDGET_TYPE_HSCROLL,
- FB_WIDGET_TYPE_VSCROLL,
- FB_WIDGET_TYPE_USER,
-};
-
-typedef struct fbtk_widget_list_s fbtk_widget_list_t;
-
-/* wrapper struct for all widget types */
-struct fbtk_widget_s {
- /* Generic properties */
- int x;
- int y;
- int width;
- int height;
- colour bg;
- colour fg;
-
- /* event callback handlers */
- fbtk_callback callback[FBTK_CBT_END];
- void *callback_context[FBTK_CBT_END];
-
- bool redraw_required; /* the widget requires redrawing */
-
- fbtk_widget_t *parent; /* parent widget */
-
- /* Widget specific */
- enum fbtk_widgettype_e type;
-
- union {
- /* toolkit base handle */
- struct {
- nsfb_t *fb;
- fbtk_widget_t *rootw;
- fbtk_widget_t *input;
- } root;
-
- /* window */
- struct {
- /* widgets associated with this window */
- fbtk_widget_list_t *widgets; /* begining of list */
- fbtk_widget_list_t *widgets_end; /* end of list */
- } window;
-
- /* bitmap */
- struct {
- struct bitmap *bitmap;
- } bitmap;
-
- /* text */
- struct {
- char* text;
- bool outline;
- fbtk_enter_t enter;
- void *pw;
- int idx;
- } text;
-
- /* application driven widget */
- struct {
- void *pw; /* private data for user widget */
- } user;
-
- struct {
- int pos;
- int pct;
- struct fbtk_widget_s *btnul; /* scroll button up/left */
- struct fbtk_widget_s *btndr; /* scroll button down/right*/
- } scroll;
-
- } u;
-};
-
-
-/* widget manipulation functions */
-
-fbtk_widget_t *get_root_widget(fbtk_widget_t *widget);
-
-fbtk_widget_t *new_widget(enum fbtk_widgettype_e type);
-
-fbtk_widget_t *add_widget_to_window(fbtk_widget_t *window, fbtk_widget_t *widget);
-
-#endif
diff --git a/framebuffer/fbtk_widget_scroll.c b/framebuffer/fbtk_widget_scroll.c
deleted file mode 100644
index c28887bda..000000000
--- a/framebuffer/fbtk_widget_scroll.c
+++ /dev/null
@@ -1,305 +0,0 @@
-/*
- * Copyright 2008 Vincent Sanders <vince@simtec.co.uk>
- *
- * Framebuffer windowing toolkit scrollbar widgets
- *
- * 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 <libnsfb.h>
-#include <libnsfb_plot.h>
-#include <libnsfb_event.h>
-#include <libnsfb_cursor.h>
-
-#include "utils/log.h"
-#include "desktop/browser.h"
-
-#include "framebuffer/gui.h"
-#include "framebuffer/fbtk.h"
-#include "framebuffer/fbtk_widget.h"
-#include "framebuffer/bitmap.h"
-#include "framebuffer/image_data.h"
-
-/** Vertical scroll widget */
-
-static int
-vscroll_redraw(fbtk_widget_t *widget, fbtk_callback_info *cbi)
-{
- int vscroll;
- int vpos;
-
- nsfb_bbox_t bbox;
- nsfb_bbox_t rect;
- fbtk_widget_t *root = get_root_widget(widget);
-
- fbtk_get_bbox(widget, &bbox);
-
- nsfb_claim(root->u.root.fb, &bbox);
-
- rect = bbox;
-
- /* background */
- nsfb_plot_rectangle_fill(root->u.root.fb, &rect, widget->bg);
-
- rect.x0 = bbox.x0 + 2;
- rect.y0 = bbox.y0 + 1;
- rect.x1 = bbox.x1 - 3;
- rect.y1 = bbox.y1 - 2;
- nsfb_plot_rectangle_fill(root->u.root.fb, &rect, widget->fg);
-
- /* scroll well */
- nsfb_plot_rectangle(root->u.root.fb, &rect, 1, 0xFF999999, false, false);
-
- /* scroll well outline */
- vscroll = ((widget->height - 4) * widget->u.scroll.pct) / 100 ;
- vpos = ((widget->height - 4) * widget->u.scroll.pos) / 100 ;
-
- LOG(("scroll %d",vscroll));
-
- rect.x0 = bbox.x0 + 5;
- rect.y0 = bbox.y0 + 3 + vpos;
- rect.x1 = bbox.x0 + widget->width - 5;
- rect.y1 = bbox.y0 + vscroll + vpos;
-
- nsfb_plot_rectangle_fill(root->u.root.fb, &rect, widget->bg);
-
- nsfb_update(root->u.root.fb, &bbox);
-
- return 0;
-}
-
-static int
-vscrollu_click(fbtk_widget_t *widget, fbtk_callback_info *cbi)
-{
- int ret = 0;
- if (cbi->event->type == NSFB_EVENT_KEY_DOWN)
- ret = fbtk_post_callback(cbi->context, FBTK_CBT_SCROLLY, -1);
- return ret;
-}
-
-static int
-vscrolld_click(fbtk_widget_t *widget, fbtk_callback_info *cbi)
-{
- int ret = 0;
- if (cbi->event->type == NSFB_EVENT_KEY_DOWN)
- ret = fbtk_post_callback(cbi->context, FBTK_CBT_SCROLLY, 1);
- return ret;
-}
-
-static int
-vscrollarea_click(fbtk_widget_t *widget, fbtk_callback_info *cbi)
-{
- int vscroll;
- int vpos;
- int ret = 0;
-
- if (cbi->event->type != NSFB_EVENT_KEY_DOWN)
- return 0;
-
- vscroll = ((widget->height - 4) * widget->u.scroll.pct) / 100 ;
- vpos = ((widget->height - 4) * widget->u.scroll.pos) / 100 ;
-
- if (cbi->y < vpos) {
- /* above bar */
- ret = fbtk_post_callback(cbi->context, FBTK_CBT_SCROLLY, -1);
- } else if (cbi->y > (vpos + vscroll)) {
- /* below bar */
- ret = fbtk_post_callback(cbi->context, FBTK_CBT_SCROLLY, 1);
- }
- return ret;
-}
-
-
-fbtk_widget_t *
-fbtk_create_vscroll(fbtk_widget_t *window,
- int x, int y,
- int width, int height,
- colour fg,
- colour bg,
- fbtk_callback callback,
- void *context)
-{
- fbtk_widget_t *neww = new_widget(FB_WIDGET_TYPE_VSCROLL);
-
- neww->x = x;
- neww->y = y + scrollu.height;
- neww->width = width;
- neww->height = height - scrollu.height - scrolld.height;
- neww->fg = fg;
- neww->bg = bg;
-
- fbtk_set_handler(neww, FBTK_CBT_REDRAW, vscroll_redraw, NULL);
-
- fbtk_set_handler(neww, FBTK_CBT_CLICK, vscrollarea_click, neww);
-
- fbtk_set_handler(neww, FBTK_CBT_SCROLLY, callback, context);
-
- neww->u.scroll.btnul = fbtk_create_button(window, x + (width - scrollu.width) / 2, y, fg, &scrollu, vscrollu_click, neww);
-
- neww->u.scroll.btndr = fbtk_create_button(window, x + (width - scrolld.width) / 2, y + height - scrolld.height, fg, &scrolld, vscrolld_click, neww);
-
-
- return add_widget_to_window(window, neww);
-}
-
-/* Horizontal scroll widget */
-
-static int
-hscroll_redraw(fbtk_widget_t *widget, fbtk_callback_info *cbi)
-{
- int hscroll;
- int hpos;
- nsfb_bbox_t bbox;
- nsfb_bbox_t rect;
- fbtk_widget_t *root = get_root_widget(widget);
-
- fbtk_get_bbox(widget, &bbox);
-
- nsfb_claim(root->u.root.fb, &bbox);
-
- rect = bbox;
-
- /* background */
- nsfb_plot_rectangle_fill(root->u.root.fb, &rect, widget->bg);
-
- /* scroll well */
- rect.x0 = bbox.x0 + 1;
- rect.y0 = bbox.y0 + 2;
- rect.x1 = bbox.x1 - 2;
- rect.y1 = bbox.y1 - 3;
- nsfb_plot_rectangle_fill(root->u.root.fb, &rect, widget->fg);
-
- /* scroll well outline */
- nsfb_plot_rectangle(root->u.root.fb, &rect, 1, 0xFF999999, false, false);
-
- hscroll = ((widget->width - 4) * widget->u.scroll.pct) / 100 ;
- hpos = ((widget->width - 4) * widget->u.scroll.pos) / 100 ;
-
- LOG(("hscroll %d",hscroll));
-
- rect.x0 = bbox.x0 + 3 + hpos;
- rect.y0 = bbox.y0 + 5;
- rect.x1 = bbox.x0 + hscroll + hpos;
- rect.y1 = bbox.y0 + widget->height - 5;
-
- nsfb_plot_rectangle_fill(root->u.root.fb, &rect, widget->bg);
-
- nsfb_update(root->u.root.fb, &bbox);
-
- return 0;
-}
-
-static int
-hscrolll_click(fbtk_widget_t *widget, fbtk_callback_info *cbi)
-{
- int ret = 0;
- if (cbi->event->type == NSFB_EVENT_KEY_DOWN)
- ret = fbtk_post_callback(cbi->context, FBTK_CBT_SCROLLX, -1);
- return ret;
-}
-
-static int
-hscrollr_click(fbtk_widget_t *widget, fbtk_callback_info *cbi)
-{
- int ret = 0;
- if (cbi->event->type == NSFB_EVENT_KEY_DOWN)
- ret = fbtk_post_callback(cbi->context, FBTK_CBT_SCROLLX, 1);
- return ret;
-}
-
-static int
-hscrollarea_click(fbtk_widget_t *widget, fbtk_callback_info *cbi)
-{
- int hscroll;
- int hpos;
- int ret;
-
- if (cbi->event->type != NSFB_EVENT_KEY_DOWN)
- return 0;
-
- hscroll = ((widget->width - 4) * widget->u.scroll.pct) / 100 ;
- hpos = ((widget->width - 4) * widget->u.scroll.pos) / 100 ;
-
- if (cbi->x < hpos) {
- /* above bar */
- ret = fbtk_post_callback(cbi->context, FBTK_CBT_SCROLLX, -1);
- } else if (cbi->x > (hpos + hscroll)) {
- /* below bar */
- ret = fbtk_post_callback(cbi->context, FBTK_CBT_SCROLLX, 1);
- }
- return ret;
-}
-
-fbtk_widget_t *
-fbtk_create_hscroll(fbtk_widget_t *window,
- int x, int y,
- int width, int height,
- colour fg,
- colour bg,
- fbtk_callback callback,
- void *context)
-{
- fbtk_widget_t *neww = new_widget(FB_WIDGET_TYPE_HSCROLL);
-
- neww->x = x + scrolll.width;
- neww->y = y;
- neww->width = width - scrolll.width - scrollr.width;
- neww->height = height;
- neww->fg = fg;
- neww->bg = bg;
-
- fbtk_set_handler(neww, FBTK_CBT_REDRAW, hscroll_redraw, NULL);
- fbtk_set_handler(neww, FBTK_CBT_CLICK, hscrollarea_click, neww);
- fbtk_set_handler(neww, FBTK_CBT_SCROLLX, callback, context);
-
- neww->u.scroll.btnul = fbtk_create_button(window, x, y + ((height - scrolll.height) / 2), fg, &scrolll, hscrolll_click, neww);
-
- neww->u.scroll.btndr = fbtk_create_button(window, x + width - scrollr.width, y + ((height - scrolll.height) / 2), fg, &scrollr, hscrollr_click, neww);
-
- return add_widget_to_window(window, neww);
-}
-
-
-void
-fbtk_set_scroll(fbtk_widget_t *widget, int pct)
-{
- if (widget == NULL)
- return;
-
- if ((widget->type == FB_WIDGET_TYPE_HSCROLL) ||
- (widget->type == FB_WIDGET_TYPE_VSCROLL)) {
-
- widget->u.scroll.pct = pct;
- fbtk_request_redraw(widget);
- }
-}
-
-void
-fbtk_set_scroll_pos(fbtk_widget_t *widget, int pos)
-{
- if (widget == NULL)
- return;
-
- if ((widget->type == FB_WIDGET_TYPE_HSCROLL) ||
- (widget->type == FB_WIDGET_TYPE_VSCROLL)) {
-
- widget->u.scroll.pos = pos;
-
- fbtk_request_redraw(widget);
- }
-}
-
diff --git a/framebuffer/framebuffer.c b/framebuffer/framebuffer.c
index 0400a1abe..6c7ba102b 100644
--- a/framebuffer/framebuffer.c
+++ b/framebuffer/framebuffer.c
@@ -67,14 +67,16 @@ framebuffer_plot_arc(int x, int y, int radius, int angle1, int angle2, const plo
return nsfb_plot_arc(nsfb, x, y, radius, angle1, angle2, style->fill_colour);
}
-static bool framebuffer_plot_polygon(const int *p, unsigned int n, const plot_style_t *style)
+static bool
+framebuffer_plot_polygon(const int *p, unsigned int n, const plot_style_t *style)
{
return nsfb_plot_polygon(nsfb, p, n, style->fill_colour);
}
#ifdef FB_USE_FREETYPE
-static bool framebuffer_plot_text(int x, int y, const char *text, size_t length,
+static bool
+framebuffer_plot_text(int x, int y, const char *text, size_t length,
const plot_font_style_t *fstyle)
{
uint32_t ucs4;
diff --git a/framebuffer/gui.c b/framebuffer/gui.c
index 50c3da2ff..a329f4a46 100644
--- a/framebuffer/gui.c
+++ b/framebuffer/gui.c
@@ -53,6 +53,7 @@
#include "framebuffer/findfile.h"
#include "framebuffer/image_data.h"
#include "framebuffer/font.h"
+#include "framebuffer/options.h"
#include "content/urldb.h"
#include "desktop/history_core.h"
@@ -63,7 +64,6 @@ char *quirks_stylesheet_url;
char *adblock_stylesheet_url;
char *options_file_location;
-
fbtk_widget_t *fbtk;
struct gui_window *input_window = NULL;
@@ -81,8 +81,8 @@ struct browser_widget_s {
*/
bbox_t redraw_box; /**< Area requiring redraw. */
bool pan_required; /**< flag indicating the foreground loop
- * needs to pan the window.
- */
+ * needs to pan the window.
+ */
int panx, pany; /**< Panning required. */
};
@@ -91,67 +91,115 @@ struct browser_widget_s {
static void
fb_queue_redraw(struct fbtk_widget_s *widget, int x0, int y0, int x1, int y1)
{
- struct browser_widget_s *bwidget = fbtk_get_userpw(widget);
+ struct browser_widget_s *bwidget = fbtk_get_userpw(widget);
- bwidget->redraw_box.x0 = min(bwidget->redraw_box.x0, x0);
- bwidget->redraw_box.y0 = min(bwidget->redraw_box.y0, y0);
- bwidget->redraw_box.x1 = max(bwidget->redraw_box.x1, x1);
- bwidget->redraw_box.y1 = max(bwidget->redraw_box.y1, y1);
+ bwidget->redraw_box.x0 = min(bwidget->redraw_box.x0, x0);
+ bwidget->redraw_box.y0 = min(bwidget->redraw_box.y0, y0);
+ bwidget->redraw_box.x1 = max(bwidget->redraw_box.x1, x1);
+ bwidget->redraw_box.y1 = max(bwidget->redraw_box.y1, y1);
- if (fbtk_clip_to_widget(widget, &bwidget->redraw_box)) {
- bwidget->redraw_required = true;
- fbtk_request_redraw(widget);
- } else {
- bwidget->redraw_box.y0 = bwidget->redraw_box.x0 = INT_MAX;
- bwidget->redraw_box.y1 = bwidget->redraw_box.x1 = -(INT_MAX);
- bwidget->redraw_required = false;
- }
+ if (fbtk_clip_to_widget(widget, &bwidget->redraw_box)) {
+ bwidget->redraw_required = true;
+ fbtk_request_redraw(widget);
+ } else {
+ bwidget->redraw_box.y0 = bwidget->redraw_box.x0 = INT_MAX;
+ bwidget->redraw_box.y1 = bwidget->redraw_box.x1 = -(INT_MAX);
+ bwidget->redraw_required = false;
+ }
}
-static void fb_pan(fbtk_widget_t *widget,
- struct browser_widget_s *bwidget,
- struct browser_window *bw)
+/* queue a window scroll */
+static void
+widget_scroll_y(struct gui_window *gw, int y, bool abs)
{
- int x;
- int y;
- int width;
+ struct browser_widget_s *bwidget = fbtk_get_userpw(gw->browser);
+ int content_height;
int height;
- nsfb_bbox_t srcbox;
- nsfb_bbox_t dstbox;
- nsfb_t *nsfb = fbtk_get_nsfb(widget);
+ LOG(("window scroll"));
+ if (abs) {
+ bwidget->pany = y - bwidget->scrolly;
+ } else {
+ bwidget->pany += y;
+ }
+ bwidget->pan_required = true;
- int content_height = content_get_height(bw->current_content);
- int content_width = content_get_width(bw->current_content);
+ content_height = content_get_height(gw->bw->current_content);
- height = fbtk_get_height(widget);
- width = fbtk_get_width(widget);
- x = fbtk_get_x(widget);
- y = fbtk_get_y(widget);
+ height = fbtk_get_height(gw->browser);
/* dont pan off the top */
if ((bwidget->scrolly + bwidget->pany) < 0)
- bwidget->pany = - bwidget->scrolly;
+ bwidget->pany = -bwidget->scrolly;
- /* do not pan off the bottom of the content */
+ /* do not pan off the bottom of the content */
if ((bwidget->scrolly + bwidget->pany) > (content_height - height))
bwidget->pany = (content_height - height) - bwidget->scrolly;
+ fbtk_request_redraw(gw->browser);
+
+ fbtk_set_scroll_position(gw->vscroll, bwidget->scrolly + bwidget->pany);
+}
+
+/* queue a window scroll */
+static void
+widget_scroll_x(struct gui_window *gw, int x, bool abs)
+{
+ struct browser_widget_s *bwidget = fbtk_get_userpw(gw->browser);
+ int content_width;
+ int width;
+
+ if (abs) {
+ bwidget->panx = x - bwidget->scrollx;
+ } else {
+ bwidget->panx += x;
+ }
+ bwidget->pan_required = true;
+
+ content_width = content_get_width(gw->bw->current_content);
+
+ width = fbtk_get_width(gw->browser);
+
+
/* dont pan off the left */
if ((bwidget->scrollx + bwidget->panx) < 0)
bwidget->panx = - bwidget->scrollx;
- /* do not pan off the right of the content */
+ /* do not pan off the right of the content */
if ((bwidget->scrollx + bwidget->panx) > (content_width - width))
bwidget->panx = (content_width - width) - bwidget->scrollx;
- LOG(("panning %d, %d",bwidget->panx, bwidget->pany));
+ fbtk_request_redraw(gw->browser);
+
+ fbtk_set_scroll_position(gw->hscroll, bwidget->scrollx + bwidget->panx);
+}
+
+static void
+fb_pan(fbtk_widget_t *widget,
+ struct browser_widget_s *bwidget,
+ struct browser_window *bw)
+{
+ int x;
+ int y;
+ int width;
+ int height;
+ nsfb_bbox_t srcbox;
+ nsfb_bbox_t dstbox;
+
+ nsfb_t *nsfb = fbtk_get_nsfb(widget);
+
+ height = fbtk_get_height(widget);
+ width = fbtk_get_width(widget);
+
+ LOG(("panning %d, %d", bwidget->panx, bwidget->pany));
+
+ x = fbtk_get_absx(widget);
+ y = fbtk_get_absy(widget);
- /* pump up the volume. dance, dance! lets do it */
+ /* if the pan exceeds the viewport size just redraw the whole area */
if (bwidget->pany > height || bwidget->pany < -height ||
- bwidget->panx > width || bwidget->panx < -width) {
+ bwidget->panx > width || bwidget->panx < -width) {
- /* pan in any direction by more than viewport size */
bwidget->scrolly += bwidget->pany;
bwidget->scrollx += bwidget->panx;
fb_queue_redraw(widget, 0, 0, width, height);
@@ -163,7 +211,6 @@ static void fb_pan(fbtk_widget_t *widget,
if (bwidget->pany < 0) {
/* pan up by less then viewport height */
-
srcbox.x0 = x;
srcbox.y0 = y;
srcbox.x1 = srcbox.x0 + width;
@@ -184,7 +231,6 @@ static void fb_pan(fbtk_widget_t *widget,
if (bwidget->pany > 0) {
/* pan down by less then viewport height */
-
srcbox.x0 = x;
srcbox.y0 = y + bwidget->pany;
srcbox.x1 = srcbox.x0 + width;
@@ -200,13 +246,11 @@ static void fb_pan(fbtk_widget_t *widget,
/* redraw newly exposed area */
bwidget->scrolly += bwidget->pany;
- fb_queue_redraw(widget, 0, height - bwidget->pany, width,
- height);
+ fb_queue_redraw(widget, 0, height - bwidget->pany, width, height);
}
if (bwidget->panx < 0) {
/* pan left by less then viewport width */
-
srcbox.x0 = x;
srcbox.y0 = y;
srcbox.x1 = srcbox.x0 + width + bwidget->panx;
@@ -242,8 +286,7 @@ static void fb_pan(fbtk_widget_t *widget,
/* redraw newly exposed area */
bwidget->scrollx += bwidget->panx;
- fb_queue_redraw(widget, width - bwidget->panx, 0, width,
- height);
+ fb_queue_redraw(widget, width - bwidget->panx, 0, width, height);
}
@@ -252,101 +295,110 @@ static void fb_pan(fbtk_widget_t *widget,
bwidget->pany = 0;
}
-static void fb_redraw(fbtk_widget_t *widget,
- struct browser_widget_s *bwidget,
- struct browser_window *bw)
+static void
+fb_redraw(fbtk_widget_t *widget,
+ struct browser_widget_s *bwidget,
+ struct browser_window *bw)
{
- int x;
- int y;
- int width;
- int height;
+ int x;
+ int y;
+ int width;
+ int height;
+ if (bw->current_content == NULL)
+ return;
- LOG(("redraw box %d,%d to %d,%d",bwidget->redraw_box.x0,bwidget->redraw_box.y0, bwidget->redraw_box.x1, bwidget->redraw_box.y1));
+ LOG(("%d,%d to %d,%d",
+ bwidget->redraw_box.x0,
+ bwidget->redraw_box.y0,
+ bwidget->redraw_box.x1,
+ bwidget->redraw_box.y1));
- height = fbtk_get_height(widget);
- width = fbtk_get_width(widget);
- x = fbtk_get_x(widget);
- y = fbtk_get_y(widget);
+ height = fbtk_get_height(widget);
+ width = fbtk_get_width(widget);
+ x = fbtk_get_absx(widget);
+ y = fbtk_get_absy(widget);
- /* adjust clipping co-ordinates according to window location */
- bwidget->redraw_box.y0 += y;
- bwidget->redraw_box.y1 += y;
- bwidget->redraw_box.x0 += x;
- bwidget->redraw_box.x1 += x;
+ /* adjust clipping co-ordinates according to window location */
+ bwidget->redraw_box.y0 += y;
+ bwidget->redraw_box.y1 += y;
+ bwidget->redraw_box.x0 += x;
+ bwidget->redraw_box.x1 += x;
- nsfb_claim(fbtk_get_nsfb(widget), &bwidget->redraw_box);
+ nsfb_claim(fbtk_get_nsfb(widget), &bwidget->redraw_box);
- /* redraw bounding box is relative to window */
+ /* redraw bounding box is relative to window */
current_redraw_browser = bw;
- content_redraw(bw->current_content,
- x - bwidget->scrollx, y - bwidget->scrolly,
- width, height,
- bwidget->redraw_box.x0, bwidget->redraw_box.y0,
- bwidget->redraw_box.x1, bwidget->redraw_box.y1,
- bw->scale, 0xFFFFFF);
+ content_redraw(bw->current_content,
+ x - bwidget->scrollx, y - bwidget->scrolly,
+ width, height,
+ bwidget->redraw_box.x0, bwidget->redraw_box.y0,
+ bwidget->redraw_box.x1, bwidget->redraw_box.y1,
+ bw->scale, 0xFFFFFF);
current_redraw_browser = NULL;
- nsfb_update(fbtk_get_nsfb(widget), &bwidget->redraw_box);
+ nsfb_update(fbtk_get_nsfb(widget), &bwidget->redraw_box);
- bwidget->redraw_box.y0 = bwidget->redraw_box.x0 = INT_MAX;
- bwidget->redraw_box.y1 = bwidget->redraw_box.x1 = -(INT_MAX);
- bwidget->redraw_required = false;
+ bwidget->redraw_box.y0 = bwidget->redraw_box.x0 = INT_MAX;
+ bwidget->redraw_box.y1 = bwidget->redraw_box.x1 = INT_MIN;
+ bwidget->redraw_required = false;
}
static int
fb_browser_window_redraw(fbtk_widget_t *widget, fbtk_callback_info *cbi)
{
- struct gui_window *gw = cbi->context;
- struct browser_widget_s *bwidget;
-
- bwidget = fbtk_get_userpw(widget);
- if (bwidget == NULL) {
- LOG(("browser widget from widget %p was null", widget));
- return -1;
- }
+ struct gui_window *gw = cbi->context;
+ struct browser_widget_s *bwidget;
- if (bwidget->pan_required) {
- int pos;
- fb_pan(widget, bwidget, gw->bw);
- pos = (bwidget->scrollx * 100) / content_get_width(gw->bw->current_content);
- fbtk_set_scroll_pos(gw->hscroll, pos);
- pos = (bwidget->scrolly * 100) / content_get_height(gw->bw->current_content);
- fbtk_set_scroll_pos(gw->vscroll, pos);
+ bwidget = fbtk_get_userpw(widget);
+ if (bwidget == NULL) {
+ LOG(("browser widget from widget %p was null", widget));
+ return -1;
+ }
- }
+ if (bwidget->pan_required) {
+ fb_pan(widget, bwidget, gw->bw);
+ }
- if (bwidget->redraw_required) {
- fb_redraw(widget, bwidget, gw->bw);
- }
- return 0;
+ if (bwidget->redraw_required) {
+ fb_redraw(widget, bwidget, gw->bw);
+ } else {
+ bwidget->redraw_box.x0 = 0;
+ bwidget->redraw_box.y0 = 0;
+ bwidget->redraw_box.x1 = fbtk_get_width(widget);
+ bwidget->redraw_box.y1 = fbtk_get_height(widget);
+ fb_redraw(widget, bwidget, gw->bw);
+ }
+ return 0;
}
+
static const char *fename;
static int febpp;
static int fewidth;
static int feheight;
static const char *feurl;
-static bool process_cmdline(int argc, char** argv)
+static bool
+process_cmdline(int argc, char** argv)
{
int opt;
- LOG(("argc %d, argv %p", argc, argv));
+ LOG(("argc %d, argv %p", argc, argv));
fename = "sdl";
febpp = 32;
- if ((option_window_width != 0) && (option_window_height != 0)) {
- fewidth = option_window_width;
- feheight = option_window_height;
- } else {
- fewidth = 800;
- feheight = 600;
- }
+ if ((option_window_width != 0) && (option_window_height != 0)) {
+ fewidth = option_window_width;
+ feheight = option_window_height;
+ } else {
+ fewidth = 800;
+ feheight = 600;
+ }
- if (option_homepage_url != NULL && option_homepage_url[0] != '\0')
- feurl = option_homepage_url;
+ if (option_homepage_url != NULL && option_homepage_url[0] != '\0')
+ feurl = option_homepage_url;
else
feurl = NETSURF_HOMEPAGE;
@@ -370,9 +422,9 @@ static bool process_cmdline(int argc, char** argv)
break;
default:
- fprintf(stderr,
+ fprintf(stderr,
"Usage: %s [-f frontend] [-b bpp] url\n",
- argv[0]);
+ argv[0]);
return false;
}
}
@@ -385,10 +437,11 @@ static bool process_cmdline(int argc, char** argv)
}
-static void gui_init(int argc, char** argv)
+static void
+gui_init(int argc, char** argv)
{
char buf[PATH_MAX];
- nsfb_t *nsfb;
+ nsfb_t *nsfb;
fb_find_resource(buf, "Aliases", "./framebuffer/res/Aliases");
LOG(("Using '%s' as Aliases file", buf));
@@ -405,29 +458,32 @@ static void gui_init(int argc, char** argv)
fb_find_resource(buf, "quirks.css", "./framebuffer/res/quirks.css");
quirks_stylesheet_url = path_to_url(buf);
- if (process_cmdline(argc,argv) != true)
+ if (process_cmdline(argc,argv) != true)
die("unable to process command line.\n");
- nsfb = framebuffer_initialise(fename, fewidth, feheight, febpp);
- if (nsfb == NULL)
- die("Unable to initialise framebuffer");
+ nsfb = framebuffer_initialise(fename, fewidth, feheight, febpp);
+ if (nsfb == NULL)
+ die("Unable to initialise framebuffer");
+
+ framebuffer_set_cursor(&pointer_image);
- framebuffer_set_cursor(&pointer_image);
+ if (fb_font_init() == false)
+ die("Unable to initialise the font system");
- if (fb_font_init() == false)
- die("Unable to initialise the font system");
+ fbtk = fbtk_init(nsfb);
- fbtk = fbtk_init(nsfb);
+ fbtk_enable_oskb(fbtk);
}
/** Entry point from OS.
*
- * /param argc The number of arguments in the string vector.
+ * /param argc The number of arguments in the string vector.
* /param argv The argument string vector.
* /return The return code to the OS
*/
-int main(int argc, char** argv)
+int
+main(int argc, char** argv)
{
struct browser_window *bw;
char options[PATH_MAX];
@@ -443,7 +499,7 @@ int main(int argc, char** argv)
gui_init(argc, argv);
- LOG(("calling browser_window_create"));
+ LOG(("calling browser_window_create"));
bw = browser_window_create(feurl, 0, 0, true, false);
netsurf_main_loop();
@@ -456,42 +512,45 @@ int main(int argc, char** argv)
}
-void gui_multitask(void)
+void
+gui_multitask(void)
{
- // LOG(("gui_multitask"));
+ /* LOG(("gui_multitask")); */
}
-void gui_poll(bool active)
+void
+gui_poll(bool active)
{
- nsfb_event_t event;
- int timeout; /* timeout in miliseconds */
+ nsfb_event_t event;
+ int timeout; /* timeout in miliseconds */
/* run the scheduler and discover how long to wait for the next event */
timeout = schedule_run();
- /* if active do not wait for event, return immediately */
+ /* if active do not wait for event, return immediately */
if (active)
- timeout = 0;
+ timeout = 0;
- /* if redraws are pending do not wait for event, return immediately */
- if (fbtk_redraw_pending(fbtk))
- timeout = 0;
+ /* if redraws are pending do not wait for event, return immediately */
+ if (fbtk_get_redraw_pending(fbtk))
+ timeout = 0;
- if (fbtk_event(fbtk, &event, timeout)) {
- if ((event.type == NSFB_EVENT_CONTROL) &&
- (event.value.controlcode == NSFB_CONTROL_QUIT))
- netsurf_quit = true;
- }
+ if (fbtk_event(fbtk, &event, timeout)) {
+ if ((event.type == NSFB_EVENT_CONTROL) &&
+ (event.value.controlcode == NSFB_CONTROL_QUIT))
+ netsurf_quit = true;
+ }
- fbtk_redraw(fbtk);
+ fbtk_redraw(fbtk);
}
-void gui_quit(void)
+void
+gui_quit(void)
{
- LOG(("gui_quit"));
- framebuffer_finalise();
+ LOG(("gui_quit"));
+ framebuffer_finalise();
/* We don't care if this fails as we're about to exit, anyway */
hubbub_finalise(ns_realloc, NULL);
@@ -501,174 +560,174 @@ void gui_quit(void)
static int
fb_browser_window_click(fbtk_widget_t *widget, fbtk_callback_info *cbi)
{
- struct browser_window *bw = cbi->context;
- struct browser_widget_s *bwidget = fbtk_get_userpw(widget);
+ struct gui_window *gw = cbi->context;
+ struct browser_widget_s *bwidget = fbtk_get_userpw(widget);
- if (cbi->event->type != NSFB_EVENT_KEY_DOWN &&
+ if (cbi->event->type != NSFB_EVENT_KEY_DOWN &&
cbi->event->type != NSFB_EVENT_KEY_UP)
- return 0;
-
- LOG(("browser window clicked at %d,%d",cbi->x,cbi->y));
-
- switch (cbi->event->type) {
- case NSFB_EVENT_KEY_DOWN:
- switch (cbi->event->value.keycode) {
- case NSFB_KEY_MOUSE_1:
- browser_window_mouse_click(bw,
- BROWSER_MOUSE_PRESS_1,
- cbi->x + bwidget->scrollx,
- cbi->y + bwidget->scrolly);
- break;
-
- case NSFB_KEY_MOUSE_3:
- browser_window_mouse_click(bw,
- BROWSER_MOUSE_PRESS_2,
- cbi->x + bwidget->scrollx,
- cbi->y + bwidget->scrolly);
- break;
-
- case NSFB_KEY_MOUSE_4:
- /* scroll up */
- fb_window_scroll(widget, 0, -100);
- break;
-
- case NSFB_KEY_MOUSE_5:
- /* scroll down */
- fb_window_scroll(widget, 0, 100);
- break;
-
- default:
- break;
-
- }
+ return 0;
+
+ LOG(("browser window clicked at %d,%d", cbi->x, cbi->y));
+
+ switch (cbi->event->type) {
+ case NSFB_EVENT_KEY_DOWN:
+ switch (cbi->event->value.keycode) {
+ case NSFB_KEY_MOUSE_1:
+ browser_window_mouse_click(gw->bw,
+ BROWSER_MOUSE_PRESS_1,
+ cbi->x + bwidget->scrollx,
+ cbi->y + bwidget->scrolly);
+ break;
+
+ case NSFB_KEY_MOUSE_3:
+ browser_window_mouse_click(gw->bw,
+ BROWSER_MOUSE_PRESS_2,
+ cbi->x + bwidget->scrollx,
+ cbi->y + bwidget->scrolly);
+ break;
+
+ case NSFB_KEY_MOUSE_4:
+ /* scroll up */
+ widget_scroll_y(gw, -100, false);
+ break;
+
+ case NSFB_KEY_MOUSE_5:
+ /* scroll down */
+ widget_scroll_y(gw, 100, false);
+ break;
+
+ default:
+ break;
+
+ }
break;
- case NSFB_EVENT_KEY_UP:
- switch (cbi->event->value.keycode) {
- case NSFB_KEY_MOUSE_1:
- browser_window_mouse_click(bw,
- BROWSER_MOUSE_CLICK_1,
- cbi->x + bwidget->scrollx,
- cbi->y + bwidget->scrolly);
- break;
-
- case NSFB_KEY_MOUSE_3:
- browser_window_mouse_click(bw,
- BROWSER_MOUSE_CLICK_2,
- cbi->x + bwidget->scrollx,
- cbi->y + bwidget->scrolly);
- break;
-
- default:
- break;
-
- }
+ case NSFB_EVENT_KEY_UP:
+ switch (cbi->event->value.keycode) {
+ case NSFB_KEY_MOUSE_1:
+ browser_window_mouse_click(gw->bw,
+ BROWSER_MOUSE_CLICK_1,
+ cbi->x + bwidget->scrollx,
+ cbi->y + bwidget->scrolly);
+ break;
+
+ case NSFB_KEY_MOUSE_3:
+ browser_window_mouse_click(gw->bw,
+ BROWSER_MOUSE_CLICK_2,
+ cbi->x + bwidget->scrollx,
+ cbi->y + bwidget->scrolly);
+ break;
+
+ default:
+ break;
+
+ }
break;
- default:
- break;
+ default:
+ break;
- }
- return 1;
+ }
+ return 1;
}
/* called back when movement in browser window */
static int
fb_browser_window_move(fbtk_widget_t *widget, fbtk_callback_info *cbi)
{
- struct browser_window *bw = cbi->context;
- struct browser_widget_s *bwidget = fbtk_get_userpw(widget);
+ struct gui_window *gw = cbi->context;
+ struct browser_widget_s *bwidget = fbtk_get_userpw(widget);
- browser_window_mouse_track(bw,
- 0,
- cbi->x + bwidget->scrollx,
- cbi->y + bwidget->scrolly);
+ browser_window_mouse_track(gw->bw,
+ 0,
+ cbi->x + bwidget->scrollx,
+ cbi->y + bwidget->scrolly);
- return 0;
+ return 0;
}
static int
fb_browser_window_input(fbtk_widget_t *widget, fbtk_callback_info *cbi)
{
- struct gui_window *gw = cbi->context;
- int res = 0;
- static uint8_t modifier = 0;
- int ucs4 = -1;
-
- LOG(("got value %d", cbi->event->value.keycode));
-
- switch (cbi->event->type) {
- case NSFB_EVENT_KEY_DOWN:
- switch (cbi->event->value.keycode) {
-
- case NSFB_KEY_PAGEUP:
- if (browser_window_key_press(gw->bw, KEY_PAGE_UP) == false)
- fb_window_scroll(gw->browser, 0, -fbtk_get_height(gw->browser));
- break;
-
- case NSFB_KEY_PAGEDOWN:
- if (browser_window_key_press(gw->bw, KEY_PAGE_DOWN) == false)
- fb_window_scroll(gw->browser, 0, fbtk_get_height(gw->browser));
- break;
-
- case NSFB_KEY_RIGHT:
- if (browser_window_key_press(gw->bw, KEY_RIGHT) == false)
- fb_window_scroll(gw->browser, 100, 0);
- break;
-
- case NSFB_KEY_LEFT:
- if (browser_window_key_press(gw->bw, KEY_LEFT) == false)
- fb_window_scroll(gw->browser, -100, 0);
- break;
-
- case NSFB_KEY_UP:
- if (browser_window_key_press(gw->bw, KEY_UP) == false)
- fb_window_scroll(gw->browser, 0, -100);
- break;
-
- case NSFB_KEY_DOWN:
- if (browser_window_key_press(gw->bw, KEY_DOWN) == false)
- fb_window_scroll(gw->browser, 0, 100);
- break;
-
- case NSFB_KEY_RSHIFT:
- modifier |= 1;
- break;
-
- case NSFB_KEY_LSHIFT:
- modifier |= 1<<1;
- break;
-
- default:
- ucs4 = fbtk_keycode_to_ucs4(cbi->event->value.keycode,
+ struct gui_window *gw = cbi->context;
+ int res = 0;
+ static uint8_t modifier = 0;
+ int ucs4 = -1;
+
+ LOG(("got value %d", cbi->event->value.keycode));
+
+ switch (cbi->event->type) {
+ case NSFB_EVENT_KEY_DOWN:
+ switch (cbi->event->value.keycode) {
+
+ case NSFB_KEY_PAGEUP:
+ if (browser_window_key_press(gw->bw, KEY_PAGE_UP) == false)
+ widget_scroll_y(gw, -fbtk_get_height(gw->browser), false);
+ break;
+
+ case NSFB_KEY_PAGEDOWN:
+ if (browser_window_key_press(gw->bw, KEY_PAGE_DOWN) == false)
+ widget_scroll_y(gw, fbtk_get_height(gw->browser), false);
+ break;
+
+ case NSFB_KEY_RIGHT:
+ if (browser_window_key_press(gw->bw, KEY_RIGHT) == false)
+ widget_scroll_x(gw, 100, false);
+ break;
+
+ case NSFB_KEY_LEFT:
+ if (browser_window_key_press(gw->bw, KEY_LEFT) == false)
+ widget_scroll_x(gw, -100, false);
+ break;
+
+ case NSFB_KEY_UP:
+ if (browser_window_key_press(gw->bw, KEY_UP) == false)
+ widget_scroll_y(gw, -100, false);
+ break;
+
+ case NSFB_KEY_DOWN:
+ if (browser_window_key_press(gw->bw, KEY_DOWN) == false)
+ widget_scroll_y(gw, 100, false);
+ break;
+
+ case NSFB_KEY_RSHIFT:
+ modifier |= 1;
+ break;
+
+ case NSFB_KEY_LSHIFT:
+ modifier |= 1<<1;
+ break;
+
+ default:
+ ucs4 = fbtk_keycode_to_ucs4(cbi->event->value.keycode,
modifier);
- if (ucs4 != -1)
- res = browser_window_key_press(gw->bw, ucs4);
- break;
- }
- break;
+ if (ucs4 != -1)
+ res = browser_window_key_press(gw->bw, ucs4);
+ break;
+ }
+ break;
- case NSFB_EVENT_KEY_UP:
- switch (cbi->event->value.keycode) {
- case NSFB_KEY_RSHIFT:
- modifier &= ~1;
- break;
+ case NSFB_EVENT_KEY_UP:
+ switch (cbi->event->value.keycode) {
+ case NSFB_KEY_RSHIFT:
+ modifier &= ~1;
+ break;
- case NSFB_KEY_LSHIFT:
- modifier &= ~(1<<1);
- break;
+ case NSFB_KEY_LSHIFT:
+ modifier &= ~(1<<1);
+ break;
- default:
- break;
- }
- break;
+ default:
+ break;
+ }
+ break;
- default:
- break;
- }
+ default:
+ break;
+ }
- return 0;
+ return 0;
}
static void
@@ -686,79 +745,91 @@ fb_update_back_forward(struct gui_window *gw)
/* left icon click routine */
static int
-fb_leftarrow_click(fbtk_widget_t *widget,fbtk_callback_info *cbi)
+fb_leftarrow_click(fbtk_widget_t *widget, fbtk_callback_info *cbi)
{
- struct gui_window *gw = cbi->context;
- struct browser_window *bw = gw->bw;
+ struct gui_window *gw = cbi->context;
+ struct browser_window *bw = gw->bw;
- if (cbi->event->type != NSFB_EVENT_KEY_DOWN)
- return 0;
+ if (cbi->event->type != NSFB_EVENT_KEY_DOWN)
+ return 0;
- if (history_back_available(bw->history))
- history_back(bw, bw->history);
+ if (history_back_available(bw->history))
+ history_back(bw, bw->history);
- fb_update_back_forward(gw);
+ fb_update_back_forward(gw);
- return 1;
+ return 1;
}
/* right arrow icon click routine */
static int
-fb_rightarrow_click(fbtk_widget_t *widget,fbtk_callback_info *cbi)
+fb_rightarrow_click(fbtk_widget_t *widget, fbtk_callback_info *cbi)
{
- struct gui_window *gw = cbi->context;
- struct browser_window *bw = gw->bw;
+ struct gui_window *gw = cbi->context;
+ struct browser_window *bw = gw->bw;
- if (cbi->event->type != NSFB_EVENT_KEY_DOWN)
- return 0;
+ if (cbi->event->type != NSFB_EVENT_KEY_DOWN)
+ return 0;
- if (history_forward_available(bw->history))
- history_forward(bw, bw->history);
+ if (history_forward_available(bw->history))
+ history_forward(bw, bw->history);
- fb_update_back_forward(gw);
- return 1;
+ fb_update_back_forward(gw);
+ return 1;
}
/* reload icon click routine */
static int
-fb_reload_click(fbtk_widget_t *widget,fbtk_callback_info *cbi)
+fb_reload_click(fbtk_widget_t *widget, fbtk_callback_info *cbi)
{
- struct browser_window *bw = cbi->context;
+ struct browser_window *bw = cbi->context;
- if (cbi->event->type != NSFB_EVENT_KEY_DOWN)
- return 0;
+ if (cbi->event->type != NSFB_EVENT_KEY_DOWN)
+ return 0;
- browser_window_reload(bw, true);
- return 1;
+ browser_window_reload(bw, true);
+ return 1;
}
/* stop icon click routine */
static int
-fb_stop_click(fbtk_widget_t *widget,fbtk_callback_info *cbi)
+fb_stop_click(fbtk_widget_t *widget, fbtk_callback_info *cbi)
{
- struct browser_window *bw = cbi->context;
+ struct browser_window *bw = cbi->context;
- if (cbi->event->type != NSFB_EVENT_KEY_DOWN)
- return 0;
+ if (cbi->event->type != NSFB_EVENT_KEY_DOWN)
+ return 0;
browser_window_stop(bw);
- return 0;
+ return 0;
+}
+
+static int
+fb_osk_click(fbtk_widget_t *widget, fbtk_callback_info *cbi)
+{
+
+ if (cbi->event->type != NSFB_EVENT_KEY_DOWN)
+ return 0;
+
+ map_osk();
+
+ return 0;
}
static int
fb_scroll_callback(fbtk_widget_t *widget, fbtk_callback_info *cbi)
{
- struct gui_window *gw = cbi->context;
+ struct gui_window *gw = cbi->context;
switch (cbi->type) {
case FBTK_CBT_SCROLLY:
- fb_window_scroll(gw->browser, 0, 100 * cbi->y);
+ widget_scroll_y(gw, cbi->y, true);
break;
-
+
case FBTK_CBT_SCROLLX:
- fb_window_scroll(gw->browser, 100 * cbi->x, 0);
+ widget_scroll_x(gw, cbi->x, true);
break;
default:
@@ -770,470 +841,554 @@ fb_scroll_callback(fbtk_widget_t *widget, fbtk_callback_info *cbi)
static int
fb_url_enter(void *pw, char *text)
{
- struct browser_window *bw = pw;
- browser_window_go(bw, text, 0, true);
- return 0;
+ struct browser_window *bw = pw;
+ browser_window_go(bw, text, 0, true);
+ return 0;
}
static int
fb_url_move(fbtk_widget_t *widget, fbtk_callback_info *cbi)
{
- framebuffer_set_cursor(&caret_image);
- return 0;
+ framebuffer_set_cursor(&caret_image);
+ return 0;
}
static int
set_ptr_default_move(fbtk_widget_t *widget, fbtk_callback_info *cbi)
{
- framebuffer_set_cursor(&pointer_image);
- return 0;
+ framebuffer_set_cursor(&pointer_image);
+ return 0;
}
-struct gui_window *
-gui_create_browser_window(struct browser_window *bw,
- struct browser_window *clone,
- bool new_tab)
+static int
+fb_localhistory_btn_clik(fbtk_widget_t *widget, fbtk_callback_info *cbi)
+{
+ struct gui_window *gw = cbi->context;
+
+ if (cbi->event->type != NSFB_EVENT_KEY_DOWN)
+ return 0;
+
+ fb_localhistory_map(gw->localhistory);
+
+ return 0;
+}
+
+
+
+static void
+create_toolbar(struct gui_window *gw, int toolbar_height)
+{
+ fbtk_widget_t *toolbar;
+ fbtk_widget_t *widget;
+ int url_bar_height = 0;
+ int xpos = 0;
+ int spacing_width = 0;
+
+ spacing_width = 2;
+
+ xpos = spacing_width;
+
+ url_bar_height = toolbar_height - 6;
+
+ toolbar = fbtk_create_window(gw->window, 0, 0, 0, toolbar_height, FB_FRAME_COLOUR);
+ fbtk_set_handler(toolbar, FBTK_CBT_POINTERENTER, set_ptr_default_move, NULL);
+
+ /* back button */
+ gw->back = fbtk_create_button(toolbar, xpos, spacing_width, left_arrow.width, -spacing_width, FB_FRAME_COLOUR, &left_arrow, fb_leftarrow_click, gw);
+ xpos += left_arrow.width + spacing_width;
+
+ /* history window */
+ widget = fbtk_create_button(toolbar,
+ xpos,
+ spacing_width,
+ history_image.width,
+ -spacing_width,
+ FB_FRAME_COLOUR,
+ &history_image,
+ fb_localhistory_btn_clik,
+ gw);
+ xpos += fbtk_get_width(widget) + spacing_width;
+
+ /* forward button */
+ gw->forward = fbtk_create_button(toolbar,
+ xpos,
+ spacing_width,
+ right_arrow.width,
+ -spacing_width,
+ FB_FRAME_COLOUR,
+ &right_arrow,
+ fb_rightarrow_click,
+ gw);
+ xpos += right_arrow.width + spacing_width;
+
+ /* stop button */
+ widget = fbtk_create_button(toolbar,
+ xpos,
+ spacing_width,
+ stop_image.width,
+ -spacing_width,
+ FB_FRAME_COLOUR,
+ &stop_image,
+ fb_stop_click,
+ gw->bw);
+ xpos += stop_image.width + spacing_width;
+
+ /* reload button */
+ widget = fbtk_create_button(toolbar,
+ xpos,
+ spacing_width,
+ reload.width,
+ -spacing_width,
+ FB_FRAME_COLOUR,
+ &reload,
+ fb_reload_click,
+ gw->bw);
+ xpos += reload.width + spacing_width;
+
+ /* url widget */
+ xpos += spacing_width; /* extra spacing for url bar */
+ gw->url = fbtk_create_writable_text(toolbar,
+ xpos,
+ spacing_width,
+ -(spacing_width + throbber0.width),
+ -spacing_width,
+ FB_COLOUR_WHITE,
+ FB_COLOUR_BLACK,
+ true,
+ fb_url_enter,
+ gw->bw);
+ fbtk_set_handler(gw->url, FBTK_CBT_POINTERENTER, fb_url_move, gw->bw);
+ xpos += fbtk_get_width(gw->url) + spacing_width;
+
+ /* throbber */
+ gw->throbber = fbtk_create_bitmap(toolbar,
+ xpos,
+ spacing_width,
+ throbber0.width,
+ -spacing_width,
+ FB_FRAME_COLOUR, &throbber0);
+
+ fbtk_set_mapping(toolbar, true);
+
+}
+
+static void
+create_normal_browser_window(struct gui_window *gw,
+ int furniture_width,
+ int toolbar_height)
{
- struct gui_window *gw;
- struct browser_widget_s *browser_widget;
- fbtk_widget_t *widget;
- int toolbar_height = 0;
- int furniture_width = 0;
- int spacing_width = 0;
- int url_bar_height = 0;
- int statusbar_width = 0;
- int xpos = 0;
+ fbtk_widget_t *widget;
+ int statusbar_width = 0;
- gw = calloc(1, sizeof(struct gui_window));
+ gw->window = fbtk_create_window(fbtk, 0, 0, 0, 0, 0);
- if (gw == NULL)
- return NULL;
+ statusbar_width = option_toolbar_status_width *
+ fbtk_get_width(gw->window) / 10000;
- /* seems we need to associate the gui window with the underlying
- * browser window
- */
- gw->bw = bw;
+ LOG(("Normal window"));
- switch(bw->browser_window_type) {
- case BROWSER_WINDOW_NORMAL:
- gw->window = fbtk_create_window(fbtk, 0, 0, 0, 0);
-
- /* area and widget dimensions */
- toolbar_height = 30;
- furniture_width = 18;
- spacing_width = 2;
- url_bar_height = 24;
-
- statusbar_width = option_toolbar_status_width *
- fbtk_get_width(gw->window) / 10000;
-
- xpos = spacing_width;
-
- LOG(("Normal window"));
-
- /* fill toolbar background */
- widget = fbtk_create_fill(gw->window,
- 0, 0, 0, toolbar_height,
- FB_FRAME_COLOUR);
- fbtk_set_handler(widget, FBTK_CBT_POINTERMOVE, set_ptr_default_move, bw);
-
- /* back button */
- gw->back = fbtk_create_button(gw->window,
- xpos, (toolbar_height - left_arrow.height) / 2,
- FB_FRAME_COLOUR, &left_arrow,
- fb_leftarrow_click, gw);
- xpos += left_arrow.width + spacing_width;
-
- /* forward button */
- gw->forward = fbtk_create_button(gw->window,
- xpos, (toolbar_height - right_arrow.height) / 2,
- FB_FRAME_COLOUR, &right_arrow,
- fb_rightarrow_click, gw);
- xpos += right_arrow.width + spacing_width;
-
- /* reload button */
- widget = fbtk_create_button(gw->window,
- xpos, (toolbar_height - stop_image.height) / 2,
- FB_FRAME_COLOUR, &stop_image,
- fb_stop_click, bw);
- xpos += stop_image.width + spacing_width;
-
- /* reload button */
- widget = fbtk_create_button(gw->window,
- xpos, (toolbar_height - reload.height) / 2,
- FB_FRAME_COLOUR, &reload,
- fb_reload_click, bw);
- xpos += reload.width + spacing_width;
-
- /* url widget */
- xpos += 1; /* extra spacing for url bar */
- gw->url = fbtk_create_writable_text(gw->window,
- xpos, (toolbar_height - url_bar_height) / 2,
- fbtk_get_width(gw->window) - xpos -
- spacing_width - spacing_width -
- throbber0.width,
- url_bar_height,
- FB_COLOUR_WHITE, FB_COLOUR_BLACK,
- true, fb_url_enter, bw);
- fbtk_set_handler(gw->url, FBTK_CBT_POINTERMOVE, fb_url_move, bw);
- xpos += fbtk_get_width(gw->window) - xpos -
- spacing_width - throbber0.width;
-
- /* throbber */
- gw->throbber = fbtk_create_bitmap(gw->window,
- xpos, (toolbar_height - throbber0.height) / 2,
- FB_FRAME_COLOUR, &throbber0);
-
-
-
- /* status bar */
- xpos = 0;
- gw->status = fbtk_create_text(gw->window,
- xpos,
- fbtk_get_height(gw->window) - furniture_width,
- statusbar_width, furniture_width,
- FB_FRAME_COLOUR, FB_COLOUR_BLACK,
- false);
- fbtk_set_handler(gw->status, FBTK_CBT_POINTERMOVE, set_ptr_default_move, bw);
-
- /* create horizontal scrollbar */
- gw->hscroll = fbtk_create_hscroll(gw->window,
- statusbar_width,
- fbtk_get_height(gw->window) - furniture_width,
- fbtk_get_width(gw->window) - statusbar_width - furniture_width,
- furniture_width,
- FB_SCROLL_COLOUR,
- FB_FRAME_COLOUR,
- fb_scroll_callback,
- gw);
-
- /* fill bottom right area */
- widget = fbtk_create_fill(gw->window,
- fbtk_get_width(gw->window) - furniture_width,
- fbtk_get_height(gw->window) - furniture_width,
- furniture_width,
- furniture_width,
- FB_FRAME_COLOUR);
- fbtk_set_handler(widget, FBTK_CBT_POINTERMOVE, set_ptr_default_move, bw);
+ create_toolbar(gw, toolbar_height);
- /* create vertical scrollbar */
- gw->vscroll = fbtk_create_vscroll(gw->window,
- fbtk_get_width(gw->window) - furniture_width,
- toolbar_height,
- furniture_width,
- fbtk_get_height(gw->window) - toolbar_height - furniture_width,
- FB_SCROLL_COLOUR,
- FB_FRAME_COLOUR,
- fb_scroll_callback,
- gw);
+ /* status bar */
+ gw->status = fbtk_create_text(gw->window,
+ 0,
+ fbtk_get_height(gw->window) - furniture_width,
+ statusbar_width, furniture_width,
+ FB_FRAME_COLOUR, FB_COLOUR_BLACK,
+ 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)));
- break;
+ /* create horizontal scrollbar */
+ gw->hscroll = fbtk_create_hscroll(gw->window,
+ statusbar_width,
+ fbtk_get_height(gw->window) - furniture_width,
+ fbtk_get_width(gw->window) - statusbar_width - furniture_width,
+ furniture_width,
+ FB_SCROLL_COLOUR,
+ FB_FRAME_COLOUR,
+ fb_scroll_callback,
+ gw);
+
+ /* fill bottom right area */
+
+ if (option_fb_osk == true) {
+ widget = fbtk_create_text_button(gw->window,
+ fbtk_get_width(gw->window) - furniture_width,
+ fbtk_get_height(gw->window) - furniture_width,
+ furniture_width,
+ furniture_width,
+ FB_FRAME_COLOUR, FB_COLOUR_BLACK,
+ fb_osk_click,
+ NULL);
+ fbtk_set_text(widget, "\xe2\x8c\xa8");
+ } else {
+ widget = fbtk_create_fill(gw->window,
+ fbtk_get_width(gw->window) - furniture_width,
+ fbtk_get_height(gw->window) - furniture_width,
+ furniture_width,
+ furniture_width,
+ FB_FRAME_COLOUR);
+
+ fbtk_set_handler(widget, FBTK_CBT_POINTERENTER, set_ptr_default_move, NULL);
+ }
- case BROWSER_WINDOW_FRAME:
- gw->window = fbtk_create_window(bw->parent->window->window, 0, 0, 0, 0);
- LOG(("create frame"));
- break;
+ /* create vertical scrollbar */
+ gw->vscroll = fbtk_create_vscroll(gw->window,
+ fbtk_get_width(gw->window) - furniture_width,
+ toolbar_height,
+ furniture_width,
+ fbtk_get_height(gw->window) - toolbar_height - furniture_width,
+ FB_SCROLL_COLOUR,
+ FB_FRAME_COLOUR,
+ fb_scroll_callback,
+ gw);
- default:
- gw->window = fbtk_create_window(bw->parent->window->window, 0, 0, 0, 0);
- LOG(("unhandled type"));
- }
+}
- browser_widget = calloc(1, sizeof(struct browser_widget_s));
+static void
+create_browser_widget(struct gui_window *gw, int toolbar_height, int furniture_width)
+{
+ struct browser_widget_s *browser_widget;
+ browser_widget = calloc(1, sizeof(struct browser_widget_s));
- gw->browser = fbtk_create_user(gw->window, 0, toolbar_height, -furniture_width, - (furniture_width + toolbar_height), browser_widget);
+ gw->browser = fbtk_create_user(gw->window,
+ 0,
+ toolbar_height,
+ -furniture_width,
+ -furniture_width,
+ browser_widget);
fbtk_set_handler(gw->browser, FBTK_CBT_REDRAW, fb_browser_window_redraw, gw);
fbtk_set_handler(gw->browser, FBTK_CBT_INPUT, fb_browser_window_input, gw);
- fbtk_set_handler(gw->browser, FBTK_CBT_CLICK, fb_browser_window_click, bw);
- fbtk_set_handler(gw->browser, FBTK_CBT_POINTERMOVE, fb_browser_window_move, bw);
-
- return gw;
+ fbtk_set_handler(gw->browser, FBTK_CBT_CLICK, fb_browser_window_click, gw);
+ fbtk_set_handler(gw->browser, FBTK_CBT_POINTERMOVE, fb_browser_window_move, gw);
}
-void gui_window_destroy(struct gui_window *gw)
+struct gui_window *
+gui_create_browser_window(struct browser_window *bw,
+ struct browser_window *clone,
+ bool new_tab)
{
- fbtk_destroy_widget(gw->window);
+ struct gui_window *gw;
+
+ gw = calloc(1, sizeof(struct gui_window));
+
+ if (gw == NULL)
+ return NULL;
+
+ /* seems we need to associate the gui window with the underlying
+ * browser window
+ */
+ gw->bw = bw;
+
- free(gw);
+ switch(bw->browser_window_type) {
+ case BROWSER_WINDOW_NORMAL:
+ create_normal_browser_window(gw, option_fb_furniture_size, option_fb_toolbar_size);
+ gw->localhistory = fb_create_localhistory(bw, fbtk, option_fb_furniture_size);
+ create_browser_widget(gw, option_fb_toolbar_size, option_fb_furniture_size);
+
+ /* map and request redraw of gui window */
+ fbtk_set_mapping(gw->window, true);
+
+ break;
+
+ case BROWSER_WINDOW_FRAME:
+ gw->window = fbtk_create_window(bw->parent->window->window, 0, 0, 0, 0, 0);
+ create_browser_widget(gw, 0, 0);
+ LOG(("create frame"));
+ break;
+
+ default:
+ gw->window = fbtk_create_window(bw->parent->window->window, 0, 0, 0, 0, 0);
+ create_browser_widget(gw, 0, 0);
+ LOG(("unhandled type"));
+ }
+ return gw;
}
-void gui_window_set_title(struct gui_window *g, const char *title)
+void
+gui_window_destroy(struct gui_window *gw)
{
- LOG(("%p, %s", g, title));
-}
+ fbtk_destroy_widget(gw->window);
+ free(gw);
-void fb_window_scroll(struct fbtk_widget_s *browser, int x, int y)
-{
- struct browser_widget_s *bwidget = fbtk_get_userpw(browser);
- LOG(("window scroll"));
- bwidget->panx += x;
- bwidget->pany += y;
- bwidget->pan_required = true;
+}
- fbtk_request_redraw(browser);
+void
+gui_window_set_title(struct gui_window *g, const char *title)
+{
+ LOG(("%p, %s", g, title));
}
-void gui_window_redraw(struct gui_window *g, int x0, int y0, int x1, int y1)
+void
+gui_window_redraw(struct gui_window *g, int x0, int y0, int x1, int y1)
{
- fb_queue_redraw(g->browser, x0, y0, x1, y1);
+ fb_queue_redraw(g->browser, x0, y0, x1, y1);
}
-void gui_window_redraw_window(struct gui_window *g)
+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) );
+ fb_queue_redraw(g->browser, 0, 0, fbtk_get_width(g->browser), fbtk_get_height(g->browser) );
}
-void gui_window_update_box(struct gui_window *g,
- const union content_msg_data *data)
+void
+gui_window_update_box(struct gui_window *g, const union content_msg_data *data)
{
- struct browser_widget_s *bwidget = fbtk_get_userpw(g->browser);
- fb_queue_redraw(g->browser,
- data->redraw.x - bwidget->scrollx,
- data->redraw.y - bwidget->scrolly,
- data->redraw.x - bwidget->scrollx +
- data->redraw.width,
- data->redraw.y - bwidget->scrolly +
- data->redraw.height);
+ struct browser_widget_s *bwidget = fbtk_get_userpw(g->browser);
+ fb_queue_redraw(g->browser,
+ data->redraw.x - bwidget->scrollx,
+ data->redraw.y - bwidget->scrolly,
+ data->redraw.x - bwidget->scrollx +
+ data->redraw.width,
+ data->redraw.y - bwidget->scrolly +
+ data->redraw.height);
}
-bool gui_window_get_scroll(struct gui_window *g, int *sx, int *sy)
+bool
+gui_window_get_scroll(struct gui_window *g, int *sx, int *sy)
{
- struct browser_widget_s *bwidget = fbtk_get_userpw(g->browser);
+ struct browser_widget_s *bwidget = fbtk_get_userpw(g->browser);
- *sx = bwidget->scrollx;
- *sy = bwidget->scrolly;
+ *sx = bwidget->scrollx;
+ *sy = bwidget->scrolly;
- return true;
+ return true;
}
-void gui_window_set_scroll(struct gui_window *g, int sx, int sy)
+void
+gui_window_set_scroll(struct gui_window *gw, int sx, int sy)
{
- struct browser_widget_s *bwidget = fbtk_get_userpw(g->browser);
+ struct browser_widget_s *bwidget = fbtk_get_userpw(gw->browser);
assert(bwidget);
- bwidget->panx = sx - bwidget->scrollx;
- bwidget->pany = sy - bwidget->scrolly;
-
- bwidget->pan_required = true;
-
- fbtk_request_redraw(g->browser);
+ widget_scroll_x(gw, sx, true);
+ widget_scroll_y(gw, sy, true);
}
-void gui_window_scroll_visible(struct gui_window *g, int x0, int y0,
- int x1, int y1)
+void
+gui_window_scroll_visible(struct gui_window *g, int x0, int y0,
+ int x1, int y1)
{
- LOG(("%s:(%p, %d, %d, %d, %d)", __func__, g, x0, y0, x1, y1));
+ LOG(("%s:(%p, %d, %d, %d, %d)", __func__, g, x0, y0, x1, y1));
}
-void gui_window_position_frame(struct gui_window *g, int x0, int y0,
- int x1, int y1)
+void
+gui_window_position_frame(struct gui_window *g, int x0, int y0, int x1, int y1)
{
- struct gui_window *parent;
- int px, py;
- int w, h;
- LOG(("%s: %d, %d, %d, %d", g->bw->name, x0, y0, x1, y1));
- parent = g->bw->parent->window;
+ struct gui_window *parent;
+ int px, py;
+ int w, h;
+ LOG(("%s: %d, %d, %d, %d", g->bw->name, x0, y0, x1, y1));
+ parent = g->bw->parent->window;
- if (parent->window == NULL)
- return; /* doesnt have an fbtk widget */
+ if (parent->window == NULL)
+ return; /* doesnt have an fbtk widget */
- px = fbtk_get_x(parent->browser) + x0;
- py = fbtk_get_y(parent->browser) + y0;
- w = x1 - x0;
- h = y1 - y0;
- if (w > (fbtk_get_width(parent->browser) - px))
- w = fbtk_get_width(parent->browser) - px;
+ px = fbtk_get_absx(parent->browser) + x0;
+ py = fbtk_get_absy(parent->browser) + y0;
+ w = x1 - x0;
+ h = y1 - y0;
+ if (w > (fbtk_get_width(parent->browser) - px))
+ w = fbtk_get_width(parent->browser) - px;
- if (h > (fbtk_get_height(parent->browser) - py))
- h = fbtk_get_height(parent->browser) - py;
+ if (h > (fbtk_get_height(parent->browser) - py))
+ h = fbtk_get_height(parent->browser) - py;
- fbtk_set_pos_and_size(g->window, px, py , w , h);
+ fbtk_set_pos_and_size(g->window, px, py , w , h);
- fbtk_request_redraw(parent->browser);
+ fbtk_request_redraw(parent->browser);
}
-void gui_window_get_dimensions(struct gui_window *g, int *width, int *height,
- bool scaled)
+void
+gui_window_get_dimensions(struct gui_window *g,
+ int *width,
+ int *height,
+ bool scaled)
{
- *width = fbtk_get_width(g->browser);
- *height = fbtk_get_height(g->browser);
+ *width = fbtk_get_width(g->browser);
+ *height = fbtk_get_height(g->browser);
}
-void gui_window_update_extent(struct gui_window *gw)
+void
+gui_window_update_extent(struct gui_window *gw)
{
- int pct;
- int width;
- int height;
+ fbtk_set_scroll_parameters(gw->hscroll, 0, content_get_width(gw->bw->current_content), fbtk_get_width(gw->browser), 100);
- width = content_get_width(gw->bw->current_content);
- if (width != 0) {
- pct = (fbtk_get_width(gw->browser) * 100) / width;
- fbtk_set_scroll(gw->hscroll, pct);
- }
+ fbtk_set_scroll_parameters(gw->vscroll, 0, content_get_height(gw->bw->current_content), fbtk_get_height(gw->browser), 100);
- height = content_get_height(gw->bw->current_content);
- if (height != 0) {
- pct = (fbtk_get_height(gw->browser) * 100) / height;
- fbtk_set_scroll(gw->vscroll, pct);
- }
}
-void gui_window_set_status(struct gui_window *g, const char *text)
+void
+gui_window_set_status(struct gui_window *g, const char *text)
{
- fbtk_set_text(g->status, text);
+ fbtk_set_text(g->status, text);
}
-void gui_window_set_pointer(struct gui_window *g, gui_pointer_shape shape)
+void
+gui_window_set_pointer(struct gui_window *g, gui_pointer_shape shape)
{
- switch (shape) {
- case GUI_POINTER_POINT:
- framebuffer_set_cursor(&hand_image);
- break;
+ switch (shape) {
+ case GUI_POINTER_POINT:
+ framebuffer_set_cursor(&hand_image);
+ break;
- case GUI_POINTER_CARET:
- framebuffer_set_cursor(&caret_image);
- break;
+ case GUI_POINTER_CARET:
+ framebuffer_set_cursor(&caret_image);
+ break;
- case GUI_POINTER_MENU:
- framebuffer_set_cursor(&menu_image);
- break;
+ case GUI_POINTER_MENU:
+ framebuffer_set_cursor(&menu_image);
+ break;
- case GUI_POINTER_PROGRESS:
- framebuffer_set_cursor(&progress_image);
- break;
+ case GUI_POINTER_PROGRESS:
+ framebuffer_set_cursor(&progress_image);
+ break;
- default:
- framebuffer_set_cursor(&pointer_image);
- break;
- }
+ default:
+ framebuffer_set_cursor(&pointer_image);
+ break;
+ }
}
-void gui_window_hide_pointer(struct gui_window *g)
+void
+gui_window_hide_pointer(struct gui_window *g)
{
}
-void gui_window_set_url(struct gui_window *g, const char *url)
+void
+gui_window_set_url(struct gui_window *g, const char *url)
{
- fbtk_set_text(g->url, url);
+ fbtk_set_text(g->url, url);
}
static void
throbber_advance(void *pw)
{
- struct gui_window *g = pw;
- struct bitmap *image;
-
- switch (g->throbber_index) {
- case 0:
- image = &throbber1;
- g->throbber_index = 1;
- break;
-
- case 1:
- image = &throbber2;
- g->throbber_index = 2;
- break;
-
- case 2:
- image = &throbber3;
- g->throbber_index = 3;
- break;
-
- case 3:
- image = &throbber4;
- g->throbber_index = 4;
- break;
-
- case 4:
- image = &throbber5;
- g->throbber_index = 5;
- break;
-
- case 5:
- image = &throbber6;
- g->throbber_index = 6;
- break;
-
- case 6:
- image = &throbber7;
- g->throbber_index = 7;
- break;
-
- case 7:
- image = &throbber8;
- g->throbber_index = 0;
- break;
+ struct gui_window *g = pw;
+ struct bitmap *image;
+
+ switch (g->throbber_index) {
+ case 0:
+ image = &throbber1;
+ g->throbber_index = 1;
+ break;
+
+ case 1:
+ image = &throbber2;
+ g->throbber_index = 2;
+ break;
+
+ case 2:
+ image = &throbber3;
+ g->throbber_index = 3;
+ break;
+
+ case 3:
+ image = &throbber4;
+ g->throbber_index = 4;
+ break;
+
+ case 4:
+ image = &throbber5;
+ g->throbber_index = 5;
+ break;
+
+ case 5:
+ image = &throbber6;
+ g->throbber_index = 6;
+ break;
+
+ case 6:
+ image = &throbber7;
+ g->throbber_index = 7;
+ break;
+
+ case 7:
+ image = &throbber8;
+ g->throbber_index = 0;
+ break;
default:
return;
- }
+ }
- if (g->throbber_index >= 0) {
- fbtk_set_bitmap(g->throbber, image);
- schedule(10, throbber_advance, g);
- }
+ if (g->throbber_index >= 0) {
+ fbtk_set_bitmap(g->throbber, image);
+ schedule(10, throbber_advance, g);
+ }
}
-void gui_window_start_throbber(struct gui_window *g)
+void
+gui_window_start_throbber(struct gui_window *g)
{
- g->throbber_index = 0;
- schedule(10, throbber_advance, g);
+ g->throbber_index = 0;
+ schedule(10, throbber_advance, g);
}
-void gui_window_stop_throbber(struct gui_window *gw)
+void
+gui_window_stop_throbber(struct gui_window *gw)
{
- gw->throbber_index = -1;
- fbtk_set_bitmap(gw->throbber, &throbber0);
+ gw->throbber_index = -1;
+ fbtk_set_bitmap(gw->throbber, &throbber0);
- fb_update_back_forward(gw);
+ fb_update_back_forward(gw);
}
-void gui_window_place_caret(struct gui_window *g, int x, int y, int height)
+void
+gui_window_place_caret(struct gui_window *g, int x, int y, int height)
{
}
-void gui_window_remove_caret(struct gui_window *g)
+void
+gui_window_remove_caret(struct gui_window *g)
{
}
-void gui_window_new_content(struct gui_window *g)
+void
+gui_window_new_content(struct gui_window *g)
{
}
-bool gui_window_scroll_start(struct gui_window *g)
+bool
+gui_window_scroll_start(struct gui_window *g)
{
return true;
}
-bool gui_window_box_scroll_start(struct gui_window *g,
- int x0, int y0, int x1, int y1)
+bool
+gui_window_box_scroll_start(struct gui_window *g,
+ int x0, int y0, int x1, int y1)
{
return true;
}
-bool gui_window_frame_resize_start(struct gui_window *g)
+bool
+gui_window_frame_resize_start(struct gui_window *g)
{
LOG(("resize frame\n"));
return true;
}
-void
+void
gui_window_save_link(struct gui_window *g, const char *url, const char *title)
{
}
-void gui_window_set_scale(struct gui_window *g, float scale)
+void
+gui_window_set_scale(struct gui_window *g, float scale)
{
LOG(("set scale\n"));
}
@@ -1247,85 +1402,103 @@ gui_window_set_icon(struct gui_window *g, hlcache_handle *icon)
}
/**
-* set gui display of a retrieved favicon representing the search provider
-* \param ico may be NULL for local calls; then access current cache from
-* search_web_ico()
-*/
+ * set gui display of a retrieved favicon representing the search provider
+ * \param ico may be NULL for local calls; then access current cache from
+ * search_web_ico()
+ */
void
gui_window_set_search_ico(hlcache_handle *ico)
{
}
-struct gui_download_window *gui_download_window_create(download_context *ctx,
- struct gui_window *parent)
+struct gui_download_window *
+gui_download_window_create(download_context *ctx, struct gui_window *parent)
{
- return NULL;
+ return NULL;
}
-nserror gui_download_window_data(struct gui_download_window *dw,
- const char *data, unsigned int size)
+nserror
+gui_download_window_data(struct gui_download_window *dw,
+ const char *data,
+ unsigned int size)
{
return NSERROR_OK;
}
-void gui_download_window_error(struct gui_download_window *dw,
- const char *error_msg)
+void
+gui_download_window_error(struct gui_download_window *dw,
+ const char *error_msg)
{
}
-void gui_download_window_done(struct gui_download_window *dw)
+void
+gui_download_window_done(struct gui_download_window *dw)
{
}
-void gui_drag_save_object(gui_save_type type, hlcache_handle *c,
- struct gui_window *w)
+void
+gui_drag_save_object(gui_save_type type,
+ hlcache_handle *c,
+ struct gui_window *w)
{
}
-void gui_drag_save_selection(struct selection *s, struct gui_window *g)
+void
+gui_drag_save_selection(struct selection *s, struct gui_window *g)
{
}
-void gui_start_selection(struct gui_window *g)
+void
+gui_start_selection(struct gui_window *g)
{
}
-void gui_paste_from_clipboard(struct gui_window *g, int x, int y)
+void
+gui_paste_from_clipboard(struct gui_window *g, int x, int y)
{
}
-bool gui_empty_clipboard(void)
+bool
+gui_empty_clipboard(void)
{
- return false;
+ return false;
}
-bool gui_add_to_clipboard(const char *text, size_t length, bool space)
+bool
+gui_add_to_clipboard(const char *text, size_t length, bool space)
{
- return false;
+ return false;
}
-bool gui_commit_clipboard(void)
+bool
+gui_commit_clipboard(void)
{
- return false;
+ return false;
}
-bool gui_copy_to_clipboard(struct selection *s)
+bool
+gui_copy_to_clipboard(struct selection *s)
{
- return false;
+ return false;
}
-void gui_create_form_select_menu(struct browser_window *bw,
- struct form_control *control)
+void
+gui_create_form_select_menu(struct browser_window *bw,
+ struct form_control *control)
{
}
-void gui_launch_url(const char *url)
+void
+gui_launch_url(const char *url)
{
}
-void gui_cert_verify(const char *url, const struct ssl_cert_info *certs,
- unsigned long num,
- nserror (*cb)(bool proceed, void *pw), void *cbpw)
+void
+gui_cert_verify(const char *url,
+ const struct ssl_cert_info *certs,
+ unsigned long num,
+ nserror (*cb)(bool proceed, void *pw),
+ void *cbpw)
{
cb(false, cbpw);
}
diff --git a/framebuffer/gui.h b/framebuffer/gui.h
index 98110ac6c..c1fa3cc1d 100644
--- a/framebuffer/gui.h
+++ b/framebuffer/gui.h
@@ -24,26 +24,41 @@ 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;
-
- struct fbtk_widget_s *window;
- struct fbtk_widget_s *back;
- struct fbtk_widget_s *forward;
- struct fbtk_widget_s *url;
- struct fbtk_widget_s *status;
- struct fbtk_widget_s *throbber;
- struct fbtk_widget_s *hscroll;
- struct fbtk_widget_s *vscroll;
- struct fbtk_widget_s *browser;
- int throbber_index;
+ struct browser_window *bw;
+
+ struct fbtk_widget_s *window;
+ struct fbtk_widget_s *back;
+ struct fbtk_widget_s *forward;
+ struct fbtk_widget_s *url;
+ struct fbtk_widget_s *status;
+ struct fbtk_widget_s *throbber;
+ struct fbtk_widget_s *hscroll;
+ struct fbtk_widget_s *vscroll;
+ struct fbtk_widget_s *browser;
+
+ int throbber_index;
+
+ struct gui_localhistory *localhistory;
};
extern struct gui_window *window_list;
-/* scroll a window */
-void fb_window_scroll(struct fbtk_widget_s *browser, int x, int y);
+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);
+
#endif /* NETSURF_FB_GUI_H */
@@ -52,5 +67,3 @@ void fb_window_scroll(struct fbtk_widget_s *browser, int x, int y);
* c-basic-offset:8
* End:
*/
-
-
diff --git a/framebuffer/image_data.h b/framebuffer/image_data.h
index fcf1c366f..42c9900fd 100644
--- a/framebuffer/image_data.h
+++ b/framebuffer/image_data.h
@@ -25,10 +25,13 @@ extern struct bitmap left_arrow;
extern struct bitmap right_arrow;
extern struct bitmap reload;
extern struct bitmap stop_image;
+extern struct bitmap history_image;
+
extern struct bitmap left_arrow_g;
extern struct bitmap right_arrow_g;
extern struct bitmap reload_g;
extern struct bitmap stop_image_g;
+extern struct bitmap history_image_g;
extern struct bitmap scrolll;
extern struct bitmap scrollr;
diff --git a/framebuffer/localhistory.c b/framebuffer/localhistory.c
new file mode 100644
index 000000000..76e4bd989
--- /dev/null
+++ b/framebuffer/localhistory.c
@@ -0,0 +1,162 @@
+/*
+ * 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 <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <sys/ioctl.h>
+#include <limits.h>
+#include <unistd.h>
+#include <assert.h>
+#include <string.h>
+#include <stdbool.h>
+#include <stdlib.h>
+
+#include <libnsfb.h>
+#include <libnsfb_plot.h>
+#include <libnsfb_event.h>
+
+#include "desktop/gui.h"
+#include "desktop/plotters.h"
+#include "desktop/netsurf.h"
+#include "desktop/options.h"
+#include "utils/log.h"
+#include "utils/url.h"
+#include "utils/messages.h"
+#include "utils/utils.h"
+#include "desktop/textinput.h"
+#include "render/form.h"
+
+#include "framebuffer/gui.h"
+#include "framebuffer/fbtk.h"
+#include "framebuffer/framebuffer.h"
+#include "framebuffer/bitmap.h"
+#include "framebuffer/schedule.h"
+#include "framebuffer/findfile.h"
+#include "framebuffer/image_data.h"
+#include "framebuffer/font.h"
+
+#include "content/urldb.h"
+#include "desktop/history_core.h"
+#include "content/fetch.h"
+
+static int
+localhistory_redraw(fbtk_widget_t *widget, fbtk_callback_info *cbi)
+{
+ struct gui_localhistory *glh = cbi->context;
+ nsfb_bbox_t rbox;
+
+ 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);
+
+ history_redraw_rectangle(glh->bw->history,
+ glh->scrollx,
+ glh->scrolly,
+ fbtk_get_width(widget) + glh->scrollx,
+ fbtk_get_height(widget) + glh->scrolly,
+ 0, 0);
+
+ 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_DOWN)
+ return 0;
+
+ history_click(glh->bw, glh->bw->history, 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/framebuffer/options.h b/framebuffer/options.h
index f2f52ae49..fff5fd192 100644
--- a/framebuffer/options.h
+++ b/framebuffer/options.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2008 Daniel Silverstone <dsilvers@netsurf-browser.org>
+ * Copyright 2008, 2010 Daniel Silverstone <dsilvers@netsurf-browser.org>
*
* This file is part of NetSurf, http://www.netsurf-browser.org/
*
@@ -23,10 +23,14 @@
extern int option_fb_depth;
extern int option_fb_refresh;
-extern bool option_fb_font_monochrome; /* render font monochrome */
extern char *option_fb_device;
extern char *option_fb_input_devpath;
extern char *option_fb_input_glob;
+extern int option_fb_furniture_size; /* toolkit furniture size */
+extern int option_fb_toolbar_size; /* toolbar furniture size */
+extern bool option_fb_osk; /* enable on screen keyboard */
+
+extern bool option_fb_font_monochrome; /* render font monochrome */
extern char *option_fb_face_sans_serif; /* default sans face */
extern char *option_fb_face_sans_serif_bold; /* bold sans face */
extern char *option_fb_face_sans_serif_italic; /* bold sans face */
@@ -35,27 +39,33 @@ extern char *option_fb_face_monospace; /* monospace face */
extern char *option_fb_face_serif; /* serif face */
extern char *option_fb_face_serif_bold; /* bold serif face */
-#define EXTRA_OPTION_DEFINE \
- int option_fb_depth = 32; \
- int option_fb_refresh = 70; \
- bool option_fb_font_monochrome = false; \
- char *option_fb_device = 0; \
- char *option_fb_input_devpath = 0; \
- char *option_fb_input_glob = 0; \
- char *option_fb_face_sans_serif; \
- char *option_fb_face_sans_serif_bold; \
- char *option_fb_face_sans_serif_italic; \
- char *option_fb_face_sans_serif_italic_bold; \
- char *option_fb_face_monospace; \
- char *option_fb_face_serif; \
- char *option_fb_face_serif_bold;
+#define EXTRA_OPTION_DEFINE \
+ int option_fb_depth = 32; \
+ int option_fb_refresh = 70; \
+ char *option_fb_device = 0; \
+ char *option_fb_input_devpath = 0; \
+ char *option_fb_input_glob = 0; \
+ int option_fb_furniture_size = 18; \
+ int option_fb_toolbar_size = 30; \
+ bool option_fb_osk = false; \
+ bool option_fb_font_monochrome = false; \
+ char *option_fb_face_sans_serif; \
+ char *option_fb_face_sans_serif_bold; \
+ char *option_fb_face_sans_serif_italic; \
+ char *option_fb_face_sans_serif_italic_bold; \
+ char *option_fb_face_monospace; \
+ char *option_fb_face_serif; \
+ char *option_fb_face_serif_bold;
#define EXTRA_OPTION_TABLE \
- { "fb_depth", OPTION_INTEGER, &option_fb_depth }, \
- { "fb_refresh", OPTION_INTEGER, &option_fb_refresh }, \
+ { "fb_depth", OPTION_INTEGER, &option_fb_depth }, \
+ { "fb_refresh", OPTION_INTEGER, &option_fb_refresh }, \
{ "fb_device", OPTION_STRING, &option_fb_device }, \
{ "fb_input_devpath", OPTION_STRING, &option_fb_input_devpath }, \
{ "fb_input_glob", OPTION_STRING, &option_fb_input_glob }, \
+ { "fb_furniture_size", OPTION_INTEGER, &option_fb_furniture_size }, \
+ { "fb_toolbar_size", OPTION_INTEGER, &option_fb_toolbar_size }, \
+ { "fb_font_osk", OPTION_BOOL, &option_fb_osk }, \
{ "fb_font_monochrome", OPTION_BOOL, &option_fb_font_monochrome }, \
{ "fb_face_sans_serif", OPTION_STRING, &option_fb_face_sans_serif }, \
{ "fb_face_sans_serif_bold", OPTION_STRING, &option_fb_face_sans_serif_bold }, \
@@ -63,6 +73,12 @@ extern char *option_fb_face_serif_bold; /* bold serif face */
{ "fb_face_sans_serif_italic_bold", OPTION_STRING, &option_fb_face_sans_serif_italic_bold }, \
{ "fb_face_monospace", OPTION_STRING, &option_fb_face_monospace }, \
{ "fb_face_serif", OPTION_STRING, &option_fb_face_serif }, \
- { "fb_serif_bold", OPTION_STRING, &option_fb_face_serif_bold }
+ { "fb_serif_bold", OPTION_STRING, &option_fb_face_serif_bold }
#endif
+
+/*
+ * Local Variables:
+ * c-basic-offset:8
+ * End:
+ */
diff --git a/framebuffer/res/icons/history.png b/framebuffer/res/icons/history.png
new file mode 100644
index 000000000..b124db7bf
--- /dev/null
+++ b/framebuffer/res/icons/history.png
Binary files differ
diff --git a/framebuffer/res/icons/history_g.png b/framebuffer/res/icons/history_g.png
new file mode 100644
index 000000000..1597d54e7
--- /dev/null
+++ b/framebuffer/res/icons/history_g.png
Binary files differ
diff --git a/framebuffer/thumbnail.c b/framebuffer/thumbnail.c
index 81419d282..47340fd6c 100644
--- a/framebuffer/thumbnail.c
+++ b/framebuffer/thumbnail.c
@@ -17,9 +17,16 @@
*/
#include "desktop/browser.h"
+#include "content/urldb.h"
-bool thumbnail_create(struct hlcache_handle *content, struct bitmap *bitmap,
- const char *url)
+bool
+thumbnail_create(struct hlcache_handle *content,
+ struct bitmap *bitmap,
+ const char *url)
{
- return false;
+ /* register the thumbnail with the URL */
+ if (url != NULL)
+ urldb_set_thumbnail(url, bitmap);
+
+ return true;
}