NetSurf
browser_history.c
Go to the documentation of this file.
1/*
2 * Copyright 2006 James Bursa <bursa@users.sourceforge.net>
3 * Copyright 2005 Richard Wilson <info@tinct.net>
4 *
5 * This file is part of NetSurf, http://www.netsurf-browser.org/
6 *
7 * NetSurf is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; version 2 of the License.
10 *
11 * NetSurf is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19
20/**
21 * \file
22 * Browser history tree implementation.
23 */
24
25#include <assert.h>
26#include <stdbool.h>
27#include <stdlib.h>
28#include <string.h>
29#include <time.h>
30
31#include "utils/log.h"
32#include "utils/utils.h"
33#include "netsurf/layout.h"
34#include "netsurf/content.h"
35#include "netsurf/window.h"
37#include "content/hlcache.h"
38#include "content/urldb.h"
39#include "netsurf/bitmap.h"
40#include "utils/corestrings.h"
41
46
47/**
48 * Clone a history entry
49 *
50 * \param history opaque history structure, as returned by history_create()
51 * \param entry entry to clone
52 * \return A cloned history entry or NULL on error
53 */
54static struct history_entry *
56 struct history_entry *entry)
57{
58 struct history_entry *child;
59 struct history_entry *new_child;
60 struct history_entry *prev = NULL;
61 struct history_entry *new_entry;
62
63 assert(entry);
64 assert(entry->page.url);
65 assert(entry->page.title);
66
67 /* clone the entry */
68 new_entry = calloc(1, sizeof *entry);
69 if (!new_entry) {
70 return NULL;
71 }
72
73 /* copy page information */
74 new_entry->page.title = strdup(entry->page.title);
75 if (new_entry->page.title == NULL) {
76 free(new_entry);
77 return NULL;
78 }
79
80 new_entry->page.url = nsurl_ref(entry->page.url);
81 if (new_entry->page.url == NULL) {
82 free(new_entry->page.title);
83 free(new_entry);
84 return NULL;
85 }
86
87 if (entry->page.frag_id == NULL) {
88 new_entry->page.frag_id = NULL;
89 } else {
90 new_entry->page.frag_id = lwc_string_ref(entry->page.frag_id);
91 if (new_entry->page.frag_id == NULL) {
92 nsurl_unref(new_entry->page.url);
93 free(new_entry);
94 return NULL;
95 }
96 }
97
98 if (entry->page.bitmap == NULL) {
99 new_entry->page.bitmap = NULL;
100 } else {
101 /* create a new bitmap and copy original into it */
102 unsigned char *bmsrc_data;
103 unsigned char *bmdst_data;
104 size_t bmsize;
105
106 new_entry->page.bitmap = guit->bitmap->create(
110
111 if (new_entry->page.bitmap != NULL) {
112 bmsrc_data = guit->bitmap->get_buffer(entry->page.bitmap);
113 bmdst_data = guit->bitmap->get_buffer(new_entry->page.bitmap);
114 bmsize = guit->bitmap->get_rowstride(new_entry->page.bitmap) *
115 guit->bitmap->get_height(new_entry->page.bitmap);
116 memcpy(bmdst_data, bmsrc_data, bmsize);
117 }
118 }
119
120 /* copy tree values */
121 new_entry->back = entry->back;
122 new_entry->next = entry->next;
123 new_entry->forward = entry->forward;
124 new_entry->forward_pref = entry->forward_pref;
125 new_entry->forward_last = entry->forward_last;
126
127 /* recurse for all children */
128 for (child = new_entry->forward; child != NULL; child = child->next) {
130 if (new_child == NULL) {
131 nsurl_unref(new_entry->page.url);
132 if (new_entry->page.frag_id) {
133 lwc_string_unref(new_entry->page.frag_id);
134 }
135 free(new_entry->page.title);
136 if (entry->page.bitmap != NULL) {
137 guit->bitmap->destroy(entry->page.bitmap);
138 }
139 free(new_entry);
140 return NULL;
141 }
142
143 new_child->back = new_entry;
144 if (prev)
145 prev->next = new_child;
146 if (new_entry->forward == child)
147 new_entry->forward = new_child;
148 if (new_entry->forward_pref == child)
149 new_entry->forward_pref = new_child;
150 if (new_entry->forward_last == child)
151 new_entry->forward_last = new_child;
152 prev = new_child;
153 }
154
155 /* update references */
156 if (history->current == entry) {
157 history->current = new_entry;
158 }
159
160 return new_entry;
161}
162
163
164/**
165 * Free an entry in the tree recursively.
166 */
167
169{
170 if (entry != NULL) {
173
174 nsurl_unref(entry->page.url);
175 if (entry->page.frag_id) {
176 lwc_string_unref(entry->page.frag_id);
177 }
178 free(entry->page.title);
179 if (entry->page.bitmap != NULL) {
180 guit->bitmap->destroy(entry->page.bitmap);
181 }
182 free(entry);
183 }
184}
185
186
187/**
188 * Recursively position a subtree.
189 *
190 * \param history history being laid out
191 * \param entry subtree to position
192 * \param x x position for entry
193 * \param y smallest available y
194 * \return greatest y used by subtree
195 */
196
198 struct history_entry *entry, int x, int y)
199{
200 struct history_entry *child;
201 int y1 = y;
202
205
206 if (!entry->forward) {
207 entry->x = x;
208 entry->y = y;
209 return y + LOCAL_HISTORY_HEIGHT;
210 }
211
212 /* layout child subtrees below each other */
213 for (child = entry->forward; child; child = child->next) {
216 if (child->next)
218 }
219
220 /* place ourselves in the middle */
221 entry->x = x;
222 entry->y = (y + y1) / 2 - LOCAL_HISTORY_HEIGHT / 2;
223
224 return y1;
225}
226
227
228/**
229 * Compute node positions.
230 *
231 * \param history history to layout
232 *
233 * Each node's x and y are filled in.
234 */
235
237{
238 if (!history)
239 return;
240
241 history->width = 0;
242 if (history->start)
247 else
248 history->height = 0;
249
252}
253
254
255
256
257
258/**
259 * Enumerate subentries in history
260 * See also history_enumerate()
261 *
262 * \param bw The browser window to enumerate history of
263 * \param entry entry to start enumeration at
264 * \param cb callback function
265 * \param ud context pointer passed to cb
266 * \return true to continue enumeration, false to cancel
267 */
269 const struct browser_window *bw,
270 const struct history_entry *entry,
272 void *ud)
273{
274 const struct history_entry *child;
275
276 if (!cb(bw, entry->x, entry->y,
277 entry->x + LOCAL_HISTORY_WIDTH,
278 entry->y + LOCAL_HISTORY_HEIGHT,
279 entry, ud))
280 return false;
281
282 for (child = entry->forward; child; child = child->next) {
284 cb, ud))
285 return false;
286 }
287
288 return true;
289}
290
291
292/* -------------------------------------------------------------------------- */
293
294
295/* exported interface documented in desktop/browser_history.h */
297{
298 struct history *history;
299
300 bw->history = NULL;
301
302 history = calloc(1, sizeof *history);
303 if (history == NULL) {
304 return NSERROR_NOMEM;
305 }
306
309
310 bw->history = history;
311
312 return NSERROR_OK;
313}
314
315
316/* exported interface documented in desktop/browser_history.h */
318 struct browser_window *clone)
319{
320 struct history *new_history;
321
322 clone->history = NULL;
323
324 if (existing == NULL || existing->history == NULL ||
325 existing->history->start == NULL)
326 /* Nothing to clone, create new history for clone window */
327 return browser_window_history_create(clone);
328
329 /* Make cloned history */
330 new_history = malloc(sizeof *new_history);
331 if (!new_history)
332 return NSERROR_NOMEM;
333
334 clone->history = new_history;
335 memcpy(new_history, existing->history, sizeof *new_history);
336
337 new_history->start = browser_window_history__clone_entry(new_history,
338 new_history->start);
339 if (!new_history->start) {
340 NSLOG(netsurf, INFO, "Insufficient memory to clone history");
342 clone->history = NULL;
343 return NSERROR_NOMEM;
344 }
345
346 return NSERROR_OK;
347}
348
349
350/* exported interface documented in desktop/browser_history.h */
353 struct hlcache_handle *content,
354 lwc_string *frag_id)
355{
356 struct history *history;
357 struct history_entry *entry;
358 char *title;
359 nserror ret;
360
361 assert(bw);
362 assert(bw->history);
363 assert(content);
364
365 history = bw->history;
366
367 entry = malloc(sizeof *entry);
368 if (entry == NULL) {
369 return NSERROR_NOMEM;
370 }
371
372 /* page information */
373 title = strdup(content_get_title(content));
374 if (title == NULL) {
375 free(entry);
376 return NSERROR_NOMEM;
377 }
378
380 entry->page.frag_id = frag_id ? lwc_string_ref(frag_id) : NULL;
381 entry->page.title = title;
382 entry->page.scroll_x = 0.0f;
383 entry->page.scroll_y = 0.0f;
384
385 /* create thumbnail for localhistory view */
386 NSLOG(netsurf, DEBUG,
387 "Creating thumbnail for %s", nsurl_access(entry->page.url));
388
389 entry->page.bitmap = guit->bitmap->create(
392 if (entry->page.bitmap != NULL) {
393 ret = guit->bitmap->render(entry->page.bitmap, content);
394 if (ret != NSERROR_OK) {
395 /* Thumbnail render failed */
396 NSLOG(netsurf, WARNING, "Thumbnail render failed");
397 }
398 }
399
400 /* insert into tree */
401 entry->back = history->current;
402 entry->next = NULL;
403 entry->forward = entry->forward_pref = entry->forward_last = NULL;
404 entry->children = 0;
405
406 if (history->current) {
408 history->current->forward_last->next = entry;
409 } else {
410 history->current->forward = entry;
411 }
412 history->current->forward_pref = entry;
413 history->current->forward_last = entry;
415 } else {
416 history->start = entry;
417 }
418 history->current = entry;
419
421
422 return NSERROR_OK;
423}
424
425
426/* exported interface documented in desktop/browser_history.h */
428 struct hlcache_handle *content)
429{
430 struct history *history;
431 char *title;
432 int sx, sy;
433
434 assert(bw != NULL);
435
436 history = bw->history;
437
438 if ((history == NULL) || (history->current == NULL)) {
439 return NSERROR_INVALID;
440 }
441
442 assert(history->current->page.url);
443 assert(history->current->page.title);
444
445 title = strdup(content_get_title(content));
446 if (title == NULL) {
447 return NSERROR_NOMEM;
448 }
449 NSLOG(netsurf, INFO, "Updating history entry for %s", title);
450 free(history->current->page.title);
451 history->current->page.title = title;
452
453 if (history->current->page.bitmap != NULL) {
455 }
456
457 if ((bw->window != NULL) &&
458 guit->window->get_scroll(bw->window, &sx, &sy)) {
459 int content_height = content_get_height(content);
460 int content_width = content_get_width(content);
461 /* clamp width and height values */
462 if (content_height < 1) {
463 content_height = 1;
464 }
465 if (content_width < 1) {
466 content_width = 1;
467 }
468 /* Successfully got scroll offsets, update the entry */
470 (float)sx / (float)content_width;
472 (float)sy / (float)content_height;
473 NSLOG(netsurf, INFO, "Updated scroll offsets to %g by %g",
476 }
477 return NSERROR_OK;
478}
479
480/* exported interface documented in desktop/browser_private.h */
483 float *sx, float *sy)
484{
485 struct history *history;
486
487 assert(bw != NULL);
488
489 history = bw->history;
490
491 if ((history== NULL) || (history->current == NULL)) {
492 return NSERROR_INVALID;
493 }
494
497
498 return NSERROR_OK;
499}
500
501/* exported interface documented in desktop/browser_history.h */
503{
504 assert(bw != NULL);
505
506 if (bw->history == NULL)
507 return;
508
510 free(bw->history);
511
512 bw->history = NULL;
513}
514
515
516
517/* exported interface documented in desktop/browser_history.h */
519{
520 if (bw != NULL && bw->internal_nav) {
521 /* All internal nav back operations ignore new_window */
522 if (bw->current_parameters.url != NULL) {
523 /* There are some internal parameters, restart from there */
525 } else {
526 /* No internal parameters, just navigate to about:blank */
528 bw,
529 corestring_nsurl_about_blank,
530 NULL, /* Referer */
532 NULL, /* Post */
533 NULL, /* Post */
534 NULL /* parent fetch */);
535 }
536 }
537
538 if (!bw || !bw->history || !bw->history->current ||
539 !bw->history->current->back) {
541 }
543 new_window);
544}
545
546
547
548/* exported interface documented in desktop/browser_history.h */
550 bool new_window)
551{
552 if (!bw || !bw->history || !bw->history->current ||
555 }
557 new_window);
558}
559
560
561/* exported interface documented in desktop/browser_history.h */
563{
564 return (bw && bw->history && bw->history->current &&
565 bw->history->current->back);
566}
567
568
569/* exported interface documented in desktop/browser_history.h */
571{
572 return (bw && bw->history && bw->history->current &&
574}
575
576/* exported interface documented in desktop/browser_history.h */
579 struct bitmap **bitmap_out)
580{
581 struct bitmap *bitmap;
582
583 if (!bw || !bw->history || !bw->history->current) {
584 return NSERROR_INVALID;
585 }
586
587 if (bw->history->current->page.bitmap == NULL) {
589 } else {
591 }
592
593 *bitmap_out = bitmap;
594
595 return NSERROR_OK;
596}
597
598/* exported interface documented in desktop/browser_history.h */
600 struct history_entry *entry, bool new_window)
601{
602 struct history *history;
603 nsurl *url;
604 struct history_entry *current;
605 nserror error;
606
607 assert(bw != NULL);
608 history = bw->history;
609
610 if (entry->page.frag_id) {
611 error = nsurl_refragment(entry->page.url,
612 entry->page.frag_id, &url);
613
614 if (error != NSERROR_OK) {
615 return error;
616 }
617 } else {
618 url = nsurl_ref(entry->page.url);
619 }
620
621 if (new_window) {
622 current = history->current;
623 history->current = entry;
624
626 url, NULL, bw, NULL);
627 history->current = current;
628 } else {
629 if (bw->current_content != NULL) {
631 }
632 history->current = entry;
633 error = browser_window_navigate(bw, url, NULL,
635 NULL, NULL, NULL);
636 }
637
638 nsurl_unref(url);
639
640 return error;
641}
642
643
644/* exported interface documented in desktop/browser_history.h */
646 browser_window_history_enumerate_cb cb, void *user_data)
647{
648 struct history_entry *e;
649
650 if (bw == NULL || bw->history == NULL || bw->history->current == NULL)
651 return;
652
653 e = bw->history->current->forward_pref;
654 for (; e != NULL; e = e->forward_pref) {
655 if (!cb(bw, e->x, e->y, e->x + LOCAL_HISTORY_WIDTH,
657 e, user_data))
658 break;
659 }
660}
661
662
663/* exported interface documented in desktop/browser_history.h */
665 browser_window_history_enumerate_cb cb, void *user_data)
666{
667 struct history_entry *e;
668
669 if (bw == NULL || bw->history == NULL || bw->history->current == NULL)
670 return;
671
672 for (e = bw->history->current->back; e != NULL; e = e->back) {
673 if (!cb(bw, e->x, e->y, e->x + LOCAL_HISTORY_WIDTH,
675 e, user_data))
676 break;
677 }
678}
679
680
681/* exported interface documented in desktop/browser_history.h */
683 browser_window_history_enumerate_cb cb, void *user_data)
684{
685 if (bw == NULL || bw->history == NULL)
686 return;
688 bw->history->start, cb, user_data);
689}
690
691
692/* exported interface documented in desktop/browser_history.h */
694{
695 return nsurl_ref(entry->page.url);
696}
697
698
699/* exported interface documented in desktop/browser_history.h */
701 const struct history_entry *entry)
702{
703 return (entry->page.frag_id) ? lwc_string_data(entry->page.frag_id) : 0;
704}
705
706
707/* exported interface documented in desktop/browser_history.h */
709 const struct history_entry *entry)
710{
711 return entry->page.title;
712}
nserror browser_window_history_add(struct browser_window *bw, struct hlcache_handle *content, lwc_string *frag_id)
Insert a url into the history tree.
static void browser_window_history__layout(struct history *history)
Compute node positions.
void browser_window_history_enumerate_back(const struct browser_window *bw, browser_window_history_enumerate_cb cb, void *user_data)
Enumerate all entries that will be reached by the 'back' button.
nserror browser_window_history_update(struct browser_window *bw, struct hlcache_handle *content)
Update the thumbnail and scroll offsets for the current entry.
nserror browser_window_history_get_thumbnail(struct browser_window *bw, struct bitmap **bitmap_out)
Get the thumbnail bitmap for the current history entry.
static struct history_entry * browser_window_history__clone_entry(struct history *history, struct history_entry *entry)
Clone a history entry.
nserror browser_window_history_forward(struct browser_window *bw, bool new_window)
Go forward in the history.
nserror browser_window_history_create(struct browser_window *bw)
Create a new history tree for a browser window window.
nsurl * browser_window_history_entry_get_url(const struct history_entry *entry)
Returns the URL to a history entry.
nserror browser_window_history_get_scroll(struct browser_window *bw, float *sx, float *sy)
Retrieve the stored scroll offsets for the current history entry.
nserror browser_window_history_go(struct browser_window *bw, struct history_entry *entry, bool new_window)
Navigate to specified history entry, optionally in new window.
static bool browser_window_history__enumerate_entry(const struct browser_window *bw, const struct history_entry *entry, browser_window_history_enumerate_cb cb, void *ud)
Enumerate subentries in history See also history_enumerate()
static int browser_window_history__layout_subtree(struct history *history, struct history_entry *entry, int x, int y)
Recursively position a subtree.
void browser_window_history_enumerate_forward(const struct browser_window *bw, browser_window_history_enumerate_cb cb, void *user_data)
Enumerate all entries that will be reached by the 'forward' button.
static void browser_window_history__free_entry(struct history_entry *entry)
Free an entry in the tree recursively.
const char * browser_window_history_entry_get_title(const struct history_entry *entry)
Returns the title of a history entry.
nserror browser_window_history_clone(const struct browser_window *existing, struct browser_window *clone)
Clone a bw's history tree for new bw.
void browser_window_history_enumerate(const struct browser_window *bw, browser_window_history_enumerate_cb cb, void *user_data)
Enumerate all entries in the history.
bool browser_window_history_forward_available(struct browser_window *bw)
Check whether it is pssible to go forwards in the history.
const char * browser_window_history_entry_get_fragment_id(const struct history_entry *entry)
Returns the URL to a history entry.
bool browser_window_history_back_available(struct browser_window *bw)
Check whether it is pssible to go back in the history.
nserror browser_window_history_back(struct browser_window *bw, bool new_window)
Go back in the history.
void browser_window_history_destroy(struct browser_window *bw)
Free a history structure.
Interface to browser history operations.
bool(* browser_window_history_enumerate_cb)(const struct browser_window *bw, int x0, int y0, int x1, int y1, const struct history_entry *entry, void *user_data)
Callback function type for history enumeration.
Browser window private structure.
nserror browser_window__reload_current_parameters(struct browser_window *bw)
Navigate a browser window to the current parameters.
Browser window creation and manipulation interface.
nserror browser_window_navigate(struct browser_window *bw, struct nsurl *url, struct nsurl *referrer, enum browser_window_nav_flags flags, char *post_urlenc, struct fetch_multipart_data *post_multipart, struct hlcache_handle *parent)
Start fetching a page in a browser window.
nserror browser_window_create(enum browser_window_create_flags flags, struct nsurl *url, struct nsurl *referrer, struct browser_window *existing, struct browser_window **bw)
Create and open a new root browser window with the given page.
@ BW_CREATE_CLONE
New gui_window to be clone of "existing" gui_window.
@ BW_NAVIGATE_HISTORY
this will form a new history node (don't set for back/reload/etc)
@ BW_NAVIGATE_NO_TERMINAL_HISTORY_UPDATE
suppress initial history updates (used by back/fwd/etc)
Useful interned string pointers (interface).
nserror
Enumeration of error codes.
Definition: errors.h:29
@ NSERROR_BAD_PARAMETER
Bad Parameter.
Definition: errors.h:48
@ NSERROR_INVALID
Invalid data.
Definition: errors.h:49
@ NSERROR_NOMEM
Memory exhaustion.
Definition: errors.h:32
@ NSERROR_OK
No error.
Definition: errors.h:30
struct netsurf_table * guit
The global interface table.
Definition: gui_factory.c:49
Interface to core interface table.
High-level resource cache interface.
Generic bitmap handling interface.
@ BITMAP_CLEAR
memory should be wiped to 0
Definition: bitmap.h:39
@ BITMAP_OPAQUE
image is opaque
Definition: bitmap.h:38
Public content interface.
struct nsurl * hlcache_handle_get_url(const struct hlcache_handle *handle)
Retrieve the URL associated with a high level cache handle.
const char * content_get_title(struct hlcache_handle *h)
Retrieve title associated with content.
Definition: content.c:1106
int content_get_height(struct hlcache_handle *h)
Retrieve height of content.
Definition: content.c:1175
struct bitmap * content_get_bitmap(struct hlcache_handle *h)
Retrieve the bitmap contained in an image content.
Definition: content.c:1264
int content_get_width(struct hlcache_handle *h)
Retrieve width of content.
Definition: content.c:1158
Interface to platform-specific layout operation table.
Interface to platform-specific graphical user interface window operations.
Interface to browser history private operations.
#define LOCAL_HISTORY_RIGHT_MARGIN
#define LOCAL_HISTORY_WIDTH
#define LOCAL_HISTORY_BOTTOM_MARGIN
#define LOCAL_HISTORY_HEIGHT
#define NSLOG(catname, level, logmsg, args...)
Definition: log.h:116
void nsurl_unref(nsurl *url)
Drop a reference to a NetSurf URL object.
nserror nsurl_refragment(const nsurl *url, lwc_string *frag, nsurl **new_url)
Create a NetSurf URL object, adding a fragment to an existing URL object.
const char * nsurl_access(const nsurl *url)
Access a NetSurf URL object as a string.
nsurl * nsurl_ref(nsurl *url)
Increment the reference count to a NetSurf URL object.
struct nsurl nsurl
NetSurf URL object.
Definition: nsurl.h:31
Interface to utility string handling.
RISC OS wimp toolkit bitmap.
Definition: bitmap.c:68
struct nsurl * url
The URL to fetch.
Browser window data.
struct gui_window * window
Platform specific window data only valid at top level.
struct history * history
local history handle.
struct hlcache_handle * current_content
Content handle of page currently displayed which must have READY or DONE status or NULL for no conten...
bool internal_nav
Internal navigation, do not update URL etc.
struct browser_fetch_parameters current_parameters
The fetch parameters for the current content.
Content which corresponds to a single URL.
int(* get_height)(void *bitmap)
Get the bitmap height.
Definition: bitmap.h:193
void(* destroy)(void *bitmap)
Destroy a bitmap.
Definition: bitmap.h:143
void *(* create)(int width, int height, enum gui_bitmap_flags flags)
Create a new bitmap.
Definition: bitmap.h:136
nserror(* render)(struct bitmap *bitmap, struct hlcache_handle *content)
Render content into a bitmap.
Definition: bitmap.h:208
size_t(* get_rowstride)(void *bitmap)
Get the number of bytes per row of the image.
Definition: bitmap.h:177
unsigned char *(* get_buffer)(void *bitmap)
Get the image buffer from a bitmap.
Definition: bitmap.h:169
bool(* get_scroll)(struct gui_window *gw, int *sx, int *sy)
Get the scroll position of a browser window.
Definition: window.h:205
A node in the history tree.
int x
Position of node.
struct history_entry * forward_last
Last child.
struct history_entry * back
Parent.
unsigned int children
Number of children.
struct history_entry * forward
First child.
struct history_entry * next
Next sibling.
struct history_page page
struct history_entry * forward_pref
Child in direction of current entry.
int y
Position of node.
float scroll_y
Scroll Y offset when visited.
lwc_string * frag_id
float scroll_x
Scroll X offset when visited.
struct bitmap * bitmap
Thumbnail bitmap, or NULL.
char * title
Fragment identifier, or NULL.
struct nsurl * url
Page URL, never NULL.
History tree for a window.
int width
Width of layout.
int height
Height of layout.
struct history_entry * current
Current position in tree.
struct history_entry * start
First page in tree (page that window opened with).
High-level cache handle.
Definition: hlcache.c:66
struct gui_window_table * window
Window table.
Definition: gui_table.h:66
struct gui_bitmap_table * bitmap
Bitmap table.
Definition: gui_table.h:144
Interface to time operations.
Unified URL information database internal interface.
Interface to a number of general purpose functionality.
static nserror bitmap(const struct redraw_context *ctx, struct bitmap *bitmap, int x, int y, int width, int height, colour bg, bitmap_flags_t flags)
Plot a bitmap.
Definition: plot.c:857