Gitweb links:

...log 
http://git.netsurf-browser.org/netsurf.git/shortlog/6b997431d34d3711c62cf4bfe7f3456f45072273
...commit 
http://git.netsurf-browser.org/netsurf.git/commit/6b997431d34d3711c62cf4bfe7f3456f45072273
...tree 
http://git.netsurf-browser.org/netsurf.git/tree/6b997431d34d3711c62cf4bfe7f3456f45072273

The branch, master has been updated
       via  6b997431d34d3711c62cf4bfe7f3456f45072273 (commit)
       via  f1fdd93ffda5181f325905c8509a2bea9d78eb41 (commit)
       via  6736ab9b724702c82b4aebc61c3d51c48d9c958c (commit)
      from  79cde2cefbec54ea08ec854471aa06cdc5c367d6 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
commitdiff 
http://git.netsurf-browser.org/netsurf.git/commit/?id=6b997431d34d3711c62cf4bfe7f3456f45072273
commit 6b997431d34d3711c62cf4bfe7f3456f45072273
Author: Vincent Sanders <[email protected]>
Commit: Vincent Sanders <[email protected]>

    update RISC OS frontend to use core window for local history

diff --git a/frontends/riscos/Makefile b/frontends/riscos/Makefile
index 87790ac..84a1c93 100644
--- a/frontends/riscos/Makefile
+++ b/frontends/riscos/Makefile
@@ -47,13 +47,14 @@ endif
 
 # S_RISCOS are sources purely for the RISC OS build
 S_FRONTEND := 401login.c assert.c bitmap.c buffer.c configure.c gui.c  \
-       dialog.c download.c filetype.c font.c help.c history.c image.c  \
+       dialog.c download.c filetype.c font.c help.c image.c    \
        iconbar.c menus.c message.c mouse.c palettes.c plotters.c       \
        print.c query.c save.c save_draw.c save_pdf.c schedule.c        \
        search.c searchweb.c textarea.c textselection.c theme.c         \
        theme_install.c toolbar.c url_suggest.c wimp.c wimp_event.c     \
        ucstables.c uri.c url_complete.c url_protocol.c window.c        \
-       corewindow.c cookies.c sslcert.c global_history.c hotlist.c     \
+       corewindow.c cookies.c sslcert.c hotlist.c                      \
+       local_history.c global_history.c                                \
        $(addprefix content-handlers/,artworks.c awrender.s draw.c      \
        sprite.c)                                                       \
        $(addprefix gui/,button_bar.c progress_bar.c status_bar.c       \
diff --git a/frontends/riscos/corewindow.c b/frontends/riscos/corewindow.c
index b57e4e0..a885977 100644
--- a/frontends/riscos/corewindow.c
+++ b/frontends/riscos/corewindow.c
@@ -236,12 +236,7 @@ static void ro_cw_mouse_at(wimp_pointer *pointer, void 
*data)
        }
        LOG("RO corewindow context %p", ro_cw);
 
-       /* no futher processing required if no drag in progress */
-       if (ro_cw->drag_status == CORE_WINDOW_DRAG_NONE) {
-               return;
-       }
-
-       /* Not a Menu click and a drag is in progress. */
+       /* Not a Menu click. */
        state.w = pointer->w;
        error = xwimp_get_window_state(&state);
        if (error) {
@@ -250,18 +245,23 @@ static void ro_cw_mouse_at(wimp_pointer *pointer, void 
*data)
                return;
        }
 
-       /* Convert the returned mouse coordinates into NetSurf's internal
-        * units.
+       /* Convert the returned mouse coordinates into
+        * NetSurf's internal units.
         */
        xpos = ((pointer->pos.x - state.visible.x0) + state.xscroll) / 2;
        ypos = ((state.visible.y1 - pointer->pos.y) -
                state.yscroll + ro_cw->origin_y) / 2;
 
