NetSurf
browser_window.c
Go to the documentation of this file.
1/*
2 * Copyright 2008 Michael Drake <tlsa@netsurf-browser.org>
3 * Copyright 2010 Daniel Silverstone <dsilvers@digital-scurf.org>
4 * Copyright 2010-2020 Vincent Sanders <vince@netsurf-browser.org>
5 *
6 * This file is part of NetSurf, http://www.netsurf-browser.org/
7 *
8 * NetSurf is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; version 2 of the License.
11 *
12 * NetSurf is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program. If not, see <http://www.gnu.org/licenses/>.
19 */
20
21/**
22 * \file
23 *
24 * Browser window creation and manipulation implementation.
25 */
26
27#include "utils/config.h"
28
29#include <stdlib.h>
30#include <string.h>
31#include <math.h>
32#include <nsutils/time.h>
33
34#include "utils/errors.h"
35#include "utils/log.h"
36#include "utils/corestrings.h"
37#include "utils/messages.h"
38#include "utils/nsoption.h"
39#include "netsurf/types.h"
41#include "netsurf/window.h"
42#include "netsurf/misc.h"
43#include "netsurf/content.h"
44#include "netsurf/search.h"
45#include "netsurf/plotters.h"
46#include "content/content.h"
47#include "content/hlcache.h"
48#include "content/urldb.h"
50
51#include "html/html.h"
52#include "html/form_internal.h"
53#include "javascript/js.h"
54
56#include "desktop/scrollbar.h"
58#include "desktop/download.h"
59#include "desktop/frames.h"
61#include "desktop/textinput.h"
62#include "desktop/hotlist.h"
63#include "desktop/knockout.h"
65#include "desktop/theme.h"
66
67#ifdef WITH_THEME_INSTALL
68#include "desktop/theme.h"
69#endif
70
71/**
72 * smallest scale that can be applied to a browser window
73 */
74#define SCALE_MINIMUM 0.2
75
76/**
77 * largests scale that can be applied to a browser window
78 */
79#define SCALE_MAXIMUM 10.0
80
81/**
82 * maximum frame depth
83 */
84#define FRAME_DEPTH 8
85
86/* Forward declare internal navigation function */
88 struct browser_window *bw, struct browser_fetch_parameters *params);
89
90
91/**
92 * Close and destroy all child browser window.
93 *
94 * \param bw browser window
95 */
97{
98 int i;
99
100 if (bw->children) {
101 for (i = 0; i < (bw->rows * bw->cols); i++) {
103 }
104 free(bw->children);
105 bw->children = NULL;
106 bw->rows = 0;
107 bw->cols = 0;
108 }
109}
110
111
112/**
113 * Free the stored fetch parameters
114 *
115 * \param bw The browser window
116 */
117static void
119{
120 if (params->url != NULL) {
121 nsurl_unref(params->url);
122 params->url = NULL;
123 }
124 if (params->referrer != NULL) {
125 nsurl_unref(params->referrer);
126 params->referrer = NULL;
127 }
128 if (params->post_urlenc != NULL) {
129 free(params->post_urlenc);
130 params->post_urlenc = NULL;
131 }
132 if (params->post_multipart != NULL) {
134 params->post_multipart = NULL;
135 }
136 if (params->parent_charset != NULL) {
137 free(params->parent_charset);
138 params->parent_charset = NULL;
139 }
140}
141
142
143/**
144 * Get position of scrollbar widget within browser window.
145 *
146 * \param bw The browser window
147 * \param horizontal Whether to get position of horizontal scrollbar
148 * \param x Updated to x-coord of top left of scrollbar widget
149 * \param y Updated to y-coord of top left of scrollbar widget
150 */
151static inline void
153 bool horizontal,
154 int *x, int *y)
155{
156 if (horizontal) {
157 *x = 0;
158 *y = bw->height - SCROLLBAR_WIDTH;
159 } else {
160 *x = bw->width - SCROLLBAR_WIDTH;
161 *y = 0;
162 }
163}
164
165
166/**
167 * Get browser window horizontal scrollbar widget length
168 *
169 * \param bw The browser window
170 * \return the scrollbar's length
171 */
172static inline int get_horz_scrollbar_len(struct browser_window *bw)
173{
174 if (bw->scroll_y == NULL) {
175 return bw->width;
176 }
177 return bw->width - SCROLLBAR_WIDTH;
178}
179
180
181/**
182 * Get browser window vertical scrollbar widget length
183 *
184 * \param bw The browser window
185 * \return the scrollbar's length
186 */
187static inline int get_vert_scrollbar_len(struct browser_window *bw)
188{
189 return bw->height;
190}
191
192
193/**
194 * Set or remove a selection.
195 *
196 * \param bw browser window with selection
197 * \param selection true if bw has a selection, false if removing selection
198 * \param read_only true iff selection is read only (e.g. can't cut it)
199 */
200static void
202 bool selection,
203 bool read_only)
204{
205 struct browser_window *top;
206
207 assert(bw != NULL);
208
210
211 assert(top != NULL);
212
213 if (bw != top->selection.bw &&
214 top->selection.bw != NULL &&
215 top->selection.bw->current_content != NULL) {
216 /* clear old selection */
218 }
219
220 if (selection) {
221 top->selection.bw = bw;
222 } else {
223 top->selection.bw = NULL;
224 }
225
227}
228
229
230/**
231 * Set the scroll position of a browser window.
232 *
233 * scrolls the viewport to ensure the specified rectangle of the
234 * content is shown.
235 *
236 * \param bw window to scroll
237 * \param rect The rectangle to ensure is shown.
238 * \return NSERROR_OK on success or apropriate error code.
239 */
240static nserror
242{
243 if (bw->window != NULL) {
244 return guit->window->set_scroll(bw->window, rect);
245 }
246
247 if (bw->scroll_x != NULL) {
248 scrollbar_set(bw->scroll_x, rect->x0, false);
249 }
250 if (bw->scroll_y != NULL) {
251 scrollbar_set(bw->scroll_y, rect->y0, false);
252 }
253
254 return NSERROR_OK;
255}
256
257
258/**
259 * Internal helper for getting the positional features
260 *
261 * \param[in] bw browser window to examine.
262 * \param[in] x x-coordinate of point of interest
263 * \param[in] y y-coordinate of point of interest
264 * \param[out] data Feature structure to update.
265 * \return NSERROR_OK or appropriate error code on faliure.
266 */
267static nserror
269 int x, int y,
270 struct browser_window_features *data)
271{
272 nserror ret = NSERROR_OK;
273
274 /* Handle (i)frame scroll offset (core-managed browser windows only) */
277
278 if (bw->children) {
279 /* Browser window has children, so pass request on to
280 * appropriate child.
281 */
282 struct browser_window *bwc;
283 int cur_child;
284 int children = bw->rows * bw->cols;
285
286 /* Loop through all children of bw */
287 for (cur_child = 0; cur_child < children; cur_child++) {
288 /* Set current child */
289 bwc = &bw->children[cur_child];
290
291 /* Skip this frame if (x, y) coord lies outside */
292 if ((x < bwc->x) ||
293 (bwc->x + bwc->width < x) ||
294 (y < bwc->y) ||
295 (bwc->y + bwc->height < y)) {
296 continue;
297 }
298
299 /* Pass request into this child */
301 (x - bwc->x), (y - bwc->y), data);
302 }
303
304 /* Coordinate not contained by any frame */
305
306 } else if (bw->current_content != NULL) {
307 /* Pass request to content */
309 x, y, data);
310 data->main = bw->current_content;
311 }
312
313 return ret;
314}
315
316
317/**
318 * implements the download operation of a window navigate
319 */
320static nserror
322 nsurl *url,
323 nsurl *nsref,
324 uint32_t fetch_flags,
325 bool fetch_is_post,
326 llcache_post_data *post)
327{
329 struct browser_window *root;
330 nserror error;
331
333 assert(root != NULL);
334
335 fetch_flags |= LLCACHE_RETRIEVE_FORCE_FETCH;
336 fetch_flags |= LLCACHE_RETRIEVE_STREAM_DATA;
337
338 error = llcache_handle_retrieve(url, fetch_flags, nsref,
339 fetch_is_post ? post : NULL,
340 NULL, NULL, &l);
341 if (error == NSERROR_NO_FETCH_HANDLER) {
342 /* no internal handler for this type, call out to frontend */
343 error = guit->misc->launch_url(url);
344 } else if (error != NSERROR_OK) {
345 NSLOG(netsurf, INFO, "Failed to fetch download: %d", error);
346 } else {
347 error = download_context_create(l, root->window);
348 if (error != NSERROR_OK) {
349 NSLOG(netsurf, INFO,
350 "Failed creating download context: %d", error);
353 }
354 }
355
356 return error;
357}
358
359
360/**
361 * recursively check browser windows for activity
362 *
363 * \param bw browser window to start checking from.
364 */
366{
367 int children, index;
368
369 if (bw->throbbing)
370 return true;
371
372 if (bw->children) {
373 children = bw->rows * bw->cols;
374 for (index = 0; index < children; index++) {
376 return true;
377 }
378 }
379
380 if (bw->iframes) {
381 for (index = 0; index < bw->iframe_count; index++) {
383 return true;
384 }
385 }
386
387 return false;
388}
389
390
391/**
392 * Start the busy indicator.
393 *
394 * \param bw browser window
395 */
397{
398 bw->throbbing = true;
399
400 while (bw->parent)
401 bw = bw->parent;
402
404}
405
406
407/**
408 * Stop the busy indicator.
409 *
410 * \param bw browser window
411 */
413{
414 nserror res = NSERROR_OK;
415
416 bw->throbbing = false;
417
418 while (bw->parent) {
419 bw = bw->parent;
420 }
421
424 }
425 return res;
426}
427
428
429/**
430 * Callback for fetchcache() for browser window favicon fetches.
431 *
432 * \param c content handle of favicon
433 * \param event The event to process
434 * \param pw a context containing the browser window
435 * \return NSERROR_OK on success else appropriate error code.
436 */
437static nserror
439 const hlcache_event *event,
440 void *pw)
441{
442 struct browser_window *bw = pw;
443
444 switch (event->type) {
445 case CONTENT_MSG_DONE:
446 if (bw->favicon.current != NULL) {
449 }
450
451 bw->favicon.current = c;
452 bw->favicon.loading = NULL;
453
454 /* content_get_bitmap on the hlcache_handle should give
455 * the favicon bitmap at this point
456 */
458 break;
459
461
462 /* clean up after ourselves */
463 if (c == bw->favicon.loading) {
464 bw->favicon.loading = NULL;
465 } else if (c == bw->favicon.current) {
466 bw->favicon.current = NULL;
467 }
468
470
471 if (bw->favicon.failed == false) {
472 nsurl *nsref = NULL;
473 nsurl *nsurl;
474 nserror error;
475
476 bw->favicon.failed = true;
477
478 error = nsurl_create("resource:favicon.ico", &nsurl);
479 if (error != NSERROR_OK) {
480 NSLOG(netsurf, INFO,
481 "Unable to create default location url");
482 } else {
485 nsref, NULL,
487 bw, NULL, CONTENT_IMAGE,
488 &bw->favicon.loading);
489
491 }
492
493 }
494 break;
495
496 default:
497 break;
498
499 }
500 return NSERROR_OK;
501}
502
503
504/**
505 * update the favicon associated with the browser window
506 *
507 * \param c the page content handle.
508 * \param bw A top level browser window.
509 * \param link A link context or NULL to attempt fallback scanning.
510 */
511static nserror
513 struct browser_window *bw,
514 struct content_rfc5988_link *link)
515{
516 nsurl *nsref = NULL;
517 nsurl *nsurl;
518 nserror res;
519
520 assert(c != NULL);
521 assert(bw !=NULL);
522
523 if (bw->window == NULL) {
524 /* Not top-level browser window; not interested */
525 return NSERROR_OK;
526 }
527
528 /* already fetching the favicon - use that */
529 if (bw->favicon.loading != NULL) {
530 return NSERROR_OK;
531 }
532
533 bw->favicon.failed = false;
534
535 if (link == NULL) {
536 /* Look for "icon" */
537 link = content_find_rfc5988_link(c, corestring_lwc_icon);
538 }
539
540 if (link == NULL) {
541 /* Look for "shortcut icon" */
542 link = content_find_rfc5988_link(c, corestring_lwc_shortcut_icon);
543 }
544
545 if (link == NULL) {
546 lwc_string *scheme;
547 bool speculative_default = false;
548 bool match;
549
551
553
554 /* If the document was fetched over http(s), then speculate
555 * that there's a favicon living at /favicon.ico */
556 if ((lwc_string_caseless_isequal(scheme,
557 corestring_lwc_http,
558 &match) == lwc_error_ok &&
559 match) ||
560 (lwc_string_caseless_isequal(scheme,
561 corestring_lwc_https,
562 &match) == lwc_error_ok &&
563 match)) {
564 speculative_default = true;
565 }
566
567 lwc_string_unref(scheme);
568
569 if (speculative_default) {
570 /* no favicon via link, try for the default location */
571 res = nsurl_join(nsurl, "/favicon.ico", &nsurl);
572 } else {
573 bw->favicon.failed = true;
574 res = nsurl_create("resource:favicon.ico", &nsurl);
575 }
576 if (res != NSERROR_OK) {
577 NSLOG(netsurf, INFO,
578 "Unable to create default location url");
579 return res;
580 }
581 } else {
582 nsurl = nsurl_ref(link->href);
583 }
584
585 if (link == NULL) {
586 NSLOG(netsurf, INFO,
587 "fetching general favicon from '%s'",
589 } else {
590 NSLOG(netsurf, INFO,
591 "fetching favicon rel:%s '%s'",
592 lwc_string_data(link->rel),
594 }
595
598 nsref,
599 NULL,
601 bw,
602 NULL,
604 &bw->favicon.loading);
605
607
608 return res;
609}
610
611
612/**
613 * Handle meta http-equiv refresh time elapsing by loading a new page.
614 *
615 * \param p browser window to refresh with new page
616 */
617static void browser_window_refresh(void *p)
618{
619 struct browser_window *bw = p;
620 nsurl *url;
621 nsurl *refresh;
622 hlcache_handle *parent = NULL;
624
625 assert(bw->current_content != NULL &&
630
631 /* Ignore if the refresh URL has gone
632 * (may happen if a fetch error occurred) */
634 if (refresh == NULL)
635 return;
636
637 /* mark this content as invalid so it gets flushed from the cache */
639
641 if ((url == NULL) || (nsurl_compare(url, refresh, NSURL_COMPLETE))) {
642 flags |= BW_NAVIGATE_HISTORY;
643 }
644
645 /* Treat an (almost) immediate refresh in a top-level browser window as
646 * if it were an HTTP redirect, and thus make the resulting fetch
647 * verifiable.
648 *
649 * See fetchcache.c for why redirected fetches should be verifiable at
650 * all.
651 */
652 if (bw->refresh_interval <= 100 && bw->parent == NULL) {
653 flags &= ~BW_NAVIGATE_UNVERIFIABLE;
654 } else {
656 }
657
659 refresh,
660 url,
661 flags,
662 NULL,
663 NULL,
664 parent);
665
666}
667
668
669/**
670 * Transfer the loading_content to a new download window.
671 */
672static void
674 llcache_handle *stream)
675{
677 nserror error;
678
679 assert(root != NULL);
680
681 error = download_context_create(stream, root->window);
682 if (error != NSERROR_OK) {
683 llcache_handle_abort(stream);
685 }
686
687 /* remove content from browser window */
689 bw->loading_content = NULL;
690
692}
693
694
695/**
696 * scroll to a fragment if present
697 *
698 * \param bw browser window
699 * \return true if the scroll was sucessful
700 */
701static bool frag_scroll(struct browser_window *bw)
702{
703 struct rect rect;
704
705 if (bw->frag_id == NULL) {
706 return false;
707 }
708
710 bw->frag_id,
711 &rect.x0,
712 &rect.y0)) {
713 return false;
714 }
715
716 rect.x1 = rect.x0;
717 rect.y1 = rect.y0;
719 if (bw->current_content != NULL &&
720 bw->history != NULL &&
721 bw->history->current != NULL) {
723 }
724 return true;
725 }
726 return false;
727}
728
729
730/**
731 * Redraw browser window, set extent to content, and update title.
732 *
733 * \param bw browser_window
734 * \param scroll_to_top move view to top of page
735 */
736static void browser_window_update(struct browser_window *bw, bool scroll_to_top)
737{
738 static const struct rect zrect = {
739 .x0 = 0,
740 .y0 = 0,
741 .x1 = 0,
742 .y1 = 0
743 };
744
745 if (bw->current_content == NULL) {
746 return;
747 }
748
749 switch (bw->browser_window_type) {
750
751 case BROWSER_WINDOW_NORMAL:
752 /* Root browser window, constituting a front end window/tab */
755
757
758 /* if frag_id exists, then try to scroll to it */
759 /** @todo don't do this if the user has scrolled */
760 if (!frag_scroll(bw)) {
761 if (scroll_to_top) {
762 browser_window_set_scroll(bw, &zrect);
763 }
764 }
765
766 guit->window->invalidate(bw->window, NULL);
767
768 break;
769
770 case BROWSER_WINDOW_IFRAME:
771 /* Internal iframe browser window */
772 assert(bw->parent != NULL);
773 assert(bw->parent->current_content != NULL);
774
776
777 if (scroll_to_top) {
778 browser_window_set_scroll(bw, &zrect);
779 }
780
781 /* if frag_id exists, then try to scroll to it */
782 /** @todo don't do this if the user has scrolled */
783 frag_scroll(bw);
784
786
787 break;
788
789 case BROWSER_WINDOW_FRAME:
790 {
791 struct rect rect;
793
794 if (scroll_to_top) {
795 browser_window_set_scroll(bw, &zrect);
796 }
797
798 /* if frag_id exists, then try to scroll to it */
799 /** @todo don't do this if the user has scrolled */
800 frag_scroll(bw);
801
804 rect.x1 = rect.x0 + bw->width;
805 rect.y1 = rect.y0 + bw->height;
806
808 }
809 break;
810
811 default:
812 case BROWSER_WINDOW_FRAMESET:
813 /* Nothing to do */
814 break;
815 }
816}
817
818
819/**
820 * handle message for content ready on browser window
821 */
823{
824 int width, height;
825 nserror res = NSERROR_OK;
826
827 /* close and release the current window content */
828 if (bw->current_content != NULL) {
831 }
832
834 bw->loading_content = NULL;
835
836 if (!bw->internal_nav) {
837 /* Transfer the fetch parameters */
840 memset(&bw->loading_parameters, 0, sizeof(bw->loading_parameters));
841 /* Transfer the certificate chain */
844 bw->loading_cert_chain = NULL;
845 }
846
847 /* Format the new content to the correct dimensions */
849 width /= bw->scale;
850 height /= bw->scale;
852
853 /* history */
854 if (bw->history_add && bw->history && !bw->internal_nav) {
856
857 if (urldb_add_url(url)) {
862
863 /* This is safe as we've just added the URL */
865 }
866 /**
867 * \todo Urldb / Thumbnails / Local history brokenness
868 *
869 * We add to local history after calling urldb_add_url rather
870 * than in the block above. If urldb_add_url fails (as it
871 * will for urls like "about:about", "about:config" etc),
872 * there would be no local history node, and later calls to
873 * history_update will either explode or overwrite the node
874 * for the previous URL.
875 *
876 * We call it after, rather than before urldb_add_url because
877 * history_add calls bitmap render, which tries to register
878 * the thumbnail with urldb. That thumbnail registration
879 * fails if the url doesn't exist in urldb already, and only
880 * urldb-registered thumbnails get freed. So if we called
881 * history_add before urldb_add_url we would leak thumbnails
882 * for all newly visited URLs. With the history_add call
883 * after, we only leak the thumbnails when urldb does not add
884 * the URL.
885 *
886 * Also, since browser_window_history_add can create a
887 * thumbnail (content_redraw), we need to do it after
888 * content_reformat.
889 */
891 }
892
894
895 if (bw->window != NULL) {
897
899 }
900
901 /* new content; set scroll_to_top */
902 browser_window_update(bw, true);
903 content_open(bw->current_content, bw, 0, 0);
905
906 /* frames */
908
909 /* iframes */
911
912 /* Indicate page status may have changed */
913 if (res == NSERROR_OK) {
916 }
917
918 return res;
919}
920
921
922/**
923 * handle message for content done on browser window
924 */
925static nserror
927{
928 float sx, sy;
929 struct rect rect;
930 int scrollx;
931 int scrolly;
932
933 if (bw->window == NULL) {
934 /* Updated browser window's scrollbars. */
935 /**
936 * \todo update browser window scrollbars before CONTENT_MSG_DONE
937 */
938 browser_window_reformat(bw, true, bw->width, bw->height);
940 }
941
942 browser_window_update(bw, false);
946
947 if (browser_window_history_get_scroll(bw, &sx, &sy) == NSERROR_OK) {
948 scrollx = (int)((float)content_get_width(bw->current_content) * sx);
949 scrolly = (int)((float)content_get_height(bw->current_content) * sy);
950 rect.x0 = rect.x1 = scrollx;
951 rect.y0 = rect.y1 = scrolly;
953 NSLOG(netsurf, WARNING,
954 "Unable to set browser scroll offsets to %d by %d",
955 scrollx, scrolly);
956 }
957 }
958
959 if (!bw->internal_nav) {
962 }
963
964 if (bw->refresh_interval != -1) {
967 }
968
969 return NSERROR_OK;
970}
971
972
973/**
974 * Handle query responses from SSL requests
975 */
976static nserror
978{
979 struct browser_window *bw = (struct browser_window *)pw;
980
981 /* If we're in the process of loading, stop the load */
982 if (bw->loading_content != NULL) {
983 /* We had a loading content (maybe auth page?) */
988 }
989
990 if (!proceed) {
991 /* We're processing a "back to safety", do a rough-and-ready
992 * nav to the old 'current' parameters, with any post data
993 * stripped away
994 */
996 }
997
998 /* We're processing a "proceed" attempt from the form */
999 /* First, we permit the SSL */
1001
1002 /* And then we navigate to the original loading parameters */
1003 bw->internal_nav = false;
1004
1006}
1007
1008
1009/**
1010 * Unpack a "username:password" to components.
1011 *
1012 * \param[in] userpass The input string to split.
1013 * \param[in] username_out Returns username on success. Owned by caller.
1014 * \param[out] password_out Returns password on success. Owned by caller.
1015 * \return NSERROR_OK, or appropriate error code.
1016 */
1017static nserror
1019 char **username_out,
1020 char **password_out)
1021{
1022 const char *tmp;
1023 char *username;
1024 char *password;
1025 size_t len;
1026
1027 if (userpass == NULL) {
1028 username = malloc(1);
1029 password = malloc(1);
1030 if (username == NULL || password == NULL) {
1031 free(username);
1032 free(password);
1033 return NSERROR_NOMEM;
1034 }
1035 username[0] = '\0';
1036 password[0] = '\0';
1037
1038 *username_out = username;
1039 *password_out = password;
1040 return NSERROR_OK;
1041 }
1042
1043 tmp = strchr(userpass, ':');
1044 if (tmp == NULL) {
1045 return NSERROR_BAD_PARAMETER;
1046 } else {
1047 size_t len2;
1048 len = tmp - userpass;
1049 len2 = strlen(++tmp);
1050
1051 username = malloc(len + 1);
1052 password = malloc(len2 + 1);
1053 if (username == NULL || password == NULL) {
1054 free(username);
1055 free(password);
1056 return NSERROR_NOMEM;
1057 }
1058 memcpy(username, userpass, len);
1059 username[len] = '\0';
1060 memcpy(password, tmp, len2 + 1);
1061 }
1062
1063 *username_out = username;
1064 *password_out = password;
1065 return NSERROR_OK;
1066}
1067
1068
1069/**
1070 * Build a "username:password" from components.
1071 *
1072 * \param[in] username The username component.
1073 * \param[in] password The password component.
1074 * \param[out] userpass_out Returns combined string on success.
1075 * Owned by caller.
1076 * \return NSERROR_OK, or appropriate error code.
1077 */
1078static nserror
1080 const char *password,
1081 char **userpass_out)
1082{
1083 char *userpass;
1084 size_t len;
1085
1086 len = strlen(username) + 1 + strlen(password) + 1;
1087
1088 userpass = malloc(len);
1089 if (userpass == NULL) {
1090 return NSERROR_NOMEM;
1091 }
1092
1093 snprintf(userpass, len, "%s:%s", username, password);
1094
1095 *userpass_out = userpass;
1096 return NSERROR_OK;
1097}
1098
1099
1100/**
1101 * Handle a response from the UI when prompted for credentials
1102 */
1103static nserror
1105 const char *realm,
1106 const char *username,
1107 const char *password,
1108 void *pw)
1109{
1110 struct browser_window *bw = (struct browser_window *)pw;
1111 char *userpass;
1112 nserror err;
1113
1114 err = browser_window__build_userpass(username, password, &userpass);
1115 if (err != NSERROR_OK) {
1116 return err;
1117 }
1118
1119 urldb_set_auth_details(url, realm, userpass);
1120
1121 free(userpass);
1122
1123 /**
1124 * \todo QUERY - Eventually this should fill out the form *NOT* nav
1125 * to the original location
1126 */
1127 /* Finally navigate to the original loading parameters */
1128 if (bw->loading_content != NULL) {
1129 /* We had a loading content (maybe auth page?) */
1134 }
1135 bw->internal_nav = false;
1137}
1138
1139
1140/**
1141 * Handle login request (BAD_AUTH) during fetch
1142 *
1143 */
1144static nserror
1146 const char *realm,
1147 nsurl *url) {
1148 char *username = NULL, *password = NULL;
1149 nserror err = NSERROR_OK;
1150 struct browser_fetch_parameters params;
1151
1152 memset(&params, 0, sizeof(params));
1153
1154 /* Step one, retrieve what we have */
1157 &username, &password);
1158 if (err != NSERROR_OK) {
1159 goto out;
1160 }
1161
1162 /* Step two, construct our fetch parameters */
1163 params.url = nsurl_ref(corestring_nsurl_about_query_auth);
1164 params.referrer = nsurl_ref(url);
1166
1168 "siteurl",
1169 nsurl_access(url));
1170 if (err != NSERROR_OK) {
1171 goto out;
1172 }
1173
1175 "realm",
1176 realm);
1177 if (err != NSERROR_OK) {
1178 goto out;
1179 }
1180
1182 "username",
1183 username);
1184 if (err != NSERROR_OK) {
1185 goto out;
1186 }
1187
1189 "password",
1190 password);
1191 if (err != NSERROR_OK) {
1192 goto out;
1193 }
1194
1195 /* Now we issue the fetch */
1196 bw->internal_nav = true;
1197 err = browser_window__navigate_internal(bw, &params);
1198
1199 if (err != NSERROR_OK) {
1200 goto out;
1201 }
1202
1203 err = guit->misc->login(url, realm, username, password,
1205
1206 if (err == NSERROR_NOT_IMPLEMENTED) {
1207 err = NSERROR_OK;
1208 }
1209 out:
1210 if (username != NULL) {
1211 free(username);
1212 }
1213 if (password != NULL) {
1214 free(password);
1215 }
1217 return err;
1218}
1219
1220
1221/**
1222 * Handle a certificate verification request (BAD_CERTS) during a fetch
1223 */
1224static nserror
1226 nsurl *url)
1227{
1228 struct browser_fetch_parameters params;
1229 nserror err;
1230 /* Initially we don't know WHY the SSL cert was bad */
1231 const char *reason = messages_get_sslcode(SSL_CERT_ERR_UNKNOWN);
1232 size_t depth;
1233 nsurl *chainurl = NULL;
1234
1235 memset(&params, 0, sizeof(params));
1236
1237 params.url = nsurl_ref(corestring_nsurl_about_query_ssl);
1238 params.referrer = nsurl_ref(url);
1240
1242 "siteurl",
1243 nsurl_access(url));
1244 if (err != NSERROR_OK) {
1245 goto out;
1246 }
1247
1248 if (bw->loading_cert_chain != NULL) {
1249 for (depth = 0; depth < bw->loading_cert_chain->depth; ++depth) {
1250 size_t idx = bw->loading_cert_chain->depth - (depth + 1);
1251 ssl_cert_err err = bw->loading_cert_chain->certs[idx].err;
1252 if (err != SSL_CERT_ERR_OK) {
1253 reason = messages_get_sslcode(err);
1254 break;
1255 }
1256 }
1257
1258 err = cert_chain_to_query(bw->loading_cert_chain, &chainurl);
1259 if (err != NSERROR_OK) {
1260 goto out;
1261 }
1262
1264 "chainurl",
1265 nsurl_access(chainurl));
1266 if (err != NSERROR_OK) {
1267 goto out;
1268 }
1269 }
1270
1272 "reason",
1273 reason);
1274 if (err != NSERROR_OK) {
1275 goto out;
1276 }
1277
1278 /* Now we issue the fetch */
1279 bw->internal_nav = true;
1280 err = browser_window__navigate_internal(bw, &params);
1281 if (err != NSERROR_OK) {
1282 goto out;
1283 }
1284
1285 out:
1287 if (chainurl != NULL)
1288 nsurl_unref(chainurl);
1289 return err;
1290}
1291
1292
1293/**
1294 * Handle a timeout during a fetch
1295 */
1296static nserror
1298{
1299 struct browser_fetch_parameters params;
1300 nserror err;
1301
1302 memset(&params, 0, sizeof(params));
1303
1304 params.url = nsurl_ref(corestring_nsurl_about_query_timeout);
1305 params.referrer = nsurl_ref(url);
1307
1309 "siteurl",
1310 nsurl_access(url));
1311 if (err != NSERROR_OK) {
1312 goto out;
1313 }
1314
1315 /* Now we issue the fetch */
1316 bw->internal_nav = true;
1317 err = browser_window__navigate_internal(bw, &params);
1318 if (err != NSERROR_OK) {
1319 goto out;
1320 }
1321
1322 out:
1324 return err;
1325}
1326
1327
1328/**
1329 * Handle non specific errors during a fetch
1330 */
1331static nserror
1333 const char *reason,
1334 nsurl *url)
1335{
1336 struct browser_fetch_parameters params;
1337 nserror err;
1338
1339 memset(&params, 0, sizeof(params));
1340
1341 params.url = nsurl_ref(corestring_nsurl_about_query_fetcherror);
1342 params.referrer = nsurl_ref(url);
1344
1346 "siteurl",
1347 nsurl_access(url));
1348 if (err != NSERROR_OK) {
1349 goto out;
1350 }
1351
1353 "reason",
1354 reason);
1355 if (err != NSERROR_OK) {
1356 goto out;
1357 }
1358
1359 /* Now we issue the fetch */
1360 bw->internal_nav = true;
1361 err = browser_window__navigate_internal(bw, &params);
1362 if (err != NSERROR_OK) {
1363 goto out;
1364 }
1365
1366 out:
1368 return err;
1369}
1370
1371
1372/**
1373 * Handle errors during content fetch
1374 */
1375static nserror
1377 hlcache_handle *c,
1378 const hlcache_event *event)
1379{
1380 const char *message = event->data.errordata.errormsg;
1381 nserror code = event->data.errordata.errorcode;
1382 nserror res;
1384
1385 /* Unexpected OK? */
1386 assert(code != NSERROR_OK);
1387
1388 if (message == NULL) {
1389 message = messages_get_errorcode(code);
1390 } else {
1391 message = messages_get(message);
1392 }
1393
1394 if (c == bw->loading_content) {
1395 bw->loading_content = NULL;
1396 } else if (c == bw->current_content) {
1397 bw->current_content = NULL;
1398 browser_window_remove_caret(bw, false);
1399 }
1400
1402
1403 switch (code) {
1404 case NSERROR_BAD_AUTH:
1405 res = browser_window__handle_login(bw, message, url);
1406 break;
1407
1408 case NSERROR_BAD_CERTS:
1410 break;
1411
1412 case NSERROR_TIMEOUT:
1414 break;
1415
1416 default:
1417 res = browser_window__handle_fetcherror(bw, message, url);
1418 break;
1419 }
1420
1421 return res;
1422}
1423
1424
1425/**
1426 * Update URL bar for a given browser window to given URL
1427 *
1428 * \param bw Browser window to update URL bar for.
1429 * \param url URL for content displayed by bw including any fragment.
1430 */
1431static inline nserror
1433{
1434 assert(bw);
1435 assert(url);
1436
1437 if ((bw->parent != NULL) || (bw->window == NULL)) {
1438 /* Not root window or no gui window so do not set a URL */
1439 return NSERROR_OK;
1440 }
1441
1442 return guit->window->set_url(bw->window, url);
1443}
1444
1445
1446/**
1447 * Browser window content event callback handler.
1448 */
1449static nserror
1451{
1452 struct browser_window *bw = pw;
1453 nserror res = NSERROR_OK;
1454
1455 switch (event->type) {
1457 /* SSL certificate information has arrived, store it */
1460 break;
1461
1462 case CONTENT_MSG_LOG:
1464 event->data.log.src,
1465 event->data.log.msg,
1466 event->data.log.msglen,
1467 event->data.log.flags);
1468 break;
1469
1471 assert(bw->loading_content == c);
1472
1474
1475 if (bw->current_content != NULL) {
1477 }
1478 break;
1479
1481 assert(bw->loading_content == c);
1482
1483#ifdef WITH_THEME_INSTALL
1484 if (content_get_type(c) == CONTENT_THEME) {
1486 bw->loading_content = NULL;
1488 } else
1489#endif
1490 {
1491 bw->refresh_interval = -1;
1494 }
1495 break;
1496
1497 case CONTENT_MSG_READY:
1498 assert(bw->loading_content == c);
1499
1501 break;
1502
1503 case CONTENT_MSG_DONE:
1504 assert(bw->current_content == c);
1505
1507 break;
1508
1509 case CONTENT_MSG_ERROR:
1510 res = browser_window__handle_error(bw, c, event);
1511 break;
1512
1514 if (urldb_add_url(event->data.redirect.from)) {
1516 }
1518 break;
1519
1520 case CONTENT_MSG_STATUS:
1521 if (event->data.explicit_status_text == NULL) {
1522 /* Object content's status text updated */
1523 const char *status = NULL;
1524 if (bw->loading_content != NULL) {
1525 /* Give preference to any loading content */
1528 }
1529
1530 if (status == NULL) {
1532 }
1533
1534 if (status != NULL) {
1536 }
1537 } else {
1538 /* Object content wants to set explicit message */
1540 event->data.explicit_status_text);
1541 }
1542 break;
1543
1545 if (c == bw->current_content) {
1546 /* recompute frameset */
1548
1549 /* recompute iframe positions, sizes and scrollbars */
1551 }
1552
1553 /* Hide any caret, but don't remove it */
1555
1556 if (!(event->data.background)) {
1557 /* Reformatted content should be redrawn */
1558 browser_window_update(bw, false);
1559 }
1560 break;
1561
1562 case CONTENT_MSG_REDRAW:
1563 {
1564 struct rect rect = {
1565 .x0 = event->data.redraw.x,
1566 .y0 = event->data.redraw.y,
1567 .x1 = event->data.redraw.x + event->data.redraw.width,
1568 .y1 = event->data.redraw.y + event->data.redraw.height
1569 };
1570
1572 }
1573 break;
1574
1576 bw->refresh_interval = event->data.delay * 100;
1577 break;
1578
1579 case CONTENT_MSG_LINK: /* content has an rfc5988 link element */
1580 {
1581 bool match;
1582
1583 /* Handle "icon" and "shortcut icon" */
1584 if ((lwc_string_caseless_isequal(
1585 event->data.rfc5988_link->rel,
1586 corestring_lwc_icon,
1587 &match) == lwc_error_ok && match) ||
1588 (lwc_string_caseless_isequal(
1589 event->data.rfc5988_link->rel,
1590 corestring_lwc_shortcut_icon,
1591 &match) == lwc_error_ok && match)) {
1592 /* it's a favicon perhaps start a fetch for it */
1594 event->data.rfc5988_link);
1595 }
1596 }
1597 break;
1598
1600 {
1601 /* only the content object created by the browser
1602 * window requires a new javascript thread object
1603 */
1604 jsthread *thread;
1605 assert(bw->loading_content == c);
1606
1607 if (js_newthread(bw->jsheap,
1608 bw,
1610 &thread) == NSERROR_OK) {
1611 /* The content which is requesting the thread
1612 * is required to keep hold of it and
1613 * to destroy it when it is finished with it.
1614 */
1615 *(event->data.jsthread) = thread;
1616 }
1617 }
1618 break;
1619
1621 {
1622 int width;
1623 int height;
1624
1626
1627 *(event->data.getdims.viewport_width) = width / bw->scale;
1628 *(event->data.getdims.viewport_height) = height / bw->scale;
1629 break;
1630 }
1631
1632 case CONTENT_MSG_SCROLL:
1633 {
1634 struct rect rect = {
1635 .x0 = event->data.scroll.x0,
1636 .y0 = event->data.scroll.y0,
1637 };
1638
1639 /* Content wants to be scrolled */
1640 if (bw->current_content != c) {
1641 break;
1642 }
1643
1644 if (event->data.scroll.area) {
1645 rect.x1 = event->data.scroll.x1;
1646 rect.y1 = event->data.scroll.y1;
1647 } else {
1648 rect.x1 = event->data.scroll.x0;
1649 rect.y1 = event->data.scroll.y0;
1650 }
1652
1653 break;
1654 }
1655
1657 {
1658 /* Content wants drag save of a content */
1660 hlcache_handle *save = event->data.dragsave.content;
1661
1662 if (save == NULL) {
1663 save = c;
1664 }
1665
1666 switch(event->data.dragsave.type) {
1667 case CONTENT_SAVE_ORIG:
1668 guit->window->drag_save_object(root->window,
1669 save,
1671 break;
1672
1673 case CONTENT_SAVE_NATIVE:
1674 guit->window->drag_save_object(root->window,
1675 save,
1677 break;
1678
1679 case CONTENT_SAVE_COMPLETE:
1680 guit->window->drag_save_object(root->window,
1681 save,
1683 break;
1684
1685 case CONTENT_SAVE_SOURCE:
1686 guit->window->drag_save_object(root->window,
1687 save,
1689 break;
1690 }
1691 }
1692 break;
1693
1695 {
1696 /* Content wants a link to be saved */
1698 guit->window->save_link(root->window,
1699 event->data.savelink.url,
1700 event->data.savelink.title);
1701 }
1702 break;
1703
1705 /* Content wants to have specific mouse pointer */
1707 break;
1708
1709 case CONTENT_MSG_DRAG:
1710 {
1712
1713 switch (event->data.drag.type) {
1714 case CONTENT_DRAG_NONE:
1715 bdt = DRAGGING_NONE;
1716 break;
1717 case CONTENT_DRAG_SCROLL:
1719 break;
1720 case CONTENT_DRAG_SELECTION:
1721 bdt = DRAGGING_SELECTION;
1722 break;
1723 }
1725 }
1726 break;
1727
1728 case CONTENT_MSG_CARET:
1729 switch (event->data.caret.type) {
1730 case CONTENT_CARET_REMOVE:
1732 break;
1733 case CONTENT_CARET_HIDE:
1735 break;
1736 case CONTENT_CARET_SET_POS:
1738 event->data.caret.pos.x,
1739 event->data.caret.pos.y,
1740 event->data.caret.pos.height,
1741 event->data.caret.pos.clip);
1742 break;
1743 }
1744 break;
1745
1748 event->data.selection.selection,
1749 event->data.selection.read_only);
1750 break;
1751
1753 if (event->data.select_menu.gadget->type == GADGET_SELECT) {
1754 struct browser_window *root =
1757 event->data.select_menu.gadget);
1758 }
1759
1760 break;
1761
1763 if (event->data.gadget_click.gadget->type == GADGET_FILE) {
1764 struct browser_window *root =
1766 guit->window->file_gadget_open(root->window, c,
1767 event->data.gadget_click.gadget);
1768 }
1769
1770 break;
1771
1772
1774 switch (event->data.textsearch.type) {
1775 case CONTENT_TEXTSEARCH_FIND:
1777 event->data.textsearch.ctx);
1778 break;
1779
1780 case CONTENT_TEXTSEARCH_MATCH:
1782 event->data.textsearch.ctx);
1783 break;
1784
1785 case CONTENT_TEXTSEARCH_BACK:
1787 event->data.textsearch.ctx);
1788 break;
1789
1790 case CONTENT_TEXTSEARCH_FORWARD:
1792 event->data.textsearch.ctx);
1793 break;
1794
1795 case CONTENT_TEXTSEARCH_RECENT:
1797 event->data.textsearch.ctx);
1798
1799 break;
1800 }
1801 break;
1802
1803 default:
1804 break;
1805 }
1806
1807 return res;
1808}
1809
1810
1811/**
1812 * internal scheduled reformat callback.
1813 *
1814 * scheduled reformat callback to allow reformats from unthreaded context.
1815 *
1816 * \param vbw The browser window to be reformatted
1817 */
1818static void scheduled_reformat(void *vbw)
1819{
1820 struct browser_window *bw = vbw;
1821 int width;
1822 int height;
1823 nserror res;
1824
1826 if (res == NSERROR_OK) {
1828 }
1829}
1830
1831/* exported interface documented in desktop/browser_private.h */
1833{
1834 assert(bw);
1835
1838
1839 /* Destroy scrollbars */
1840 if (bw->scroll_x != NULL) {
1842 }
1843
1844 if (bw->scroll_y != NULL) {
1846 }
1847
1848 /* clear any pending callbacks */
1850 NSLOG(netsurf, INFO,
1851 "Clearing reformat schedule for browser window %p", bw);
1853
1854 /* If this brower window is not the root window, and has focus, unset
1855 * the root browser window's focus pointer. */
1856 if (!bw->window) {
1858
1859 if (top->focus == bw)
1860 top->focus = top;
1861
1862 if (top->selection.bw == bw) {
1863 browser_window_set_selection(top, false, false);
1864 }
1865 }
1866
1867 /* Destruction order is important: we must ensure that the frontend
1868 * destroys any window(s) associated with this browser window before
1869 * we attempt any destructive cleanup.
1870 */
1871
1872 if (bw->window) {
1873 /* Only the root window has a GUI window */
1875 }
1876
1877 if (bw->loading_content != NULL) {
1880 bw->loading_content = NULL;
1881 }
1882
1883 if (bw->current_content != NULL) {
1886 bw->current_content = NULL;
1887 }
1888
1889 if (bw->favicon.loading != NULL) {
1892 bw->favicon.loading = NULL;
1893 }
1894
1895 if (bw->favicon.current != NULL) {
1898 bw->favicon.current = NULL;
1899 }
1900
1901 if (bw->jsheap != NULL) {
1903 bw->jsheap = NULL;
1904 }
1905
1906 /* These simply free memory, so are safe here */
1907
1908 if (bw->frag_id != NULL) {
1909 lwc_string_unref(bw->frag_id);
1910 }
1911
1913
1916 bw->current_cert_chain = NULL;
1917 bw->loading_cert_chain = NULL;
1918
1919 free(bw->name);
1920 free(bw->status.text);
1921 bw->status.text = NULL;
1924 NSLOG(netsurf, INFO, "Status text cache match:miss %d:%d",
1926
1927 return NSERROR_OK;
1928}
1929
1930
1931/**
1932 * Set browser window scale.
1933 *
1934 * \param bw Browser window.
1935 * \param absolute scale value.
1936 * \return NSERROR_OK on success else error code
1937 */
1938static nserror
1940{
1941 int i;
1942 nserror res = NSERROR_OK;
1943
1944 /* do not apply tiny changes in scale */
1945 if (fabs(bw->scale - scale) < 0.0001)
1946 return res;
1947
1948 bw->scale = scale;
1949
1950 if (bw->current_content != NULL) {
1951 if (content_can_reformat(bw->current_content) == false) {
1952 browser_window_update(bw, false);
1953 } else {
1955 }
1956 }
1957
1958 /* scale frames */
1959 for (i = 0; i < (bw->cols * bw->rows); i++) {
1961 }
1962
1963 /* scale iframes */
1964 for (i = 0; i < bw->iframe_count; i++) {
1966 }
1967
1968 return res;
1969}
1970
1971
1972/**
1973 * Find browser window.
1974 *
1975 * \param bw Browser window.
1976 * \param target Name of target.
1977 * \param depth Depth to scan.
1978 * \param page The browser window page.
1979 * \param rdepth The rdepth.
1980 * \param bw_target the output browser window.
1981 */
1982static void
1984 const char *target,
1985 int depth,
1986 struct browser_window *page,
1987 int *rdepth,
1988 struct browser_window **bw_target)
1989{
1990 int i;
1991
1992 if ((bw->name) && (!strcasecmp(bw->name, target))) {
1993 if ((bw == page) || (depth > *rdepth)) {
1994 *rdepth = depth;
1995 *bw_target = bw;
1996 }
1997 }
1998
1999 if ((!bw->children) && (!bw->iframes))
2000 return;
2001
2002 depth++;
2003
2004 if (bw->children != NULL) {
2005 for (i = 0; i < (bw->cols * bw->rows); i++) {
2006 if ((bw->children[i].name) &&
2007 (!strcasecmp(bw->children[i].name,
2008 target))) {
2009 if ((page == &bw->children[i]) ||
2010 (depth > *rdepth)) {
2011 *rdepth = depth;
2012 *bw_target = &bw->children[i];
2013 }
2014 }
2015 if (bw->children[i].children)
2017 &bw->children[i],
2018 target, depth, page,
2019 rdepth, bw_target);
2020 }
2021 }
2022
2023 if (bw->iframes != NULL) {
2024 for (i = 0; i < bw->iframe_count; i++) {
2026 target,
2027 depth,
2028 page,
2029 rdepth,
2030 bw_target);
2031 }
2032 }
2033}
2034
2035
2036/**
2037 * Handles the end of a drag operation in a browser window.
2038 *
2039 * \param bw browser window
2040 * \param mouse state of mouse buttons and modifier keys
2041 * \param x coordinate of mouse
2042 * \param y coordinate of mouse
2043 *
2044 * \todo Remove this function, once these things are associated with content,
2045 * rather than bw.
2046 */
2047static void
2049 browser_mouse_state mouse,
2050 int x, int y)
2051{
2052 int scr_x, scr_y;
2053
2054 switch (bw->drag.type) {
2055 case DRAGGING_SELECTION:
2056 case DRAGGING_OTHER:
2058 /* Drag handled by content handler */
2059 break;
2060
2061 case DRAGGING_SCR_X:
2062
2063 browser_window_get_scrollbar_pos(bw, true, &scr_x, &scr_y);
2064
2065 scr_x = x - scr_x - scrollbar_get_offset(bw->scroll_x);
2066 scr_y = y - scr_y - scrollbar_get_offset(bw->scroll_y);
2067
2068 scrollbar_mouse_drag_end(bw->scroll_x, mouse, scr_x, scr_y);
2069
2071 break;
2072
2073 case DRAGGING_SCR_Y:
2074
2075 browser_window_get_scrollbar_pos(bw, false, &scr_x, &scr_y);
2076
2077 scr_x = x - scr_x - scrollbar_get_offset(bw->scroll_x);
2078 scr_y = y - scr_y - scrollbar_get_offset(bw->scroll_y);
2079
2080 scrollbar_mouse_drag_end(bw->scroll_y, mouse, scr_x, scr_y);
2081
2083 break;
2084
2085 default:
2087 break;
2088 }
2089}
2090
2091/**
2092 * Process mouse click event
2093 *
2094 * \param bw The browsing context receiving the event
2095 * \param mouse The mouse event state
2096 * \param x The scaled x co-ordinate of the event
2097 * \param y The scaled y co-ordinate of the event
2098 */
2099static void
2101 browser_mouse_state mouse,
2102 int x, int y)
2103{
2105 const char *status = NULL;
2107
2108 if (bw->children) {
2109 /* Browser window has children (frames) */
2110 struct browser_window *child;
2111 int cur_child;
2112 int children = bw->rows * bw->cols;
2113
2114 for (cur_child = 0; cur_child < children; cur_child++) {
2115
2116 child = &bw->children[cur_child];
2117
2118 if ((x < child->x) ||
2119 (y < child->y) ||
2120 (child->x + child->width < x) ||
2121 (child->y + child->height < y)) {
2122 /* Click not in this child */
2123 continue;
2124 }
2125
2126 /* It's this child that contains the click; pass it
2127 * on to child. */
2129 child,
2130 mouse,
2131 x - child->x + scrollbar_get_offset(child->scroll_x),
2132 y - child->y + scrollbar_get_offset(child->scroll_y));
2133
2134 /* Mouse action was for this child, we're done */
2135 return;
2136 }
2137
2138 return;
2139 }
2140
2141 if (!c)
2142 return;
2143
2144 if (bw->scroll_x != NULL) {
2145 int scr_x, scr_y;
2146 browser_window_get_scrollbar_pos(bw, true, &scr_x, &scr_y);
2147 scr_x = x - scr_x - scrollbar_get_offset(bw->scroll_x);
2148 scr_y = y - scr_y - scrollbar_get_offset(bw->scroll_y);
2149
2150 if (scr_x > 0 && scr_x < get_horz_scrollbar_len(bw) &&
2151 scr_y > 0 && scr_y < SCROLLBAR_WIDTH) {
2154 bw->scroll_x, mouse,
2155 scr_x, scr_y));
2156 pointer = BROWSER_POINTER_DEFAULT;
2157
2158 if (status != NULL)
2160
2162 return;
2163 }
2164 }
2165
2166 if (bw->scroll_y != NULL) {
2167 int scr_x, scr_y;
2168 browser_window_get_scrollbar_pos(bw, false, &scr_x, &scr_y);
2169 scr_x = x - scr_x - scrollbar_get_offset(bw->scroll_x);
2170 scr_y = y - scr_y - scrollbar_get_offset(bw->scroll_y);
2171
2172 if (scr_y > 0 && scr_y < get_vert_scrollbar_len(bw) &&
2173 scr_x > 0 && scr_x < SCROLLBAR_WIDTH) {
2176 bw->scroll_y,
2177 mouse,
2178 scr_x,
2179 scr_y));
2180 pointer = BROWSER_POINTER_DEFAULT;
2181
2182 if (status != NULL) {
2184 }
2185
2187 return;
2188 }
2189 }
2190
2191 switch (content_get_type(c)) {
2192 case CONTENT_HTML:
2193 case CONTENT_TEXTPLAIN:
2194 {
2195 /* Give bw focus */
2196 struct browser_window *root_bw = browser_window_get_root(bw);
2197 if (bw != root_bw->focus) {
2199 browser_window_set_selection(bw, false, true);
2200 root_bw->focus = bw;
2201 }
2202
2203 /* Pass mouse action to content */
2204 content_mouse_action(c, bw, mouse, x, y);
2205 }
2206 break;
2207 default:
2208 if (mouse & BROWSER_MOUSE_MOD_2) {
2209 if (mouse & BROWSER_MOUSE_DRAG_2) {
2212 } else if (mouse & BROWSER_MOUSE_DRAG_1) {
2215 }
2216 } else if (mouse & (BROWSER_MOUSE_DRAG_1 |
2220 }
2221 break;
2222 }
2223}
2224
2225
2226/**
2227 * Process mouse movement event
2228 *
2229 * \param bw The browsing context receiving the event
2230 * \param mouse The mouse event state
2231 * \param x The scaled x co-ordinate of the event
2232 * \param y The scaled y co-ordinate of the event
2233 */
2234static void
2236 browser_mouse_state mouse,
2237 int x, int y)
2238{
2240 const char *status = NULL;
2242
2243 if (bw->window != NULL && bw->drag.window && bw != bw->drag.window) {
2244 /* This is the root browser window and there's an active drag
2245 * in a sub window.
2246 * Pass the mouse action straight on to that bw. */
2247 struct browser_window *drag_bw = bw->drag.window;
2248 int off_x = 0;
2249 int off_y = 0;
2250
2251 browser_window_get_position(drag_bw, true, &off_x, &off_y);
2252
2253 if (drag_bw->browser_window_type == BROWSER_WINDOW_FRAME) {
2255 mouse,
2256 x - off_x,
2257 y - off_y);
2258
2259 } else if (drag_bw->browser_window_type == BROWSER_WINDOW_IFRAME) {
2261 x - off_x / bw->scale,
2262 y - off_y / bw->scale);
2263 }
2264 return;
2265 }
2266
2267 if (bw->children) {
2268 /* Browser window has children (frames) */
2269 struct browser_window *child;
2270 int cur_child;
2271 int children = bw->rows * bw->cols;
2272
2273 for (cur_child = 0; cur_child < children; cur_child++) {
2274
2275 child = &bw->children[cur_child];
2276
2277 if ((x < child->x) ||
2278 (y < child->y) ||
2279 (child->x + child->width < x) ||
2280 (child->y + child->height < y)) {
2281 /* Click not in this child */
2282 continue;
2283 }
2284
2285 /* It's this child that contains the mouse; pass
2286 * mouse action on to child */
2288 child,
2289 mouse,
2290 x - child->x + scrollbar_get_offset(child->scroll_x),
2291 y - child->y + scrollbar_get_offset(child->scroll_y));
2292
2293 /* Mouse action was for this child, we're done */
2294 return;
2295 }
2296
2297 /* Odd if we reached here, but nothing else can use the click
2298 * when there are children. */
2299 return;
2300 }
2301
2302 if (c == NULL && bw->drag.type != DRAGGING_FRAME) {
2303 return;
2304 }
2305
2306 if (bw->drag.type != DRAGGING_NONE && !mouse) {
2308 }
2309
2310 /* Browser window's horizontal scrollbar */
2311 if (bw->scroll_x != NULL && bw->drag.type != DRAGGING_SCR_Y) {
2312 int scr_x, scr_y;
2313 browser_window_get_scrollbar_pos(bw, true, &scr_x, &scr_y);
2314 scr_x = x - scr_x - scrollbar_get_offset(bw->scroll_x);
2315 scr_y = y - scr_y - scrollbar_get_offset(bw->scroll_y);
2316
2317 if ((bw->drag.type == DRAGGING_SCR_X) ||
2318 (scr_x > 0 &&
2319 scr_x < get_horz_scrollbar_len(bw) &&
2320 scr_y > 0 &&
2321 scr_y < SCROLLBAR_WIDTH &&
2322 bw->drag.type == DRAGGING_NONE)) {
2323 /* Start a scrollbar drag, or continue existing drag */
2326 mouse,
2327 scr_x,
2328 scr_y));
2329 pointer = BROWSER_POINTER_DEFAULT;
2330
2331 if (status != NULL) {
2333 }
2334
2336 return;
2337 }
2338 }
2339
2340 /* Browser window's vertical scrollbar */
2341 if (bw->scroll_y != NULL) {
2342 int scr_x, scr_y;
2343 browser_window_get_scrollbar_pos(bw, false, &scr_x, &scr_y);
2344 scr_x = x - scr_x - scrollbar_get_offset(bw->scroll_x);
2345 scr_y = y - scr_y - scrollbar_get_offset(bw->scroll_y);
2346
2347 if ((bw->drag.type == DRAGGING_SCR_Y) ||
2348 (scr_y > 0 &&
2349 scr_y < get_vert_scrollbar_len(bw) &&
2350 scr_x > 0 &&
2351 scr_x < SCROLLBAR_WIDTH &&
2352 bw->drag.type == DRAGGING_NONE)) {
2353 /* Start a scrollbar drag, or continue existing drag */
2356 mouse,
2357 scr_x,
2358 scr_y));
2359 pointer = BROWSER_POINTER_DEFAULT;
2360
2361 if (status != NULL) {
2363 }
2364
2366 return;
2367 }
2368 }
2369
2370 if (bw->drag.type == DRAGGING_FRAME) {
2372 } else if (bw->drag.type == DRAGGING_PAGE_SCROLL) {
2373 /* mouse movement since drag started */
2374 struct rect rect;
2375
2376 rect.x0 = bw->drag.start_x - x;
2377 rect.y0 = bw->drag.start_y - y;
2378
2379 /* new scroll offsets */
2380 rect.x0 += bw->drag.start_scroll_x;
2381 rect.y0 += bw->drag.start_scroll_y;
2382
2383 bw->drag.start_scroll_x = rect.x1 = rect.x0;
2384 bw->drag.start_scroll_y = rect.y1 = rect.y0;
2385
2387 } else {
2388 assert(c != NULL);
2389 content_mouse_track(c, bw, mouse, x, y);
2390 }
2391}
2392
2393
2394/**
2395 * perform a scroll operation at a given coordinate
2396 *
2397 * \param bw The browsing context receiving the event
2398 * \param x The scaled x co-ordinate of the event
2399 * \param y The scaled y co-ordinate of the event
2400 */
2401static bool
2403 int x, int y,
2404 int scrx, int scry)
2405{
2406 bool handled_scroll = false;
2407 assert(bw != NULL);
2408
2409 /* Handle (i)frame scroll offset (core-managed browser windows only) */
2412
2413 if (bw->children) {
2414 /* Browser window has children, so pass request on to
2415 * appropriate child */
2416 struct browser_window *bwc;
2417 int cur_child;
2418 int children = bw->rows * bw->cols;
2419
2420 /* Loop through all children of bw */
2421 for (cur_child = 0; cur_child < children; cur_child++) {
2422 /* Set current child */
2423 bwc = &bw->children[cur_child];
2424
2425 /* Skip this frame if (x, y) coord lies outside */
2426 if (x < bwc->x || bwc->x + bwc->width < x ||
2427 y < bwc->y || bwc->y + bwc->height < y)
2428 continue;
2429
2430 /* Pass request into this child */
2432 bwc,
2433 (x - bwc->x),
2434 (y - bwc->y),
2435 scrx, scry);
2436 }
2437 }
2438
2439 /* Try to scroll any current content */
2440 if (bw->current_content != NULL &&
2441 content_scroll_at_point(bw->current_content, x, y, scrx, scry) == true) {
2442 /* Scroll handled by current content */
2443 return true;
2444 }
2445
2446 /* Try to scroll this window, if scroll not already handled */
2447 if (handled_scroll == false) {
2448 if (bw->scroll_y && scrollbar_scroll(bw->scroll_y, scry)) {
2449 handled_scroll = true;
2450 }
2451
2452 if (bw->scroll_x && scrollbar_scroll(bw->scroll_x, scrx)) {
2453 handled_scroll = true;
2454 }
2455 }
2456
2457 return handled_scroll;
2458}
2459
2460
2461/**
2462 * allows a dragged file to be dropped into a browser window at a position
2463 *
2464 * \param bw The browsing context receiving the event
2465 * \param x The scaled x co-ordinate of the event
2466 * \param y The scaled y co-ordinate of the event
2467 * \param file filename to be put in the widget
2468 */
2469static bool
2471 int x, int y,
2472 char *file)
2473{
2474 assert(bw != NULL);
2475
2476 /* Handle (i)frame scroll offset (core-managed browser windows only) */
2479
2480 if (bw->children) {
2481 /* Browser window has children, so pass request on to
2482 * appropriate child */
2483 struct browser_window *bwc;
2484 int cur_child;
2485 int children = bw->rows * bw->cols;
2486
2487 /* Loop through all children of bw */
2488 for (cur_child = 0; cur_child < children; cur_child++) {
2489 /* Set current child */
2490 bwc = &bw->children[cur_child];
2491
2492 /* Skip this frame if (x, y) coord lies outside */
2493 if (x < bwc->x || bwc->x + bwc->width < x ||
2494 y < bwc->y || bwc->y + bwc->height < y)
2495 continue;
2496
2497 /* Pass request into this child */
2499 bwc,
2500 (x - bwc->x),
2501 (y - bwc->y),
2502 file);
2503 }
2504 }
2505
2506 /* Pass file drop on to any content */
2507 if (bw->current_content != NULL) {
2509 x, y, file);
2510 }
2511
2512 return false;
2513}
2514
2515
2516/**
2517 * Check if this is an internal navigation URL.
2518 *
2519 * This safely checks if the given url is an internal navigation even
2520 * for urls with no scheme or path.
2521 *
2522 * \param url The URL to check
2523 * \return true if an internal navigation url else false
2524 */
2525static bool
2527{
2528 bool is_internal = false;
2529 lwc_string *scheme, *path;
2530
2531 scheme = nsurl_get_component(url, NSURL_SCHEME);
2532 if (scheme != NULL) {
2534 if (path != NULL) {
2535 if (scheme == corestring_lwc_about) {
2536 if (path == corestring_lwc_query_auth) {
2537 is_internal = true;
2538 } else if (path == corestring_lwc_query_ssl) {
2539 is_internal = true;
2540 } else if (path == corestring_lwc_query_timeout) {
2541 is_internal = true;
2542 } else if (path == corestring_lwc_query_fetcherror) {
2543 is_internal = true;
2544 }
2545 }
2546 lwc_string_unref(path);
2547 }
2548 lwc_string_unref(scheme);
2549 }
2550 return is_internal;
2551}
2552
2553
2554/* exported interface, documented in netsurf/browser_window.h */
2555nserror
2556browser_window_get_name(struct browser_window *bw, const char **out_name)
2557{
2558 assert(bw != NULL);
2559
2560 *out_name = bw->name;
2561
2562 return NSERROR_OK;
2563}
2564
2565
2566/* exported interface, documented in netsurf/browser_window.h */
2567nserror
2569{
2570 char *nname = NULL;
2571
2572 assert(bw != NULL);
2573
2574 if (name != NULL) {
2575 nname = strdup(name);
2576 if (nname == NULL) {
2577 return NSERROR_NOMEM;
2578 }
2579 }
2580
2581 if (bw->name != NULL) {
2582 free(bw->name);
2583 }
2584
2585 bw->name = nname;
2586
2587 return NSERROR_OK;
2588}
2589
2590
2591/* exported interface, documented in netsurf/browser_window.h */
2592bool
2594 int x, int y,
2595 const struct rect *clip,
2596 const struct redraw_context *ctx)
2597{
2598 struct redraw_context new_ctx = *ctx;
2599 int width = 0;
2600 int height = 0;
2601 bool plot_ok = true;
2603 struct content_redraw_data data;
2604 struct rect content_clip;
2605 nserror res;
2606
2607 if (bw == NULL) {
2608 NSLOG(netsurf, INFO, "NULL browser window");
2609 return false;
2610 }
2611
2612 x /= bw->scale;
2613 y /= bw->scale;
2614
2615 if ((bw->current_content == NULL) &&
2616 (bw->children == NULL)) {
2617 /* Browser window has no content, render blank fill */
2618 ctx->plot->clip(ctx, clip);
2619 return (ctx->plot->rectangle(ctx, plot_style_fill_white, clip) == NSERROR_OK);
2620 }
2621
2622 /* Browser window has content OR children (frames) */
2623 if ((bw->window != NULL) &&
2624 (ctx->plot->option_knockout)) {
2625 /* Root browser window: start knockout */
2626 knockout_plot_start(ctx, &new_ctx);
2627 }
2628
2629 new_ctx.plot->clip(ctx, clip);
2630
2631 /* Handle redraw of any browser window children */
2632 if (bw->children) {
2633 struct browser_window *child;
2634 int cur_child;
2635 int children = bw->rows * bw->cols;
2636
2637 if (bw->window != NULL) {
2638 /* Root browser window; start with blank fill */
2639 plot_ok &= (new_ctx.plot->rectangle(ctx,
2641 clip) == NSERROR_OK);
2642 }
2643
2644 /* Loop through all children of bw */
2645 for (cur_child = 0; cur_child < children; cur_child++) {
2646 /* Set current child */
2647 child = &bw->children[cur_child];
2648
2649 /* Get frame edge area in global coordinates */
2650 content_clip.x0 = (x + child->x) * child->scale;
2651 content_clip.y0 = (y + child->y) * child->scale;
2652 content_clip.x1 = content_clip.x0 +
2653 child->width * child->scale;
2654 content_clip.y1 = content_clip.y0 +
2655 child->height * child->scale;
2656
2657 /* Intersect it with clip rectangle */
2658 if (content_clip.x0 < clip->x0)
2659 content_clip.x0 = clip->x0;
2660 if (content_clip.y0 < clip->y0)
2661 content_clip.y0 = clip->y0;
2662 if (clip->x1 < content_clip.x1)
2663 content_clip.x1 = clip->x1;
2664 if (clip->y1 < content_clip.y1)
2665 content_clip.y1 = clip->y1;
2666
2667 /* Skip this frame if it lies outside clip rectangle */
2668 if (content_clip.x0 >= content_clip.x1 ||
2669 content_clip.y0 >= content_clip.y1)
2670 continue;
2671
2672 /* Redraw frame */
2673 plot_ok &= browser_window_redraw(child,
2674 x + child->x,
2675 y + child->y,
2676 &content_clip,
2677 &new_ctx);
2678 }
2679
2680 /* Nothing else to redraw for browser windows with children;
2681 * cleanup and return
2682 */
2683 if (bw->window != NULL && ctx->plot->option_knockout) {
2684 /* Root browser window: knockout end */
2685 knockout_plot_end(ctx);
2686 }
2687
2688 return plot_ok;
2689 }
2690
2691 /* Handle browser windows with content to redraw */
2692
2695 /* Set render area according to scale */
2698
2699 /* Non-HTML may not fill viewport to extents, so plot white
2700 * background fill */
2701 plot_ok &= (new_ctx.plot->rectangle(&new_ctx,
2703 clip) == NSERROR_OK);
2704 }
2705
2706 /* Set up content redraw data */
2707 data.x = x - scrollbar_get_offset(bw->scroll_x);
2708 data.y = y - scrollbar_get_offset(bw->scroll_y);
2709 data.width = width;
2710 data.height = height;
2711
2712 data.background_colour = 0xFFFFFF;
2713 data.scale = bw->scale;
2714 data.repeat_x = false;
2715 data.repeat_y = false;
2716
2717 content_clip = *clip;
2718
2719 if (!bw->window) {
2720 int x0 = x * bw->scale;
2721 int y0 = y * bw->scale;
2722 int x1 = (x + bw->width - ((bw->scroll_y != NULL) ?
2723 SCROLLBAR_WIDTH : 0)) * bw->scale;
2724 int y1 = (y + bw->height - ((bw->scroll_x != NULL) ?
2725 SCROLLBAR_WIDTH : 0)) * bw->scale;
2726
2727 if (content_clip.x0 < x0) content_clip.x0 = x0;
2728 if (content_clip.y0 < y0) content_clip.y0 = y0;
2729 if (x1 < content_clip.x1) content_clip.x1 = x1;
2730 if (y1 < content_clip.y1) content_clip.y1 = y1;
2731 }
2732
2733 /* Render the content */
2734 plot_ok &= content_redraw(bw->current_content, &data,
2735 &content_clip, &new_ctx);
2736
2737 /* Back to full clip rect */
2738 new_ctx.plot->clip(&new_ctx, clip);
2739
2740 if (!bw->window) {
2741 /* Render scrollbars */
2742 int off_x, off_y;
2743 if (bw->scroll_x != NULL) {
2745 &off_x, &off_y);
2747 x + off_x, y + off_y, clip,
2748 bw->scale, &new_ctx);
2749 if (res != NSERROR_OK) {
2750 plot_ok = false;
2751 }
2752 }
2753 if (bw->scroll_y != NULL) {
2755 &off_x, &off_y);
2757 x + off_x, y + off_y, clip,
2758 bw->scale, &new_ctx);
2759 if (res != NSERROR_OK) {
2760 plot_ok = false;
2761 }
2762 }
2763 }
2764
2765 if (bw->window != NULL && ctx->plot->option_knockout) {
2766 /* Root browser window: end knockout */
2767 knockout_plot_end(ctx);
2768 }
2769
2770 return plot_ok;
2771}
2772
2773
2774/* exported interface, documented in netsurf/browser_window.h */
2776{
2777 if (bw == NULL) {
2778 NSLOG(netsurf, INFO, "NULL browser window");
2779 return false;
2780 } else if (bw->current_content != NULL) {
2781 /* Can't render locked contents */
2783 }
2784
2785 return true;
2786}
2787
2788
2789/* exported interface, documented in browser_private.h */
2791{
2792 if (bw->window != NULL) {
2793 /* Front end window */
2795 } else {
2796 /* Core-managed browser window */
2798 }
2799}
2800
2801
2802/* exported interface, documented in netsurf/browser_window.h */
2803void
2805 bool root,
2806 int *pos_x,
2807 int *pos_y)
2808{
2809 *pos_x = 0;
2810 *pos_y = 0;
2811
2812 assert(bw != NULL);
2813
2814 while (bw) {
2815 switch (bw->browser_window_type) {
2816
2818 *pos_x += bw->x * bw->scale;
2819 *pos_y += bw->y * bw->scale;
2820 break;
2821
2823 /* There is no offset to the root browser window */
2824 break;
2825
2827 /* Iframe and Frame handling is identical;
2828 * fall though */
2830 *pos_x += (bw->x - scrollbar_get_offset(bw->scroll_x)) *
2831 bw->scale;
2832 *pos_y += (bw->y - scrollbar_get_offset(bw->scroll_y)) *
2833 bw->scale;
2834 break;
2835 }
2836
2837 bw = bw->parent;
2838
2839 if (!root) {
2840 /* return if we just wanted the position in the parent
2841 * browser window. */
2842 return;
2843 }
2844 }
2845}
2846
2847
2848/* exported interface, documented in netsurf/browser_window.h */
2850{
2851 assert(bw != NULL);
2852
2853 if (bw->window == NULL) {
2854 /* Core managed browser window */
2855 bw->x = x;
2856 bw->y = y;
2857 } else {
2858 NSLOG(netsurf, INFO,
2859 "Asked to set position of front end window.");
2860 assert(0);
2861 }
2862}
2863
2864
2865/* exported interface, documented in netsurf/browser_window.h */
2866void
2869 const struct rect *rect)
2870{
2871 struct browser_window *top_bw = browser_window_get_root(bw);
2872 gui_drag_type gtype;
2873
2874 bw->drag.type = type;
2875
2876 if (type == DRAGGING_NONE) {
2877 top_bw->drag.window = NULL;
2878 } else {
2879 top_bw->drag.window = bw;
2880
2881 switch (type) {
2882 case DRAGGING_SELECTION:
2883 /** \todo tell front end */
2884 return;
2885 case DRAGGING_SCR_X:
2886 case DRAGGING_SCR_Y:
2888 gtype = GDRAGGING_SCROLLBAR;
2889 break;
2890 default:
2891 gtype = GDRAGGING_OTHER;
2892 break;
2893 }
2894
2895 guit->window->drag_start(top_bw->window, gtype, rect);
2896 }
2897}
2898
2899
2900/* exported interface, documented in netsurf/browser_window.h */
2902{
2903 return bw->drag.type;
2904}
2905
2906
2907/* exported interface, documented in netsurf/browser_window.h */
2909{
2910 while (bw && bw->parent) {
2911 bw = bw->parent;
2912 }
2913 return bw;
2914}
2915
2916
2917/* exported interface, documented in netsurf/browser_window.h */
2919{
2921 assert(bw->window);
2922 assert(bw->parent == NULL);
2923
2924 if (bw->selection.bw != NULL) {
2925 ed_flags |= BW_EDITOR_CAN_COPY;
2926
2927 if (!bw->selection.read_only)
2928 ed_flags |= BW_EDITOR_CAN_CUT;
2929 }
2930
2931 if (bw->can_edit)
2932 ed_flags |= BW_EDITOR_CAN_PASTE;
2933
2934 return ed_flags;
2935}
2936
2937
2938/* exported interface, documented in netsurf/browser_window.h */
2940{
2941 if (bw == NULL || bw->current_content == NULL)
2942 return false;
2943
2944 /* TODO: We shouldn't have to know about specific content types
2945 * here. There should be a content_is_selectable() call. */
2949 return false;
2950
2951 return true;
2952}
2953
2954
2955/* exported interface, documented in netsurf/browser_window.h */
2957{
2958 assert(bw->window);
2959 assert(bw->parent == NULL);
2960
2961 if (bw->selection.bw == NULL ||
2962 bw->selection.bw->current_content == NULL)
2963 return NULL;
2964
2966}
2967
2968
2969/* exported interface, documented in netsurf/browser_window.h */
2971{
2972 if (bw == NULL || bw->current_content == NULL)
2973 return false;
2974
2975 /** \todo We shouldn't have to know about specific content
2976 * types here. There should be a content_is_searchable() call.
2977 */
2980 return false;
2981 }
2982
2983 return true;
2984}
2985
2986
2987/* exported interface, documented in netsurf/browser_window.h */
2989{
2990 return (bw->children != NULL);
2991}
2992
2993
2994/* exported interface, documented in netsurf/browser_window.h */
2995nserror
2999{
3000 *h = bw->scrolling;
3001 *v = bw->scrolling;
3002
3003 return NSERROR_OK;
3004}
3005
3006
3007/* exported interface, documented in netsurf/browser_window.h */
3008nserror
3010 int x, int y,
3011 struct browser_window_features *data)
3012{
3013 /* clear the features structure to empty values */
3014 data->link = NULL;
3015 data->object = NULL;
3016 data->main = NULL;
3017 data->form_features = CTX_FORM_NONE;
3018
3020 x / bw->scale,
3021 y / bw->scale,
3022 data);
3023}
3024
3025
3026/* exported interface, documented in netsurf/browser_window.h */
3027bool
3029 int x, int y,
3030 int scrx, int scry)
3031{
3033 x / bw->scale,
3034 y / bw->scale,
3035 scrx,
3036 scry);
3037}
3038
3039
3040/* exported interface, documented in netsurf/browser_window.h */
3041bool
3043 int x, int y,
3044 char *file)
3045{
3047 x / bw->scale,
3048 y / bw->scale,
3049 file);
3050}
3051
3052
3053/* exported interface, documented in netsurf/browser_window.h */
3054void
3056 struct form_control *gadget,
3057 const char *fn)
3058{
3060}
3061
3062
3063/* exported interface, documented in netsurf/browser_window.h */
3064nserror
3066 FILE *f,
3067 enum content_debug op)
3068{
3069 if (bw->current_content != NULL) {
3070 return content_debug_dump(bw->current_content, f, op);
3071 }
3072 return NSERROR_OK;
3073}
3074
3075
3076/* exported interface, documented in netsurf/browser_window.h */
3078{
3079 if (bw->current_content != NULL) {
3080 return content_debug(bw->current_content, op);
3081 }
3082 return NSERROR_OK;
3083}
3084
3085
3086/* exported interface, documented in netsurf/browser_window.h */
3087nserror
3089 nsurl *url,
3090 nsurl *referrer,
3091 struct browser_window *existing,
3092 struct browser_window **bw)
3093{
3095 struct browser_window *ret;
3096 nserror err;
3097
3098 /* Check parameters */
3099 if (flags & BW_CREATE_CLONE) {
3100 if (existing == NULL) {
3101 assert(0 && "Failed: No existing window provided.");
3102 return NSERROR_BAD_PARAMETER;
3103 }
3104 }
3105
3106 if (!(flags & BW_CREATE_HISTORY)) {
3107 if (!(flags & BW_CREATE_CLONE) || existing == NULL) {
3108 assert(0 && "Failed: Must have existing for history.");
3109 return NSERROR_BAD_PARAMETER;
3110 }
3111 }
3112
3113 ret = calloc(1, sizeof(struct browser_window));
3114 if (ret == NULL) {
3115 return NSERROR_NOMEM;
3116 }
3117
3118 /* Initialise common parts */
3119 err = browser_window_initialise_common(flags, ret, existing);
3120 if (err != NSERROR_OK) {
3122 return err;
3123 }
3124
3125 /* window characteristics */
3128 ret->border = true;
3129 ret->no_resize = true;
3130 ret->focus = ret;
3131
3132 /* initialise last action with creation time */
3133 nsu_getmonotonic_ms(&ret->last_action);
3134
3135 /* The existing gui_window is on the top-level existing
3136 * browser_window. */
3137 existing = browser_window_get_root(existing);
3138
3139 /* Set up gui_window creation flags */
3140 if (flags & BW_CREATE_TAB)
3141 gw_flags |= GW_CREATE_TAB;
3142 if (flags & BW_CREATE_CLONE)
3143 gw_flags |= GW_CREATE_CLONE;
3144 if (flags & BW_CREATE_FOREGROUND)
3145 gw_flags |= GW_CREATE_FOREGROUND;
3146 if (flags & BW_CREATE_FOCUS_LOCATION)
3147 gw_flags |= GW_CREATE_FOCUS_LOCATION;
3148
3149 ret->window = guit->window->create(ret,
3150 (existing != NULL) ? existing->window : NULL,
3151 gw_flags);
3152
3153 if (ret->window == NULL) {
3155 return NSERROR_BAD_PARAMETER;
3156 }
3157
3158 if (url != NULL) {
3159 enum browser_window_nav_flags nav_flags;
3161 if (flags & BW_CREATE_UNVERIFIABLE) {
3162 nav_flags |= BW_NAVIGATE_UNVERIFIABLE;
3163 }
3164 if (flags & BW_CREATE_HISTORY) {
3165 nav_flags |= BW_NAVIGATE_HISTORY;
3166 }
3168 url,
3169 referrer,
3170 nav_flags,
3171 NULL,
3172 NULL,
3173 NULL);
3174 }
3175
3176 if (bw != NULL) {
3177 *bw = ret;
3178 }
3179
3180 return NSERROR_OK;
3181}
3182
3183
3184/* exported internal interface, documented in desktop/browser_private.h */
3185nserror
3187 struct browser_window *bw,
3188 const struct browser_window *existing)
3189{
3190 nserror err;
3191 assert(bw);
3192
3193 /* new javascript context for each window/(i)frame */
3194 err = js_newheap(nsoption_int(script_timeout), &bw->jsheap);
3195 if (err != NSERROR_OK)
3196 return err;
3197
3198 if (flags & BW_CREATE_CLONE) {
3199 assert(existing != NULL);
3200
3201 /* clone history */
3202 err = browser_window_history_clone(existing, bw);
3203
3204 /* copy the scale */
3205 bw->scale = existing->scale;
3206 } else {
3207 /* create history */
3209
3210 /* default scale */
3211 bw->scale = (float) nsoption_int(scale) / 100.0;
3212 }
3213
3214 if (err != NSERROR_OK)
3215 return err;
3216
3217 /* window characteristics */
3218 bw->refresh_interval = -1;
3219
3221
3222 bw->scroll_x = NULL;
3223 bw->scroll_y = NULL;
3224
3225 bw->focus = NULL;
3226
3227 /* initialise status text cache */
3228 bw->status.text = NULL;
3229 bw->status.text_len = 0;
3230 bw->status.match = 0;
3231 bw->status.miss = 0;
3232
3233 return NSERROR_OK;
3234}
3235
3236
3237/* exported interface, documented in netsurf/browser_window.h */
3239{
3240 /* can't destoy child windows on their own */
3241 assert(!bw->parent);
3242
3243 /* destroy */
3245 free(bw);
3246}
3247
3248
3249/* exported interface, documented in netsurf/browser_window.h */
3251{
3252 nserror ret;
3253 nsurl *display_url, *url;
3254
3255 assert(bw);
3256
3257 if (bw->parent != NULL) {
3258 /* Not root window; don't set a URL in GUI URL bar */
3259 return NSERROR_OK;
3260 }
3261
3262 if (bw->current_content == NULL) {
3263 /* no content so return about:blank */
3265 corestring_nsurl_about_blank);
3266 } else if (bw->throbbing && bw->loading_parameters.url != NULL) {
3267 /* Throbbing and we have loading parameters, use those */
3268 url = bw->loading_parameters.url;
3270 } else if (bw->frag_id == NULL) {
3271 if (bw->internal_nav) {
3272 url = bw->loading_parameters.url;
3273 } else {
3275 }
3277 } else {
3278 /* Combine URL and Fragment */
3279 if (bw->internal_nav) {
3280 url = bw->loading_parameters.url;
3281 } else {
3283 }
3284 ret = nsurl_refragment(
3285 url,
3286 bw->frag_id, &display_url);
3287 if (ret == NSERROR_OK) {
3289 display_url);
3290 nsurl_unref(display_url);
3291 }
3292 }
3293
3294 return ret;
3295}
3296
3297
3298/* exported interface documented in netsurf/browser_window.h */
3299nserror
3301 nsurl *url,
3302 nsurl *referrer,
3303 enum browser_window_nav_flags flags,
3304 char *post_urlenc,
3305 struct fetch_multipart_data *post_multipart,
3307{
3308 int depth = 0;
3309 struct browser_window *cur;
3310 uint32_t fetch_flags = 0;
3311 bool fetch_is_post = (post_urlenc != NULL || post_multipart != NULL);
3312 llcache_post_data post;
3314 nserror error;
3315 bool is_internal = false;
3316 struct browser_fetch_parameters params, *pass_params = NULL;
3317
3318 assert(bw);
3319 assert(url);
3320
3321 NSLOG(netsurf, INFO, "bw %p, url %s", bw, nsurl_access(url));
3322
3323 /*
3324 * determine if navigation is internal url, if so, we do not
3325 * do certain things during the load.
3326 */
3327 is_internal = is_internal_navigate_url(url);
3328
3329 if (is_internal &&
3331 /* Internal navigation detected, but flag not set, only allow
3332 * this is there's a fetch multipart
3333 */
3334 if (post_multipart == NULL) {
3335 return NSERROR_NEED_DATA;
3336 }
3337 /* It *is* internal, set it as such */
3339 /* If we were previously internal, don't update again */
3340 if (bw->internal_nav) {
3342 }
3343 }
3344
3345 /* If we're navigating and we have a history entry and a content
3346 * then update the history entry before we navigate to save our
3347 * current state. However since history navigation pre-moves
3348 * the history state, we ensure that we only do this if we've not
3349 * been suppressed. In the suppressed case, the history code
3350 * updates the history itself before navigating.
3351 */
3352 if (bw->current_content != NULL &&
3353 bw->history != NULL &&
3354 bw->history->current != NULL &&
3355 !is_internal &&
3358 }
3359
3360 /* don't allow massively nested framesets */
3361 for (cur = bw; cur->parent; cur = cur->parent) {
3362 depth++;
3363 }
3364 if (depth > FRAME_DEPTH) {
3365 NSLOG(netsurf, INFO, "frame depth too high.");
3366 return NSERROR_FRAME_DEPTH;
3367 }
3368
3369 /* Set up retrieval parameters */
3371 fetch_flags |= LLCACHE_RETRIEVE_VERIFIABLE;
3372 }
3373
3374 if (post_multipart != NULL) {
3375 post.type = LLCACHE_POST_MULTIPART;
3377 } else if (post_urlenc != NULL) {
3378 post.type = LLCACHE_POST_URL_ENCODED;
3379 post.data.urlenc = post_urlenc;
3380 }
3381
3383 if ((parent != NULL) && (content_get_type(parent) == CONTENT_HTML)) {
3385 } else {
3386 child.quirks = false;
3387 }
3388
3389 url = nsurl_ref(url);
3390
3391 if (referrer != NULL) {
3393 }
3394
3395 /* Get download out of the way */
3396 if ((flags & BW_NAVIGATE_DOWNLOAD) != 0) {
3397 error = browser_window_download(bw,
3398 url,
3399 referrer,
3400 fetch_flags,
3401 fetch_is_post,
3402 &post);
3404 if (referrer != NULL) {
3406 }
3407 return error;
3408 }
3409
3410 if (bw->frag_id != NULL) {
3411 lwc_string_unref(bw->frag_id);
3412 }
3413 bw->frag_id = NULL;
3414
3416 bool same_url = false;
3417
3419
3420 /* Compare new URL with existing one (ignoring fragments) */
3421 if ((bw->current_content != NULL) &&
3422 (hlcache_handle_get_url(bw->current_content) != NULL)) {
3423 same_url = nsurl_compare(
3424 url,
3427 }
3428
3429 /* if we're simply moving to another ID on the same page,
3430 * don't bother to fetch, just update the window.
3431 */
3432 if ((same_url) &&
3433 (fetch_is_post == false) &&
3434 (nsurl_has_component(url, NSURL_QUERY) == false)) {
3436
3437 if (referrer != NULL) {
3439 }
3440
3441 if ((flags & BW_NAVIGATE_HISTORY) != 0) {
3443 bw->current_content,
3444 bw->frag_id);
3445 }
3446
3447 browser_window_update(bw, false);
3448
3449 if (bw->current_content != NULL) {
3451 }
3452 return NSERROR_OK;
3453 }
3454 }
3455
3457 browser_window_remove_caret(bw, false);
3460
3461 /* Set up the fetch parameters */
3462 memset(&params, 0, sizeof(params));
3463
3464 params.url = nsurl_ref(url);
3465
3466 if (referrer != NULL) {
3467 params.referrer = nsurl_ref(referrer);
3468 }
3469
3470 params.flags = flags;
3471
3472 if (post_urlenc != NULL) {
3473 params.post_urlenc = strdup(post_urlenc);
3474 }
3475
3476 if (post_multipart != NULL) {
3478 }
3479
3480 if (parent != NULL) {
3481 params.parent_charset = strdup(child.charset);
3482 params.parent_quirks = child.quirks;
3483 }
3484
3485 bw->internal_nav = is_internal;
3486
3487 if (is_internal) {
3488 pass_params = &params;
3489 } else {
3490 /* At this point, we're navigating, so store the fetch parameters */
3492 memcpy(&bw->loading_parameters, &params, sizeof(params));
3493 memset(&params, 0, sizeof(params));
3494 pass_params = &bw->loading_parameters;
3495 }
3496
3497 error = browser_window__navigate_internal(bw, pass_params);
3498
3500
3501 if (referrer != NULL) {
3503 }
3504
3505 if (is_internal) {
3507 }
3508
3509 return error;
3510}
3511
3512
3513/**
3514 * Internal navigation handler for normal fetches
3515 */
3516static nserror
3518 struct browser_fetch_parameters *params)
3519{
3520 uint32_t fetch_flags = 0;
3521 bool fetch_is_post;
3522 llcache_post_data post;
3524 nserror res;
3525 hlcache_handle *c;
3526
3527 NSLOG(netsurf, INFO, "Loading '%s'", nsurl_access(params->url));
3528
3529 fetch_is_post = (params->post_urlenc != NULL || params->post_multipart != NULL);
3530
3531 /* Clear SSL info for load */
3533 bw->loading_cert_chain = NULL;
3534
3535 /* Set up retrieval parameters */
3536 if (!(params->flags & BW_NAVIGATE_UNVERIFIABLE)) {
3537 fetch_flags |= LLCACHE_RETRIEVE_VERIFIABLE;
3538 }
3539
3540 if (params->post_multipart != NULL) {
3541 post.type = LLCACHE_POST_MULTIPART;
3542 post.data.multipart = params->post_multipart;
3543 } else if (params->post_urlenc != NULL) {
3544 post.type = LLCACHE_POST_URL_ENCODED;
3545 post.data.urlenc = params->post_urlenc;
3546 }
3547
3548 if (params->parent_charset != NULL) {
3549 child.charset = params->parent_charset;
3550 child.quirks = params->parent_quirks;
3551 }
3552
3554 bw->history_add = (params->flags & BW_NAVIGATE_HISTORY);
3555
3556 /* Verifiable fetches may trigger a download */
3557 if (!(params->flags & BW_NAVIGATE_UNVERIFIABLE)) {
3558 fetch_flags |= HLCACHE_RETRIEVE_MAY_DOWNLOAD;
3559 }
3560
3561 res = hlcache_handle_retrieve(params->url,
3562 fetch_flags | HLCACHE_RETRIEVE_SNIFF_TYPE,
3563 params->referrer,
3564 fetch_is_post ? &post : NULL,
3566 bw,
3567 params->parent_charset != NULL ? &child : NULL,
3569 &c);
3570
3571 switch (res) {
3572 case NSERROR_OK:
3573 bw->loading_content = c;
3575 if (bw->window != NULL) {
3576 guit->window->set_icon(bw->window, NULL);
3577 }
3578 if (bw->internal_nav == false) {
3580 params->url);
3581 }
3582 break;
3583
3584 case NSERROR_NO_FETCH_HANDLER: /* no handler for this type */
3585 /** \todo does this always try and download even
3586 * unverifiable content?
3587 */
3588 res = guit->misc->launch_url(params->url);
3589 break;
3590
3591 default: /* report error to user */
3593 break;
3594
3595 }
3596
3597 /* Record time */
3598 nsu_getmonotonic_ms(&bw->last_action);
3599
3600 return res;
3601}
3602
3603
3604/**
3605 * Internal navigation handler for the authentication query handler
3606 *
3607 * If the parameters indicate we're processing a *response* from the handler
3608 * then we deal with that, otherwise we pass it on to the about: handler
3609 */
3610static nserror
3612 struct browser_fetch_parameters *params)
3613{
3614 char *userpass = NULL;
3615 const char *username, *password, *realm, *siteurl;
3616 nsurl *sitensurl;
3617 nserror res;
3618 bool is_login = false, is_cancel = false;
3619
3620 assert(params->post_multipart != NULL);
3621
3622 is_login = fetch_multipart_data_find(params->post_multipart, "login") != NULL;
3623 is_cancel = fetch_multipart_data_find(params->post_multipart, "cancel") != NULL;
3624
3625 if (!(is_login || is_cancel)) {
3626 /* This is a request, so pass it on */
3627 return navigate_internal_real(bw, params);
3628 }
3629
3630 if (is_cancel) {
3631 /* We're processing a cancel, do a rough-and-ready nav to
3632 * about:blank
3633 */
3635 bw->loading_parameters.url = nsurl_ref(corestring_nsurl_about_blank);
3637 bw->internal_nav = true;
3639 }
3640
3641 /* We're processing a "login" attempt from the form */
3642
3643 /* Retrieve the data */
3644 username = fetch_multipart_data_find(params->post_multipart, "username");
3645 password = fetch_multipart_data_find(params->post_multipart, "password");
3646 realm = fetch_multipart_data_find(params->post_multipart, "realm");
3647 siteurl = fetch_multipart_data_find(params->post_multipart, "siteurl");
3648
3649 if (username == NULL || password == NULL ||
3650 realm == NULL || siteurl == NULL) {
3651 /* Bad inputs, simply fail */
3652 return NSERROR_INVALID;
3653 }
3654
3655 /* Parse the URL */
3656 res = nsurl_create(siteurl, &sitensurl);
3657 if (res != NSERROR_OK) {
3658 return res;
3659 }
3660
3661 /* Construct the username/password */
3662 res = browser_window__build_userpass(username, password, &userpass);
3663 if (res != NSERROR_OK) {
3664 nsurl_unref(sitensurl);
3665 return res;
3666 }
3667
3668 /* And let urldb know */
3669 urldb_set_auth_details(sitensurl, realm, userpass);
3670
3671 /* Clean up */
3672 free(userpass);
3673 nsurl_unref(sitensurl);
3674
3675 /* Finally navigate to the original loading parameters */
3676 bw->internal_nav = false;
3678}
3679
3680
3681/**
3682 * Internal navigation handler for the SSL/privacy query page.
3683 *
3684 * If the parameters indicate we're processing a *response* from the handler
3685 * then we deal with that, otherwise we pass it on to the about: handler
3686 */
3687static nserror
3689 struct browser_fetch_parameters *params)
3690{
3691 bool is_proceed = false, is_back = false;
3692 const char *siteurl = NULL;
3693 nsurl *siteurl_ns;
3694
3695 assert(params->post_multipart != NULL);
3696
3697 is_proceed = fetch_multipart_data_find(params->post_multipart, "proceed") != NULL;
3698 is_back = fetch_multipart_data_find(params->post_multipart, "back") != NULL;
3699 siteurl = fetch_multipart_data_find(params->post_multipart, "siteurl");
3700
3701 if (!(is_proceed || is_back) || siteurl == NULL) {
3702 /* This is a request, so pass it on */
3703 return navigate_internal_real(bw, params);
3704 }
3705
3706 if (nsurl_create(siteurl, &siteurl_ns) != NSERROR_OK) {
3707 NSLOG(netsurf, ERROR, "Unable to reset ssl loading parameters");
3708 } else {
3709 /* In order that we may proceed, replace the loading parameters */
3711 bw->loading_parameters.url = siteurl_ns;
3712 }
3713
3714 return browser_window__handle_ssl_query_response(is_proceed, bw);
3715}
3716
3717
3718/**
3719 * Internal navigation handler for the timeout query page.
3720 *
3721 * If the parameters indicate we're processing a *response* from the handler
3722 * then we deal with that, otherwise we pass it on to the about: handler
3723 */
3724static nserror
3726 struct browser_fetch_parameters *params)
3727{
3728 bool is_retry = false, is_back = false;
3729
3730 NSLOG(netsurf, INFO, "bw:%p params:%p", bw, params);
3731
3732 assert(params->post_multipart != NULL);
3733
3734 is_retry = fetch_multipart_data_find(params->post_multipart, "retry") != NULL;
3735 is_back = fetch_multipart_data_find(params->post_multipart, "back") != NULL;
3736
3737 if (is_back) {
3738 /* do a rough-and-ready nav to the old 'current'
3739 * parameters, with any post data stripped away
3740 */
3742 }
3743
3744 if (is_retry) {
3745 /* Finally navigate to the original loading parameters */
3746 bw->internal_nav = false;
3748 }
3749
3750 return navigate_internal_real(bw, params);
3751}
3752
3753
3754/**
3755 * Internal navigation handler for the fetch error query page.
3756 *
3757 * If the parameters indicate we're processing a *response* from the handler
3758 * then we deal with that, otherwise we pass it on to the about: handler
3759 */
3760static nserror
3762 struct browser_fetch_parameters *params)
3763{
3764 bool is_retry = false, is_back = false;
3765
3766 NSLOG(netsurf, INFO, "bw:%p params:%p", bw, params);
3767
3768 assert(params->post_multipart != NULL);
3769
3770 is_retry = fetch_multipart_data_find(params->post_multipart, "retry") != NULL;
3771 is_back = fetch_multipart_data_find(params->post_multipart, "back") != NULL;
3772
3773 if (is_back) {
3774 /* do a rough-and-ready nav to the old 'current'
3775 * parameters, with any post data stripped away
3776 */
3778 }
3779
3780 if (is_retry) {
3781 /* Finally navigate to the original loading parameters */
3782 bw->internal_nav = false;
3784 }
3785
3786 return navigate_internal_real(bw, params);
3787}
3788
3789
3790/**
3791 * dispatch to internal query handlers or normal navigation
3792 *
3793 * Here we determine if we're navigating to an internal query URI and
3794 * if so, what we need to do about it.
3795 *
3796 * \note these check must match those in is_internal_navigate_url()
3797 *
3798 * If we're not, then we just move on to the real navigate.
3799 */
3800nserror
3802 struct browser_fetch_parameters *params)
3803{
3804 lwc_string *scheme, *path;
3805
3806 /* All our special URIs are in the about: scheme */
3807 scheme = nsurl_get_component(params->url, NSURL_SCHEME);
3808 if (scheme != corestring_lwc_about) {
3809 lwc_string_unref(scheme);
3810 goto normal_fetch;
3811 }
3812 lwc_string_unref(scheme);
3813
3814 /* Is it the auth query handler? */
3816 if (path == corestring_lwc_query_auth) {
3817 lwc_string_unref(path);
3818 return navigate_internal_query_auth(bw, params);
3819 }
3820 if (path == corestring_lwc_query_ssl) {
3821 lwc_string_unref(path);
3822 return navigate_internal_query_ssl(bw, params);
3823 }
3824 if (path == corestring_lwc_query_timeout) {
3825 lwc_string_unref(path);
3826 return navigate_internal_query_timeout(bw, params);
3827 }
3828 if (path == corestring_lwc_query_fetcherror) {
3829 lwc_string_unref(path);
3830 return navigate_internal_query_fetcherror(bw, params);
3831 }
3832 if (path != NULL) {
3833 lwc_string_unref(path);
3834 }
3835
3836 /* Fall through to a normal about: fetch */
3837
3838 normal_fetch:
3839 return navigate_internal_real(bw, params);
3840}
3841
3842
3843/* Exported interface, documented in netsurf/browser_window.h */
3845{
3846 bool result = false;
3847
3848 if (bw != NULL && bw->current_content != NULL) {
3849 nsurl *parent;
3850 nserror err;
3852 &parent);
3853 if (err == NSERROR_OK) {
3855 bw->current_content),
3856 parent,
3857 NSURL_COMPLETE) == false;
3859 }
3860 }
3861
3862 return result;
3863}
3864
3865
3866/* Exported interface, documented in netsurf/browser_window.h */
3868{
3869 nsurl *current, *parent;
3870 nserror err;
3871
3872 if (bw == NULL)
3873 return NSERROR_BAD_PARAMETER;
3874
3875 current = browser_window_access_url(bw);
3876
3877 err = nsurl_parent(current, &parent);
3878 if (err != NSERROR_OK) {
3879 return err;
3880 }
3881
3882 if (nsurl_compare(current, parent, NSURL_COMPLETE) == true) {
3883 /* Can't go up to parent from here */
3885 return NSERROR_OK;
3886 }
3887
3888 if (new_window) {
3890 parent, NULL, bw, NULL);
3891 } else {
3892 err = browser_window_navigate(bw, parent, NULL,
3894 NULL, NULL, NULL);
3895 }
3896
3898 return err;
3899}
3900
3901
3902/* Exported interface, documented in include/netsurf/browser_window.h */
3904{
3905 assert(bw != NULL);
3906
3907 if (bw->current_content != NULL) {
3909
3910 } else if (bw->loading_content != NULL) {
3911 /* TODO: should we return this? */
3913 }
3914
3915 return corestring_nsurl_about_blank;
3916}
3917
3918
3919/* Exported interface, documented in include/netsurf/browser_window.h */
3920nserror
3921browser_window_get_url(struct browser_window *bw, bool fragment,nsurl** url_out)
3922{
3923 nserror err;
3924 nsurl *url;
3925
3926 assert(bw != NULL);
3927
3928 if (!fragment || bw->frag_id == NULL || bw->loading_content != NULL) {
3929 /* If there's a loading content, then the bw->frag_id will have
3930 * been trampled, possibly with a new frag_id, but we will
3931 * still be returning the current URL, so in this edge case
3932 * we just drop any fragment. */
3934
3935 } else {
3937 bw->frag_id, &url);
3938 if (err != NSERROR_OK) {
3939 return err;
3940 }
3941 }
3942
3943 *url_out = url;
3944 return NSERROR_OK;
3945}
3946
3947
3948/* Exported interface, documented in netsurf/browser_window.h */
3950{
3951 assert(bw != NULL);
3952
3953 if (bw->current_content != NULL) {
3955 }
3956
3957 /* no content so return about:blank */
3958 return nsurl_access(corestring_nsurl_about_blank);
3959}
3960
3961
3962/* Exported interface, documented in netsurf/browser_window.h */
3964{
3965 assert(bw != NULL);
3966
3967 return bw->history;
3968}
3969
3970
3971/* Exported interface, documented in netsurf/browser_window.h */
3973{
3974 assert(bw != NULL);
3975
3976 if (bw->current_content == NULL) {
3977 return false;
3978 }
3979
3980 return true;
3981}
3982
3983
3984/* Exported interface, documented in netsurf/browser_window.h */
3986{
3987 return bw->current_content;
3988}
3989
3990
3991/* Exported interface, documented in netsurf/browser_window.h */
3993 int *width, int *height)
3994{
3995 assert(bw != NULL);
3996
3997 if (bw->current_content == NULL) {
3998 *width = 0;
3999 *height = 0;
4000 return NSERROR_BAD_CONTENT;
4001 }
4002
4005
4006 if (scaled) {
4007 *width *= bw->scale;
4008 *height *= bw->scale;
4009 }
4010
4011 return NSERROR_OK;
4012}
4013
4014
4015/* exported internal interface, documented in desktop/browser_private.h */
4016nserror
4018 int *width,
4019 int *height)
4020{
4021 nserror res;
4022 assert(bw);
4023
4024 if (bw->window == NULL) {
4025 /* Core managed browser window */
4026 *width = bw->width;
4027 *height = bw->height;
4028 res = NSERROR_OK;
4029 } else {
4030 /* Front end window */
4032 }
4033 return res;
4034}
4035
4036
4037/* Exported interface, documented in netsurf/browser_window.h */
4038void
4040{
4041 assert(bw);
4042
4043 if (bw->window == NULL) {
4044 /* Core managed browser window */
4045 bw->width = width;
4046 bw->height = height;
4047 } else {
4048 NSLOG(netsurf, INFO,
4049 "Asked to set dimensions of front end window.");
4050 assert(0);
4051 }
4052}
4053
4054
4055/* Exported interface, documented in browser/browser_private.h */
4056nserror
4058{
4059 int pos_x;
4060 int pos_y;
4061 struct browser_window *top = bw;
4062
4063 assert(bw);
4064
4065 if (bw->window == NULL) {
4066 /* Core managed browser window */
4067 browser_window_get_position(bw, true, &pos_x, &pos_y);
4068
4070
4071 rect->x0 += pos_x / bw->scale;
4072 rect->y0 += pos_y / bw->scale;
4073 rect->x1 += pos_x / bw->scale;
4074 rect->y1 += pos_y / bw->scale;
4075 }
4076
4077 rect->x0 *= top->scale;
4078 rect->y0 *= top->scale;
4079 rect->x1 *= top->scale;
4080 rect->y1 *= top->scale;
4081
4082 return guit->window->invalidate(top->window, rect);
4083}
4084
4085
4086/* Exported interface, documented in netsurf/browser_window.h */
4088{
4089 int children, index;
4090
4091 if (bw->loading_content != NULL) {
4094 bw->loading_content = NULL;
4095 }
4096
4097 if (bw->current_content != NULL &&
4099 nserror error;
4103 assert(error == NSERROR_OK);
4104 }
4105
4107
4108 if (bw->children) {
4109 children = bw->rows * bw->cols;
4110 for (index = 0; index < children; index++)
4112 }
4113 if (bw->iframes) {
4115 for (index = 0; index < children; index++)
4116 browser_window_stop(&bw->iframes[index]);
4117 }
4118
4119 if (bw->current_content != NULL) {
4121 }
4122
4124}
4125
4126
4127/* Exported interface, documented in netsurf/browser_window.h */
4129{
4130 hlcache_handle *c;
4131 unsigned int i;
4132 struct nsurl *reload_url;
4133
4134 if ((bw->current_content) == NULL ||
4135 (bw->loading_content) != NULL) {
4136 return NSERROR_INVALID;
4137 }
4138
4139 if (all && content_get_type(bw->current_content) == CONTENT_HTML) {
4140 struct html_stylesheet *sheets;
4141 struct content_html_object *object;
4142 unsigned int count;
4143
4144 c = bw->current_content;
4145
4146 /* invalidate objects */
4147 object = html_get_objects(c, &count);
4148
4149 for (; object != NULL; object = object->next) {
4150 if (object->content != NULL)
4152 }
4153
4154 /* invalidate stylesheets */
4155 sheets = html_get_stylesheets(c, &count);
4156
4157 for (i = STYLESHEET_START; i != count; i++) {
4158 if (sheets[i].sheet != NULL) {
4159 content_invalidate_reuse_data(sheets[i].sheet);
4160 }
4161 }
4162 }
4163
4165
4166 reload_url = hlcache_handle_get_url(bw->current_content);
4167
4168 return browser_window_navigate(bw,
4169 reload_url,
4170 NULL,
4172 NULL,
4173 NULL,
4174 NULL);
4175}
4176
4177
4178/* Exported interface, documented in netsurf/browser_window.h */
4179void browser_window_set_status(struct browser_window *bw, const char *text)
4180{
4181 int text_len;
4182 /* find topmost window */
4183 while (bw->parent)
4184 bw = bw->parent;
4185
4186 if ((bw->status.text != NULL) &&
4187 (strcmp(text, bw->status.text) == 0)) {
4188 /* status text is unchanged */
4189 bw->status.match++;
4190 return;
4191 }
4192
4193 /* status text is changed */
4194
4195 text_len = strlen(text);
4196
4197 if ((bw->status.text == NULL) || (bw->status.text_len < text_len)) {
4198 /* no current string allocation or it is not long enough */
4199 free(bw->status.text);
4200 bw->status.text = strdup(text);
4201 bw->status.text_len = text_len;
4202 } else {
4203 /* current allocation has enough space */
4204 memcpy(bw->status.text, text, text_len + 1);
4205 }
4206
4207 bw->status.miss++;
4208 guit->window->set_status(bw->window, bw->status.text);
4209}
4210
4211
4212/* Exported interface, documented in netsurf/browser_window.h */
4215{
4217 gui_pointer_shape gui_shape;
4218 bool loading;
4219 uint64_t ms_now;
4220
4221 assert(root);
4222 assert(root->window);
4223
4224 loading = ((bw->loading_content != NULL) ||
4225 ((bw->current_content != NULL) &&
4227
4228 nsu_getmonotonic_ms(&ms_now);
4229
4230 if (loading && ((ms_now - bw->last_action) < 1000)) {
4231 /* If loading and less than 1 second since last link followed,
4232 * force progress indicator pointer */
4233 gui_shape = GUI_POINTER_PROGRESS;
4234
4235 } else if (shape == BROWSER_POINTER_AUTO) {
4236 /* Up to browser window to decide */
4237 if (loading) {
4238 gui_shape = GUI_POINTER_PROGRESS;
4239 } else {
4240 gui_shape = GUI_POINTER_DEFAULT;
4241 }
4242
4243 } else {
4244 /* Use what we were told */
4245 gui_shape = (gui_pointer_shape)shape;
4246 }
4247
4248 guit->window->set_pointer(root->window, gui_shape);
4249}
4250
4251
4252/* exported function documented in netsurf/browser_window.h */
4254{
4255 if (bw->window == NULL) {
4256 return NSERROR_BAD_PARAMETER;
4257 }
4258
4259 return guit->misc->schedule(0, scheduled_reformat, bw);
4260}
4261
4262
4263/* exported function documented in netsurf/browser_window.h */
4264void
4266 bool background,
4267 int width,
4268 int height)
4269{
4271
4272 if (c == NULL)
4273 return;
4274
4276 /* Iframe dimensions are already scaled in parent's layout */
4277 width /= bw->scale;
4278 height /= bw->scale;
4279 }
4280
4281 if (bw->window == NULL) {
4282 /* Core managed browser window; subtract scrollbar width */
4283 width -= bw->scroll_y ? SCROLLBAR_WIDTH : 0;
4285
4286 width = width > 0 ? width : 0;
4287 height = height > 0 ? height : 0;
4288 }
4289
4290 content_reformat(c, background, width, height);
4291}
4292
4293
4294/* exported interface documented in netsurf/browser_window.h */
4295nserror
4296browser_window_set_scale(struct browser_window *bw, float scale, bool absolute)
4297{
4298 nserror res;
4299
4300 /* get top browser window */
4301 while (bw->parent) {
4302 bw = bw->parent;
4303 }
4304
4305 if (!absolute) {
4306 /* snap small values around 1.0 */
4307 if ((scale + bw->scale) > (1.01 - scale) &&
4308 (scale + bw->scale) < (0.99 + scale)) {
4309 scale = 1.0;
4310 } else {
4311 scale += bw->scale;
4312 }
4313 }
4314
4315 /* clamp range between 0.1 and 10 (10% and 1000%) */
4316 if (scale < SCALE_MINIMUM) {
4318 } else if (scale > SCALE_MAXIMUM) {
4320 }
4321
4323 if (res == NSERROR_OK) {
4325 }
4326
4327 return res;
4328}
4329
4330
4331/* exported interface documented in netsurf/browser_window.h */
4333{
4334 if (bw == NULL) {
4335 return 1.0;
4336 }
4337
4338 return bw->scale;
4339}
4340
4341
4342/* exported interface documented in netsurf/browser_window.h */
4343struct browser_window *
4345 const char *target,
4346 browser_mouse_state mouse)
4347{
4348 struct browser_window *bw_target;
4349 struct browser_window *top;
4350 hlcache_handle *c;
4351 int rdepth;
4352 nserror error;
4353
4354 /* use the base target if we don't have one */
4355 c = bw->current_content;
4356 if (target == NULL &&
4357 c != NULL &&
4359 target = html_get_base_target(c);
4360 }
4361 if (target == NULL) {
4362 target = "_self";
4363 }
4364
4365 /* allow the simple case of target="_blank" to be ignored if requested
4366 */
4367 if ((!(mouse & BROWSER_MOUSE_CLICK_2)) &&
4368 (!((mouse & BROWSER_MOUSE_CLICK_2) &&
4369 (mouse & BROWSER_MOUSE_MOD_2))) &&
4370 (!nsoption_bool(target_blank))) {
4371 /* not a mouse button 2 click
4372 * not a mouse button 1 click with ctrl pressed
4373 * configured to ignore target="_blank" */
4374 if (!strcasecmp(target, "_blank"))
4375 return bw;
4376 }
4377
4378 /* handle reserved keywords */
4379 if (((nsoption_bool(button_2_tab)) &&
4380 (mouse & BROWSER_MOUSE_CLICK_2))||
4381 ((!nsoption_bool(button_2_tab)) &&
4382 ((mouse & BROWSER_MOUSE_CLICK_1) &&
4383 (mouse & BROWSER_MOUSE_MOD_2))) ||
4384 ((nsoption_bool(button_2_tab)) &&
4385 (!strcasecmp(target, "_blank")))) {
4386 /* open in new tab if:
4387 * - button_2 opens in new tab and button_2 was pressed
4388 * OR
4389 * - button_2 doesn't open in new tabs and button_1 was
4390 * pressed with ctrl held
4391 * OR
4392 * - button_2 opens in new tab and the link target is "_blank"
4393 */
4397 NULL,
4398 NULL,
4399 bw,
4400 &bw_target);
4401 if (error != NSERROR_OK) {
4402 return bw;
4403 }
4404 return bw_target;
4405 } else if (((!nsoption_bool(button_2_tab)) &&
4406 (mouse & BROWSER_MOUSE_CLICK_2)) ||
4407 ((nsoption_bool(button_2_tab)) &&
4408 ((mouse & BROWSER_MOUSE_CLICK_1) &&
4409 (mouse & BROWSER_MOUSE_MOD_2))) ||
4410 ((!nsoption_bool(button_2_tab)) &&
4411 (!strcasecmp(target, "_blank")))) {
4412 /* open in new window if:
4413 * - button_2 doesn't open in new tabs and button_2 was pressed
4414 * OR
4415 * - button_2 opens in new tab and button_1 was pressed with
4416 * ctrl held
4417 * OR
4418 * - button_2 doesn't open in new tabs and the link target is
4419 * "_blank"
4420 */
4423 NULL,
4424 NULL,
4425 bw,
4426 &bw_target);
4427 if (error != NSERROR_OK) {
4428 return bw;
4429 }
4430 return bw_target;
4431 } else if (!strcasecmp(target, "_self")) {
4432 return bw;
4433 } else if (!strcasecmp(target, "_parent")) {
4434 if (bw->parent)
4435 return bw->parent;
4436 return bw;
4437 } else if (!strcasecmp(target, "_top")) {
4438 while (bw->parent)
4439 bw = bw->parent;
4440 return bw;
4441 }
4442
4443 /* find frame according to B.8, ie using the following priorities:
4444 *
4445 * 1) current frame
4446 * 2) closest to front
4447 */
4448 rdepth = -1;
4449 bw_target = NULL;
4450 for (top = bw; top->parent; top = top->parent);
4451 browser_window_find_target_internal(top, target, 0, bw, &rdepth,
4452 &bw_target);
4453 if (bw_target)
4454 return bw_target;
4455
4456 /* we require a new window using the target name */
4457 if (!nsoption_bool(target_blank))
4458 return bw;
4459
4461 NULL,
4462 NULL,
4463 bw,
4464 &bw_target);
4465 if (error != NSERROR_OK) {
4466 return bw;
4467 }
4468
4469 /* frame names should begin with an alphabetic character (a-z,A-Z),
4470 * however in practice you get things such as '_new' and '2left'. The
4471 * only real effect this has is when giving out names as it can be
4472 * assumed that an author intended '_new' to create a new nameless
4473 * window (ie '_blank') whereas in the case of '2left' the intention
4474 * was for a new named window. As such we merely special case windows
4475 * that begin with an underscore. */
4476 if (target[0] != '_') {
4477 bw_target->name = strdup(target);
4478 }
4479 return bw_target;
4480}
4481
4482
4483/* exported interface documented in netsurf/browser_window.h */
4484void
4486 browser_mouse_state mouse,
4487 int x, int y)
4488{
4490 mouse,
4491 x / bw->scale,
4492 y / bw->scale);
4493}
4494
4495/* exported interface documented in netsurf/browser_window.h */
4496void
4498 browser_mouse_state mouse,
4499 int x, int y)
4500{
4502 mouse,
4503 x / bw->scale,
4504 y / bw->scale);
4505}
4506
4507
4508/* exported interface documented in netsurf/browser_window.h */
4510{
4511 assert(bw != NULL);
4512
4514
4515 bw->drag.start_x = x;
4516 bw->drag.start_y = y;
4517
4518 if (bw->window != NULL) {
4519 /* Front end window */
4523
4525 } else {
4526 /* Core managed browser window */
4529 }
4530}
4531
4532
4533/* exported interface documented in netsurf/browser_window.h */
4535{
4536 if (bw != NULL && bw->internal_nav) {
4537 /* Internal nav, back is possible */
4538 return true;
4539 }
4541}
4542
4543
4544/* exported interface documented in netsurf/browser_window.h */
4546{
4548}
4549
4550/* exported interface documented in netsurf/browser_window.h */
4552{
4553 return (bw && bw->current_content && !bw->loading_content);
4554}
4555
4556
4557/* exported interface documented in netsurf/browser_window.h */
4559{
4560 return (bw && (bw->loading_content ||
4561 (bw->current_content &&
4564}
4565
4566/* exported interface documented in netsurf/browser_window.h */
4567bool
4568browser_window_exec(struct browser_window *bw, const char *src, size_t srclen)
4569{
4570 assert(bw != NULL);
4571
4572 if (!bw->current_content) {
4573 NSLOG(netsurf, DEEPDEBUG, "Unable to exec, no content");
4574 return false;
4575 }
4576
4578 NSLOG(netsurf, DEEPDEBUG, "Unable to exec, content not done");
4579 return false;
4580 }
4581
4582 /* Okay it should be safe, forward the request through to the content
4583 * itself. Only HTML contents currently support executing code
4584 */
4585 return content_exec(bw->current_content, src, srclen);
4586}
4587
4588
4589/* exported interface documented in browser_window.h */
4590nserror
4593 const char *msg,
4594 size_t msglen,
4596{
4599
4600 assert(msg != NULL);
4601 /* We don't assert msglen > 0, if someone wants to log a real empty
4602 * string then we won't stop them. It does sometimes happen from
4603 * JavaScript for example.
4604 */
4605
4606 /* bw is the target of the log, but root is where we log it */
4607
4608 NSLOG(netsurf, DEEPDEBUG, "Logging message in %p targetted at %p", root, bw);
4609 NSLOG(netsurf, DEEPDEBUG, "Log came from %s",
4610 ((src == BW_CS_INPUT) ? "user input" :
4611 (src == BW_CS_SCRIPT_ERROR) ? "script error" :
4612 (src == BW_CS_SCRIPT_CONSOLE) ? "script console" :
4613 "unknown input location"));
4614
4615 switch (log_level) {
4617 NSLOG(netsurf, DEBUG, "%.*s", (int)msglen, msg);
4618 break;
4620 NSLOG(netsurf, VERBOSE, "%.*s", (int)msglen, msg);
4621 break;
4623 NSLOG(netsurf, INFO, "%.*s", (int)msglen, msg);
4624 break;
4626 NSLOG(netsurf, WARNING, "%.*s", (int)msglen, msg);
4627 break;
4629 NSLOG(netsurf, ERROR, "%.*s", (int)msglen, msg);
4630 break;
4631 default:
4632 /* Unreachable */
4633 break;
4634 }
4635
4636 guit->window->console_log(root->window, src, msg, msglen, flags);
4637
4638 return NSERROR_OK;
4639}
4640
4641
4642/* Exported interface, documented in browser_private.h */
4643nserror
4645{
4646 assert(bw != NULL);
4647
4648 if (bw->current_parameters.post_urlenc != NULL) {
4651 }
4652
4653 if (bw->current_parameters.post_multipart != NULL) {
4656 }
4657
4658 if (bw->current_parameters.url == NULL) {
4659 /* We have never navigated so go to about:blank */
4660 bw->current_parameters.url = nsurl_ref(corestring_nsurl_about_blank);
4661 }
4662
4663 bw->current_parameters.flags &= ~BW_NAVIGATE_HISTORY;
4664 bw->internal_nav = false;
4665
4668 memset(&bw->current_parameters, 0, sizeof(bw->current_parameters));
4670}
4671
4672/* Exported interface, documented in browser_window.h */
4674 const struct browser_window *bw)
4675{
4676 lwc_string *scheme;
4677 bool match;
4678
4679 assert(bw != NULL);
4680
4681 /* Do we have any content? If not -- UNKNOWN */
4682 if (bw->current_content == NULL) {
4683 return PAGE_STATE_UNKNOWN;
4684 }
4685
4686 scheme = nsurl_get_component(
4688
4689 /* Is this an internal scheme? */
4690 if ((lwc_string_isequal(scheme, corestring_lwc_about,
4691 &match) == lwc_error_ok &&
4692 (match == true)) ||
4693 (lwc_string_isequal(scheme, corestring_lwc_data,
4694 &match) == lwc_error_ok &&
4695 (match == true)) ||
4696 (lwc_string_isequal(scheme, corestring_lwc_resource,
4697 &match) == lwc_error_ok &&
4698 (match == true))) {
4699 lwc_string_unref(scheme);
4700 return PAGE_STATE_INTERNAL;
4701 }
4702
4703 /* Is this file:/// ? */
4704 if (lwc_string_isequal(scheme, corestring_lwc_file,
4705 &match) == lwc_error_ok &&
4706 match == true) {
4707 lwc_string_unref(scheme);
4708 return PAGE_STATE_LOCAL;
4709 }
4710
4711 /* If not https, from here on down that'd be insecure */
4712 if ((lwc_string_isequal(scheme, corestring_lwc_https,
4713 &match) == lwc_error_ok &&
4714 (match == false))) {
4715 /* Some remote content, not https, therefore insecure */
4716 lwc_string_unref(scheme);
4717 return PAGE_STATE_INSECURE;
4718 }
4719
4720 lwc_string_unref(scheme);
4721
4722 /* Did we have to override this SSL setting? */
4725 }
4726
4727 /* If we've seen insecure content internally then we need to say so */
4730 }
4731
4732 /* All is well, return secure state */
4733 return PAGE_STATE_SECURE;
4734}
4735
4736/* Exported interface, documented in browser_window.h */
4737nserror
4739 struct cert_chain **chain)
4740{
4741 assert(bw != NULL);
4742
4743 if (bw->current_cert_chain == NULL) {
4744 return NSERROR_NOT_FOUND;
4745 }
4746
4747 *chain = bw->current_cert_chain;
4748
4749 return NSERROR_OK;
4750}
4751
4752/* Exported interface, documented in browser_window.h */
4754 const struct browser_window *bw)
4755{
4756 int count = 0;
4757 char *cookies = urldb_get_cookie(browser_window_access_url(bw), true);
4758 if (cookies == NULL) {
4759 return 0;
4760 }
4761
4762 for (char *c = cookies; *c != '\0'; c++) {
4763 if (*c == ';')
4764 count++;
4765 }
4766
4767 free(cookies);
4768
4769 return count;
4770}
4771
4772/* Exported interface, documented in browser_window.h */
4774 const struct browser_window *bw)
4775{
4776 nserror err;
4778 lwc_string *host = nsurl_get_component(url, NSURL_HOST);
4779 const char *string = (host != NULL) ? lwc_string_data(host) : NULL;
4780
4781 err = guit->misc->present_cookies(string);
4782
4783 if (host != NULL) {
4784 lwc_string_unref(host);
4785 }
4786 return err;
4787}
4788
4789/* Exported interface, documented in browser_window.h */
4791{
4792 nserror res;
4793 nsurl *url;
4794
4795 if (bw->current_cert_chain == NULL) {
4796 return NSERROR_NOT_FOUND;
4797 }
4798
4800 if (res == NSERROR_OK) {
4804 url,
4805 NULL,
4806 bw,
4807 NULL);
4808
4809 nsurl_unref(url);
4810 }
4811
4812 return res;
4813}
STATIC char result[100]
Definition: arexx.c:77
nserror browser_window_history_add(struct browser_window *bw, struct hlcache_handle *content, lwc_string *frag_id)
Insert a url into the history tree.
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_create(struct browser_window *bw)
Create a new history tree for a browser window window.
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_clone(const struct browser_window *existing, struct browser_window *clone)
Clone a bw's history tree for new bw.
bool browser_window_history_forward_available(struct browser_window *bw)
Check whether it is pssible to go forwards in the history.
bool browser_window_history_back_available(struct browser_window *bw)
Check whether it is pssible to go back in the history.
void browser_window_history_destroy(struct browser_window *bw)
Free a history structure.
Interface to browser history operations.
Browser window private structure.
nserror browser_window_initialise_common(enum browser_window_create_flags flags, struct browser_window *bw, const struct browser_window *existing)
Initialise common parts of a browser window.
nserror browser_window_schedule_reformat(struct browser_window *bw)
Reformat the browser window contents in a safe context.
bool browser_window_redraw_ready(struct browser_window *bw)
Check whether browser window is ready for redraw.
static nserror browser_window__handle_ssl_query_response(bool proceed, void *pw)
Handle query responses from SSL requests.
nserror browser_window_show_certificates(struct browser_window *bw)
Show the certificate page for the current page.
void browser_window_page_drag_start(struct browser_window *bw, int x, int y)
Start drag scrolling the contents of the browser window.
static nserror browser_window_refresh_url_bar_internal(struct browser_window *bw, nsurl *url)
Update URL bar for a given browser window to given URL.
bool browser_window_can_select(struct browser_window *bw)
Find out if given browser window content is selectable.
static nserror browser_window__handle_userpass_response(nsurl *url, const char *realm, const char *username, const char *password, void *pw)
Handle a response from the UI when prompted for credentials.
void browser_window_update_extent(struct browser_window *bw)
Update the extent of the inside of a browser window to that of the current content.
nserror browser_window_refresh_url_bar(struct browser_window *bw)
Update URL bar for a given browser window to bw's content's URL.
static nserror browser_window_set_scale_internal(struct browser_window *bw, float scale)
Set browser window scale.
nserror browser_window_get_features(struct browser_window *bw, int x, int y, struct browser_window_features *data)
Get access to any page features at the given coordinates.
bool browser_window_redraw(struct browser_window *bw, int x, int y, const struct rect *clip, const struct redraw_context *ctx)
Redraw an area of a window.
static bool browser_window_check_throbber(struct browser_window *bw)
recursively check browser windows for activity
static nserror browser_window__build_userpass(const char *username, const char *password, char **userpass_out)
Build a "username:password" from components.
float browser_window_get_scale(struct browser_window *bw)
Gets the scale of a browser window.
void browser_window_set_drag_type(struct browser_window *bw, browser_drag_type type, const struct rect *rect)
Set drag type for a browser window, and inform front end.
static nserror browser_window__handle_error(struct browser_window *bw, hlcache_handle *c, const hlcache_event *event)
Handle errors during content fetch.
static int get_horz_scrollbar_len(struct browser_window *bw)
Get browser window horizontal scrollbar widget length.
static nserror browser_window__get_contextual_content(struct browser_window *bw, int x, int y, struct browser_window_features *data)
Internal helper for getting the positional features.
nsurl * browser_window_access_url(const struct browser_window *bw)
Access a browser window's URL.
bool browser_window_has_content(struct browser_window *bw)
Find out if a browser window is currently showing a content.
static void browser_window_get_scrollbar_pos(struct browser_window *bw, bool horizontal, int *x, int *y)
Get position of scrollbar widget within browser window.
static nserror browser_window__handle_fetcherror(struct browser_window *bw, const char *reason, nsurl *url)
Handle non specific errors during a fetch.
nserror browser_window_create(enum browser_window_create_flags flags, nsurl *url, nsurl *referrer, struct browser_window *existing, struct browser_window **bw)
Create and open a new root browser window with the given page.
bool browser_window_back_available(struct browser_window *bw)
Check availability of Back action for a given browser window.
nserror browser_window_get_ssl_chain(struct browser_window *bw, struct cert_chain **chain)
Request the current browser window SSL certificate chain.
static void browser_window_mouse_track_internal(struct browser_window *bw, browser_mouse_state mouse, int x, int y)
Process mouse movement event.
nserror browser_window_get_name(struct browser_window *bw, const char **out_name)
Obtain a browsing contexts name.
bool browser_window_exec(struct browser_window *bw, const char *src, size_t srclen)
Execute some JavaScript code in a browsing context.
static nserror navigate_internal_query_auth(struct browser_window *bw, struct browser_fetch_parameters *params)
Internal navigation handler for the authentication query handler.
nserror browser_window_get_scrollbar_type(struct browser_window *bw, browser_scrolling *h, browser_scrolling *v)
Get the browser window's scrollbar details.
static void scheduled_reformat(void *vbw)
internal scheduled reformat callback.
nserror browser_window_debug(struct browser_window *bw, enum content_debug op)
Set debug options on a window.
static bool browser_window_scroll_at_point_internal(struct browser_window *bw, int x, int y, int scrx, int scry)
perform a scroll operation at a given coordinate
bool browser_window_can_search(struct browser_window *bw)
Find out if given browser window can be searched.
static void browser_window_refresh(void *p)
Handle meta http-equiv refresh time elapsing by loading a new page.
void browser_window_mouse_click(struct browser_window *bw, browser_mouse_state mouse, int x, int y)
Handle mouse clicks in a browser window.
static nserror browser_window_favicon_callback(hlcache_handle *c, const hlcache_event *event, void *pw)
Callback for fetchcache() for browser window favicon fetches.
bool browser_window_scroll_at_point(struct browser_window *bw, int x, int y, int scrx, int scry)
Send a scroll request to a browser window at a particular point.
nserror browser_window_console_log(struct browser_window *bw, browser_window_console_source src, const char *msg, size_t msglen, browser_window_console_flags flags)
Log a console message into the browser window console.
nserror browser_window_show_cookies(const struct browser_window *bw)
Open cookie viewer for the current page.
static nserror browser_window_start_throbber(struct browser_window *bw)
Start the busy indicator.
static nserror browser_window_content_ready(struct browser_window *bw)
handle message for content ready on browser window
bool browser_window_up_available(struct browser_window *bw)
Return true if a browser window can navigate upwards.
void browser_window_destroy(struct browser_window *bw)
Close and destroy a browser window.
static nserror browser_window__handle_bad_certs(struct browser_window *bw, nsurl *url)
Handle a certificate verification request (BAD_CERTS) during a fetch.
void browser_window_set_position(struct browser_window *bw, int x, int y)
Set the position of the current browser window with respect to the parent browser window.
static nserror browser_window__unpack_userpass(const char *userpass, char **username_out, char **password_out)
Unpack a "username:password" to components.
static nserror navigate_internal_query_ssl(struct browser_window *bw, struct browser_fetch_parameters *params)
Internal navigation handler for the SSL/privacy query page.
static nserror browser_window_set_scroll(struct browser_window *bw, const struct rect *rect)
Set the scroll position of a browser window.
nserror browser_window_navigate_up(struct browser_window *bw, bool new_window)
Navigate to a browser_window's parent URL.
nserror browser_window_reload(struct browser_window *bw, bool all)
Reload the page in a browser window.
nserror browser_window_get_dimensions(struct browser_window *bw, int *width, int *height)
Get the dimensions of the area a browser window occupies.
static void browser_window_set_selection(struct browser_window *bw, bool selection, bool read_only)
Set or remove a selection.
static nserror navigate_internal_query_timeout(struct browser_window *bw, struct browser_fetch_parameters *params)
Internal navigation handler for the timeout query page.
nserror browser_window_destroy_internal(struct browser_window *bw)
Release all memory associated with a browser window.
bool browser_window_reload_available(struct browser_window *bw)
Check availability of Reload action for a given browser window.
static bool frag_scroll(struct browser_window *bw)
scroll to a fragment if present
bool browser_window_forward_available(struct browser_window *bw)
Check availability of Forward action for a given browser window.
nserror browser_window_invalidate_rect(struct browser_window *bw, struct rect *rect)
Cause an area of a browser window to be marked invalid and hence redrawn.
void browser_window_set_dimensions(struct browser_window *bw, int width, int height)
Set the dimensions of the area a browser window occupies.
char * browser_window_get_selection(struct browser_window *bw)
Get the current selection from a root browser window, ownership passed to caller, who must free() it.
nserror browser_window_get_url(struct browser_window *bw, bool fragment, nsurl **url_out)
Access a browser window's URL.
static bool is_internal_navigate_url(nsurl *url)
Check if this is an internal navigation URL.
#define SCALE_MAXIMUM
largests scale that can be applied to a browser window
const char * browser_window_get_title(struct browser_window *bw)
Get the title of a browser_window.
static void browser_window_convert_to_download(struct browser_window *bw, llcache_handle *stream)
Transfer the loading_content to a new download window.
static void browser_window_mouse_click_internal(struct browser_window *bw, browser_mouse_state mouse, int x, int y)
Process mouse click event.
int browser_window_get_cookie_count(const struct browser_window *bw)
Get the number of cookies in use for the current page.
static nserror browser_window__handle_timeout(struct browser_window *bw, nsurl *url)
Handle a timeout during a fetch.
#define FRAME_DEPTH
maximum frame depth
nserror browser_window_get_extents(struct browser_window *bw, bool scaled, int *width, int *height)
Get a browser window's content extents.
void browser_window_stop(struct browser_window *bw)
Stop all fetching activity in a browser window.
bool browser_window_is_frameset(struct browser_window *bw)
Find out if a browser window contains a frameset.
static nserror browser_window_callback(hlcache_handle *c, const hlcache_event *event, void *pw)
Browser window content event callback handler.
nserror browser_window__reload_current_parameters(struct browser_window *bw)
Navigate a browser window to the current parameters.
nserror browser_window_set_scale(struct browser_window *bw, float scale, bool absolute)
Sets the scale of a browser window.
struct history * browser_window_get_history(struct browser_window *bw)
Get a browser window's history object.
void browser_window_reformat(struct browser_window *bw, bool background, int width, int height)
Reformat a browser window contents to a new width or height.
nserror browser_window_navigate(struct browser_window *bw, nsurl *url, nsurl *referrer, enum browser_window_nav_flags flags, char *post_urlenc, struct fetch_multipart_data *post_multipart, hlcache_handle *parent)
Start fetching a page in a browser window.
static nserror browser_window__handle_login(struct browser_window *bw, const char *realm, nsurl *url)
Handle login request (BAD_AUTH) during fetch.
static void browser_window_update(struct browser_window *bw, bool scroll_to_top)
Redraw browser window, set extent to content, and update title.
static nserror navigate_internal_query_fetcherror(struct browser_window *bw, struct browser_fetch_parameters *params)
Internal navigation handler for the fetch error query page.
void browser_window_get_position(struct browser_window *bw, bool root, int *pos_x, int *pos_y)
Get the position of the current browser window with respect to the root or parent browser window.
nserror browser_window_set_name(struct browser_window *bw, const char *name)
Set a browsing contexts name.
browser_window_page_info_state browser_window_get_page_info_state(const struct browser_window *bw)
Request the current browser window page info state.
struct hlcache_handle * browser_window_get_content(struct browser_window *bw)
Get a cache handle for the content within a browser window.
static void browser_window_find_target_internal(struct browser_window *bw, const char *target, int depth, struct browser_window *page, int *rdepth, struct browser_window **bw_target)
Find browser window.
#define SCALE_MINIMUM
smallest scale that can be applied to a browser window
nserror browser_window_debug_dump(struct browser_window *bw, FILE *f, enum content_debug op)
Dump debug info concerning the browser window's contents to file.
static nserror browser_window__navigate_internal(struct browser_window *bw, struct browser_fetch_parameters *params)
dispatch to internal query handlers or normal navigation
static bool browser_window_drop_file_at_point_internal(struct browser_window *bw, int x, int y, char *file)
allows a dragged file to be dropped into a browser window at a position
browser_editor_flags browser_window_get_editor_flags(struct browser_window *bw)
Check whether browser window can accept a cut/copy/paste, or has a selection that could be saved.
static void browser_window_mouse_drag_end(struct browser_window *bw, browser_mouse_state mouse, int x, int y)
Handles the end of a drag operation in a browser window.
bool browser_window_stop_available(struct browser_window *bw)
Check availability of Stop action for a given browser window.
static nserror browser_window_stop_throbber(struct browser_window *bw)
Stop the busy indicator.
static nserror browser_window_content_done(struct browser_window *bw)
handle message for content done on browser window
static int get_vert_scrollbar_len(struct browser_window *bw)
Get browser window vertical scrollbar widget length.
struct browser_window * browser_window_find_target(struct browser_window *bw, const char *target, browser_mouse_state mouse)
Locate a browser window in the specified stack according.
static nserror navigate_internal_real(struct browser_window *bw, struct browser_fetch_parameters *params)
Internal navigation handler for normal fetches.
static nserror browser_window_download(struct browser_window *bw, nsurl *url, nsurl *nsref, uint32_t fetch_flags, bool fetch_is_post, llcache_post_data *post)
implements the download operation of a window navigate
bool browser_window_drop_file_at_point(struct browser_window *bw, int x, int y, char *file)
Drop a file onto a browser window at a particular point, or determine if a file may be dropped onto t...
static void browser_window_destroy_children(struct browser_window *bw)
Close and destroy all child browser window.
void browser_window_set_status(struct browser_window *bw, const char *text)
Change the status bar of a browser window.
struct browser_window * browser_window_get_root(struct browser_window *bw)
Get the root level browser window.
static void browser_window__free_fetch_parameters(struct browser_fetch_parameters *params)
Free the stored fetch parameters.
static nserror browser_window_update_favicon(hlcache_handle *c, struct browser_window *bw, struct content_rfc5988_link *link)
update the favicon associated with the browser window
browser_drag_type browser_window_get_drag_type(struct browser_window *bw)
Get type of any current drag for a browser window.
void browser_window_mouse_track(struct browser_window *bw, browser_mouse_state mouse, int x, int y)
Handle non-click mouse action in a browser window.
void browser_window_set_pointer(struct browser_window *bw, browser_pointer_shape shape)
Change the shape of the mouse pointer.
void browser_window_set_gadget_filename(struct browser_window *bw, struct form_control *gadget, const char *fn)
set filename on form control.
Browser window creation and manipulation interface.
browser_drag_type
type of browser window drag in progess
@ DRAGGING_SELECTION
@ DRAGGING_SCR_Y
@ DRAGGING_CONTENT_SCROLLBAR
@ DRAGGING_SCR_X
@ DRAGGING_NONE
@ DRAGGING_OTHER
@ DRAGGING_PAGE_SCROLL
@ DRAGGING_FRAME
browser_editor_flags
@ BW_EDITOR_CAN_PASTE
Can paste, input.
@ BW_EDITOR_NONE
No selection, no editing.
@ BW_EDITOR_CAN_CUT
Selection not read-only.
@ BW_EDITOR_CAN_COPY
Have selection.
browser_scrolling
@ BW_SCROLLING_YES
browser_window_page_info_state
Browser window page information states.
@ PAGE_STATE_INSECURE
Insecure page load.
@ PAGE_STATE_UNKNOWN
Unable to determine.
@ PAGE_STATE_SECURE_ISSUES
Secure load, but has insecure elements.
@ PAGE_STATE_SECURE
Secure load.
@ PAGE_STATE_SECURE_OVERRIDE
Secure load, but had to override.
@ PAGE_STATE_LOCAL
Page loaded from file:/// etc.
@ PAGE_STATE_INTERNAL
Page loaded from internal handler.
browser_window_create_flags
flags to browser_window_create
@ BW_CREATE_HISTORY
this will form a new history node (don't set for back/reload/etc)
@ BW_CREATE_TAB
New gui_window to be tab in same window as "existing" gui_window.
@ BW_CREATE_FOREGROUND
Request foreground opening.
@ BW_CREATE_CLONE
New gui_window to be clone of "existing" gui_window.
@ BW_CREATE_FOCUS_LOCATION
Request location bar focus.
@ BW_CREATE_UNVERIFIABLE
Window not opened by user interaction (e.g.
browser_window_nav_flags
flags to browser_window_navigate
@ BW_NAVIGATE_DOWNLOAD
download rather than render the uri
@ 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)
@ BW_NAVIGATE_NONE
No flags set.
@ BW_NAVIGATE_UNVERIFIABLE
Transation not caused by user interaction (e.g.
@ BW_NAVIGATE_INTERNAL
Internal navigation (set only by core features using such)
static uint32_t count(const http_directive *list, lwc_string *key)
browser_window_console_source
Sources of messages which end up in the browser window console.
Definition: console.h:30
@ BW_CS_SCRIPT_CONSOLE
Logging from some running script.
Definition: console.h:33
@ BW_CS_INPUT
Input from the client.
Definition: console.h:31
@ BW_CS_SCRIPT_ERROR
Error from some running script.
Definition: console.h:32
browser_window_console_flags
Flags for browser window console logging.
Definition: console.h:41
@ BW_CS_FLAG_LEVEL_LOG
Logged at the 'log' level, please only use one of the LEVEL flags.
Definition: console.h:55
@ BW_CS_FLAG_LEVEL_DEBUG
Logged at the 'debug' level, please use only one of the LEVEL flags.
Definition: console.h:53
@ BW_CS_FLAG_LEVEL_INFO
Logged at the 'info' level, please use only one of the LEVEL flags.
Definition: console.h:57
@ BW_CS_FLAG_LEVEL_MASK
Mask for the error level to allow easy comparison using the above.
Definition: console.h:64
@ BW_CS_FLAG_LEVEL_WARN
Logged at the 'warn' level, please use only one of the LEVEL flags.
Definition: console.h:59
@ BW_CS_FLAG_LEVEL_ERROR
Logged at the 'error' level, please use only one of the LEVEL flags.
Definition: console.h:61
Content handling interface.
nserror fetch_multipart_data_new_kv(struct fetch_multipart_data **list, const char *name, const char *value)
Create an entry for a fetch_multipart_data.
Definition: fetch.c:721
const char * fetch_multipart_data_find(const struct fetch_multipart_data *list, const char *name)
Find an entry in a fetch_multipart_data.
Definition: fetch.c:686
struct fetch_multipart_data * fetch_multipart_data_clone(const struct fetch_multipart_data *list)
Clone a linked list of fetch_multipart_data.
Definition: fetch.c:620
void fetch_multipart_data_destroy(struct fetch_multipart_data *list)
Free a linked list of fetch_multipart_data.
Definition: fetch.c:701
char * content_get_selection(hlcache_handle *h)
Get a text selection from a content.
Definition: content.c:858
bool content_get_quirks(hlcache_handle *h)
Retrieve quirkiness of a content.
Definition: content.c:1308
nserror content_debug_dump(struct hlcache_handle *h, FILE *f, enum content_debug op)
Dump debug information to file.
Definition: content.c:922
bool content_exec(struct hlcache_handle *h, const char *src, size_t srclen)
Execute some JavaScript code inside a content object.
Definition: content.c:477
bool content_is_locked(hlcache_handle *h)
Return whether a content is currently locked.
Definition: content.c:1344
struct content_rfc5988_link * content_find_rfc5988_link(hlcache_handle *h, lwc_string *rel)
find link in content that matches the rel string.
Definition: content.c:954
void content_mouse_action(hlcache_handle *h, struct browser_window *bw, browser_mouse_state mouse, int x, int y)
Handle mouse clicks and movements in a content window.
Definition: content.c:421
void content_clear_selection(hlcache_handle *h)
Tell a content that any selection it has, or one of its objects has, must be cleared.
Definition: content.c:847
nserror content_close(hlcache_handle *h)
The window containing the content has been closed.
Definition: content.c:813
bool content_saw_insecure_objects(struct hlcache_handle *h)
Determine if the content referred to any insecure objects.
Definition: content.c:500
bool content_scroll_at_point(struct hlcache_handle *h, int x, int y, int scrx, int scry)
scroll content at coordnate
Definition: content.c:890
nserror content_get_contextual_content(struct hlcache_handle *h, int x, int y, struct browser_window_features *data)
Get positional contextural information for a content.
Definition: content.c:872
void content_mouse_track(hlcache_handle *h, struct browser_window *bw, browser_mouse_state mouse, int x, int y)
Handle mouse movements in a content window.
Definition: content.c:398
bool content_can_reformat(hlcache_handle *h)
Get whether a content can reformat.
Definition: content.c:258
bool content_drop_file_at_point(struct hlcache_handle *h, int x, int y, char *file)
Drag and drop a file at coordinate.
Definition: content.c:906
void content_reformat(hlcache_handle *h, bool background, int width, int height)
Reformat to new size.
Definition: content.c:321
nsurl * content_get_refresh_url(hlcache_handle *h)
Retrieve the refresh URL for a content.
Definition: content.c:1247
const char * content_get_status_message(hlcache_handle *h)
Retrieve status message associated with content.
Definition: content.c:1141
nserror content_open(hlcache_handle *h, struct browser_window *bw, struct content *page, struct object_params *params)
A window containing the content has been opened.
Definition: content.c:791
content_status content_get_status(hlcache_handle *h)
Retrieve status of content.
Definition: content.c:1124
Interface to content handling debug.
@ CONTENT_STATUS_READY
Some parts of content still being loaded, but can be displayed.
Definition: content_type.h:92
@ CONTENT_STATUS_DONE
Content has completed all processing.
Definition: content_type.h:95
content_type
The type of a content.
Definition: content_type.h:53
@ CONTENT_IMAGE
All images.
Definition: content_type.h:67
@ CONTENT_ANY
Any content matches.
Definition: content_type.h:82
@ CONTENT_THEME
RISC OS themes content.
Definition: content_type.h:73
@ CONTENT_HTML
content is HTML
Definition: content_type.h:58
@ CONTENT_TEXTPLAIN
content is plain text
Definition: content_type.h:61
@ CONTENT_MSG_TEXTSEARCH
A free text search action has occurred.
Definition: content_type.h:179
@ CONTENT_MSG_LINK
RFC5988 link.
Definition: content_type.h:143
@ CONTENT_MSG_SELECTMENU
Create a select menu.
Definition: content_type.h:173
@ CONTENT_MSG_REFRESH
wants refresh
Definition: content_type.h:137
@ CONTENT_MSG_GETDIMS
Get viewport dimensions.
Definition: content_type.h:149
@ CONTENT_MSG_GADGETCLICK
A gadget has been clicked on (mainly for file)
Definition: content_type.h:176
@ CONTENT_MSG_STATUS
new status string
Definition: content_type.h:128
@ CONTENT_MSG_SCROLL
Request to scroll content.
Definition: content_type.h:152
@ CONTENT_MSG_LOG
Content wishes to log something.
Definition: content_type.h:107
@ CONTENT_MSG_DONE
content has finished processing
Definition: content_type.h:119
@ CONTENT_MSG_DOWNLOAD
download, not for display
Definition: content_type.h:140
@ CONTENT_MSG_LOADING
fetching or converting
Definition: content_type.h:113
@ CONTENT_MSG_ERROR
error occurred
Definition: content_type.h:122
@ CONTENT_MSG_REDIRECT
fetch url redirect occured
Definition: content_type.h:125
@ CONTENT_MSG_DRAGSAVE
Allow drag saving of content.
Definition: content_type.h:155
@ CONTENT_MSG_POINTER
Wants a specific mouse pointer set.
Definition: content_type.h:161
@ CONTENT_MSG_SELECTION
A selection made or cleared.
Definition: content_type.h:164
@ CONTENT_MSG_SSL_CERTS
Content is from SSL and this is its chain.
Definition: content_type.h:110
@ CONTENT_MSG_DRAG
A drag started or ended.
Definition: content_type.h:170
@ CONTENT_MSG_GETTHREAD
Javascript thread.
Definition: content_type.h:146
@ CONTENT_MSG_REDRAW
needs redraw (eg.
Definition: content_type.h:134
@ CONTENT_MSG_READY
may be displayed
Definition: content_type.h:116
@ CONTENT_MSG_SAVELINK
Allow URL to be saved.
Definition: content_type.h:158
@ CONTENT_MSG_REFORMAT
content_reformat done
Definition: content_type.h:131
@ CONTENT_MSG_CARET
Caret movement / hiding.
Definition: content_type.h:167
content_debug
Debugging dump operations.
Definition: content_type.h:30
@ CONTENT_ENCODING_NORMAL
The content encoding.
Definition: content_type.h:45
Useful interned string pointers (interface).
nserror download_context_create(llcache_handle *llcache, struct gui_window *parent)
Create a download context.
Definition: download.c:248
Core download context (interface)
nserror global_history_add(nsurl *url)
Add an entry to the global history.
void hotlist_update_url(nsurl *url)
Update given URL, e.g.
Definition: hotlist.c:1603
GUI Themeing interface.
wimp_w parent
Definition: dialog.c:88
Error codes.
nserror
Enumeration of error codes.
Definition: errors.h:29
@ NSERROR_TIMEOUT
Operation timed out.
Definition: errors.h:65
@ NSERROR_NOT_FOUND
Requested item not found.
Definition: errors.h:34
@ NSERROR_BAD_CONTENT
Bad Content.
Definition: errors.h:56
@ NSERROR_BAD_AUTH
Fetch needs authentication data.
Definition: errors.h:63
@ NSERROR_NOT_IMPLEMENTED
Functionality is not implemented.
Definition: errors.h:61
@ NSERROR_BAD_PARAMETER
Bad Parameter.
Definition: errors.h:48
@ NSERROR_BAD_CERTS
Fetch needs certificate chain check.
Definition: errors.h:64
@ NSERROR_NO_FETCH_HANDLER
No fetch handler for URL scheme.
Definition: errors.h:33
@ NSERROR_NEED_DATA
More data needed.
Definition: errors.h:46
@ NSERROR_FRAME_DEPTH
Exceeded frame depth.
Definition: errors.h:57
@ NSERROR_INVALID
Invalid data.
Definition: errors.h:49
@ NSERROR_NOMEM
Memory exhaustion.
Definition: errors.h:32
@ NSERROR_OK
No error.
Definition: errors.h:30
static struct directory * root
Definition: filename.c:55
const char * type
Definition: filetype.cpp:44
Interface to form handling functions internal to HTML content handler.
@ GADGET_FILE
Definition: form_internal.h:58
@ GADGET_SELECT
Definition: form_internal.h:52
nserror browser_window_destroy_iframes(struct browser_window *bw)
Destroy iframes opened in browser_window_create_iframes()
Definition: frames.c:307
void browser_window_recalculate_frameset(struct browser_window *bw)
Recalculate frameset positions following a resize.
Definition: frames.c:718
void browser_window_recalculate_iframes(struct browser_window *bw)
Recalculate iframe positions following a resize.
Definition: frames.c:291
void browser_window_handle_scrollbars(struct browser_window *bw)
Create, remove, and update browser window scrollbars.
Definition: frames.c:99
nserror browser_window_create_iframes(struct browser_window *bw)
Create and open iframes for a browser window.
Definition: frames.c:192
nserror browser_window_invalidate_iframe(struct browser_window *bw)
Invalidate an iframe causing a redraw.
Definition: frames.c:185
void browser_window_resize_frame(struct browser_window *bw, int x, int y)
Resize a browser window that is a frame.
Definition: frames.c:740
nserror browser_window_create_frameset(struct browser_window *bw)
Create and open a frameset for a browser window.
Definition: frames.c:693
Frame and frameset creation and manipulation (interface).
struct netsurf_table * guit
The global interface table.
Definition: gui_factory.c:49
Interface to core interface table.
struct content * hlcache_handle_get_content(const hlcache_handle *handle)
Retrieve a content object from a cache handle.
Definition: hlcache.c:776
nserror hlcache_handle_abort(hlcache_handle *handle)
Abort a high-level cache fetch.
Definition: hlcache.c:786
nserror hlcache_handle_release(hlcache_handle *handle)
Release a high-level cache handle.
Definition: hlcache.c:740
nserror hlcache_handle_retrieve(nsurl *url, uint32_t flags, nsurl *referer, llcache_post_data *post, hlcache_handle_callback cb, void *pw, hlcache_child_context *child, content_type accepted_types, hlcache_handle **result)
Retrieve a high-level cache handle for an object.
Definition: hlcache.c:679
High-level resource cache interface.
@ HLCACHE_RETRIEVE_SNIFF_TYPE
Definition: hlcache.h:75
@ HLCACHE_RETRIEVE_MAY_DOWNLOAD
It's permitted to convert this request into a download.
Definition: hlcache.h:73
struct html_stylesheet * html_get_stylesheets(hlcache_handle *h, unsigned int *n)
Retrieve stylesheets used by HTML document.
Definition: css.c:498
const char * html_get_base_target(hlcache_handle *h)
Retrieve an HTML content's base target.
Definition: html.c:2054
bool html_get_id_offset(hlcache_handle *h, lwc_string *frag_id, int *x, int *y)
Retrieve layout coordinates of box with given id.
Definition: html.c:2073
void html_set_file_gadget_filename(struct hlcache_handle *hl, struct form_control *gadget, const char *fn)
set filename on a file gadget
Definition: html.c:1666
Interface to text/html content handler.
struct content_html_object * html_get_objects(struct hlcache_handle *h, unsigned int *n)
Retrieve objects used by HTML document.
Definition: object.c:60
#define STYLESHEET_START
Definition: html.h:152
Public content interface.
bool content_redraw(struct hlcache_handle *h, struct content_redraw_data *data, const struct rect *clip, const struct redraw_context *ctx)
Display content on screen with optional tiling.
Definition: content.c:558
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
int content_get_width(struct hlcache_handle *h)
Retrieve width of content.
Definition: content.c:1158
void content_invalidate_reuse_data(struct hlcache_handle *h)
Invalidate content reuse data.
Definition: content.c:1229
const char * content_get_encoding(struct hlcache_handle *h, enum content_encoding_type op)
Retrieve the encoding of a content.
Definition: content.c:1321
content_type content_get_type(struct hlcache_handle *h)
Retrieve computed type of content.
Definition: content.c:1061
Interface to platform-specific miscellaneous browser operation table.
browser_pointer_shape
Mouse pointer type.
Definition: mouse.h:112
@ BROWSER_POINTER_AUTO
Definition: mouse.h:132
@ BROWSER_POINTER_MOVE
Definition: mouse.h:126
@ BROWSER_POINTER_DEFAULT
Definition: mouse.h:113
browser_mouse_state
Mouse state.
Definition: mouse.h:43
@ BROWSER_MOUSE_CLICK_2
button 2 clicked.
Definition: mouse.h:57
@ BROWSER_MOUSE_CLICK_1
button 1 clicked.
Definition: mouse.h:55
@ BROWSER_MOUSE_MOD_2
2nd modifier key pressed (eg.
Definition: mouse.h:80
@ BROWSER_MOUSE_DRAG_1
start of button 1 drag
Definition: mouse.h:65
@ BROWSER_MOUSE_DRAG_2
start of button 2 drag
Definition: mouse.h:67
gui_pointer_shape
Definition: mouse.h:89
@ GUI_POINTER_PROGRESS
Definition: mouse.h:108
@ GUI_POINTER_DEFAULT
Definition: mouse.h:90
Target independent plotting interface.
Interface to platform-specific search operations.
Interface to platform-specific graphical user interface window operations.
gui_window_create_flags
Window creation control flags.
Definition: window.h:66
@ GW_CREATE_NONE
New window.
Definition: window.h:67
@ GW_CREATE_TAB
Create tab in same window as existing.
Definition: window.h:69
@ GW_CREATE_FOREGROUND
Request this window/tab is foregrounded.
Definition: window.h:70
@ GW_CREATE_FOCUS_LOCATION
Definition: window.h:71
@ GW_CREATE_CLONE
Clone existing window.
Definition: window.h:68
@ GUI_SAVE_OBJECT_ORIG
Definition: window.h:45
@ GUI_SAVE_SOURCE
Definition: window.h:40
@ GUI_SAVE_OBJECT_NATIVE
Definition: window.h:46
@ GUI_SAVE_COMPLETE
Definition: window.h:44
gui_drag_type
Definition: window.h:56
@ GDRAGGING_SCROLLBAR
Definition: window.h:58
@ GDRAGGING_OTHER
Definition: window.h:60
@ GW_EVENT_SCROLL_START
Starts drag scrolling of a browser window.
Definition: window.h:113
@ GW_EVENT_PAGE_INFO_CHANGE
Page status has changed and so the padlock should be updated.
Definition: window.h:129
@ GW_EVENT_NEW_CONTENT
Called when the gui_window has new content.
Definition: window.h:118
@ GW_EVENT_STOP_THROBBER
stop the navigation throbber.
Definition: window.h:108
@ GW_EVENT_UPDATE_EXTENT
Update the extent of the inside of a browser window to that of the current content.
Definition: window.h:93
@ GW_EVENT_START_THROBBER
start the navigation throbber.
Definition: window.h:103
Interface to javascript engine functions.
void js_destroyheap(jsheap *heap)
Destroy a previously created heap.
Definition: dukky.c:638
nserror js_newheap(int timeout, jsheap **heap)
Create a new javascript heap.
Definition: dukky.c:598
nserror js_newthread(jsheap *heap, void *win_priv, void *doc_priv, jsthread **thread)
Create a new javascript thread.
Definition: dukky.c:650
bool knockout_plot_end(const struct redraw_context *ctx)
End a knockout plotting session.
Definition: knockout.c:997
bool knockout_plot_start(const struct redraw_context *ctx, struct redraw_context *knk_ctx)
Start a knockout plotting session.
Definition: knockout.c:971
Knockout rendering (interface).
nserror llcache_handle_abort(llcache_handle *handle)
Abort a low-level fetch, informing all users of this action.
Definition: llcache.c:4098
nserror llcache_handle_retrieve(nsurl *url, uint32_t flags, nsurl *referer, const llcache_post_data *post, llcache_handle_callback cb, void *pw, llcache_handle **result)
Retrieve a handle for a low-level cache object.
Definition: llcache.c:3990
nserror llcache_handle_release(llcache_handle *handle)
Release a low-level cache handle.
Definition: llcache.c:4058
@ LLCACHE_RETRIEVE_STREAM_DATA
Definition: llcache.h:63
@ LLCACHE_RETRIEVE_VERIFIABLE
Requested URL was verified.
Definition: llcache.h:59
@ LLCACHE_RETRIEVE_FORCE_FETCH
Force a new fetch.
Definition: llcache.h:57
#define NSLOG(catname, level, logmsg, args...)
Definition: log.h:116
const char * messages_get_errorcode(nserror code)
lookup of a message by errorcode from the standard Messages hash.
Definition: messages.c:248
const char * messages_get(const char *key)
Fast lookup of a message by key from the standard Messages hash.
Definition: messages.c:241
const char * messages_get_sslcode(ssl_cert_err code)
lookup of a message by SSL error code from the standard Messages hash.
Definition: messages.c:405
Localised message support (interface).
bool nsurl_compare(const nsurl *url1, const nsurl *url2, nsurl_component parts)
Compare two URLs.
nserror nsurl_create(const char *const url_s, nsurl **url)
Create a NetSurf URL object from a URL string.
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.
bool nsurl_has_component(const nsurl *url, nsurl_component part)
Enquire about the existence of componenets in a given URL.
nsurl * nsurl_ref(nsurl *url)
Increment the reference count to a NetSurf URL object.
lwc_string * nsurl_get_component(const nsurl *url, nsurl_component part)
Get part of a URL as a lwc_string, from a NetSurf URL object.
@ NSURL_FRAGMENT
Definition: nsurl.h:56
@ NSURL_SCHEME
Definition: nsurl.h:45
@ NSURL_PATH
Definition: nsurl.h:52
@ NSURL_HOST
Definition: nsurl.h:49
@ NSURL_COMPLETE
Definition: nsurl.h:54
@ NSURL_QUERY
Definition: nsurl.h:53
nserror nsurl_join(const nsurl *base, const char *rel, nsurl **joined)
Join a base url to a relative link part, creating a new NetSurf URL object.
struct nsurl nsurl
NetSurf URL object.
Definition: nsurl.h:31
nserror nsurl_parent(const nsurl *url, nsurl **new_url)
Create a NetSurf URL object for URL with parent location of an existing URL.
plot_style_t * plot_style_fill_white
Definition: plot_style.c:32
int width
Definition: gui.c:159
int height
Definition: gui.c:160
const char * scrollbar_mouse_status_to_message(scrollbar_mouse_status status)
Get a status bar message from a scrollbar mouse input status.
Definition: scrollbar.c:888
scrollbar_mouse_status scrollbar_mouse_action(struct scrollbar *s, browser_mouse_state mouse, int x, int y)
Handle mouse actions other then drag ends.
Definition: scrollbar.c:768
int scrollbar_get_offset(struct scrollbar *s)
Get the current scroll offset to the visible part of the full area.
Definition: scrollbar.c:627
nserror scrollbar_redraw(struct scrollbar *s, int x, int y, const struct rect *clip, float scale, const struct redraw_context *ctx)
Redraw a part of the scrollbar.
Definition: scrollbar.c:239
bool scrollbar_scroll(struct scrollbar *s, int change)
Scroll the scrollbar by given amount.
Definition: scrollbar.c:562
void scrollbar_destroy(struct scrollbar *s)
Destroy a scrollbar.
Definition: scrollbar.c:138
void scrollbar_set(struct scrollbar *s, int value, bool bar_pos)
Set the scroll value of the scrollbar.
Definition: scrollbar.c:512
void scrollbar_mouse_drag_end(struct scrollbar *s, browser_mouse_state mouse, int x, int y)
Handle end of mouse drags.
Definition: scrollbar.c:932
Scrollbar widget interface.
#define SCROLLBAR_WIDTH
Definition: scrollbar.h:32
ssl_cert_err
ssl certificate error status
Definition: ssl_certs.h:36
@ SSL_CERT_ERR_OK
Nothing wrong with this certificate.
Definition: ssl_certs.h:37
@ SSL_CERT_ERR_UNKNOWN
Unknown error.
Definition: ssl_certs.h:38
nserror cert_chain_dup(const struct cert_chain *src, struct cert_chain **dst_out)
duplicate a certificate chain
Definition: ssl_certs.c:101
nserror cert_chain_free(struct cert_chain *chain)
free a certificate chain
Definition: ssl_certs.c:317
nserror cert_chain_to_query(struct cert_chain *chain, struct nsurl **url_out)
create a fetch query string from a certificate chain
Definition: ssl_certs.c:226
Interface to utility string handling.
The parameters for a fetch.
struct nsurl * url
The URL to fetch.
enum browser_window_nav_flags flags
Navigation flags.
char * parent_charset
Optional parent character set.
bool parent_quirks
Optional parent quirks.
struct fetch_multipart_data * post_multipart
Multipart post data.
char * post_urlenc
URL encoded post data.
struct nsurl * referrer
Optional refererer.
Page features at a specific spatial location.
struct hlcache_handle * object
Object at position or NULL.
struct hlcache_handle * main
handle of top level content.
enum browser_window_features::@56 form_features
type of form feature.
struct nsurl * link
URL of a link or NULL.
Browser window data.
struct browser_fetch_parameters loading_parameters
The fetch parameters for the loading content.
browser_scrolling scrolling
struct browser_window * iframes
struct scrollbar * scroll_x
Horizontal scroll.
struct browser_window::@59 drag
Current drag status.
int x
Window dimensions.
struct browser_window * bw
float scale
scale of window contents
int rows
frameset characteristics
struct browser_window::@58 favicon
Favicon.
char * text
Current status bar text.
int start_scroll_x
Scroll offsets at start of current scroll draw.
int match
Number of times an idempotent status-set operation was performed.
struct scrollbar * scroll_y
Vertical scroll.
int miss
Number of times status was really updated.
bool history_add
Add loading_content to the window history when it loads.
bool failed
flag to indicate favicon fetch already failed which prevents infinite error looping.
int iframe_count
[iframe_count] iframes
struct cert_chain * loading_cert_chain
The certificate chain for the loading content.
int refresh_interval
Refresh interval (-1 if undefined)
struct browser_window * parent
struct browser_window::@62 status
cache of the currently displayed status text.
struct cert_chain * current_cert_chain
The certificate chain for the current content.
lwc_string * frag_id
Fragment identifier for current_content.
uint64_t last_action
Last time a link was followed in this window.
struct hlcache_handle * current
content handle of current page favicon
struct gui_window * window
Platform specific window data only valid at top level.
int text_len
Length of the status::text buffer.
int start_x
Mouse position at start of current scroll drag.
bool no_resize
frame characteristics
bool throbbing
Busy indicator is active.
struct hlcache_handle * loading
content handle for favicon which we started loading early
struct history * history
local history handle.
struct jsheap * jsheap
current javascript context
struct browser_window * children
[cols * rows] children
browser_drag_type type
the type of drag in progress
struct hlcache_handle * current_content
Content handle of page currently displayed which must have READY or DONE status or NULL for no conten...
struct browser_window::@61 selection
Current selection.
bool internal_nav
Internal navigation, do not update URL etc.
char * name
frame name for targetting
struct hlcache_handle * loading_content
Content handle of page in process of being loaded or NULL if no page is being loaded.
enum browser_window::@60 browser_window_type
Window characteristics.
struct browser_fetch_parameters current_parameters
The fetch parameters for the current content.
struct browser_window * focus
browser window child of root browser window which has input focus
X509 certificate chain.
Definition: ssl_certs.h:59
struct cert_chain::@57 certs[MAX_CERT_DEPTH]
size_t depth
the number of certificates in the chain
Definition: ssl_certs.h:63
ssl_cert_err err
Whatever is wrong with this certificate.
Definition: ssl_certs.h:68
An object (img, object, etc.
Definition: html.h:93
struct hlcache_handle * content
Content, or 0.
Definition: html.h:97
parameters to content redraw
Definition: content.h:40
int height
vertical dimension
Definition: content.h:48
bool repeat_y
whether content is tiled in y direction
Definition: content.h:59
bool repeat_x
whether content is tiled in x direction
Definition: content.h:58
int y
coordinate for top-left of redraw
Definition: content.h:42
int x
coordinate for top-left of redraw
Definition: content.h:41
colour background_colour
The background colour.
Definition: content.h:51
int width
dimensions to render content at (for scaling contents with intrinsic dimensions)
Definition: content.h:47
float scale
Scale for redraw (for scaling contents without intrinsic dimensions)
Definition: content.h:56
Fetch POST multipart data.
Definition: fetch.h:109
Form control.
Definition: form_internal.h:73
form_control_type type
Type of control.
Definition: form_internal.h:79
nserror(* schedule)(int t, void(*callback)(void *p), void *p)
Schedule a callback.
Definition: misc.h:58
nserror(* launch_url)(struct nsurl *url)
core has no fetcher for url
Definition: misc.h:71
nserror(* login)(struct nsurl *url, const char *realm, const char *username, const char *password, nserror(*cb)(struct nsurl *url, const char *realm, const char *username, const char *password, void *pw), void *cbpw)
Retrieve username/password for a given url+realm if there is one stored in a frontend-specific way (e...
Definition: misc.h:105
nserror(* present_cookies)(const char *search_term)
Request that the cookie manager be displayed.
Definition: misc.h:126
void(* back_state)(bool active, void *p)
activate search back button in gui
Definition: search.h:72
void(* add_recent)(const char *string, void *p)
add search string to recent searches list front has full liberty how to implement the bare notificati...
Definition: search.h:56
void(* forward_state)(bool active, void *p)
activate search forwards button in gui
Definition: search.h:64
void(* status)(bool found, void *p)
Change the displayed search status.
Definition: search.h:38
void(* hourglass)(bool active, void *p)
display hourglass while searching.
Definition: search.h:46
nserror(* get_dimensions)(struct gui_window *gw, int *width, int *height)
Find the current dimensions of a browser window's content area.
Definition: window.h:241
void(* set_title)(struct gui_window *gw, const char *title)
Set the title of a window.
Definition: window.h:264
nserror(* set_scroll)(struct gui_window *gw, const struct rect *rect)
Set the scroll position of a browser window.
Definition: window.h:224
bool(* drag_start)(struct gui_window *g, gui_drag_type type, const struct rect *rect)
start a drag operation within a window
Definition: window.h:317
void(* set_pointer)(struct gui_window *g, enum gui_pointer_shape shape)
Change mouse pointer shape.
Definition: window.h:296
nserror(* save_link)(struct gui_window *g, struct nsurl *url, const char *title)
save link operation
Definition: window.h:327
void(* set_icon)(struct gui_window *gw, struct hlcache_handle *icon)
Set a favicon for a gui window.
Definition: window.h:280
nserror(* invalidate)(struct gui_window *gw, const struct rect *rect)
Invalidate an area of a window.
Definition: window.h:194
nserror(* event)(struct gui_window *gw, enum gui_window_event event)
Miscellaneous event occurred for a window.
Definition: window.h:254
void(* destroy)(struct gui_window *gw)
Destroy previously created gui window.
Definition: window.h:174
bool(* get_scroll)(struct gui_window *gw, int *sx, int *sy)
Get the scroll position of a browser window.
Definition: window.h:205
void(* create_form_select_menu)(struct gui_window *gw, struct form_control *control)
create a form select menu
Definition: window.h:335
void(* drag_save_object)(struct gui_window *gw, struct hlcache_handle *c, gui_save_type type)
object dragged to window
Definition: window.h:353
void(* console_log)(struct gui_window *gw, browser_window_console_source src, const char *msg, size_t msglen, browser_window_console_flags flags)
console logging happening.
Definition: window.h:374
struct gui_window *(* create)(struct browser_window *bw, struct gui_window *existing, gui_window_create_flags flags)
Create and open a gui window for a browsing context.
Definition: window.h:164
nserror(* set_url)(struct gui_window *gw, struct nsurl *url)
Set the navigation url.
Definition: window.h:272
void(* set_status)(struct gui_window *g, const char *text)
Set the status bar message of a browser window.
Definition: window.h:288
void(* file_gadget_open)(struct gui_window *gw, struct hlcache_handle *hl, struct form_control *gadget)
Called when file chooser gadget is activated.
Definition: window.h:344
History tree for a window.
struct history_entry * current
Current position in tree.
Context for retrieving a child object.
Definition: hlcache.h:37
bool quirks
Whether parent is quirky.
Definition: hlcache.h:39
const char * charset
Charset of parent.
Definition: hlcache.h:38
High-level cache event.
Definition: hlcache.h:43
content_msg type
Event type.
Definition: hlcache.h:44
union content_msg_data data
Event data.
Definition: hlcache.h:45
High-level cache handle.
Definition: hlcache.c:66
Container for stylesheets used by an HTML document.
Definition: html.h:58
dukky javascript thread
Definition: dukky.c:70
Handle to low-level cache object.
Definition: llcache.c:76
POST data object for low-level cache requests.
Definition: llcache.h:40
struct fetch_multipart_data * multipart
Multipart data.
Definition: llcache.h:47
enum llcache_post_data::@122 type
Type of POST data.
union llcache_post_data::@123 data
POST data content.
char * urlenc
URL encoded data.
Definition: llcache.h:46
struct gui_misc_table * misc
Browser table.
Definition: gui_table.h:57
struct gui_search_table * search
Page search table.
Definition: gui_table.h:113
struct gui_window_table * window
Window table.
Definition: gui_table.h:66
bool option_knockout
flag to enable knockout rendering.
Definition: plotters.h:328
nserror(* rectangle)(const struct redraw_context *ctx, const plot_style_t *pstyle, const struct rect *rectangle)
Plots a rectangle.
Definition: plotters.h:188
nserror(* clip)(const struct redraw_context *ctx, const struct rect *clip)
Sets a clip rectangle for subsequent plot operations.
Definition: plotters.h:111
Rectangle coordinates.
Definition: types.h:40
int x0
Definition: types.h:41
int y0
Top left.
Definition: types.h:41
int x1
Definition: types.h:42
int y1
Bottom right.
Definition: types.h:42
Redraw context.
Definition: plotters.h:51
const struct plotter_table * plot
Current plot operation table.
Definition: plotters.h:73
void browser_window_remove_caret(struct browser_window *bw, bool only_hide)
Removes the caret and callback for key process.
Definition: textinput.c:88
void browser_window_place_caret(struct browser_window *bw, int x, int y, int height, const struct rect *clip)
Position the caret and assign a callback for key presses.
Definition: textinput.c:53
Textual input handling interface.
void theme_install_start(struct hlcache_handle *c)
Handle a CONTENT_THEME that has started loading.
Definition: theme_install.c:56
NetSurf types.
struct content_msg_data::@103 scroll
CONTENT_MSG_SCROLL - Part of content to scroll to show.
int x
Carret x-coord.
Definition: content.h:110
browser_window_console_flags flags
The flags of the logging.
Definition: content.h:72
const char * msg
The message to log.
Definition: content.h:68
const struct rect * clip
Carret clip rect.
Definition: content.h:215
struct content_msg_data::@111 textsearch
CONTENT_MSG_TEXTSEARCH - Free text search action.
struct content_msg_data::@110 gadget_click
CONTENT_MSG_GADGETCLICK - User clicked on a form gadget.
int height
Carret height.
Definition: content.h:110
size_t msglen
The length of that message.
Definition: content.h:70
browser_pointer_shape pointer
CONTENT_MSG_POINTER - Mouse pointer to set.
Definition: content.h:192
struct content_msg_data::@107 caret
CONTENT_MSG_CARET - set caret position or, hide caret.
const char * title
Definition: content.h:186
struct content_msg_data::@105 savelink
CONTENT_MSG_SAVELINK - Save a URL.
bool selection
false for selection cleared
Definition: content.h:198
const struct cert_chain * chain
CONTENT_MSG_SSL_CERTS - The certificate chain from the underlying fetch.
Definition: content.h:79
struct content_rfc5988_link * rfc5988_link
CONTENT_MSG_RFC5988_LINK - rfc5988 link data.
Definition: content.h:138
struct nsurl * to
Redirect target.
Definition: content.h:103
struct content_msg_data::@104 dragsave
CONTENT_MSG_DRAGSAVE - Drag save a content.
unsigned * viewport_height
Definition: content.h:151
struct content_msg_data::@108 drag
CONTENT_MSG_DRAG - Drag start or end.
struct content_msg_data::@109 select_menu
CONTENT_MSG_SELECTMENU - Create select menu at pointer.
struct nsurl * from
Redirect origin.
Definition: content.h:102
struct content_msg_data::@98 log
CONTENT_MSG_LOG - Information for logging.
struct llcache_handle * download
CONTENT_MSG_DOWNLOAD - Low-level cache handle.
Definition: content.h:133
struct form_control * gadget
Definition: content.h:235
browser_window_console_source src
The source of the logging.
Definition: content.h:66
struct content_msg_data::@102 getdims
CONTENT_MSG_GETDIMS - Get the viewport dimensions.
bool state
state for operation
Definition: content.h:281
const char * string
search string
Definition: content.h:285
enum content_msg_data::@104::@112 type
int y
Carret y-coord.
Definition: content.h:110
struct content_msg_data::@100 redirect
CONTENT_MSG_REDIRECT - Redirect info.
struct nsurl * url
Definition: content.h:185
const struct rect * rect
Definition: content.h:228
void * ctx
context passed to browser_window_search()
Definition: content.h:277
const char * explicit_status_text
CONTENT_MSG_STATUS - Status message update.
Definition: content.h:128
struct content_msg_data::@107::@114 pos
With CONTENT_CARET_SET_POS.
bool background
CONTENT_MSG_REFORMAT - Reformat should not cause a redraw.
Definition: content.h:121
void urldb_set_cert_permissions(struct nsurl *url, bool permit)
Set certificate verification permissions.
Definition: urldb.c:3455
nsurl * urldb_get_url(nsurl *url)
Extract an URL from the db.
Definition: urldb.c:3327
nserror urldb_set_url_title(nsurl *url, const char *title)
Set an URL's title string, replacing any existing one.
Definition: urldb.c:3226
bool urldb_add_url(nsurl *url)
Insert an URL into the database.
Definition: urldb.c:3140
void urldb_set_auth_details(nsurl *url, const char *realm, const char *auth)
Set authentication data for an URL.
Definition: urldb.c:3342
bool urldb_get_cert_permissions(nsurl *url)
Retrieve certificate verification permissions from database.
Definition: urldb.c:3480
const char * urldb_get_auth_details(nsurl *url, const char *realm)
Look up authentication details in database.
Definition: urldb.c:3405
nserror urldb_update_url_visit_data(nsurl *url)
Update an URL's visit data.
Definition: urldb.c:3274
nserror urldb_set_url_content_type(nsurl *url, content_type type)
Set an URL's content type.
Definition: urldb.c:3256
char * urldb_get_cookie(nsurl *url, bool include_http_only)
Retrieve cookies for an URL.
Definition: urldb.c:3997
Unified URL information database internal interface.
Option reading and saving interface.
#define nsoption_int(OPTION)
Get the value of an integer option.
Definition: nsoption.h:279
#define nsoption_bool(OPTION)
Get the value of a boolean option.
Definition: nsoption.h:270
static nserror path(const struct redraw_context *ctx, const plot_style_t *pstyle, const float *p, unsigned int n, const float transform[6])
Plots a path.
Definition: plot.c:821
static nserror text(const struct redraw_context *ctx, const struct plot_font_style *fstyle, int x, int y, const char *text, size_t length)
Text plotting.
Definition: plot.c:978
static nserror clip(const struct redraw_context *ctx, const struct rect *clip)
Sets a clip rectangle for subsequent plot operations.
Definition: plot.c:357