NetSurf
local_history.c
Go to the documentation of this file.
1/*
2 * Copyright 2017 Vincent Sanders <vince@netsurf-browser.org>
3 *
4 * This file is part of NetSurf, http://www.netsurf-browser.org/
5 *
6 * NetSurf is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; version 2 of the License.
9 *
10 * NetSurf is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18
19/**
20 * \file
21 * Implementation of RISC OS local history.
22 */
23
24#include <stdint.h>
25#include <stdlib.h>
26#include <oslib/wimp.h>
27
28#include "utils/nsoption.h"
29#include "utils/messages.h"
30#include "utils/log.h"
31#include "utils/nsurl.h"
32#include "netsurf/window.h"
33#include "netsurf/plotters.h"
34#include "netsurf/keypress.h"
36
37#include "riscos/dialog.h"
38#include "riscos/gui.h"
39#include "riscos/menus.h"
40#include "riscos/save.h"
41#include "riscos/toolbar.h"
42#include "riscos/wimp.h"
43#include "riscos/wimp_event.h"
44#include "riscos/wimputils.h"
45#include "riscos/corewindow.h"
47
50
51 /** local history window context */
53
54 /** tooltip previous x */
55 int x;
56 /** tooltip previous y */
57 int y;
58};
59
60/** local_history window is a singleton */
62
63/** riscos template for local_history window */
65
66
67/**
68 * callback to draw on drawable area of ro local history window
69 *
70 * \param ro_cw The riscos core window structure.
71 * \param r The rectangle of the window that needs updating.
72 * \param originx The risc os plotter x origin.
73 * \param originy The risc os plotter y origin.
74 * \return NSERROR_OK on success otherwise apropriate error code
75 */
76static nserror
78 int originx,
79 int originy,
80 struct rect *r)
81{
82 struct redraw_context ctx = {
83 .interactive = true,
84 .background_images = true,
85 .plot = &ro_plotters
86 };
87 struct ro_local_history_window *lhw;
88
89 lhw = (struct ro_local_history_window *)ro_cw;
90
91 ro_plot_origin_x = originx;
92 ro_plot_origin_y = originy;
93 no_font_blending = true;
94 local_history_redraw(lhw->session, 0, 0, r, &ctx);
95 no_font_blending = false;
96
97 return NSERROR_OK;
98}
99
100
101/**
102 * callback for keypress on ro coookie window
103 *
104 * \param ro_cw The ro core window structure.
105 * \param nskey The netsurf key code.
106 * \return NSERROR_OK if key processed,
107 * NSERROR_NOT_IMPLEMENTED if key not processed
108 * otherwise apropriate error code
109 */
110static nserror
111ro_local_history_key(struct ro_corewindow *ro_cw, uint32_t nskey)
112{
113 struct ro_local_history_window *lhw;
114
115 lhw = (struct ro_local_history_window *)ro_cw;
116
117 if (local_history_keypress(lhw->session, nskey)) {
118 return NSERROR_OK;
119 }
121}
122
123
124/**
125 * handle hover mouse movement for tooltips
126 */
127static nserror
129{
130 int width;
131 nsurl *url;
132 wimp_window_state state;
133 wimp_icon_state ic;
134 os_box box = {0, 0, 0, 0};
135 os_error *error;
136 wimp_pointer pointer;
137 nserror res;
138
139 /* check if tooltip are required */
140 if (!nsoption_bool(history_tooltip)) {
141 return NSERROR_OK;
142 }
143
144 /* ensure pointer has moved */
145 if ((lhw->x == x) && (lhw->y == y)) {
146 return NSERROR_OK;
147 }
148
149 lhw->x = x;
150 lhw->y = y;
151
152 res = local_history_get_url(lhw->session, x, y, &url);
153 if (res != NSERROR_OK) {
154 /* not over a tree entry => close tooltip window. */
155 error = xwimp_close_window(dialog_tooltip);
156 if (error) {
157 NSLOG(netsurf, INFO, "xwimp_close_window: 0x%x: %s",
158 error->errnum, error->errmess);
159 ro_warn_user("WimpError", error->errmess);
160 return NSERROR_NOMEM;
161 }
162 return NSERROR_OK;
163 }
164
165 /* get width of string */
166 error = xwimptextop_string_width(nsurl_access(url),
167 nsurl_length(url) > 256 ? 256 : nsurl_length(url),
168 &width);
169 if (error) {
170 NSLOG(netsurf, INFO, "xwimptextop_string_width: 0x%x: %s",
171 error->errnum, error->errmess);
172 ro_warn_user("WimpError", error->errmess);
173 nsurl_unref(url);
174 return NSERROR_NOMEM;
175 }
176
178 nsurl_unref(url);
179
180 /* resize icon appropriately */
181 ic.w = dialog_tooltip;
182 ic.i = 0;
183 error = xwimp_get_icon_state(&ic);
184 if (error) {
185 NSLOG(netsurf, INFO, "xwimp_get_icon_state: 0x%x: %s",
186 error->errnum, error->errmess);
187 ro_warn_user("WimpError", error->errmess);
188 return NSERROR_NOMEM;
189 }
190 error = xwimp_resize_icon(dialog_tooltip, 0,
191 ic.icon.extent.x0, ic.icon.extent.y0,
192 width + 16, ic.icon.extent.y1);
193 if (error) {
194 NSLOG(netsurf, INFO, "xwimp_resize_icon: 0x%x: %s",
195 error->errnum, error->errmess);
196 ro_warn_user("WimpError", error->errmess);
197 return NSERROR_NOMEM;
198 }
199
200 state.w = dialog_tooltip;
201 error = xwimp_get_window_state(&state);
202 if (error) {
203 NSLOG(netsurf, INFO, "xwimp_get_window_state: 0x%x: %s",
204 error->errnum, error->errmess);
205 ro_warn_user("WimpError", error->errmess);
206 return NSERROR_NOMEM;
207 }
208
209 /* update window extent */
210 box.x1 = width + 16;
211 box.y0 = -36;
212 error = xwimp_set_extent(dialog_tooltip, &box);
213 if (error) {
214 NSLOG(netsurf, INFO, "xwimp_set_extent: 0x%x: %s",
215 error->errnum, error->errmess);
216 ro_warn_user("WimpError", error->errmess);
217 return NSERROR_NOMEM;
218 }
219
220 error = xwimp_get_pointer_info(&pointer);
221 if (error) {
222 NSLOG(netsurf, INFO, "xwimp_get_pointer_info: 0x%x: %s",
223 error->errnum, error->errmess);
224 ro_warn_user("WimpError", error->errmess);
225 return NSERROR_NOMEM;
226 }
227
228 /* set visible area */
229 state.visible.x0 = pointer.pos.x + 24;
230 state.visible.y0 = pointer.pos.y - 22 - 36;
231 state.visible.x1 = pointer.pos.x + 24 + width + 16;
232 state.visible.y1 = pointer.pos.y - 22;
233 state.next = wimp_TOP;
234 /* open window */
235 error = xwimp_open_window(PTR_WIMP_OPEN(&state));
236 if (error) {
237 NSLOG(netsurf, INFO, "xwimp_open_window: 0x%x: %s",
238 error->errnum, error->errmess);
239 ro_warn_user("WimpError", error->errmess);
240 return NSERROR_NOMEM;
241 }
242 return NSERROR_OK;
243}
244
245
246/**
247 * callback for mouse event on ro local_history window
248 *
249 * \param ro_cw The ro core window structure.
250 * \param mouse_state mouse state
251 * \param x location of event
252 * \param y location of event
253 * \return NSERROR_OK on sucess otherwise apropriate error code.
254 */
255static nserror
257 browser_mouse_state mouse_state,
258 int x, int y)
259{
260 struct ro_local_history_window *lhw;
261
262 lhw = (struct ro_local_history_window *)ro_cw;
263
264 switch (mouse_state) {
265
268 break;
269
272 break;
273
274 default:
275 local_history_mouse_action(lhw->session, mouse_state, x, y);
276 break;
277 }
278
279 return NSERROR_OK;
280}
281
282
283/**
284 * Creates the window for the local_history tree.
285 *
286 * \return NSERROR_OK on success else appropriate error code on faliure.
287 */
288static nserror
290 struct ro_local_history_window **win_out)
291{
292 os_error *error;
293 struct ro_local_history_window *ncwin;
294 nserror res;
295
296 /* memoise window so it can be represented when necessary
297 * instead of recreating every time.
298 */
299 if ((*win_out) != NULL) {
300 res = local_history_set((*win_out)->session, bw);
301 return res;
302 }
303
304 ncwin = calloc(1, sizeof(*ncwin));
305 if (ncwin == NULL) {
306 return NSERROR_NOMEM;
307 }
308
309 /* create window from template */
310 error = xwimp_create_window(dialog_local_history_template,
311 &ncwin->core.wh);
312 if (error) {
313 NSLOG(netsurf, INFO, "xwimp_create_window: 0x%x: %s",
314 error->errnum, error->errmess);
315 ro_warn_user("WimpError", error->errmess);
316 free(ncwin);
317 return NSERROR_NOMEM;
318 }
319
320 /* initialise callbacks */
324
325 /* initialise core window */
326 res = ro_corewindow_init(&ncwin->core,
327 NULL,
328 NULL,
329 0,
330 NULL);
331 if (res != NSERROR_OK) {
332 free(ncwin);
333 return res;
334 }
335
336 res = local_history_init(ncwin->core.cb_table,
337 (struct core_window *)ncwin,
338 bw,
339 &ncwin->session);
340 if (res != NSERROR_OK) {
341 free(ncwin);
342 return res;
343 }
344
345 *win_out = ncwin;
346
347 return NSERROR_OK;
348}
349
350
351/**
352 * open RISC OS local history window at the correct size
353 */
354static nserror
356{
357 nserror res;
358 int width, height;
359 os_box box = {0, 0, 0, 0};
360 wimp_window_state state;
361 os_error *error;
362
364 if (res != NSERROR_OK) {
365 return res;
366 }
367
368 width *= 2;
369 height *= 2;
370
371 /* set extent */
372 box.x1 = width;
373 box.y0 = -height;
374 error = xwimp_set_extent(lhw->core.wh, &box);
375 if (error) {
376 NSLOG(netsurf, INFO, "xwimp_set_extent: 0x%x: %s",
377 error->errnum, error->errmess);
378 ro_warn_user("WimpError", error->errmess);
379 return NSERROR_NOMEM;
380 }
381
382 /* open full size */
383 state.w = lhw->core.wh;
384 error = xwimp_get_window_state(&state);
385 if (error) {
386 NSLOG(netsurf, INFO, "xwimp_get_window_state: 0x%x: %s",
387 error->errnum, error->errmess);
388 ro_warn_user("WimpError", error->errmess);
389 return NSERROR_NOMEM;
390 }
391 state.visible.x0 = 0;
392 state.visible.y0 = 0;
393 state.visible.x1 = width;
394 state.visible.y1 = height;
395 state.next = wimp_HIDDEN;
396 error = xwimp_open_window(PTR_WIMP_OPEN(&state));
397 if (error) {
398 NSLOG(netsurf, INFO, "xwimp_open_window: 0x%x: %s",
399 error->errnum, error->errmess);
400 ro_warn_user("WimpError", error->errmess);
401 return NSERROR_NOMEM;
402 }
403
405
406 /* Give the window focus. */
407 error = xwimp_set_caret_position(lhw->core.wh, -1, 0, 0, -1, 0);
408 if (error) {
409 NSLOG(netsurf, INFO,
410 "xwimp_set_caret_position: 0x%x : %s",
411 error->errnum,
412 error->errmess);
413 }
414
416
417 return NSERROR_OK;
418}
419
420/* exported interface documented in riscos/local_history.h */
422{
423 nserror res;
424
426 if (res == NSERROR_OK) {
427 NSLOG(netsurf, INFO, "Presenting");
429 } else {
430 NSLOG(netsurf, INFO, "Failed presenting error code %d", res);
431 }
432
433 return res;
434}
435
436
437/* exported interface documented in riscos/local_history.h */
439{
441}
442
443
444/* exported interface documented in riscos/local_history.h */
446{
447 nserror res;
448
449 if (local_history_window == NULL) {
450 return NSERROR_OK;
451 }
452
454 if (res == NSERROR_OK) {
456
459 }
460
461 return res;
462}
nserror local_history_init(struct core_window_callback_table *cw_t, void *core_window_handle, struct browser_window *bw, struct local_history_session **session)
Initialise the local history.
nserror local_history_redraw(struct local_history_session *session, int x, int y, struct rect *clip, const struct redraw_context *ctx)
Redraw the local history.
nserror local_history_scroll_to_cursor(struct local_history_session *session)
Scroll the local history window to ensure the current cursor is shown.
nserror local_history_get_size(struct local_history_session *session, int *width, int *height)
get size of local history content area.
nserror local_history_set(struct local_history_session *session, struct browser_window *bw)
Change the browser window to draw local history for.
nserror local_history_fini(struct local_history_session *session)
Finalise the local history.
bool local_history_keypress(struct local_history_session *session, uint32_t key)
Key press handling.
nserror local_history_get_url(struct local_history_session *session, int x, int y, nsurl **url_out)
get url of entry at position in local history content area.
nserror local_history_mouse_action(struct local_history_session *session, enum browser_mouse_state mouse, int x, int y)
Handles all kinds of mouse action.
wimp_w parent
Definition: dialog.c:88
wimp_w dialog_tooltip
Definition: dialog.c:76
void ro_gui_dialog_open_persistent(wimp_w parent, wimp_w w, bool pointer)
Open a persistent dialog box relative to the pointer.
Definition: dialog.c:591
wimp_window * ro_gui_dialog_load_template(const char *template_name)
Load a template without creating a window.
Definition: dialog.c:242
void ro_gui_dialog_close(wimp_w close)
Close a dialog box.
Definition: dialog.c:335
nserror
Enumeration of error codes.
Definition: errors.h:29
@ NSERROR_NOT_IMPLEMENTED
Functionality is not implemented.
Definition: errors.h:61
@ NSERROR_NOMEM
Memory exhaustion.
Definition: errors.h:32
@ NSERROR_OK
No error.
Definition: errors.h:30
bool no_font_blending
Definition: font.c:48
static nserror ro_local_history_mouse(struct ro_corewindow *ro_cw, browser_mouse_state mouse_state, int x, int y)
callback for mouse event on ro local_history window
static nserror ro_local_history_draw(struct ro_corewindow *ro_cw, int originx, int originy, struct rect *r)
callback to draw on drawable area of ro local history window
Definition: local_history.c:77
static struct ro_local_history_window * local_history_window
local_history window is a singleton
Definition: local_history.c:61
static nserror ro_local_history_tooltip(struct ro_local_history_window *lhw, int x, int y)
handle hover mouse movement for tooltips
static nserror ro_local_history_key(struct ro_corewindow *ro_cw, uint32_t nskey)
callback for keypress on ro coookie window
static wimp_window * dialog_local_history_template
riscos template for local_history window
Definition: local_history.c:64
nserror ro_gui_local_history_present(wimp_w parent, struct browser_window *bw)
make the local history window visible.
void ro_gui_local_history_initialise(void)
initialise the local history window template ready for subsequent use.
nserror ro_gui_local_history_finalise(void)
Free any resources allocated for the local history window.
static nserror ro_local_history_init(struct browser_window *bw, struct ro_local_history_window **win_out)
Creates the window for the local_history tree.
static nserror ro_local_history_open(struct ro_local_history_window *lhw, wimp_w parent)
open RISC OS local history window at the correct size
RISC OS local history interface.
browser_mouse_state
Mouse state.
Definition: mouse.h:43
@ BROWSER_MOUSE_HOVER
No mouse buttons pressed, May be used to indicate hover or end of drag.
Definition: mouse.h:47
@ BROWSER_MOUSE_LEAVE
pointer leaving window
Definition: mouse.h:85
Target independent plotting interface.
Interface to platform-specific graphical user interface window operations.
Interface to key press operations.
#define NSLOG(catname, level, logmsg, args...)
Definition: log.h:116
Localised message support (interface).
NetSurf URL handling (interface).
void nsurl_unref(nsurl *url)
Drop a reference to a NetSurf URL object.
const char * nsurl_access(const nsurl *url)
Access a NetSurf URL object as a string.
size_t nsurl_length(const nsurl *url)
Find the length of a NetSurf URL object's URL, as returned by nsurl_access.
struct nsurl nsurl
NetSurf URL object.
Definition: nsurl.h:31
nserror ro_corewindow_fini(struct ro_corewindow *ro_cw)
finalise elements of ro core window.
Definition: corewindow.c:1079
nserror ro_corewindow_init(struct ro_corewindow *ro_cw, const struct button_bar_buttons *tb_buttons, char *tb_order, theme_style tb_style, const char *tb_help)
initialise elements of riscos core window.
Definition: corewindow.c:1001
RISC OS core window interface.
int width
Definition: gui.c:159
nserror ro_warn_user(const char *warning, const char *detail)
Display a warning for a serious problem (eg memory exhaustion).
Definition: gui.c:2076
int height
Definition: gui.c:160
int ro_plot_origin_x
Definition: plotters.c:40
int ro_plot_origin_y
Definition: plotters.c:41
const struct plotter_table ro_plotters
RISC OS plotter operation table.
Definition: plotters.c:727
File/object/selection saving (Interface).
Window toolbars (interface).
Node in box tree.
Definition: box.h:177
Browser window data.
local history viewer context
Definition: local_history.c:50
Rectangle coordinates.
Definition: types.h:40
Redraw context.
Definition: plotters.h:51
bool interactive
Redraw to show interactive features.
Definition: plotters.h:59
ro core window state
Definition: corewindow.h:37
struct core_window_callback_table * cb_table
table of callbacks for core window operations
Definition: corewindow.h:57
nserror(* mouse)(struct ro_corewindow *ro_cw, browser_mouse_state mouse_state, int x, int y)
callback for mouse event on ro core window
Definition: corewindow.h:90
wimp_w wh
window handle
Definition: corewindow.h:39
nserror(* key)(struct ro_corewindow *ro_cw, uint32_t nskey)
callback for keypress on ro core window
Definition: corewindow.h:79
nserror(* draw)(struct ro_corewindow *ro_cw, int originx, int originy, struct rect *r)
callback to draw on drawable area of ro core window
Definition: corewindow.h:68
int x
tooltip previous x
Definition: local_history.c:55
int y
tooltip previous y
Definition: local_history.c:57
struct local_history_session * session
local history window context
Definition: local_history.c:52
struct ro_corewindow core
Definition: local_history.c:49
Option reading and saving interface.
#define nsoption_bool(OPTION)
Get the value of a boolean option.
Definition: nsoption.h:270
void ro_gui_set_icon_string(wimp_w w, wimp_i i, const char *text, bool is_utf8)
Set the contents of a text or sprite icon to a string.
Definition: wimp.c:269
General RISC OS WIMP/OS library functions (interface).
Automated RISC OS WIMP event handling (interface).
A collection of grubby utilities for working with OSLib's wimp API.
#define PTR_WIMP_OPEN(pstate)
Definition: wimputils.h:39