-       /* Start to process the mouse click. */
-       mouse = ro_gui_mouse_drag_state(pointer->buttons,
-                                       wimp_BUTTON_DOUBLE_CLICK_DRAG);
+       /* if no drag in progress report hover */
+       if (ro_cw->drag_status == CORE_WINDOW_DRAG_NONE) {
+               mouse = BROWSER_MOUSE_HOVER;
+       } else {
+               /* Start to process the mouse click. */
+               mouse = ro_gui_mouse_drag_state(pointer->buttons,
+                                               wimp_BUTTON_DOUBLE_CLICK_DRAG);
 
-       ro_cw->mouse(ro_cw, mouse, xpos, ypos);
+               ro_cw->mouse(ro_cw, mouse, xpos, ypos);
+       }
 
        if (!(mouse & BROWSER_MOUSE_DRAG_ON)) {
                ro_cw->mouse(ro_cw, BROWSER_MOUSE_HOVER, xpos, ypos);
@@ -373,6 +373,30 @@ ro_cw_drag_start(struct ro_corewindow *ro_cw,
 
 
 /**
+ * Handle Pointer Leaving Window events.
+ *
+ * These events are delivered as the termination callback handler from
+ * ro_mouse's mouse tracking.
+ *
+ * \param leaving The Wimp_PointerLeavingWindow block.
+ * \param data NULL data pointer.
+ */
+static void ro_cw_pointer_leaving(wimp_leaving *leaving, void *data)
+{
+       struct ro_corewindow *ro_cw;
+
+       ro_cw = (struct ro_corewindow 
*)ro_gui_wimp_event_get_user_data(leaving->w);
+       if (ro_cw == NULL) {
+               LOG("no corewindow conext for window: 0x%x",
+                   (unsigned int)leaving->w);
+               return;
+       }
+
+       ro_cw->mouse(ro_cw, BROWSER_MOUSE_LEAVE, 0, 0);
+}
+
+
+/**
  * Wimp callback on pointer entering window.
  *
  * The wimp has issued an event to the window because the pointer has
@@ -382,7 +406,7 @@ ro_cw_drag_start(struct ro_corewindow *ro_cw,
  */
 static void ro_cw_pointer_entering(wimp_entering *entering)
 {
-       ro_mouse_track_start(NULL, ro_cw_mouse_at, NULL);
+       ro_mouse_track_start(ro_cw_pointer_leaving, ro_cw_mouse_at, NULL);
 }
 
 
diff --git a/frontends/riscos/dialog.c b/frontends/riscos/dialog.c
index 1758221..7a0197c 100644
--- a/frontends/riscos/dialog.c
+++ b/frontends/riscos/dialog.c
@@ -44,6 +44,7 @@
 #include "riscos/configure.h"
 #include "riscos/cookies.h"
 #include "riscos/dialog.h"
+#include "riscos/local_history.h"
 #include "riscos/global_history.h"
 #include "riscos/gui.h"
 #include "riscos/hotlist.h"
@@ -176,7 +177,7 @@ void ro_gui_dialog_init(void)
                        ro_gui_dialog_zoom_apply);
        ro_gui_wimp_event_set_help_prefix(dialog_zoom, "HelpScaleView");
 
-       /* Treeview initialisation has moved to the end, to allow any
+       /* core window based initialisation done last to allow any
         * associated dialogues to be set up first.
         */
 
@@ -186,6 +187,9 @@ void ro_gui_dialog_init(void)
        /* hotlist window */
        ro_gui_hotlist_initialise();
 
+       /* local history window */
+       ro_gui_local_history_initialise();
+
        /* global history window */
        ro_gui_global_history_initialise();
 
diff --git a/frontends/riscos/gui.c b/frontends/riscos/gui.c
index d3ce31c..576e1ff 100644
--- a/frontends/riscos/gui.c
+++ b/frontends/riscos/gui.c
@@ -74,6 +74,7 @@
 #include "riscos/window.h"
 #include "riscos/iconbar.h"
 #include "riscos/sslcert.h"
+#include "riscos/local_history.h"
 #include "riscos/global_history.h"
 #include "riscos/cookies.h"
 #include "riscos/wimp_event.h"
@@ -1252,9 +1253,6 @@ static nserror gui_init(int argc, char** argv)
        /* Initialise query windows */
        ro_gui_query_init();
 
-       /* Initialise the history subsystem */
-       ro_gui_history_init();
-
        /* Initialise toolbars */
        ro_toolbar_init();
 
@@ -1560,6 +1558,7 @@ static void gui_quit(void)
        urldb_save_cookies(nsoption_charp(cookie_jar));
        urldb_save(nsoption_charp(url_save));
        ro_gui_window_quit();
+       ro_gui_local_history_finalise();
        ro_gui_global_history_finalise();
        ro_gui_hotlist_finalise();
        ro_gui_cookies_finalise();
diff --git a/frontends/riscos/gui.h b/frontends/riscos/gui.h
index 1f50700..35be4e1 100644
--- a/frontends/riscos/gui.h
+++ b/frontends/riscos/gui.h
@@ -59,7 +59,6 @@ extern wimp_w dialog_info, dialog_saveas, dialog_zoom, 
dialog_pageinfo,
 extern wimp_w current_menu_window;
 extern bool current_menu_open;
 extern wimp_menu *recent_search_menu;  /* search.c */
-extern wimp_w history_window;
 extern bool gui_redraw_debug;
 extern osspriteop_area *gui_sprites;
 extern bool dialog_folder_add, dialog_entry_add, hotlist_insert;
@@ -169,10 +168,6 @@ bool ro_gui_ctrl_pressed(void);
 bool ro_gui_alt_pressed(void);
 void gui_window_set_pointer(struct gui_window *g, enum gui_pointer_shape 
shape);
 
-/* in history.c */
-void ro_gui_history_init(void);
-void ro_gui_history_open(struct gui_window *g, bool pointer);
-
 /* in schedule.c */
 extern bool sched_active;
 extern os_t sched_time;
diff --git a/frontends/riscos/history.c b/frontends/riscos/history.c
deleted file mode 100644
index de3af08..0000000
--- a/frontends/riscos/history.c
+++ /dev/null
@@ -1,336 +0,0 @@
-/*
- * Copyright 2006 James Bursa <[email protected]>
- * Copyright 2005 Richard Wilson <[email protected]>
- *
- * This file is part of NetSurf, http://www.netsurf-browser.org/
- *
- * NetSurf is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * NetSurf is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-/** \file
- * Browser history window (RISC OS implementation).
- *
- * There is only one history window, not one per browser window.
- */
-
-#include <stdbool.h>
-#include <stdlib.h>
-#include <string.h>
-#include "oslib/wimp.h"
-
-#include "utils/nsoption.h"
-#include "utils/log.h"
-#include "desktop/browser_history.h"
-#include "netsurf/plotters.h"
-
-#include "riscos/dialog.h"
-#include "riscos/gui.h"
-#include "riscos/mouse.h"
-#include "riscos/wimp.h"
-#include "riscos/wimp_event.h"
-#include "riscos/wimputils.h"
-
-static struct browser_window *history_bw;
-/* Last position of mouse in window. */
-static int mouse_x = 0;
-/* Last position of mouse in window. */
-static int mouse_y = 0;
-wimp_w history_window;
-
-static void ro_gui_history_redraw(wimp_draw *redraw);
-static bool ro_gui_history_click(wimp_pointer *pointer);
-static void ro_gui_history_pointer_entering(wimp_entering *entering);
-static void ro_gui_history_track_end(wimp_leaving *leaving, void *data);
-static void ro_gui_history_mouse_at(wimp_pointer *pointer, void *data);
-
-
-/**
- * Create history window.
- */
-
-void ro_gui_history_init(void)
-{
-       history_window = ro_gui_dialog_create("history");
-       ro_gui_wimp_event_register_redraw_window(history_window,
-                       ro_gui_history_redraw);
-       ro_gui_wimp_event_register_mouse_click(history_window,
-                       ro_gui_history_click);
-       ro_gui_wimp_event_register_pointer_entering_window(history_window,
-                       ro_gui_history_pointer_entering);
-       ro_gui_wimp_event_set_help_prefix(history_window, "HelpHistory");
-}
-
-
-/**
- * Open history window.
- *
- * \param g The riscos window to open history for.
- * \param at_pointer open the window at the pointer.
- */
-
-void ro_gui_history_open(struct gui_window *g, bool at_pointer)
-{
-       struct browser_window *bw;
-       int width, height;
-       os_box box = {0, 0, 0, 0};
-       wimp_window_state state;
-       os_error *error;
-
-       assert(g != NULL);
-       assert(g->bw != NULL);
-       bw = g->bw;
-       history_bw = bw;
-
-       browser_window_history_size(bw, &width, &height);
-       width *= 2;
-       height *= 2;
-
-       /* set extent */
-       box.x1 = width;
-       box.y0 = -height;
-       error = xwimp_set_extent(history_window, &box);
-       if (error) {
-               LOG("xwimp_set_extent: 0x%x: %s", error->errnum, 
error->errmess);
-               ro_warn_user("WimpError", error->errmess);
-               return;
-       }
-
-       /* open full size */
-       state.w = history_window;
-       error = xwimp_get_window_state(&state);
-       if (error) {
-               LOG("xwimp_get_window_state: 0x%x: %s", error->errnum, 
error->errmess);
-               ro_warn_user("WimpError", error->errmess);
-               return;
-       }
-       state.visible.x0 = 0;
-       state.visible.y0 = 0;
-       state.visible.x1 = width;
-       state.visible.y1 = height;
-       state.next = wimp_HIDDEN;
-       error = xwimp_open_window(PTR_WIMP_OPEN(&state));
-       if (error) {
-               LOG("xwimp_open_window: 0x%x: %s", error->errnum, 
error->errmess);
-               ro_warn_user("WimpError", error->errmess);
-               return;
-       }
-
-       ro_gui_dialog_open_persistent(g->window, history_window, at_pointer);
-}
-
-
-/**
- * Redraw history window.
- */
-
-void ro_gui_history_redraw(wimp_draw *redraw)
-{
-       osbool more;
-       os_error *error;
-       struct redraw_context ctx = {
-               .interactive = true,
-               .background_images = true,
-               .plot = &ro_plotters
-       };
-
-       error = xwimp_redraw_window(redraw, &more);
-       if (error) {
-               LOG("xwimp_redraw_window: 0x%x: %s", error->errnum, 
error->errmess);
-               ro_warn_user("WimpError", error->errmess);
-               return;
-       }
-       while (more) {
-               ro_plot_origin_x = redraw->box.x0 - redraw->xscroll;
-               ro_plot_origin_y = redraw->box.y1 - redraw->yscroll;
-               browser_window_history_redraw(history_bw, &ctx);
-               error = xwimp_get_rectangle(redraw, &more);
-               if (error) {
-                       LOG("xwimp_get_rectangle: 0x%x: %s", error->errnum, 
error->errmess);
-                       ro_warn_user("WimpError", error->errmess);
-                       return;
-               }
-       }
-}
-
-
-/**
- * Handle Pointer Entering Window events the history window.
- *
- * \param *entering            The Wimp_PointerEnteringWindow block.
- */
-
-void ro_gui_history_pointer_entering(wimp_entering *entering)
-{
-       ro_mouse_track_start(ro_gui_history_track_end,
-                       ro_gui_history_mouse_at, NULL);
-} 
-
-
-/**
- * Handle Pointer Leaving Window events the history window. These arrive as the
- * termination callback handler from ro_mouse's mouse tracking.
- *
- * \param *leaving             The Wimp_PointerLeavingWindow block.
- * \param *data                        NULL data pointer.
- */
-
-void ro_gui_history_track_end(wimp_leaving *leaving, void *data)
-{
-       ro_gui_dialog_close(dialog_tooltip);
-} 
-
-
-/**
- * Handle mouse movements over the history window.
- */
-
-void ro_gui_history_mouse_at(wimp_pointer *pointer, void *data)
-{
-       int x, y;
-       int width;
-       const char *url;
-       wimp_window_state state;
-       wimp_icon_state ic;
-       os_box box = {0, 0, 0, 0};
-       os_error *error;
-       
-       LOG("Mouse at...");
-
-       /* If the mouse hasn't moved, or if we don't want tooltips, exit */
-       if ((mouse_x == pointer->pos.x && mouse_y == pointer->pos.y) ||
-           !nsoption_bool(history_tooltip))
-               return;
-
-       /* Update mouse position */
-       mouse_x = pointer->pos.x;
-       mouse_y = pointer->pos.y;
-
-       /* Find history tree entry under mouse */
-       state.w = history_window;
-       error = xwimp_get_window_state(&state);
-       if (error) {
-               LOG("xwimp_get_window_state: 0x%x: %s", error->errnum, 
error->errmess);
-               ro_warn_user("WimpError", error->errmess);
-               return;
-       }
-
-       x = (pointer->pos.x - (state.visible.x0 - state.xscroll)) / 2;
-       y = -(pointer->pos.y - (state.visible.y1 - state.yscroll)) / 2;
-       url = browser_window_history_position_url(history_bw, x, y);
-       if (!url) {
-               /* not over a tree entry => close tooltip window. */
-               error = xwimp_close_window(dialog_tooltip);
-               if (error) {
-                       LOG("xwimp_close_window: 0x%x: %s", error->errnum, 
error->errmess);
-                       ro_warn_user("WimpError", error->errmess);
-                       return;
-               }
-               return;
-       }
-
-       /* get width of string */
-       error = xwimptextop_string_width(url,
-                       strlen(url) > 256 ? 256 : strlen(url),
-                       &width);
-       if (error) {
-               LOG("xwimptextop_string_width: 0x%x: %s", error->errnum, 
error->errmess);
-               ro_warn_user("WimpError", error->errmess);
-               return;
-       }
-
-       ro_gui_set_icon_string(dialog_tooltip, 0, url, true);
-
-       /* resize icon appropriately */
-       ic.w = dialog_tooltip;
-       ic.i = 0;
-       error = xwimp_get_icon_state(&ic);
-       if (error) {
-               LOG("xwimp_get_icon_state: 0x%x: %s", error->errnum, 
error->errmess);
-               ro_warn_user("WimpError", error->errmess);
-               return;
-       }
-       error = xwimp_resize_icon(dialog_tooltip, 0,
-                       ic.icon.extent.x0, ic.icon.extent.y0,
-                       width + 16, ic.icon.extent.y1);
-       if (error) {
-               LOG("xwimp_resize_icon: 0x%x: %s", error->errnum, 
error->errmess);
-               ro_warn_user("WimpError", error->errmess);
-               return;
-       }
-
-       state.w = dialog_tooltip;
-       error = xwimp_get_window_state(&state);
-       if (error) {
-               LOG("xwimp_get_window_state: 0x%x: %s", error->errnum, 
error->errmess);
-               ro_warn_user("WimpError", error->errmess);
-               return;
-       }
-
-       /* update window extent */
-       box.x1 = width + 16;
-       box.y0 = -36;
-       error = xwimp_set_extent(dialog_tooltip, &box);
-       if (error) {
-               LOG("xwimp_set_extent: 0x%x: %s", error->errnum, 
error->errmess);
-               ro_warn_user("WimpError", error->errmess);
-               return;
-       }
-
-       /* set visible area */
-       state.visible.x0 = pointer->pos.x + 24;
-       state.visible.y0 = pointer->pos.y - 22 - 36;
-       state.visible.x1 = pointer->pos.x + 24 + width + 16;
-       state.visible.y1 = pointer->pos.y - 22;
-       state.next = wimp_TOP;
-       /* open window */
-       error = xwimp_open_window(PTR_WIMP_OPEN(&state));
-       if (error) {
-               LOG("xwimp_open_window: 0x%x: %s", error->errnum, 
error->errmess);
-               ro_warn_user("WimpError", error->errmess);
-               return;
-       }
-}
-
-
-/**
- * Handle mouse clicks in the history window.
- *
- * \return true if the event was handled, false to pass it on
- */
-
-bool ro_gui_history_click(wimp_pointer *pointer)
-{
-       int x, y;
-       wimp_window_state state;
-       os_error *error;
-
-       if (pointer->buttons != wimp_CLICK_SELECT &&
-                       pointer->buttons != wimp_CLICK_ADJUST)
-               /* return if not select or adjust click */
-               return true;
-
-       state.w = history_window;
-       error = xwimp_get_window_state(&state);
-       if (error) {
-               LOG("xwimp_get_window_state: 0x%x: %s", error->errnum, 
error->errmess);
-               ro_warn_user("WimpError", error->errmess);
-               return true;
-       }
-
-       x = (pointer->pos.x - (state.visible.x0 - state.xscroll)) / 2;
-       y = -(pointer->pos.y - (state.visible.y1 - state.yscroll)) / 2;
-       browser_window_history_click(history_bw, x, y,
-                       pointer->buttons == wimp_CLICK_ADJUST);
-
-       return true;
-}
diff --git a/frontends/riscos/local_history.c b/frontends/riscos/local_history.c
new file mode 100644
index 0000000..fae78e6
--- /dev/null
+++ b/frontends/riscos/local_history.c
@@ -0,0 +1,438 @@
+/*
+ * Copyright 2017 Vincent Sanders <[email protected]>
+ *
+ * This file is part of NetSurf, http://www.netsurf-browser.org/
+ *
+ * NetSurf is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * NetSurf is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/**
+ * \file
+ * Implementation of RISC OS local history.
+ */
+
+#include <stdint.h>
+#include <stdlib.h>
+#include <oslib/wimp.h>
+
+#include "utils/nsoption.h"
+#include "utils/messages.h"
+#include "utils/log.h"
+#include "netsurf/window.h"
+#include "netsurf/plotters.h"
+#include "netsurf/keypress.h"
+#include "desktop/local_history.h"
+
+#include "riscos/dialog.h"
+#include "riscos/gui.h"
+#include "riscos/menus.h"
+#include "riscos/save.h"
+#include "riscos/toolbar.h"
+#include "riscos/wimp.h"
+#include "riscos/wimp_event.h"
+#include "riscos/wimputils.h"
+#include "riscos/corewindow.h"
+#include "riscos/local_history.h"
+
+struct ro_local_history_window {
+       struct ro_corewindow core;
+
+       /** local history window context */
+       struct local_history_session *session;
+
+       /** tooltip previous x */
+       int x;
+       /** tooltip previous y */
+       int y;
+};
+
+/** local_history window is a singleton */
+static struct ro_local_history_window *local_history_window = NULL;
+
+/** riscos template for local_history window */
+static wimp_window *dialog_local_history_template;
+
+
+/**
+ * callback to draw on drawable area of ro local history window
+ *
+ * \param ro_cw The riscos core window structure.
+ * \param r The rectangle of the window that needs updating.
+ * \param originx The risc os plotter x origin.
+ * \param originy The risc os plotter y origin.
+ * \return NSERROR_OK on success otherwise apropriate error code
+ */
+static nserror
+ro_local_history_draw(struct ro_corewindow *ro_cw,
+                     int originx,
+                     int originy,
+                     struct rect *r)
+{
+       struct redraw_context ctx = {
+               .interactive = true,
+               .background_images = true,
+               .plot = &ro_plotters
+       };
+       struct ro_local_history_window *lhw;
+
+       lhw = (struct ro_local_history_window *)ro_cw;
+
+       ro_plot_origin_x = originx;
+       ro_plot_origin_y = originy;
+       no_font_blending = true;
+       local_history_redraw(lhw->session, r->x0, r->y0, r, &ctx);
+       no_font_blending = false;
+
+       return NSERROR_OK;
+}
+
+
+/**
+ * callback for keypress on ro coookie window
+ *
+ * \param ro_cw The ro core window structure.
+ * \param nskey The netsurf key code.
+ * \return NSERROR_OK if key processed,
+ *         NSERROR_NOT_IMPLEMENTED if key not processed
+ *         otherwise apropriate error code
+ */
+static nserror
+ro_local_history_key(struct ro_corewindow *ro_cw, uint32_t nskey)
+{
+       struct ro_local_history_window *lhw;
+
+       lhw = (struct ro_local_history_window *)ro_cw;
+
+       if (local_history_keypress(lhw->session, nskey)) {
+               return NSERROR_OK;
+       }
+       return NSERROR_NOT_IMPLEMENTED;
+}
+
+
+/**
+ * handle hover mouse movement for tooltips
+ */
+static nserror
+ro_local_history_tooltip(struct ro_local_history_window *lhw, int x, int y)
+{
+       int width;
+       const char *url;
+       wimp_window_state state;
+       wimp_icon_state ic;
+       os_box box = {0, 0, 0, 0};
+       os_error *error;
+       wimp_pointer pointer;
+       nserror res;
+
+       /* check if tooltip are required */
+       if (!nsoption_bool(history_tooltip)) {
+               return NSERROR_OK;
+       }
+
+       /* ensure pointer has moved */
+       if ((lhw->x == x) && (lhw->y == y)) {
+               return NSERROR_OK;
+       }
+
+       lhw->x = x;
+       lhw->y = y;
+
+       res = local_history_get_url(lhw->session, x, y, &url);
+       if (res != NSERROR_OK) {
+               /* not over a tree entry => close tooltip window. */
+               error = xwimp_close_window(dialog_tooltip);
+               if (error) {
+                       LOG("xwimp_close_window: 0x%x: %s",
+                           error->errnum, error->errmess);
+                       ro_warn_user("WimpError", error->errmess);
+                       return NSERROR_NOMEM;
+               }
+               return NSERROR_OK;
+       }
+
+       /* get width of string */
+       error = xwimptextop_string_width(url,
+                                        strlen(url) > 256 ? 256 : strlen(url),
+                                        &width);
+       if (error) {
+               LOG("xwimptextop_string_width: 0x%x: %s",
+                   error->errnum, error->errmess);
+               ro_warn_user("WimpError", error->errmess);
+               return NSERROR_NOMEM;
+       }
+
+       ro_gui_set_icon_string(dialog_tooltip, 0, url, true);
+
+       /* resize icon appropriately */
+       ic.w = dialog_tooltip;
+       ic.i = 0;
+       error = xwimp_get_icon_state(&ic);
+       if (error) {
+               LOG("xwimp_get_icon_state: 0x%x: %s",
+                   error->errnum, error->errmess);
+               ro_warn_user("WimpError", error->errmess);
+               return NSERROR_NOMEM;
+       }
+       error = xwimp_resize_icon(dialog_tooltip, 0,
+                                 ic.icon.extent.x0, ic.icon.extent.y0,
+                                 width + 16, ic.icon.extent.y1);
+       if (error) {
+               LOG("xwimp_resize_icon: 0x%x: %s",
+                   error->errnum, error->errmess);
+               ro_warn_user("WimpError", error->errmess);
+               return NSERROR_NOMEM;
+       }
+
+       state.w = dialog_tooltip;
+       error = xwimp_get_window_state(&state);
+       if (error) {
+               LOG("xwimp_get_window_state: 0x%x: %s",
+                   error->errnum, error->errmess);
+               ro_warn_user("WimpError", error->errmess);
+               return NSERROR_NOMEM;
+       }
+
+       /* update window extent */
+       box.x1 = width + 16;
+       box.y0 = -36;
+       error = xwimp_set_extent(dialog_tooltip, &box);
+       if (error) {
+               LOG("xwimp_set_extent: 0x%x: %s", error->errnum, 
error->errmess);
+               ro_warn_user("WimpError", error->errmess);
+               return NSERROR_NOMEM;
+       }
+
+       error = xwimp_get_pointer_info(&pointer);
+       if (error) {
+               LOG("xwimp_get_pointer_info: 0x%x: %s",
+                   error->errnum, error->errmess);
+               ro_warn_user("WimpError", error->errmess);
+               return NSERROR_NOMEM;
+       }
+
+       /* set visible area */
+       state.visible.x0 = pointer.pos.x + 24;
+       state.visible.y0 = pointer.pos.y - 22 - 36;
+       state.visible.x1 = pointer.pos.x + 24 + width + 16;
+       state.visible.y1 = pointer.pos.y - 22;
+       state.next = wimp_TOP;
+       /* open window */
+       error = xwimp_open_window(PTR_WIMP_OPEN(&state));
+       if (error) {
+               LOG("xwimp_open_window: 0x%x: %s",
+                   error->errnum, error->errmess);
+               ro_warn_user("WimpError", error->errmess);
+               return NSERROR_NOMEM;
+       }
+       return NSERROR_OK;
+}
+
+
+/**
+ * callback for mouse event on ro local_history window
+ *
+ * \param ro_cw The ro core window structure.
+ * \param mouse_state mouse state
+ * \param x location of event
+ * \param y location of event
+ * \return NSERROR_OK on sucess otherwise apropriate error code.
+ */
+static nserror
+ro_local_history_mouse(struct ro_corewindow *ro_cw,
+                      browser_mouse_state mouse_state,
+                      int x, int y)
+{
+       struct ro_local_history_window *lhw;
+
+       lhw = (struct ro_local_history_window *)ro_cw;
+
+       switch (mouse_state) {
+
+       case BROWSER_MOUSE_HOVER:
+               ro_local_history_tooltip(lhw, x, y);
+               break;
+
+       case BROWSER_MOUSE_LEAVE:
+               ro_gui_dialog_close(dialog_tooltip);
+               break;
+
+       default:
+               local_history_mouse_action(lhw->session, mouse_state, x, y);
+               break;
+       }
+
+       return NSERROR_OK;
+}
+
+
+/**
+ * Creates the window for the local_history tree.
+ *
+ * \return NSERROR_OK on success else appropriate error code on faliure.
+ */
+static nserror
+ro_local_history_init(struct browser_window *bw,
+                     struct ro_local_history_window **win_out)
+{
+       struct ro_local_history_window *ncwin;
+       nserror res;
+
+       /* memoise window so it can be represented when necessary
+        * instead of recreating every time.
+        */
+       if ((*win_out) != NULL) {
+               res = local_history_set((*win_out)->session, bw);
+               return res;
+       }
+
+       ncwin = malloc(sizeof(struct ro_local_history_window));
+       if (ncwin == NULL) {
+               return NSERROR_NOMEM;
+       }
+
+       /* create window from template */
+       ncwin->core.wh = wimp_create_window(dialog_local_history_template);
+
+       /* initialise callbacks */
+       ncwin->core.draw = ro_local_history_draw;
+       ncwin->core.key = ro_local_history_key;
+       ncwin->core.mouse = ro_local_history_mouse;
+
+       /* initialise core window */
+       res = ro_corewindow_init(&ncwin->core,
+                                NULL,
+                                NULL,
+                                0,
+                                NULL);
+       if (res != NSERROR_OK) {
+               free(ncwin);
+               return res;
+       }
+
+       res = local_history_init(ncwin->core.cb_table,
+                                (struct core_window *)ncwin,
+                                bw,
+                                &ncwin->session);
+       if (res != NSERROR_OK) {
+               free(ncwin);
+               return res;
+       }
+
+       *win_out = ncwin;
+
+       return NSERROR_OK;
+}
+
+
+/**
+ * open RISC OS local history window at the correct size
+ */
+static nserror
+ro_local_history_open(struct ro_local_history_window *lhw, wimp_w parent)
+{
+       nserror res;
+       int width, height;
+       os_box box = {0, 0, 0, 0};
+       wimp_window_state state;
+       os_error *error;
+
+       res = local_history_get_size(lhw->session, &width, &height);
+       if (res != NSERROR_OK) {
+               return res;
+       }
+
+       width *= 2;
+       height *= 2;
+
+       /* set extent */
+       box.x1 = width;
+       box.y0 = -height;
+       error = xwimp_set_extent(lhw->core.wh, &box);
+       if (error) {
+               LOG("xwimp_set_extent: 0x%x: %s",
+                   error->errnum, error->errmess);
+               ro_warn_user("WimpError", error->errmess);
+               return NSERROR_NOMEM;
+       }
+
+       /* open full size */
+       state.w = lhw->core.wh;
+       error = xwimp_get_window_state(&state);
+       if (error) {
+               LOG("xwimp_get_window_state: 0x%x: %s",
+                   error->errnum, error->errmess);
+               ro_warn_user("WimpError", error->errmess);
+               return NSERROR_NOMEM;
+       }
+       state.visible.x0 = 0;
+       state.visible.y0 = 0;
+       state.visible.x1 = width;
+       state.visible.y1 = height;
+       state.next = wimp_HIDDEN;
+       error = xwimp_open_window(PTR_WIMP_OPEN(&state));
+       if (error) {
+               LOG("xwimp_open_window: 0x%x: %s",
+                   error->errnum, error->errmess);
+               ro_warn_user("WimpError", error->errmess);
+               return NSERROR_NOMEM;
+       }
+
+       ro_gui_dialog_open_persistent(parent, lhw->core.wh, true);
+
+       return NSERROR_OK;
+}
+
+/* exported interface documented in riscos/local_history.h */
+nserror ro_gui_local_history_present(wimp_w parent, struct browser_window *bw)
+{
+       nserror res;
+
+       res = ro_local_history_init(bw, &local_history_window);
+       if (res == NSERROR_OK) {
+               LOG("Presenting");
+               res = ro_local_history_open(local_history_window, parent);
+       } else {
+               LOG("Failed presenting error code %d", res);
+       }
+
+       return res;
+}
+
+
+/* exported interface documented in riscos/local_history.h */
+void ro_gui_local_history_initialise(void)
+{
+       dialog_local_history_template = ro_gui_dialog_load_template("history");
+}
+
+
+/* exported interface documented in riscos/local_history.h */
+nserror ro_gui_local_history_finalise(void)
+{
+       nserror res;
+
+       if (local_history_window == NULL) {
+               return NSERROR_OK;
+       }
+
+       res = local_history_fini(local_history_window->session);
+       if (res == NSERROR_OK) {
+               res = ro_corewindow_fini(&local_history_window->core);
+
+               free(local_history_window);
+               local_history_window = NULL;
+       }
+
+       return res;
+}
diff --git a/frontends/riscos/local_history.h b/frontends/riscos/local_history.h
new file mode 100644
index 0000000..d5b22b4
--- /dev/null
+++ b/frontends/riscos/local_history.h
@@ -0,0 +1,46 @@
+/*
+ * Copyright 2017 Vincent Sanders <[email protected]>
+ *
+ * This file is part of NetSurf, http://www.netsurf-browser.org/
+ *
+ * NetSurf is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * NetSurf is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/**
+ * \file
+ * RISC OS local history interface.
+ */
+
+#ifndef RISCOS_LOCALHISTORY_H
+#define RISCOS_LOCALHISTORY_H
+
+/**
+ * initialise the local history window template ready for subsequent use.
+ */
+void ro_gui_local_history_initialise(void);
+
+/**
+ * make the local history window visible.
+ *
+ * \return NSERROR_OK on success else appropriate error code on faliure.
+ */
+nserror ro_gui_local_history_present(wimp_w parent, struct browser_window *bw);
+
+/**
+ * Free any resources allocated for the local history window.
+ *
+ * \return NSERROR_OK on success else appropriate error code on faliure.
+ */
+nserror ro_gui_local_history_finalise(void);
+
+#endif
diff --git a/frontends/riscos/window.c b/frontends/riscos/window.c
index 3496d4b..de0fcab 100644
--- a/frontends/riscos/window.c
+++ b/frontends/riscos/window.c
@@ -69,6 +69,7 @@
 #include "riscos/buffer.h"
 #include "riscos/cookies.h"
 #include "riscos/dialog.h"
+#include "riscos/local_history.h"
 #include "riscos/global_history.h"
 #include "riscos/gui.h"
 #include "riscos/gui/status_bar.h"
@@ -3947,13 +3948,22 @@ void ro_gui_window_action_new_window(struct gui_window 
*g)
 /**
  * Open a local history pane for a browser window.
  *
- * \param *g                   The browser window to act on.
+ * \param g The browser window to act on.
  */
 
-void ro_gui_window_action_local_history(struct gui_window *g)
+void ro_gui_window_action_local_history(struct gui_window *gw)
 {
-       if (g != NULL && g->bw != NULL)
-               ro_gui_history_open(g, true);
+       nserror res;
+
+       if ((gw == NULL) || (gw->bw == NULL)) {
+               return;
+       }
+
+       res = ro_gui_local_history_present(gw->window, gw->bw);
+
+       if (res != NSERROR_OK) {
+               ro_warn_user(messages_get_errorcode(res), 0);
+       }
 }
 
 
diff --git a/include/netsurf/mouse.h b/include/netsurf/mouse.h
index 1b16998..999f5a5 100644
--- a/include/netsurf/mouse.h
+++ b/include/netsurf/mouse.h
@@ -79,7 +79,10 @@ typedef enum browser_mouse_state {
        /** 2nd modifier key pressed (eg. Ctrl) */
        BROWSER_MOUSE_MOD_2 = (1 << 12),
        /** 3rd modifier key pressed (eg. Alt) */
-       BROWSER_MOUSE_MOD_3 = (1 << 13)
+       BROWSER_MOUSE_MOD_3 = (1 << 13),
+
+       /** pointer leaving window */
+       BROWSER_MOUSE_LEAVE = (1 << 14),
 } browser_mouse_state;
 
 


commitdiff 
http://git.netsurf-browser.org/netsurf.git/commit/?id=f1fdd93ffda5181f325905c8509a2bea9d78eb41
commit f1fdd93ffda5181f325905c8509a2bea9d78eb41
Author: Vincent Sanders <[email protected]>
Commit: Vincent Sanders <[email protected]>

    Add local history get url API

diff --git a/desktop/local_history.c b/desktop/local_history.c
index 06f3002..6d07c8a 100644
--- a/desktop/local_history.c
+++ b/desktop/local_history.c
@@ -91,7 +91,10 @@ local_history_mouse_action(struct local_history_session 
*session,
 {
        if (mouse & BROWSER_MOUSE_PRESS_1) {
                browser_window_history_click(session->bw, x, y, false);
+       } else  if (mouse & BROWSER_MOUSE_PRESS_2) {
+               browser_window_history_click(session->bw, x, y, true);
        }
+
 }
 
 /* exported interface documented in desktop/local_history.h */
@@ -134,3 +137,21 @@ local_history_get_size(struct local_history_session 
*session,
 
        return NSERROR_OK;
 }
+
+
+/* exported interface documented in desktop/local_history.h */
+nserror
+local_history_get_url(struct local_history_session *session,
+                     int x, int y,
+                     const char **url_out)
+{
+       const char *url;
+       url = browser_window_history_position_url(session->bw, x, y);
+       if (url == NULL) {
+               return NSERROR_NOT_FOUND;
+       }
+
+       *url_out = url;
+
+       return NSERROR_OK;
+}
diff --git a/desktop/local_history.h b/desktop/local_history.h
index 5425e70..2ce2a5c 100644
--- a/desktop/local_history.h
+++ b/desktop/local_history.h
@@ -33,9 +33,9 @@ struct local_history_session;
 struct browser_window;
 
 /**
- * Initialise the global history.
+ * Initialise the local history.
  *
- * This iterates through the URL database, generating the global history data,
+ * This iterates through the URL database, generating the local history data,
  * and creates a treeview.
  *
  * This must be called before any other local_history_* function.
@@ -52,10 +52,10 @@ nserror local_history_init(struct 
core_window_callback_table *cw_t,
                           struct local_history_session **session);
 
 /**
- * Finalise the global history.
+ * Finalise the local history.
  *
- * This destroys the global history treeview and the global history module's
- * internal data.  After calling this if global history is required again,
+ * This destroys the local history treeview and the local history module's
+ * internal data.  After calling this if ocall history is required again,
  * local_history_init must be called.
  *
  * \param session The local history session to finalise.
@@ -65,7 +65,7 @@ nserror local_history_fini(struct local_history_session 
*session);
 
 
 /**
- * Redraw the global history.
+ * Redraw the local history.
  *
  * \param session The local history session context.
  * \param x     X coordinate to render history at
@@ -104,13 +104,27 @@ bool local_history_keypress(struct local_history_session 
*session, uint32_t key)
 nserror local_history_set(struct local_history_session *session, struct 
browser_window *bw);
 
 /**
- * get size of local history content area
+ * get size of local history content area.
  *
- * \param session The local history session context.
+ * \param[in] session The local history session context.
  * \param[out] width on sucessful return the width of the localhistory content
  * \param[out] height on sucessful return the height of the localhistory 
content
  * \return NSERROR_OK or appropriate error code.
  */
 nserror local_history_get_size(struct local_history_session *session, int 
*width, int *height);
 
+/**
+ * get url of entry at position in local history content area.
+ *
+ * \todo the returned url should be a referenced nsurl.
+ *
+ * \param[in] session The local history session context.
+ * \param[in] x The x coordinate to get url of.
+ * \param[in] y The y coordinate to get url of.
+ * \param[out] url_out string representation of the url at the coordinates.
+ * \return NSERROR_OK and url_out updated or NSERROR_NOT_FOUND if no url at
+ *          location.
+ */
+nserror local_history_get_url(struct local_history_session *session, int x, 
int y, const char **url_out);
+
 #endif


commitdiff 
http://git.netsurf-browser.org/netsurf.git/commit/?id=6736ab9b724702c82b4aebc61c3d51c48d9c958c
commit 6736ab9b724702c82b4aebc61c3d51c48d9c958c
Author: Vincent Sanders <[email protected]>
Commit: Vincent Sanders <[email protected]>

    fix risc os dialog opening relative to parent

diff --git a/frontends/riscos/dialog.c b/frontends/riscos/dialog.c
index 18df1bf..1758221 100644
--- a/frontends/riscos/dialog.c
+++ b/frontends/riscos/dialog.c
@@ -510,7 +510,8 @@ void ro_gui_dialog_open_xy(wimp_w w, int x, int y)
  * /param parent the parent window (NULL for centre of screen)
  * /param child the child window
  */
-void ro_gui_dialog_open_centre_parent(wimp_w parent, wimp_w child) {
+static void ro_gui_dialog_open_centre_parent(wimp_w parent, wimp_w child)
+{
        os_error *error;
        wimp_window_state state;
        int mid_x, mid_y;
@@ -545,7 +546,7 @@ void ro_gui_dialog_open_centre_parent(wimp_w parent, wimp_w 
child) {
 
        /* move to the centre of the parent at the top of the stack */
        dimension = state.visible.x1 - state.visible.x0;
-       scroll_width = ro_get_vscroll_width(history_window);
+       scroll_width = ro_get_vscroll_width(parent);
        state.visible.x0 = mid_x - (dimension + scroll_width) / 2;
        state.visible.x1 = state.visible.x0 + dimension;
        dimension = state.visible.y1 - state.visible.y0;
@@ -567,10 +568,11 @@ void ro_gui_dialog_open_centre_parent(wimp_w parent, 
wimp_w child) {
 
 void ro_gui_dialog_open_persistent(wimp_w parent, wimp_w w, bool pointer) {
 
-       if (pointer)
+       if (pointer) {
                ro_gui_dialog_open_at_pointer(w);
-       else
+       } else {
                ro_gui_dialog_open_centre_parent(parent, w);
+       }
 
        /* todo: use wimp_event definitions rather than special cases */
        if ((w == dialog_pageinfo) || (w == dialog_objinfo))
diff --git a/frontends/riscos/dialog.h b/frontends/riscos/dialog.h
index 4630484..2ec86c3 100644
--- a/frontends/riscos/dialog.h
+++ b/frontends/riscos/dialog.h
@@ -33,7 +33,6 @@ bool ro_gui_dialog_open_top(wimp_w w, struct toolbar *toolbar,
                int width, int height);
 void ro_gui_dialog_open_at_pointer(wimp_w w);
 void ro_gui_dialog_open_xy(wimp_w, int x, int y);
-void ro_gui_dialog_open_centre_parent(wimp_w parent, wimp_w w);
 
 void ro_gui_dialog_open_persistent(wimp_w parent, wimp_w w, bool pointer);
 void ro_gui_dialog_add_persistent(wimp_w parent, wimp_w w);


-----------------------------------------------------------------------

Summary of changes:
 desktop/local_history.c                   |   21 ++
 desktop/local_history.h                   |   30 +-
 frontends/riscos/Makefile                 |    5 +-
 frontends/riscos/corewindow.c             |   50 +++-
 frontends/riscos/dialog.c                 |   16 +-
 frontends/riscos/dialog.h                 |    1 -
 frontends/riscos/gui.c                    |    5 +-
 frontends/riscos/gui.h                    |    5 -
 frontends/riscos/history.c                |  336 ----------------------
 frontends/riscos/local_history.c          |  438 +++++++++++++++++++++++++++++
 frontends/{gtk => riscos}/local_history.h |   25 +-
 frontends/riscos/window.c                 |   18 +-
 include/netsurf/mouse.h                   |    5 +-
 13 files changed, 563 insertions(+), 392 deletions(-)
 delete mode 100644 frontends/riscos/history.c
 create mode 100644 frontends/riscos/local_history.c
 copy frontends/{gtk => riscos}/local_history.h (65%)

diff --git a/desktop/local_history.c b/desktop/local_history.c
index 06f3002..6d07c8a 100644
--- a/desktop/local_history.c
+++ b/desktop/local_history.c
@@ -91,7 +91,10 @@ local_history_mouse_action(struct local_history_session 
*session,
 {
        if (mouse & BROWSER_MOUSE_PRESS_1) {
                browser_window_history_click(session->bw, x, y, false);
+       } else  if (mouse & BROWSER_MOUSE_PRESS_2) {
+               browser_window_history_click(session->bw, x, y, true);
        }
+
 }
 
 /* exported interface documented in desktop/local_history.h */
@@ -134,3 +137,21 @@ local_history_get_size(struct local_history_session 
*session,
 
        return NSERROR_OK;
 }
+
+
+/* exported interface documented in desktop/local_history.h */
+nserror
+local_history_get_url(struct local_history_session *session,
+                     int x, int y,
+                     const char **url_out)
+{
+       const char *url;
+       url = browser_window_history_position_url(session->bw, x, y);
+       if (url == NULL) {
+               return NSERROR_NOT_FOUND;
+       }
+
+       *url_out = url;
+
+       return NSERROR_OK;
+}
diff --git a/desktop/local_history.h b/desktop/local_history.h
index 5425e70..2ce2a5c 100644
--- a/desktop/local_history.h
+++ b/desktop/local_history.h
@@ -33,9 +33,9 @@ struct local_history_session;
 struct browser_window;
 
 /**
- * Initialise the global history.
+ * Initialise the local history.
  *
- * This iterates through the URL database, generating the global history data,
+ * This iterates through the URL database, generating the local history data,
  * and creates a treeview.
  *
  * This must be called before any other local_history_* function.
@@ -52,10 +52,10 @@ nserror local_history_init(struct 
core_window_callback_table *cw_t,
                           struct local_history_session **session);
 
 /**
- * Finalise the global history.
+ * Finalise the local history.
  *
- * This destroys the global history treeview and the global history module's
- * internal data.  After calling this if global history is required again,
+ * This destroys the local history treeview and the local history module's
+ * internal data.  After calling this if ocall history is required again,
  * local_history_init must be called.
  *
  * \param session The local history session to finalise.
@@ -65,7 +65,7 @@ nserror local_history_fini(struct local_history_session 
*session);
 
 
 /**
- * Redraw the global history.
+ * Redraw the local history.
  *
  * \param session The local history session context.
  * \param x     X coordinate to render history at
@@ -104,13 +104,27 @@ bool local_history_keypress(struct local_history_session 
*session, uint32_t key)
 nserror local_history_set(struct local_history_session *session, struct 
browser_window *bw);
 
 /**
- * get size of local history content area
+ * get size of local history content area.
  *
- * \param session The local history session context.
+ * \param[in] session The local history session context.
  * \param[out] width on sucessful return the width of the localhistory content
  * \param[out] height on sucessful return the height of the localhistory 
content
  * \return NSERROR_OK or appropriate error code.
  */
 nserror local_history_get_size(struct local_history_session *session, int 
*width, int *height);
 
+/**
+ * get url of entry at position in local history content area.
+ *
+ * \todo the returned url should be a referenced nsurl.
+ *
+ * \param[in] session The local history session context.
+ * \param[in] x The x coordinate to get url of.
+ * \param[in] y The y coordinate to get url of.
+ * \param[out] url_out string representation of the url at the coordinates.
+ * \return NSERROR_OK and url_out updated or NSERROR_NOT_FOUND if no url at
+ *          location.
+ */
+nserror local_history_get_url(struct local_history_session *session, int x, 
int y, const char **url_out);
+
 #endif
diff --git a/frontends/riscos/Makefile b/frontends/riscos/Makefile
index 87790ac..84a1c93 100644
--- a/frontends/riscos/Makefile
+++ b/frontends/riscos/Makefile
@@ -47,13 +47,14 @@ endif
 
 # S_RISCOS are sources purely for the RISC OS build
 S_FRONTEND := 401login.c assert.c bitmap.c buffer.c configure.c gui.c  \
-       dialog.c download.c filetype.c font.c help.c history.c image.c  \
+       dialog.c download.c filetype.c font.c help.c image.c    \
        iconbar.c menus.c message.c mouse.c palettes.c plotters.c       \
        print.c query.c save.c save_draw.c save_pdf.c schedule.c        \
        search.c searchweb.c textarea.c textselection.c theme.c         \
        theme_install.c toolbar.c url_suggest.c wimp.c wimp_event.c     \
        ucstables.c uri.c url_complete.c url_protocol.c window.c        \
-       corewindow.c cookies.c sslcert.c global_history.c hotlist.c     \
+       corewindow.c cookies.c sslcert.c hotlist.c                      \
+       local_history.c global_history.c                                \
        $(addprefix content-handlers/,artworks.c awrender.s draw.c      \
        sprite.c)                                                       \
        $(addprefix gui/,button_bar.c progress_bar.c status_bar.c       \
diff --git a/frontends/riscos/corewindow.c b/frontends/riscos/corewindow.c
index b57e4e0..a885977 100644
--- a/frontends/riscos/corewindow.c
+++ b/frontends/riscos/corewindow.c
@@ -236,12 +236,7 @@ static void ro_cw_mouse_at(wimp_pointer *pointer, void 
*data)
        }
        LOG("RO corewindow context %p", ro_cw);
 
-       /* no futher processing required if no drag in progress */
-       if (ro_cw->drag_status == CORE_WINDOW_DRAG_NONE) {
-               return;
-       }
-
-       /* Not a Menu click and a drag is in progress. */
+       /* Not a Menu click. */
        state.w = pointer->w;
        error = xwimp_get_window_state(&state);
        if (error) {
@@ -250,18 +245,23 @@ static void ro_cw_mouse_at(wimp_pointer *pointer, void 
*data)
                return;
        }
 
-       /* Convert the returned mouse coordinates into NetSurf's internal
-        * units.
+       /* Convert the returned mouse coordinates into
+        * NetSurf's internal units.
         */
        xpos = ((pointer->pos.x - state.visible.x0) + state.xscroll) / 2;
        ypos = ((state.visible.y1 - pointer->pos.y) -
                state.yscroll + ro_cw->origin_y) / 2;
 
-       /* Start to process the mouse click. */
-       mouse = ro_gui_mouse_drag_state(pointer->buttons,
-                                       wimp_BUTTON_DOUBLE_CLICK_DRAG);
+       /* if no drag in progress report hover */
+       if (ro_cw->drag_status == CORE_WINDOW_DRAG_NONE) {
+               mouse = BROWSER_MOUSE_HOVER;
+       } else {
+               /* Start to process the mouse click. */
+               mouse = ro_gui_mouse_drag_state(pointer->buttons,
+                                               wimp_BUTTON_DOUBLE_CLICK_DRAG);
 
-       ro_cw->mouse(ro_cw, mouse, xpos, ypos);
+               ro_cw->mouse(ro_cw, mouse, xpos, ypos);
+       }
 
        if (!(mouse & BROWSER_MOUSE_DRAG_ON)) {
                ro_cw->mouse(ro_cw, BROWSER_MOUSE_HOVER, xpos, ypos);
@@ -373,6 +373,30 @@ ro_cw_drag_start(struct ro_corewindow *ro_cw,
 
 
 /**
+ * Handle Pointer Leaving Window events.
+ *
+ * These events are delivered as the termination callback handler from
+ * ro_mouse's mouse tracking.
+ *
+ * \param leaving The Wimp_PointerLeavingWindow block.
+ * \param data NULL data pointer.
+ */
+static void ro_cw_pointer_leaving(wimp_leaving *leaving, void *data)
+{
+       struct ro_corewindow *ro_cw;
+
+       ro_cw = (struct ro_corewindow 
*)ro_gui_wimp_event_get_user_data(leaving->w);
+       if (ro_cw == NULL) {
+               LOG("no corewindow conext for window: 0x%x",
+                   (unsigned int)leaving->w);
+               return;
+       }
+
+       ro_cw->mouse(ro_cw, BROWSER_MOUSE_LEAVE, 0, 0);
+}
+
+
+/**
  * Wimp callback on pointer entering window.
  *
  * The wimp has issued an event to the window because the pointer has
@@ -382,7 +406,7 @@ ro_cw_drag_start(struct ro_corewindow *ro_cw,
  */
 static void ro_cw_pointer_entering(wimp_entering *entering)
 {
-       ro_mouse_track_start(NULL, ro_cw_mouse_at, NULL);
+       ro_mouse_track_start(ro_cw_pointer_leaving, ro_cw_mouse_at, NULL);
 }
 
 
diff --git a/frontends/riscos/dialog.c b/frontends/riscos/dialog.c
index 18df1bf..7a0197c 100644
--- a/frontends/riscos/dialog.c
+++ b/frontends/riscos/dialog.c
@@ -44,6 +44,7 @@
 #include "riscos/configure.h"
 #include "riscos/cookies.h"
 #include "riscos/dialog.h"
+#include "riscos/local_history.h"
 #include "riscos/global_history.h"
 #include "riscos/gui.h"
 #include "riscos/hotlist.h"
@@ -176,7 +177,7 @@ void ro_gui_dialog_init(void)
                        ro_gui_dialog_zoom_apply);
        ro_gui_wimp_event_set_help_prefix(dialog_zoom, "HelpScaleView");
 
-       /* Treeview initialisation has moved to the end, to allow any
+       /* core window based initialisation done last to allow any
         * associated dialogues to be set up first.
         */
 
@@ -186,6 +187,9 @@ void ro_gui_dialog_init(void)
        /* hotlist window */
        ro_gui_hotlist_initialise();
 
+       /* local history window */
+       ro_gui_local_history_initialise();
+
        /* global history window */
        ro_gui_global_history_initialise();
 
@@ -510,7 +514,8 @@ void ro_gui_dialog_open_xy(wimp_w w, int x, int y)
  * /param parent the parent window (NULL for centre of screen)
  * /param child the child window
  */
-void ro_gui_dialog_open_centre_parent(wimp_w parent, wimp_w child) {
+static void ro_gui_dialog_open_centre_parent(wimp_w parent, wimp_w child)
+{
        os_error *error;
        wimp_window_state state;
        int mid_x, mid_y;
@@ -545,7 +550,7 @@ void ro_gui_dialog_open_centre_parent(wimp_w parent, wimp_w 
child) {
 
        /* move to the centre of the parent at the top of the stack */
        dimension = state.visible.x1 - state.visible.x0;
-       scroll_width = ro_get_vscroll_width(history_window);
+       scroll_width = ro_get_vscroll_width(parent);
        state.visible.x0 = mid_x - (dimension + scroll_width) / 2;
        state.visible.x1 = state.visible.x0 + dimension;
        dimension = state.visible.y1 - state.visible.y0;
@@ -567,10 +572,11 @@ void ro_gui_dialog_open_centre_parent(wimp_w parent, 
wimp_w child) {
 
 void ro_gui_dialog_open_persistent(wimp_w parent, wimp_w w, bool pointer) {
 
-       if (pointer)
+       if (pointer) {
                ro_gui_dialog_open_at_pointer(w);
-       else
+       } else {
                ro_gui_dialog_open_centre_parent(parent, w);
+       }
 
        /* todo: use wimp_event definitions rather than special cases */
        if ((w == dialog_pageinfo) || (w == dialog_objinfo))
diff --git a/frontends/riscos/dialog.h b/frontends/riscos/dialog.h
index 4630484..2ec86c3 100644
--- a/frontends/riscos/dialog.h
+++ b/frontends/riscos/dialog.h
@@ -33,7 +33,6 @@ bool ro_gui_dialog_open_top(wimp_w w, struct toolbar *toolbar,
                int width, int height);
 void ro_gui_dialog_open_at_pointer(wimp_w w);
 void ro_gui_dialog_open_xy(wimp_w, int x, int y);
-void ro_gui_dialog_open_centre_parent(wimp_w parent, wimp_w w);
 
 void ro_gui_dialog_open_persistent(wimp_w parent, wimp_w w, bool pointer);
 void ro_gui_dialog_add_persistent(wimp_w parent, wimp_w w);
diff --git a/frontends/riscos/gui.c b/frontends/riscos/gui.c
index d3ce31c..576e1ff 100644
--- a/frontends/riscos/gui.c
+++ b/frontends/riscos/gui.c
@@ -74,6 +74,7 @@
 #include "riscos/window.h"
 #include "riscos/iconbar.h"
 #include "riscos/sslcert.h"
+#include "riscos/local_history.h"
 #include "riscos/global_history.h"
 #include "riscos/cookies.h"
 #include "riscos/wimp_event.h"
@@ -1252,9 +1253,6 @@ static nserror gui_init(int argc, char** argv)
        /* Initialise query windows */
        ro_gui_query_init();
 
-       /* Initialise the history subsystem */
-       ro_gui_history_init();
-
        /* Initialise toolbars */
        ro_toolbar_init();
 
@@ -1560,6 +1558,7 @@ static void gui_quit(void)
        urldb_save_cookies(nsoption_charp(cookie_jar));
        urldb_save(nsoption_charp(url_save));
        ro_gui_window_quit();
+       ro_gui_local_history_finalise();
        ro_gui_global_history_finalise();
        ro_gui_hotlist_finalise();
        ro_gui_cookies_finalise();
diff --git a/frontends/riscos/gui.h b/frontends/riscos/gui.h
index 1f50700..35be4e1 100644
--- a/frontends/riscos/gui.h
+++ b/frontends/riscos/gui.h
@@ -59,7 +59,6 @@ extern wimp_w dialog_info, dialog_saveas, dialog_zoom, 
dialog_pageinfo,
 extern wimp_w current_menu_window;
 extern bool current_menu_open;
 extern wimp_menu *recent_search_menu;  /* search.c */
-extern wimp_w history_window;
 extern bool gui_redraw_debug;
 extern osspriteop_area *gui_sprites;
 extern bool dialog_folder_add, dialog_entry_add, hotlist_insert;
@@ -169,10 +168,6 @@ bool ro_gui_ctrl_pressed(void);
 bool ro_gui_alt_pressed(void);
 void gui_window_set_pointer(struct gui_window *g, enum gui_pointer_shape 
shape);
 
-/* in history.c */
-void ro_gui_history_init(void);
-void ro_gui_history_open(struct gui_window *g, bool pointer);
-
 /* in schedule.c */
 extern bool sched_active;
 extern os_t sched_time;
diff --git a/frontends/riscos/history.c b/frontends/riscos/history.c
deleted file mode 100644
index de3af08..0000000
--- a/frontends/riscos/history.c
+++ /dev/null
@@ -1,336 +0,0 @@
-/*
- * Copyright 2006 James Bursa <[email protected]>
- * Copyright 2005 Richard Wilson <[email protected]>
- *
- * This file is part of NetSurf, http://www.netsurf-browser.org/
- *
- * NetSurf is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * NetSurf is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-/** \file
- * Browser history window (RISC OS implementation).
- *
- * There is only one history window, not one per browser window.
- */
-
-#include <stdbool.h>
-#include <stdlib.h>
-#include <string.h>
-#include "oslib/wimp.h"
-
-#include "utils/nsoption.h"
-#include "utils/log.h"
-#include "desktop/browser_history.h"
-#include "netsurf/plotters.h"
-
-#include "riscos/dialog.h"
-#include "riscos/gui.h"
-#include "riscos/mouse.h"
-#include "riscos/wimp.h"
-#include "riscos/wimp_event.h"
-#include "riscos/wimputils.h"
-
-static struct browser_window *history_bw;
-/* Last position of mouse in window. */
-static int mouse_x = 0;
-/* Last position of mouse in window. */
-static int mouse_y = 0;
-wimp_w history_window;
-
-static void ro_gui_history_redraw(wimp_draw *redraw);
-static bool ro_gui_history_click(wimp_pointer *pointer);
-static void ro_gui_history_pointer_entering(wimp_entering *entering);
-static void ro_gui_history_track_end(wimp_leaving *leaving, void *data);
-static void ro_gui_history_mouse_at(wimp_pointer *pointer, void *data);
-
-
-/**
- * Create history window.
- */
-
-void ro_gui_history_init(void)
-{
-       history_window = ro_gui_dialog_create("history");
-       ro_gui_wimp_event_register_redraw_window(history_window,
-                       ro_gui_history_redraw);
-       ro_gui_wimp_event_register_mouse_click(history_window,
-                       ro_gui_history_click);
-       ro_gui_wimp_event_register_pointer_entering_window(history_window,
-                       ro_gui_history_pointer_entering);
-       ro_gui_wimp_event_set_help_prefix(history_window, "HelpHistory");
-}
-
-
-/**
- * Open history window.
- *
- * \param g The riscos window to open history for.
- * \param at_pointer open the window at the pointer.
- */
-
-void ro_gui_history_open(struct gui_window *g, bool at_pointer)
-{
-       struct browser_window *bw;
-       int width, height;
-       os_box box = {0, 0, 0, 0};
-       wimp_window_state state;
-       os_error *error;
-
-       assert(g != NULL);
-       assert(g->bw != NULL);
-       bw = g->bw;
-       history_bw = bw;
-
-       browser_window_history_size(bw, &width, &height);
-       width *= 2;
-       height *= 2;
-
-       /* set extent */
-       box.x1 = width;
-       box.y0 = -height;
-       error = xwimp_set_extent(history_window, &box);
-       if (error) {
-               LOG("xwimp_set_extent: 0x%x: %s", error->errnum, 
error->errmess);
-               ro_warn_user("WimpError", error->errmess);
-               return;
-       }
-
-       /* open full size */
-       state.w = history_window;
-       error = xwimp_get_window_state(&state);
-       if (error) {
-               LOG("xwimp_get_window_state: 0x%x: %s", error->errnum, 
error->errmess);
-               ro_warn_user("WimpError", error->errmess);
-               return;
-       }
-       state.visible.x0 = 0;
-       state.visible.y0 = 0;
-       state.visible.x1 = width;
-       state.visible.y1 = height;
-       state.next = wimp_HIDDEN;
-       error = xwimp_open_window(PTR_WIMP_OPEN(&state));
-       if (error) {
-               LOG("xwimp_open_window: 0x%x: %s", error->errnum, 
error->errmess);
-               ro_warn_user("WimpError", error->errmess);
-               return;
-       }
-
-       ro_gui_dialog_open_persistent(g->window, history_window, at_pointer);
-}
-
-
-/**
- * Redraw history window.
- */
-
-void ro_gui_history_redraw(wimp_draw *redraw)
-{
-       osbool more;
-       os_error *error;
-       struct redraw_context ctx = {
-               .interactive = true,
-               .background_images = true,
-               .plot = &ro_plotters
-       };
-
-       error = xwimp_redraw_window(redraw, &more);
-       if (error) {
-               LOG("xwimp_redraw_window: 0x%x: %s", error->errnum, 
error->errmess);
-               ro_warn_user("WimpError", error->errmess);
-               return;
-       }
-       while (more) {
-               ro_plot_origin_x = redraw->box.x0 - redraw->xscroll;
-               ro_plot_origin_y = redraw->box.y1 - redraw->yscroll;
-               browser_window_history_redraw(history_bw, &ctx);
-               error = xwimp_get_rectangle(redraw, &more);
-               if (error) {
-                       LOG("xwimp_get_rectangle: 0x%x: %s", error->errnum, 
error->errmess);
-                       ro_warn_user("WimpError", error->errmess);
-                       return;
-               }
-       }
-}
-
-
-/**
- * Handle Pointer Entering Window events the history window.
- *
- * \param *entering            The Wimp_PointerEnteringWindow block.
- */
-
-void ro_gui_history_pointer_entering(wimp_entering *entering)
-{
-       ro_mouse_track_start(ro_gui_history_track_end,
-                       ro_gui_history_mouse_at, NULL);
-} 
-
-
-/**
- * Handle Pointer Leaving Window events the history window. These arrive as the
- * termination callback handler from ro_mouse's mouse tracking.
- *
- * \param *leaving             The Wimp_PointerLeavingWindow block.
- * \param *data                        NULL data pointer.
- */
-
-void ro_gui_history_track_end(wimp_leaving *leaving, void *data)
-{
-       ro_gui_dialog_close(dialog_tooltip);
-} 
-
-
-/**
- * Handle mouse movements over the history window.
- */
-
-void ro_gui_history_mouse_at(wimp_pointer *pointer, void *data)
-{
-       int x, y;
-       int width;
-       const char *url;
-       wimp_window_state state;
-       wimp_icon_state ic;
-       os_box box = {0, 0, 0, 0};
-       os_error *error;
-       
-       LOG("Mouse at...");
-
-       /* If the mouse hasn't moved, or if we don't want tooltips, exit */
-       if ((mouse_x == pointer->pos.x && mouse_y == pointer->pos.y) ||
-           !nsoption_bool(history_tooltip))
-               return;
-
-       /* Update mouse position */
-       mouse_x = pointer->pos.x;
-       mouse_y = pointer->pos.y;
-
-       /* Find history tree entry under mouse */
-       state.w = history_window;
-       error = xwimp_get_window_state(&state);
-       if (error) {
-               LOG("xwimp_get_window_state: 0x%x: %s", error->errnum, 
error->errmess);
-               ro_warn_user("WimpError", error->errmess);
-               return;
-       }
-
-       x = (pointer->pos.x - (state.visible.x0 - state.xscroll)) / 2;
-       y = -(pointer->pos.y - (state.visible.y1 - state.yscroll)) / 2;
-       url = browser_window_history_position_url(history_bw, x, y);
-       if (!url) {
-               /* not over a tree entry => close tooltip window. */
-               error = xwimp_close_window(dialog_tooltip);
-               if (error) {
-                       LOG("xwimp_close_window: 0x%x: %s", error->errnum, 
error->errmess);
-                       ro_warn_user("WimpError", error->errmess);
-                       return;
-               }
-               return;
-       }
-
-       /* get width of string */
-       error = xwimptextop_string_width(url,
-                       strlen(url) > 256 ? 256 : strlen(url),
-                       &width);
-       if (error) {
-               LOG("xwimptextop_string_width: 0x%x: %s", error->errnum, 
error->errmess);
-               ro_warn_user("WimpError", error->errmess);
-               return;
-       }
-
-       ro_gui_set_icon_string(dialog_tooltip, 0, url, true);
-
-       /* resize icon appropriately */
-       ic.w = dialog_tooltip;
-       ic.i = 0;
-       error = xwimp_get_icon_state(&ic);
-       if (error) {
-               LOG("xwimp_get_icon_state: 0x%x: %s", error->errnum, 
error->errmess);
-               ro_warn_user("WimpError", error->errmess);
-               return;
-       }
-       error = xwimp_resize_icon(dialog_tooltip, 0,
-                       ic.icon.extent.x0, ic.icon.extent.y0,
-                       width + 16, ic.icon.extent.y1);
-       if (error) {
-               LOG("xwimp_resize_icon: 0x%x: %s", error->errnum, 
error->errmess);
-               ro_warn_user("WimpError", error->errmess);
-               return;
-       }
-
-       state.w = dialog_tooltip;
-       error = xwimp_get_window_state(&state);
-       if (error) {
-               LOG("xwimp_get_window_state: 0x%x: %s", error->errnum, 
error->errmess);
-               ro_warn_user("WimpError", error->errmess);
-               return;
-       }
-
-       /* update window extent */
-       box.x1 = width + 16;
-       box.y0 = -36;
-       error = xwimp_set_extent(dialog_tooltip, &box);
-       if (error) {
-               LOG("xwimp_set_extent: 0x%x: %s", error->errnum, 
error->errmess);
-               ro_warn_user("WimpError", error->errmess);
-               return;
-       }
-
-       /* set visible area */
-       state.visible.x0 = pointer->pos.x + 24;
-       state.visible.y0 = pointer->pos.y - 22 - 36;
-       state.visible.x1 = pointer->pos.x + 24 + width + 16;
-       state.visible.y1 = pointer->pos.y - 22;
-       state.next = wimp_TOP;
-       /* open window */
-       error = xwimp_open_window(PTR_WIMP_OPEN(&state));
-       if (error) {
-               LOG("xwimp_open_window: 0x%x: %s", error->errnum, 
error->errmess);
-               ro_warn_user("WimpError", error->errmess);
-               return;
-       }
-}
-
-
-/**
- * Handle mouse clicks in the history window.
- *
- * \return true if the event was handled, false to pass it on
- */
-
-bool ro_gui_history_click(wimp_pointer *pointer)
-{
-       int x, y;
-       wimp_window_state state;
-       os_error *error;
-
-       if (pointer->buttons != wimp_CLICK_SELECT &&
-                       pointer->buttons != wimp_CLICK_ADJUST)
-               /* return if not select or adjust click */
-               return true;
-
-       state.w = history_window;
-       error = xwimp_get_window_state(&state);
-       if (error) {
-               LOG("xwimp_get_window_state: 0x%x: %s", error->errnum, 
error->errmess);
-               ro_warn_user("WimpError", error->errmess);
-               return true;
-       }
-
-       x = (pointer->pos.x - (state.visible.x0 - state.xscroll)) / 2;
-       y = -(pointer->pos.y - (state.visible.y1 - state.yscroll)) / 2;
-       browser_window_history_click(history_bw, x, y,
-                       pointer->buttons == wimp_CLICK_ADJUST);
-
-       return true;
-}
diff --git a/frontends/riscos/local_history.c b/frontends/riscos/local_history.c
new file mode 100644
index 0000000..fae78e6
--- /dev/null
+++ b/frontends/riscos/local_history.c
@@ -0,0 +1,438 @@
+/*
+ * Copyright 2017 Vincent Sanders <[email protected]>
+ *
+ * This file is part of NetSurf, http://www.netsurf-browser.org/
+ *
+ * NetSurf is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * NetSurf is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/**
+ * \file
+ * Implementation of RISC OS local history.
+ */
+
+#include <stdint.h>
+#include <stdlib.h>
+#include <oslib/wimp.h>
+
+#include "utils/nsoption.h"
+#include "utils/messages.h"
+#include "utils/log.h"
+#include "netsurf/window.h"
+#include "netsurf/plotters.h"
+#include "netsurf/keypress.h"
+#include "desktop/local_history.h"
+
+#include "riscos/dialog.h"
+#include "riscos/gui.h"
+#include "riscos/menus.h"
+#include "riscos/save.h"
+#include "riscos/toolbar.h"
+#include "riscos/wimp.h"
+#include "riscos/wimp_event.h"
+#include "riscos/wimputils.h"
+#include "riscos/corewindow.h"
+#include "riscos/local_history.h"
+
+struct ro_local_history_window {
+       struct ro_corewindow core;
+
+       /** local history window context */
+       struct local_history_session *session;
+
+       /** tooltip previous x */
+       int x;
+       /** tooltip previous y */
+       int y;
+};
+
+/** local_history window is a singleton */
+static struct ro_local_history_window *local_history_window = NULL;
+
+/** riscos template for local_history window */
+static wimp_window *dialog_local_history_template;
+
+
+/**
+ * callback to draw on drawable area of ro local history window
+ *
+ * \param ro_cw The riscos core window structure.
+ * \param r The rectangle of the window that needs updating.
+ * \param originx The risc os plotter x origin.
+ * \param originy The risc os plotter y origin.
+ * \return NSERROR_OK on success otherwise apropriate error code
+ */
+static nserror
+ro_local_history_draw(struct ro_corewindow *ro_cw,
+                     int originx,
+                     int originy,
+                     struct rect *r)
+{
+       struct redraw_context ctx = {
+               .interactive = true,
+               .background_images = true,
+               .plot = &ro_plotters
+       };
+       struct ro_local_history_window *lhw;
+
+       lhw = (struct ro_local_history_window *)ro_cw;
+
+       ro_plot_origin_x = originx;
+       ro_plot_origin_y = originy;
+       no_font_blending = true;
+       local_history_redraw(lhw->session, r->x0, r->y0, r, &ctx);
+       no_font_blending = false;
+
+       return NSERROR_OK;
+}
+
+
+/**
+ * callback for keypress on ro coookie window
+ *
+ * \param ro_cw The ro core window structure.
+ * \param nskey The netsurf key code.
+ * \return NSERROR_OK if key processed,
+ *         NSERROR_NOT_IMPLEMENTED if key not processed
+ *         otherwise apropriate error code
+ */
+static nserror
+ro_local_history_key(struct ro_corewindow *ro_cw, uint32_t nskey)
+{
+       struct ro_local_history_window *lhw;
+
+       lhw = (struct ro_local_history_window *)ro_cw;
+
+       if (local_history_keypress(lhw->session, nskey)) {
+               return NSERROR_OK;
+       }
+       return NSERROR_NOT_IMPLEMENTED;
+}
+
+
+/**
+ * handle hover mouse movement for tooltips
+ */
+static nserror
+ro_local_history_tooltip(struct ro_local_history_window *lhw, int x, int y)
+{
+       int width;
+       const char *url;
+       wimp_window_state state;
+       wimp_icon_state ic;
+       os_box box = {0, 0, 0, 0};
+       os_error *error;
+       wimp_pointer pointer;
+       nserror res;
+
+       /* check if tooltip are required */
+       if (!nsoption_bool(history_tooltip)) {
+               return NSERROR_OK;
+       }
+
+       /* ensure pointer has moved */
+       if ((lhw->x == x) && (lhw->y == y)) {
+               return NSERROR_OK;
+       }
+
+       lhw->x = x;
+       lhw->y = y;
+
+       res = local_history_get_url(lhw->session, x, y, &url);
+       if (res != NSERROR_OK) {
+               /* not over a tree entry => close tooltip window. */
+               error = xwimp_close_window(dialog_tooltip);
+               if (error) {
+                       LOG("xwimp_close_window: 0x%x: %s",
+                           error->errnum, error->errmess);
+                       ro_warn_user("WimpError", error->errmess);
+                       return NSERROR_NOMEM;
+               }
+               return NSERROR_OK;
+       }
+
+       /* get width of string */
+       error = xwimptextop_string_width(url,
+                                        strlen(url) > 256 ? 256 : strlen(url),
+                                        &width);
+       if (error) {
+               LOG("xwimptextop_string_width: 0x%x: %s",
+                   error->errnum, error->errmess);
+               ro_warn_user("WimpError", error->errmess);
+               return NSERROR_NOMEM;
+       }
+
+       ro_gui_set_icon_string(dialog_tooltip, 0, url, true);
+
+       /* resize icon appropriately */
+       ic.w = dialog_tooltip;
+       ic.i = 0;
+       error = xwimp_get_icon_state(&ic);
+       if (error) {
+               LOG("xwimp_get_icon_state: 0x%x: %s",
+                   error->errnum, error->errmess);
+               ro_warn_user("WimpError", error->errmess);
+               return NSERROR_NOMEM;
+       }
+       error = xwimp_resize_icon(dialog_tooltip, 0,
+                                 ic.icon.extent.x0, ic.icon.extent.y0,
+                                 width + 16, ic.icon.extent.y1);
+       if (error) {
+               LOG("xwimp_resize_icon: 0x%x: %s",
+                   error->errnum, error->errmess);
+               ro_warn_user("WimpError", error->errmess);
+               return NSERROR_NOMEM;
+       }
+
+       state.w = dialog_tooltip;
+       error = xwimp_get_window_state(&state);
+       if (error) {
+               LOG("xwimp_get_window_state: 0x%x: %s",
+                   error->errnum, error->errmess);
+               ro_warn_user("WimpError", error->errmess);
+               return NSERROR_NOMEM;
+       }
+
+       /* update window extent */
+       box.x1 = width + 16;
+       box.y0 = -36;
+       error = xwimp_set_extent(dialog_tooltip, &box);
+       if (error) {
+               LOG("xwimp_set_extent: 0x%x: %s", error->errnum, 
error->errmess);
+               ro_warn_user("WimpError", error->errmess);
+               return NSERROR_NOMEM;
+       }
+
+       error = xwimp_get_pointer_info(&pointer);
+       if (error) {
+               LOG("xwimp_get_pointer_info: 0x%x: %s",
+                   error->errnum, error->errmess);
+               ro_warn_user("WimpError", error->errmess);
+               return NSERROR_NOMEM;
+       }
+
+       /* set visible area */
+       state.visible.x0 = pointer.pos.x + 24;
+       state.visible.y0 = pointer.pos.y - 22 - 36;
+       state.visible.x1 = pointer.pos.x + 24 + width + 16;
+       state.visible.y1 = pointer.pos.y - 22;
+       state.next = wimp_TOP;
+       /* open window */
+       error = xwimp_open_window(PTR_WIMP_OPEN(&state));
+       if (error) {
+               LOG("xwimp_open_window: 0x%x: %s",
+                   error->errnum, error->errmess);
+               ro_warn_user("WimpError", error->errmess);
+               return NSERROR_NOMEM;
+       }
+       return NSERROR_OK;
+}
+
+
+/**
+ * callback for mouse event on ro local_history window
+ *
+ * \param ro_cw The ro core window structure.
+ * \param mouse_state mouse state
+ * \param x location of event
+ * \param y location of event
+ * \return NSERROR_OK on sucess otherwise apropriate error code.
+ */
+static nserror
+ro_local_history_mouse(struct ro_corewindow *ro_cw,
+                      browser_mouse_state mouse_state,
+                      int x, int y)
+{
+       struct ro_local_history_window *lhw;
+
+       lhw = (struct ro_local_history_window *)ro_cw;
+
+       switch (mouse_state) {
+
+       case BROWSER_MOUSE_HOVER:
+               ro_local_history_tooltip(lhw, x, y);
+               break;
+
+       case BROWSER_MOUSE_LEAVE:
+               ro_gui_dialog_close(dialog_tooltip);
+               break;
+
+       default:
+               local_history_mouse_action(lhw->session, mouse_state, x, y);
+               break;
+       }
+
+       return NSERROR_OK;
+}
+
+
+/**
+ * Creates the window for the local_history tree.
+ *
+ * \return NSERROR_OK on success else appropriate error code on faliure.
+ */
+static nserror
+ro_local_history_init(struct browser_window *bw,
+                     struct ro_local_history_window **win_out)
+{
+       struct ro_local_history_window *ncwin;
+       nserror res;
+
+       /* memoise window so it can be represented when necessary
+        * instead of recreating every time.
+        */
+       if ((*win_out) != NULL) {
+               res = local_history_set((*win_out)->session, bw);
+               return res;
+       }
+
+       ncwin = malloc(sizeof(struct ro_local_history_window));
+       if (ncwin == NULL) {
+               return NSERROR_NOMEM;
+       }
+
+       /* create window from template */
+       ncwin->core.wh = wimp_create_window(dialog_local_history_template);
+
+       /* initialise callbacks */
+       ncwin->core.draw = ro_local_history_draw;
+       ncwin->core.key = ro_local_history_key;
+       ncwin->core.mouse = ro_local_history_mouse;
+
+       /* initialise core window */
+       res = ro_corewindow_init(&ncwin->core,
+                                NULL,
+                                NULL,
+                                0,
+                                NULL);
+       if (res != NSERROR_OK) {
+               free(ncwin);
+               return res;
+       }
+
+       res = local_history_init(ncwin->core.cb_table,
+                                (struct core_window *)ncwin,
+                                bw,
+                                &ncwin->session);
+       if (res != NSERROR_OK) {
+               free(ncwin);
+               return res;
+       }
+
+       *win_out = ncwin;
+
+       return NSERROR_OK;
+}
+
+
+/**
+ * open RISC OS local history window at the correct size
+ */
+static nserror
+ro_local_history_open(struct ro_local_history_window *lhw, wimp_w parent)
+{
+       nserror res;
+       int width, height;
+       os_box box = {0, 0, 0, 0};
+       wimp_window_state state;
+       os_error *error;
+
+       res = local_history_get_size(lhw->session, &width, &height);
+       if (res != NSERROR_OK) {
+               return res;
+       }
+
+       width *= 2;
+       height *= 2;
+
+       /* set extent */
+       box.x1 = width;
+       box.y0 = -height;
+       error = xwimp_set_extent(lhw->core.wh, &box);
+       if (error) {
+               LOG("xwimp_set_extent: 0x%x: %s",
+                   error->errnum, error->errmess);
+               ro_warn_user("WimpError", error->errmess);
+               return NSERROR_NOMEM;
+       }
+
+       /* open full size */
+       state.w = lhw->core.wh;
+       error = xwimp_get_window_state(&state);
+       if (error) {
+               LOG("xwimp_get_window_state: 0x%x: %s",
+                   error->errnum, error->errmess);
+               ro_warn_user("WimpError", error->errmess);
+               return NSERROR_NOMEM;
+       }
+       state.visible.x0 = 0;
+       state.visible.y0 = 0;
+       state.visible.x1 = width;
+       state.visible.y1 = height;
+       state.next = wimp_HIDDEN;
+       error = xwimp_open_window(PTR_WIMP_OPEN(&state));
+       if (error) {
+               LOG("xwimp_open_window: 0x%x: %s",
+                   error->errnum, error->errmess);
+               ro_warn_user("WimpError", error->errmess);
+               return NSERROR_NOMEM;
+       }
+
+       ro_gui_dialog_open_persistent(parent, lhw->core.wh, true);
+
+       return NSERROR_OK;
+}
+
+/* exported interface documented in riscos/local_history.h */
+nserror ro_gui_local_history_present(wimp_w parent, struct browser_window *bw)
+{
+       nserror res;
+
+       res = ro_local_history_init(bw, &local_history_window);
+       if (res == NSERROR_OK) {
+               LOG("Presenting");
+               res = ro_local_history_open(local_history_window, parent);
+       } else {
+               LOG("Failed presenting error code %d", res);
+       }
+
+       return res;
+}
+
+
+/* exported interface documented in riscos/local_history.h */
+void ro_gui_local_history_initialise(void)
+{
+       dialog_local_history_template = ro_gui_dialog_load_template("history");
+}
+
+
+/* exported interface documented in riscos/local_history.h */
+nserror ro_gui_local_history_finalise(void)
+{
+       nserror res;
+
+       if (local_history_window == NULL) {
+               return NSERROR_OK;
+       }
+
+       res = local_history_fini(local_history_window->session);
+       if (res == NSERROR_OK) {
+               res = ro_corewindow_fini(&local_history_window->core);
+
+               free(local_history_window);
+               local_history_window = NULL;
+       }
+
+       return res;
+}
diff --git a/frontends/gtk/local_history.h b/frontends/riscos/local_history.h
similarity index 65%
copy from frontends/gtk/local_history.h
copy to frontends/riscos/local_history.h
index 605405d..d5b22b4 100644
--- a/frontends/gtk/local_history.h
+++ b/frontends/riscos/local_history.h
@@ -1,5 +1,5 @@
 /*
- * Copyright 2017 Vincent Sanders <[email protected]>
+ * Copyright 2017 Vincent Sanders <[email protected]>
  *
  * This file is part of NetSurf, http://www.netsurf-browser.org/
  *
@@ -18,32 +18,29 @@
 
 /**
  * \file
- * Interface to GTK local history manager
+ * RISC OS local history interface.
  */
 
-#ifndef NSGTK_LOCAL_HISTORY_H
-#define NSGTK_LOCAL_HISTORY_H
+#ifndef RISCOS_LOCALHISTORY_H
+#define RISCOS_LOCALHISTORY_H
 
-struct browser_window;
+/**
+ * initialise the local history window template ready for subsequent use.
+ */
+void ro_gui_local_history_initialise(void);
 
 /**
  * make the local history window visible.
  *
  * \return NSERROR_OK on success else appropriate error code on faliure.
  */
-nserror nsgtk_local_history_present(GtkWindow *parent, struct browser_window 
*bw);
+nserror ro_gui_local_history_present(wimp_w parent, struct browser_window *bw);
 
 /**
- * hide the local history window from being visible.
+ * Free any resources allocated for the local history window.
  *
  * \return NSERROR_OK on success else appropriate error code on faliure.
  */
-nserror nsgtk_local_history_hide(void);
-
-/**
- * Destroys the local history window and performs any other necessary cleanup
- * actions.
- */
-nserror nsgtk_local_history_destroy(void);
+nserror ro_gui_local_history_finalise(void);
 
 #endif
diff --git a/frontends/riscos/window.c b/frontends/riscos/window.c
index 3496d4b..de0fcab 100644
--- a/frontends/riscos/window.c
+++ b/frontends/riscos/window.c
@@ -69,6 +69,7 @@
 #include "riscos/buffer.h"
 #include "riscos/cookies.h"
 #include "riscos/dialog.h"
+#include "riscos/local_history.h"
 #include "riscos/global_history.h"
 #include "riscos/gui.h"
 #include "riscos/gui/status_bar.h"
@@ -3947,13 +3948,22 @@ void ro_gui_window_action_new_window(struct gui_window 
*g)
 /**
  * Open a local history pane for a browser window.
  *
- * \param *g                   The browser window to act on.
+ * \param g The browser window to act on.
  */
 
-void ro_gui_window_action_local_history(struct gui_window *g)
+void ro_gui_window_action_local_history(struct gui_window *gw)
 {
-       if (g != NULL && g->bw != NULL)
-               ro_gui_history_open(g, true);
+       nserror res;
+
+       if ((gw == NULL) || (gw->bw == NULL)) {
+               return;
+       }
+
+       res = ro_gui_local_history_present(gw->window, gw->bw);
+
+       if (res != NSERROR_OK) {
+               ro_warn_user(messages_get_errorcode(res), 0);
+       }
 }
 
 
diff --git a/include/netsurf/mouse.h b/include/netsurf/mouse.h
index 1b16998..999f5a5 100644
--- a/include/netsurf/mouse.h
+++ b/include/netsurf/mouse.h
@@ -79,7 +79,10 @@ typedef enum browser_mouse_state {
        /** 2nd modifier key pressed (eg. Ctrl) */
        BROWSER_MOUSE_MOD_2 = (1 << 12),
        /** 3rd modifier key pressed (eg. Alt) */
-       BROWSER_MOUSE_MOD_3 = (1 << 13)
+       BROWSER_MOUSE_MOD_3 = (1 << 13),
+
+       /** pointer leaving window */
+       BROWSER_MOUSE_LEAVE = (1 << 14),
 } browser_mouse_state;
 
 


-- 
NetSurf Browser

_______________________________________________
netsurf-commits mailing list
[email protected]
http://listmaster.pepperfish.net/cgi-bin/mailman/listinfo/netsurf-commits-netsurf-browser.org

Reply via email to