NetSurf
gui.c
Go to the documentation of this file.
1/*
2 * Copyright 2003 Phil Mellor <monkeyson@users.sourceforge.net>
3 * Copyright 2004-2008 James Bursa <bursa@users.sourceforge.net>
4 * Copyright 2003 John M Bell <jmb202@ecs.soton.ac.uk>
5 * Copyright 2005 Richard Wilson <info@tinct.net>
6 * Copyright 2004 Andrew Timmins <atimmins@blueyonder.co.uk>
7 * Copyright 2004-2009 John Tytgat <joty@netsurf-browser.org>
8 *
9 * This file is part of NetSurf, http://www.netsurf-browser.org/
10 *
11 * NetSurf is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; version 2 of the License.
14 *
15 * NetSurf is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program. If not, see <http://www.gnu.org/licenses/>.
22 */
23
24#include <stdbool.h>
25#include <string.h>
26#include <assert.h>
27#include <errno.h>
28#include <signal.h>
29#include <unixlib/local.h>
30#include <fpu_control.h>
31#include <oslib/help.h>
32#include <oslib/uri.h>
33#include <oslib/inetsuite.h>
34#include <oslib/pdriver.h>
35#include <oslib/osfile.h>
36#include <oslib/hourglass.h>
37#include <oslib/osgbpb.h>
38#include <oslib/osbyte.h>
39#include <oslib/osmodule.h>
40#include <oslib/osfscontrol.h>
41
42#include "utils/utils.h"
43#include "utils/nsoption.h"
44#include "utils/log.h"
45#include "utils/messages.h"
46#include "utils/file.h"
47#include "utils/filename.h"
48#include "utils/url.h"
49#include "utils/corestrings.h"
50#include "netsurf/fetch.h"
51#include "netsurf/misc.h"
52#include "netsurf/content.h"
53#include "netsurf/netsurf.h"
55#include "netsurf/cookie_db.h"
56#include "netsurf/url_db.h"
58#include "desktop/hotlist.h"
59#include "desktop/searchweb.h"
61
62#include "riscos/gui.h"
63#include "riscos/bitmap.h"
64#include "riscos/wimputils.h"
65#include "riscos/hotlist.h"
66#include "riscos/buffer.h"
68#include "riscos/print.h"
69#include "riscos/save.h"
70#include "riscos/dialog.h"
71#include "riscos/wimp.h"
72#include "riscos/message.h"
73#include "riscos/help.h"
74#include "riscos/query.h"
75#include "riscos/window.h"
76#include "riscos/toolbar.h"
77#include "riscos/corewindow.h"
78#include "riscos/iconbar.h"
81#include "riscos/cookies.h"
82#include "riscos/pageinfo.h"
83#include "riscos/wimp_event.h"
84#include "riscos/uri.h"
85#include "riscos/url_protocol.h"
86#include "riscos/mouse.h"
87#include "riscos/ucstables.h"
88#include "riscos/filetype.h"
89#include "riscos/font.h"
93
94bool riscos_done = false;
95
96extern bool ro_plot_patterned_lines;
97
98int os_version = 0;
100
101const char * const __dynamic_da_name = "NetSurf"; /**< For UnixLib. */
102int __dynamic_da_max_size = 128 * 1024 * 1024; /**< For UnixLib. */
103int __feature_imagefs_is_file = 1; /**< For UnixLib. */
104/* default filename handling */
105int __riscosify_control = __RISCOSIFY_NO_SUFFIX |
106 __RISCOSIFY_NO_REVERSE_SUFFIX;
107#ifndef __ELF__
108extern int __dynamic_num;
109#endif
110
111const char * NETSURF_DIR;
112
113static const char *task_name = "NetSurf";
114#define CHOICES_PREFIX "<Choices$Write>.WWW.NetSurf."
115
117wimp_t task_handle; /**< RISC OS wimp task handle. */
118static clock_t gui_last_poll; /**< Time of last wimp_poll. */
119osspriteop_area *gui_sprites; /**< Sprite area containing pointer and hotlist sprites */
120
121#define DIR_SEP ('.')
122
123/**
124 * Accepted wimp user messages.
125 */
127 message_HELP_REQUEST,
128 {
129 message_DATA_SAVE,
130 message_DATA_SAVE_ACK,
131 message_DATA_LOAD,
132 message_DATA_LOAD_ACK,
133 message_DATA_OPEN,
134 message_PRE_QUIT,
135 message_SAVE_DESKTOP,
136 message_MENU_WARNING,
137 message_MENUS_DELETED,
138 message_WINDOW_INFO,
139 message_CLAIM_ENTITY,
140 message_DATA_REQUEST,
141 message_DRAGGING,
142 message_DRAG_CLAIM,
143 message_MODE_CHANGE,
144 message_PALETTE_CHANGE,
145 message_FONT_CHANGED,
146 message_URI_PROCESS,
147 message_URI_RETURN_RESULT,
148 message_INET_SUITE_OPEN_URL,
149 message_PRINT_SAVE,
150 message_PRINT_ERROR,
151 message_PRINT_TYPE_ODD,
154 0
155 }
156};
157
158
159static struct
160{
161 int width; /* in OS units */
164
165
166/**
167 * Callback to translate resource to full url for RISC OS.
168 *
169 * Transforms a resource: path into a full URL. The returned URL is
170 * used as the target for a redirect. The caller takes ownership of
171 * the returned nsurl including unrefing it when finished with it.
172 *
173 * \param path The path of the resource to locate.
174 * \return A string containing the full URL of the target object or
175 * NULL if no suitable resource can be found.
176 */
177static nsurl *gui_get_resource_url(const char *path)
178{
179 static const char base_url[] = "file:///NetSurf:/Resources/";
180 const char *lang;
181 size_t path_len, length;
182 char *raw;
183 nsurl *url = NULL;
184
185 /* Map paths first */
186 if (strcmp(path, "adblock.css") == 0) {
187 path = "AdBlock";
188
189 } else if (strcmp(path, "default.css") == 0) {
190 path = "CSS";
191
192 } else if (strcmp(path, "quirks.css") == 0) {
193 path = "Quirks";
194
195 } else if (strcmp(path, "favicon.ico") == 0) {
196 path = "Icons/content.png";
197
198 } else if (strcmp(path, "user.css") == 0) {
199 /* Special case; this file comes from Choices: */
200 nsurl_create("file:///Choices:WWW/NetSurf/User", &url);
201 return url;
202 }
203
204 path_len = strlen(path);
205
207
208 /* Find max URL length */
209 length = SLEN(base_url) +
210 strlen(lang) + 1 + /* <lang> + / */
211 path_len + 1; /* + NUL */
212
213 raw = malloc(length);
214 if (raw != NULL) {
215 /* Insert base URL */
216 char *ptr = memcpy(raw, base_url, SLEN(base_url));
217 ptr += SLEN(base_url);
218
219 /* Add language directory to URL, for translated files */
220 /* TODO: handle non-html translated files */
221 if (path_len > SLEN(".html") &&
222 strncmp(path + path_len - SLEN(".html"),
223 ".html", SLEN(".html")) == 0) {
224 ptr += sprintf(ptr, "%s/", lang);
225 }
226
227 /* Add filename to URL */
228 memcpy(ptr, path, path_len);
229 ptr += path_len;
230
231 /* Terminate string */
232 *ptr = '\0';
233
234 nsurl_create(raw, &url);
235 free(raw);
236 }
237
238 return url;
239}
240
241
242/**
243 * Set colour option from wimp.
244 *
245 * \param opts The netsurf options.
246 * \param wimp wimp colour value
247 * \param option the netsurf option enum.
248 * \param def_colour The default colour value to use.
249 * \return NSERROR_OK on success or error code.
250 */
251static nserror
253 wimp_colour wimp,
254 enum nsoption_e option,
255 colour def_colour)
256{
257 os_error *error;
258 os_PALETTE(20) palette;
259
260 error = xwimp_read_true_palette((os_palette *) &palette);
261 if (error != NULL) {
262 NSLOG(netsurf, INFO,
263 "xwimp_read_palette: 0x%x: %s",
264 error->errnum,
265 error->errmess);
266 } else {
267 /* entries are in B0G0R0LL */
268 def_colour = palette.entries[wimp] >> 8;
269 }
270
271 opts[option].value.c = def_colour;
272
273 return NSERROR_OK;
274}
275
276
277/**
278 * Set option defaults for riscos frontend
279 *
280 * @param defaults The option table to update.
281 * @return error status.
282 *
283 * @todo The wimp_COLOUR_... values here map the colour definitions to
284 * parts of the RISC OS desktop palette. In places this is fairly
285 * arbitrary, and could probably do with re-checking.
286 */
288{
289 int idx;
290 static const struct {
291 enum nsoption_e option;
292 wimp_colour wcol;
293 colour c;
294 } sys_colour_map[]= {
295 { NSOPTION_sys_colour_AccentColor, wimp_COLOUR_CREAM, 0x00dddddd },
296 { NSOPTION_sys_colour_AccentColorText, wimp_COLOUR_BLACK, 0x00000000 },
297 { NSOPTION_sys_colour_ActiveText, wimp_COLOUR_BLACK, 0x00000000 },
298 { NSOPTION_sys_colour_ButtonBorder, wimp_COLOUR_VERY_LIGHT_GREY,0x00aa0000 },
299 { NSOPTION_sys_colour_ButtonFace, wimp_COLOUR_VERY_LIGHT_GREY, 0x00aaaaaa },
300 { NSOPTION_sys_colour_ButtonText, wimp_COLOUR_BLACK, 0x00000000 },
301 { NSOPTION_sys_colour_Canvas, wimp_COLOUR_VERY_LIGHT_GREY, 0x00aaaaaa },
302 { NSOPTION_sys_colour_CanvasText, wimp_COLOUR_BLACK, 0x00000000 },
303 { NSOPTION_sys_colour_Field, wimp_COLOUR_WHITE, 0x00ffffff },
304 { NSOPTION_sys_colour_FieldText, wimp_COLOUR_BLACK, 0x00000000 },
305 { NSOPTION_sys_colour_GrayText, wimp_COLOUR_MID_LIGHT_GREY, 0x00777777 },
306 { NSOPTION_sys_colour_Highlight, wimp_COLOUR_BLACK, 0x00ee0000 },
307 { NSOPTION_sys_colour_HighlightText, wimp_COLOUR_WHITE, 0x00ffffff },
308 { NSOPTION_sys_colour_LinkText, wimp_COLOUR_BLACK, 0x00ee0000 },
309 { NSOPTION_sys_colour_Mark, wimp_COLOUR_VERY_LIGHT_GREY,0x00eeeeee },
310 { NSOPTION_sys_colour_MarkText, wimp_COLOUR_BLACK, 0x00000000},
311 { NSOPTION_sys_colour_SelectedItem, wimp_COLOUR_MID_LIGHT_GREY, 0x00777777 },
312 { NSOPTION_sys_colour_SelectedItemText, wimp_COLOUR_BLACK, 0x00000000 },
313 { NSOPTION_sys_colour_VisitedText, wimp_COLOUR_BLACK, 0x00000000 },
314 { NSOPTION_LISTEND, 0, 0},
315 };
316
317 /* Set defaults for absent option strings */
318 nsoption_setnull_charp(ca_bundle, strdup("<NetSurf$CABundle>"));
319 nsoption_setnull_charp(cookie_file, strdup("NetSurf:Cookies"));
320 nsoption_setnull_charp(cookie_jar, strdup(CHOICES_PREFIX "Cookies"));
321
322 if (nsoption_charp(ca_bundle) == NULL ||
323 nsoption_charp(cookie_file) == NULL ||
324 nsoption_charp(cookie_jar) == NULL) {
325 NSLOG(netsurf, INFO, "Failed initialising default options");
327 }
328
329 /* RISC OS platform does not generally benefit from disc cache
330 * so the default should be off.
331 */
332 nsoption_set_uint(disc_cache_size, 0);
333
334 /* Override core default treeview font size with 12 pt.
335 * TODO: 12 is the normal desktop font size, but users might run
336 * with something different.
337 */
338 nsoption_set_int(treeview_font_size, 12 * 10);
339
340 /* set default system colours for riscos ui */
341 for (idx = 0; sys_colour_map[idx].option != NSOPTION_LISTEND; idx++) {
343 sys_colour_map[idx].wcol,
344 sys_colour_map[idx].option,
345 sys_colour_map[idx].c);
346 }
347
348 return NSERROR_OK;
349}
350
351
352
353
354/**
355 * Create intermediate directories for Choices and User Data files
356 */
357static void ro_gui_create_dirs(void)
358{
359 char buf[256];
360 char *path;
361
362 /* Choices */
363 path = getenv("NetSurf$ChoicesSave");
364 if (!path)
365 die("Failed to find NetSurf Choices save path");
366
367 snprintf(buf, sizeof(buf), "%s", path);
369
370 /* URL */
371 snprintf(buf, sizeof(buf), "%s", nsoption_charp(url_save));
373
374 /* Hotlist */
375 snprintf(buf, sizeof(buf), "%s", nsoption_charp(hotlist_save));
377
378 /* Recent */
379 snprintf(buf, sizeof(buf), "%s", nsoption_charp(recent_save));
381
382 /* Theme */
383 snprintf(buf, sizeof(buf), "%s", nsoption_charp(theme_save));
385 /* and the final directory part (as theme_save is a directory) */
386 xosfile_create_dir(buf, 0);
387}
388
389
390/**
391 * Ensures the gui exits cleanly.
392 */
393static void ro_gui_cleanup(void)
394{
396 xhourglass_off();
397 /* Uninstall NetSurf-specific fonts */
398 xos_cli("FontRemove NetSurf:Resources.Fonts.");
399}
400
401
402/**
403 * Handles a signal
404 */
405static void ro_gui_signal(int sig)
406{
407 static const os_error error = { 1, "NetSurf has detected a serious "
408 "error and must exit. Please submit a bug report, "
409 "attaching the browser log file." };
410 os_colour old_sand, old_glass;
411
413
414 xhourglass_on();
415 xhourglass_colours(0x0000ffff, 0x000000ff, &old_sand, &old_glass);
416 nsoption_dump(stderr, NULL);
417 /*rufl_dump_state();*/
418
419#ifndef __ELF__
420 /* save WimpSlot and DA to files if NetSurf$CoreDump exists */
421 int used;
422 xos_read_var_val_size("NetSurf$CoreDump", 0, 0, &used, 0, 0);
423 if (used) {
424 int curr_slot;
425 xwimp_slot_size(-1, -1, &curr_slot, 0, 0);
426 NSLOG(netsurf, INFO, "saving WimpSlot, size 0x%x", curr_slot);
427 xosfile_save("$.NetSurf_Slot", 0x8000, 0,
428 (byte *) 0x8000,
429 (byte *) 0x8000 + curr_slot);
430
431 if (__dynamic_num != -1) {
432 int size;
433 byte *base_address;
434 xosdynamicarea_read(__dynamic_num, &size,
435 &base_address, 0, 0, 0, 0, 0);
436 NSLOG(netsurf, INFO,
437 "saving DA %i, base %p, size 0x%x",
439 base_address,
440 size);
441 xosfile_save("$.NetSurf_DA",
442 (bits) base_address, 0,
443 base_address,
444 base_address + size);
445 }
446 }
447#else
448 /* Save WimpSlot and UnixLib managed DAs when UnixEnv$coredump
449 * defines a coredump directory. */
450 const _kernel_oserror *err = __unixlib_write_coredump (NULL);
451 if (err != NULL)
452 NSLOG(netsurf, INFO, "Coredump failed: %s", err->errmess);
453#endif
454
455 xhourglass_colours(old_sand, old_glass, 0, 0);
456 xhourglass_off();
457
458 __write_backtrace(sig);
459
460 xwimp_report_error_by_category(&error,
461 wimp_ERROR_BOX_GIVEN_CATEGORY |
462 wimp_ERROR_BOX_CATEGORY_ERROR <<
463 wimp_ERROR_BOX_CATEGORY_SHIFT,
464 "NetSurf", "!netsurf",
465 (osspriteop_area *) 1, "Quit", 0);
466 xos_cli("Filer_Run <Wimp$ScrapDir>.WWW.NetSurf.Log");
467
468 _Exit(sig);
469}
470
471
472/**
473 * Read a "line" from an Acorn URI file.
474 *
475 * \param fp file pointer to read from
476 * \param b buffer for line, size 400 bytes
477 * \return true on success, false on EOF
478 */
479static bool ro_gui_uri_file_parse_line(FILE *fp, char *b)
480{
481 int c;
482 unsigned int i = 0;
483
484 c = getc(fp);
485 if (c == EOF)
486 return false;
487
488 /* skip comment lines */
489 while (c == '#') {
490 do { c = getc(fp); } while (c != EOF && 32 <= c);
491 if (c == EOF)
492 return false;
493 do { c = getc(fp); } while (c != EOF && c < 32);
494 if (c == EOF)
495 return false;
496 }
497
498 /* read "line" */
499 do {
500 if (i == 399)
501 return false;
502 b[i++] = c;
503 c = getc(fp);
504 } while (c != EOF && 32 <= c);
505
506 /* skip line ending control characters */
507 while (c != EOF && c < 32)
508 c = getc(fp);
509
510 if (c != EOF)
511 ungetc(c, fp);
512
513 b[i] = 0;
514 return true;
515}
516
517
518/**
519 * Parse an Acorn URI file.
520 *
521 * \param file_name file to read
522 * \param uri_title pointer to receive title data, or NULL for no data
523 * \return URL from file, or 0 on error and error reported
524 */
525static char *ro_gui_uri_file_parse(const char *file_name, char **uri_title)
526{
527 /* See the "Acorn URI Handler Functional Specification" for the
528 * definition of the URI file format. */
529 char line[400];
530 char *url = NULL;
531 FILE *fp;
532
533 *uri_title = NULL;
534 fp = fopen(file_name, "rb");
535 if (!fp) {
536 NSLOG(netsurf, INFO, "fopen(\"%s\", \"rb\"): %i: %s",
537 file_name, errno, strerror(errno));
538 ro_warn_user("LoadError", strerror(errno));
539 return 0;
540 }
541
542 /* "URI" */
543 if (!ro_gui_uri_file_parse_line(fp, line) || strcmp(line, "URI") != 0)
544 goto uri_syntax_error;
545
546 /* version */
548 strspn(line, "0123456789") != strlen(line))
549 goto uri_syntax_error;
550
551 /* URI */
553 goto uri_syntax_error;
554
555 url = strdup(line);
556 if (!url) {
557 ro_warn_user("NoMemory", 0);
558 fclose(fp);
559 return 0;
560 }
561
562 /* title */
564 goto uri_free;
565 if (uri_title && line[0] && ((line[0] != '*') || line[1])) {
566 *uri_title = strdup(line);
567 if (!*uri_title) /* non-fatal */
568 ro_warn_user("NoMemory", 0);
569 }
570 fclose(fp);
571
572 return url;
573
574uri_free:
575 free(url);
576
577uri_syntax_error:
578 fclose(fp);
579 ro_warn_user("URIError", 0);
580 return 0;
581}
582
583
584/**
585 * Parse an ANT URL file.
586 *
587 * \param file_name file to read
588 * \return URL from file, or 0 on error and error reported
589 */
590static char *ro_gui_url_file_parse(const char *file_name)
591{
592 char line[400];
593 char *url;
594 FILE *fp;
595
596 fp = fopen(file_name, "r");
597 if (!fp) {
598 NSLOG(netsurf, INFO, "fopen(\"%s\", \"r\"): %i: %s",
599 file_name, errno, strerror(errno));
600 ro_warn_user("LoadError", strerror(errno));
601 return 0;
602 }
603
604 if (!fgets(line, sizeof line, fp)) {
605 if (ferror(fp)) {
606 NSLOG(netsurf, INFO, "fgets: %i: %s", errno,
607 strerror(errno));
608 ro_warn_user("LoadError", strerror(errno));
609 } else
610 ro_warn_user("LoadError", messages_get("EmptyError"));
611 fclose(fp);
612 return 0;
613 }
614
615 fclose(fp);
616
617 if (line[strlen(line) - 1] == '\n')
618 line[strlen(line) - 1] = '\0';
619
620 url = strdup(line);
621 if (!url) {
622 ro_warn_user("NoMemory", 0);
623 return 0;
624 }
625
626 return url;
627}
628
629
630/**
631 * Parse an IEURL file.
632 *
633 * \param file_name file to read
634 * \return URL from file, or 0 on error and error reported
635 */
636static char *ro_gui_ieurl_file_parse(const char *file_name)
637{
638 char line[400];
639 char *url = 0;
640 FILE *fp;
641
642 fp = fopen(file_name, "r");
643 if (!fp) {
644 NSLOG(netsurf, INFO, "fopen(\"%s\", \"r\"): %i: %s",
645 file_name, errno, strerror(errno));
646 ro_warn_user("LoadError", strerror(errno));
647 return 0;
648 }
649
650 while (fgets(line, sizeof line, fp)) {
651 if (strncmp(line, "URL=", 4) == 0) {
652 if (line[strlen(line) - 1] == '\n')
653 line[strlen(line) - 1] = '\0';
654 url = strdup(line + 4);
655 if (!url) {
656 fclose(fp);
657 ro_warn_user("NoMemory", 0);
658 return 0;
659 }
660 break;
661 }
662 }
663 if (ferror(fp)) {
664 NSLOG(netsurf, INFO, "fgets: %i: %s", errno, strerror(errno));
665 ro_warn_user("LoadError", strerror(errno));
666 fclose(fp);
667 return 0;
668 }
669
670 fclose(fp);
671
672 if (!url)
673 ro_warn_user("URIError", 0);
674
675 return url;
676}
677
678
679/**
680 * Handle Message_DataOpen (double-click on file in the Filer).
681 *
682 * \param message The wimp message to open.
683 */
684static void ro_msg_dataopen(wimp_message *message)
685{
686 int file_type = message->data.data_xfer.file_type;
687 char *url = 0;
688 os_error *oserror;
689 nsurl *urlns;
690 nserror error;
691 size_t len;
692
693 switch (file_type) {
694 case 0xb28: /* ANT URL file */
695 url = ro_gui_url_file_parse(message->data.data_xfer.file_name);
696 error = nsurl_create(url, &urlns);
697 free(url);
698 break;
699
700 case 0xfaf: /* HTML file */
701 error = netsurf_path_to_nsurl(message->data.data_xfer.file_name,
702 &urlns);
703 break;
704
705 case 0x1ba: /* IEURL file */
706 url = ro_gui_ieurl_file_parse(message->
707 data.data_xfer.file_name);
708 error = nsurl_create(url, &urlns);
709 free(url);
710 break;
711
712 case 0x2000: /* application */
713 len = strlen(message->data.data_xfer.file_name);
714 if (len < 9 || strcmp(".!NetSurf",
715 message->data.data_xfer.file_name + len - 9))
716 return;
717
718 if (nsoption_charp(homepage_url) &&
719 nsoption_charp(homepage_url)[0]) {
720 error = nsurl_create(nsoption_charp(homepage_url),
721 &urlns);
722 } else {
723 error = nsurl_create(NETSURF_HOMEPAGE, &urlns);
724 }
725 break;
726
727 default:
728 return;
729 }
730
731 /* send DataLoadAck */
732 message->action = message_DATA_LOAD_ACK;
733 message->your_ref = message->my_ref;
734 oserror = xwimp_send_message(wimp_USER_MESSAGE, message, message->sender);
735 if (oserror) {
736 NSLOG(netsurf, INFO, "xwimp_send_message: 0x%x: %s",
737 oserror->errnum, oserror->errmess);
738 ro_warn_user("WimpError", oserror->errmess);
739 return;
740 }
741
742 if (error != NSERROR_OK) {
744 return;
745 }
746
747 /* create a new window with the file */
749 urlns,
750 NULL,
751 NULL,
752 NULL);
753 nsurl_unref(urlns);
754 if (error != NSERROR_OK) {
756 }
757}
758
759
760/**
761 * Handle Message_DataLoad (file dragged in).
762 */
763static void ro_msg_dataload(wimp_message *message)
764{
765 int file_type = message->data.data_xfer.file_type;
766 char *urltxt = NULL;
767 char *title = NULL;
768 struct gui_window *g;
769 os_error *oserror;
770 nsurl *url;
771 nserror error;
772
773 g = ro_gui_window_lookup(message->data.data_xfer.w);
774 if (g) {
775 if (ro_gui_window_dataload(g, message))
776 return;
777 }
778 else {
779 g = ro_gui_toolbar_lookup(message->data.data_xfer.w);
780 if (g && ro_gui_toolbar_dataload(g, message))
781 return;
782 }
783
784 switch (file_type) {
786 urltxt = ro_gui_uri_file_parse(message->data.data_xfer.file_name,
787 &title);
788 error = nsurl_create(urltxt, &url);
789 free(urltxt);
790 break;
791
792 case FILETYPE_ANT_URL:
793 urltxt = ro_gui_url_file_parse(message->data.data_xfer.file_name);
794 error = nsurl_create(urltxt, &url);
795 free(urltxt);
796 break;
797
798 case FILETYPE_IEURL:
799 urltxt = ro_gui_ieurl_file_parse(message->data.data_xfer.file_name);
800 error = nsurl_create(urltxt, &url);
801 free(urltxt);
802 break;
803
804 case FILETYPE_HTML:
805 case FILETYPE_JNG:
806 case FILETYPE_CSS:
807 case FILETYPE_MNG:
808 case FILETYPE_GIF:
809 case FILETYPE_BMP:
810 case FILETYPE_ICO:
811 case osfile_TYPE_DRAW:
812 case FILETYPE_PNG:
813 case FILETYPE_JPEG:
814 case osfile_TYPE_SPRITE:
815 case osfile_TYPE_TEXT:
817 case FILETYPE_SVG:
818 case FILETYPE_WEBP:
819 /* display the actual file */
820 error = netsurf_path_to_nsurl(message->data.data_xfer.file_name, &url);
821 break;
822
823 default:
824 return;
825 }
826
827 /* report error to user */
828 if (error != NSERROR_OK) {
830 return;
831 }
832
833
834 if (g) {
835 error = browser_window_navigate(g->bw,
836 url,
837 NULL,
839 NULL,
840 NULL,
841 NULL);
842 } else {
844 url,
845 NULL,
846 NULL,
847 NULL);
848 }
850 if (error != NSERROR_OK) {
852 }
853
854
855 /* send DataLoadAck */
856 message->action = message_DATA_LOAD_ACK;
857 message->your_ref = message->my_ref;
858 oserror = xwimp_send_message(wimp_USER_MESSAGE, message,
859 message->sender);
860 if (oserror) {
861 NSLOG(netsurf, INFO, "xwimp_send_message: 0x%x: %s",
862 oserror->errnum, oserror->errmess);
863 ro_warn_user("WimpError", oserror->errmess);
864 return;
865 }
866
867}
868
869
870/**
871 * Ensure that the filename in a data transfer message is NULL terminated
872 * (some applications, especially BASIC programs use CR)
873 *
874 * \param message message to be corrected
875 */
876static void ro_msg_terminate_filename(wimp_full_message_data_xfer *message)
877{
878 const char *ep = (char*)message + message->size;
879 char *p = message->file_name;
880
881 if ((size_t)message->size >= sizeof(*message))
882 ep = (char*)message + sizeof(*message) - 1;
883
884 while (p < ep && *p >= ' ') p++;
885 *p = '\0';
886}
887
888
889/**
890 * Handle Message_DataSave
891 */
892static void ro_msg_datasave(wimp_message *message)
893{
894 wimp_full_message_data_xfer *dataxfer = (wimp_full_message_data_xfer*)message;
895
896 /* remove ghost caret if drag-and-drop protocol was used */
897// ro_gui_selection_drag_reset();
898
900
902 return;
903
904 switch (dataxfer->file_type) {
906 case FILETYPE_ANT_URL:
907 case FILETYPE_IEURL:
908 case FILETYPE_HTML:
909 case FILETYPE_JNG:
910 case FILETYPE_CSS:
911 case FILETYPE_MNG:
912 case FILETYPE_GIF:
913 case FILETYPE_BMP:
914 case FILETYPE_ICO:
915 case osfile_TYPE_DRAW:
916 case FILETYPE_PNG:
917 case FILETYPE_JPEG:
918 case osfile_TYPE_SPRITE:
919 case osfile_TYPE_TEXT:
921 case FILETYPE_SVG:
922 case FILETYPE_WEBP: {
923 os_error *error;
924
925 dataxfer->your_ref = dataxfer->my_ref;
926 dataxfer->size = offsetof(wimp_full_message_data_xfer, file_name) + 16;
927 dataxfer->action = message_DATA_SAVE_ACK;
928 dataxfer->est_size = -1;
929 memcpy(dataxfer->file_name, "<Wimp$Scrap>", 13);
930
931 error = xwimp_send_message(wimp_USER_MESSAGE, (wimp_message*)dataxfer, message->sender);
932 if (error) {
933 NSLOG(netsurf, INFO,
934 "xwimp_send_message: 0x%x: %s",
935 error->errnum,
936 error->errmess);
937 ro_warn_user("WimpError", error->errmess);
938 }
939 }
940 break;
941 }
942}
943
944
945/**
946 * Handle Message_DataSaveAck.
947 */
948static void ro_msg_datasave_ack(wimp_message *message)
949{
950 ro_msg_terminate_filename((wimp_full_message_data_xfer*)message);
951
952 if (ro_print_ack(message))
953 return;
954
955 switch (gui_current_drag_type) {
958 break;
959
960 case GUI_DRAG_SAVE:
963 break;
964
965 default:
966 break;
967 }
968
970}
971
972
973/**
974 * Handle PreQuit message
975 *
976 * \param message PreQuit message from Wimp
977 */
978static void ro_msg_prequit(wimp_message *message)
979{
980 if (!ro_gui_prequit()) {
981 os_error *error;
982
983 /* we're objecting to the close down */
984 message->your_ref = message->my_ref;
985 error = xwimp_send_message(wimp_USER_MESSAGE_ACKNOWLEDGE,
986 message, message->sender);
987 if (error) {
988 NSLOG(netsurf, INFO, "xwimp_send_message: 0x%x:%s",
989 error->errnum, error->errmess);
990 ro_warn_user("WimpError", error->errmess);
991 }
992 }
993}
994
995
996/**
997 * Handle SaveDesktop message.
998 *
999 * \param message SaveDesktop message from Wimp.
1000 */
1001static void ro_msg_save_desktop(wimp_message *message)
1002{
1003 os_error *error;
1004
1005 error = xosgbpb_writew(message->data.save_desktopw.file,
1006 (const byte*)"Run ", 4, NULL);
1007 if (!error) {
1008 error = xosgbpb_writew(message->data.save_desktopw.file,
1009 (const byte*)NETSURF_DIR, strlen(NETSURF_DIR), NULL);
1010 if (!error)
1011 error = xos_bputw('\n', message->data.save_desktopw.file);
1012 }
1013
1014 if (error) {
1015 NSLOG(netsurf, INFO, "xosgbpb_writew/xos_bputw: 0x%x:%s",
1016 error->errnum, error->errmess);
1017 ro_warn_user("SaveError", error->errmess);
1018
1019 /* we must cancel the save by acknowledging the message */
1020 message->your_ref = message->my_ref;
1021 error = xwimp_send_message(wimp_USER_MESSAGE_ACKNOWLEDGE,
1022 message, message->sender);
1023 if (error) {
1024 NSLOG(netsurf, INFO, "xwimp_send_message: 0x%x:%s",
1025 error->errnum, error->errmess);
1026 ro_warn_user("WimpError", error->errmess);
1027 }
1028 }
1029}
1030
1031
1032/**
1033 * Handle WindowInfo message (part of the iconising protocol)
1034 *
1035 * \param message WindowInfo message from the Iconiser
1036 */
1037static void ro_msg_window_info(wimp_message *message)
1038{
1039 wimp_full_message_window_info *wi;
1040 struct gui_window *g;
1041
1042 /* allow the user to turn off thumbnail icons */
1043 if (!nsoption_bool(thumbnail_iconise))
1044 return;
1045
1046 wi = (wimp_full_message_window_info*)message;
1047 g = ro_gui_window_lookup(wi->w);
1048
1049 /* ic_<task name> will suffice for our other windows */
1050 if (g) {
1051 ro_gui_window_iconise(g, wi);
1053 }
1054}
1055
1056
1057/**
1058 * Get screen properties following a mode change.
1059 */
1061{
1062 static const ns_os_vdu_var_list vars = {
1063 os_MODEVAR_XWIND_LIMIT,
1064 {
1065 os_MODEVAR_YWIND_LIMIT,
1066 os_MODEVAR_XEIG_FACTOR,
1067 os_MODEVAR_YEIG_FACTOR,
1068 os_VDUVAR_END_LIST
1069 }
1070 };
1071 os_error *error;
1072 int vals[4];
1073
1074 error = xos_read_vdu_variables(PTR_OS_VDU_VAR_LIST(&vars), vals);
1075 if (error) {
1076 NSLOG(netsurf, INFO, "xos_read_vdu_variables: 0x%x: %s",
1077 error->errnum, error->errmess);
1078 ro_warn_user("MiscError", error->errmess);
1079 return;
1080 }
1081 screen_info.width = (vals[0] + 1) << vals[2];
1082 screen_info.height = (vals[1] + 1) << vals[3];
1083}
1084
1085
1086/**
1087 * Warn the user if Inet$Resolvers is not set.
1088 */
1089static void ro_gui_check_resolvers(void)
1090{
1091 char *resolvers;
1092 resolvers = getenv("Inet$Resolvers");
1093 if (resolvers && resolvers[0]) {
1094 NSLOG(netsurf, INFO, "Inet$Resolvers '%s'", resolvers);
1095 } else {
1096 NSLOG(netsurf, INFO, "Inet$Resolvers not set or empty");
1097 ro_warn_user("Resolvers", 0);
1098 }
1099}
1100
1101/**
1102 * Determine whether the OS version supports alpha channels.
1103 *
1104 * \return true iff alpha channels are supported, false otherwise.
1105 */
1107{
1108 os_error *error;
1109 int var_val;
1110 bits psr;
1111
1112 psr = 0;
1113 error = xos_read_mode_variable(alpha_SPRITE_MODE,
1114 os_MODEVAR_MODE_FLAGS, &var_val, &psr);
1115 if (error) {
1116 NSLOG(netsurf, ERROR, "xos_read_mode_variable: 0x%x: %s",
1117 error->errnum, error->errmess);
1118 return false;
1119 }
1120
1121 return (var_val == (1 << 15));
1122}
1123
1124/**
1125 * Initialise the RISC OS specific GUI.
1126 *
1127 * \param argc The number of command line arguments.
1128 * \param argv The string vector of command line arguments.
1129 */
1130static nserror gui_init(int argc, char** argv)
1131{
1132 struct {
1133 void (*sigabrt)(int);
1134 void (*sigfpe)(int);
1135 void (*sigill)(int);
1136 void (*sigint)(int);
1137 void (*sigsegv)(int);
1138 void (*sigterm)(int);
1139 void (*sigoserror)(int);
1140 } prev_sigs;
1141 char path[40];
1142 os_error *error;
1143 int length;
1144 char *nsdir_temp;
1145 byte *base;
1146 nsurl *url;
1147 nserror ret;
1148 bool open_window;
1149
1150 /* re-enable all FPU exceptions/traps except inexact operations,
1151 * which we're not interested in, and underflow which is incorrectly
1152 * raised when converting an exact value of 0 from double-precision
1153 * to single-precision on FPEmulator v4.09-4.11 (MVFD F0,#0:MVFS F0,F0)
1154 * - UnixLib disables all FP exceptions by default */
1155
1156 _FPU_SETCW(_FPU_IEEE & ~(_FPU_MASK_PM | _FPU_MASK_UM));
1157
1158 xhourglass_start(1);
1159
1160 /* read OS version for code that adapts to conform to the OS
1161 * (remember that it's preferable to check for specific features
1162 * being present) */
1163 xos_byte(osbyte_IN_KEY, 0, 0xff, &os_version, NULL);
1164
1166 NSLOG(netsurf, INFO, "OS supports alpha sprites: %s",
1167 os_alpha_sprite_supported ? "yes" : "no");
1168
1169 /* the first release version of the A9home OS is incapable of
1170 plotting patterned lines (presumably a fault in the hw acceleration) */
1171 if (!xosmodule_lookup("VideoHWSMI", NULL, NULL, &base, NULL, NULL)) {
1172#if 0 // this fault still hasn't been fixed, so disable patterned lines for all versions until it has
1173 const char *help = (char*)base + ((int*)base)[5];
1174 while (*help > 9) help++;
1175 while (*help == 9) help++;
1176 if (!memcmp(help, "0.55", 4))
1177#endif
1179 }
1180
1181 /* Create our choices directories */
1183
1184 /* Register exit and signal handlers */
1185 atexit(ro_gui_cleanup);
1186 prev_sigs.sigabrt = signal(SIGABRT, ro_gui_signal);
1187 prev_sigs.sigfpe = signal(SIGFPE, ro_gui_signal);
1188 prev_sigs.sigill = signal(SIGILL, ro_gui_signal);
1189 prev_sigs.sigint = signal(SIGINT, ro_gui_signal);
1190 prev_sigs.sigsegv = signal(SIGSEGV, ro_gui_signal);
1191 prev_sigs.sigterm = signal(SIGTERM, ro_gui_signal);
1192 prev_sigs.sigoserror = signal(SIGOSERROR, ro_gui_signal);
1193
1194 if (prev_sigs.sigabrt == SIG_ERR || prev_sigs.sigfpe == SIG_ERR ||
1195 prev_sigs.sigill == SIG_ERR ||
1196 prev_sigs.sigint == SIG_ERR ||
1197 prev_sigs.sigsegv == SIG_ERR ||
1198 prev_sigs.sigterm == SIG_ERR ||
1199 prev_sigs.sigoserror == SIG_ERR)
1200 die("Failed registering signal handlers");
1201
1202 /* Load in UI sprites */
1203 gui_sprites = ro_gui_load_sprite_file("NetSurf:Resources.Sprites");
1204 if (!gui_sprites)
1205 die("Unable to load Sprites.");
1206
1207 /* Find NetSurf directory */
1208 nsdir_temp = getenv("NetSurf$Dir");
1209 if (!nsdir_temp)
1210 die("Failed to locate NetSurf directory");
1211 NETSURF_DIR = strdup(nsdir_temp);
1212 if (!NETSURF_DIR)
1213 die("Failed duplicating NetSurf directory string");
1214
1215 /* web search engine */
1216 search_web_init("NetSurf:Resources.SearchEngines");
1217 search_web_select_provider(nsoption_charp(search_web_provider));
1218
1219 /* Initialise filename allocator */
1221
1222 /* Initialise save complete functionality */
1224
1225 /* Load in visited URLs and Cookies */
1226 urldb_load(nsoption_charp(url_path));
1227 urldb_load_cookies(nsoption_charp(cookie_file));
1228
1229 /* Initialise with the wimp */
1230 error = xwimp_initialise(wimp_VERSION_RO38, task_name,
1232 &task_handle);
1233 if (error) {
1234 NSLOG(netsurf, INFO, "xwimp_initialise: 0x%x: %s",
1235 error->errnum, error->errmess);
1236 die(error->errmess);
1237 }
1238 /* Register message handlers */
1239 ro_message_register_route(message_HELP_REQUEST,
1241 ro_message_register_route(message_DATA_OPEN,
1243 ro_message_register_route(message_DATA_SAVE,
1245 ro_message_register_route(message_DATA_SAVE_ACK,
1247 ro_message_register_route(message_PRE_QUIT,
1249 ro_message_register_route(message_SAVE_DESKTOP,
1251 ro_message_register_route(message_DRAGGING,
1253 ro_message_register_route(message_DRAG_CLAIM,
1255 ro_message_register_route(message_WINDOW_INFO,
1257
1258 /* Initialise the font subsystem (must be after Wimp_Initialise) */
1259 nsfont_init();
1260
1261 /* Initialise the hotlist (must be after fonts) */
1262 hotlist_init(nsoption_charp(hotlist_path),
1263 nsoption_bool(external_hotlists) ?
1264 NULL :
1266
1267 /* Initialise global information */
1270
1271 /* Issue a *Desktop to poke AcornURI into life */
1272 if (getenv("NetSurf$Start_URI_Handler"))
1273 xwimp_start_task("Desktop", 0);
1274
1275 /* Open the templates */
1276 if ((length = snprintf(path, sizeof(path),
1277 "NetSurf:Resources.%s.Templates",
1278 nsoption_charp(language))) < 0 || length >= (int)sizeof(path))
1279 die("Failed to locate Templates resource.");
1280 error = xwimp_open_template(path);
1281 if (error) {
1282 NSLOG(netsurf, INFO, "xwimp_open_template failed: 0x%x: %s",
1283 error->errnum, error->errmess);
1284 die(error->errmess);
1285 }
1286
1287 /* Initialise themes before dialogs */
1289
1290 /* Initialise dialog windows (must be after UI sprites are loaded) */
1292
1293 /* Initialise download window */
1295
1296 /* Initialise menus */
1298
1299 /* Initialise query windows */
1301
1302 /* Initialise toolbars */
1304
1305 /* Initialise url bar module */
1307
1308 /* Initialise browser windows */
1310
1311 /* Done with the templates file */
1312 wimp_close_template();
1313
1314 /* Create Iconbar icon and menus */
1316
1317 /* Finally, check Inet$Resolvers for sanity */
1319
1320 open_window = nsoption_bool(open_browser_at_startup);
1321
1322 /* parse command-line arguments */
1323 if (argc == 2) {
1324 NSLOG(netsurf, INFO, "parameters: '%s'", argv[1]);
1325 /* this is needed for launching URI files */
1326 if (strcasecmp(argv[1], "-nowin") == 0) {
1327 return NSERROR_OK;
1328 }
1329 ret = nsurl_create(NETSURF_HOMEPAGE, &url);
1330 }
1331 else if (argc == 3) {
1332 NSLOG(netsurf, INFO, "parameters: '%s' '%s'", argv[1],
1333 argv[2]);
1334 open_window = true;
1335
1336 /* HTML files */
1337 if (strcasecmp(argv[1], "-html") == 0) {
1338 ret = netsurf_path_to_nsurl(argv[2], &url);
1339 }
1340 /* URL files */
1341 else if (strcasecmp(argv[1], "-urlf") == 0) {
1342 char *urlf = ro_gui_url_file_parse(argv[2]);
1343 if (!urlf) {
1344 NSLOG(netsurf, INFO, "allocation failed");
1345 die("Insufficient memory for URL");
1346 }
1347 ret = nsurl_create(urlf, &url);
1348 free(urlf);
1349 }
1350 /* ANT URL Load */
1351 else if (strcasecmp(argv[1], "-url") == 0) {
1352 ret = nsurl_create(argv[2], &url);
1353 }
1354 /* Unknown => exit here. */
1355 else {
1356 NSLOG(netsurf, INFO, "Unknown parameters: '%s' '%s'",
1357 argv[1], argv[2]);
1358 return NSERROR_BAD_PARAMETER;
1359 }
1360 }
1361 /* get user's homepage (if configured) */
1362 else if (nsoption_charp(homepage_url) &&
1363 nsoption_charp(homepage_url)[0]) {
1364 ret = nsurl_create(nsoption_charp(homepage_url), &url);
1365 }
1366 /* default homepage */
1367 else {
1368 ret = nsurl_create(NETSURF_HOMEPAGE, &url);
1369 }
1370
1371 /* check for url creation error */
1372 if (ret != NSERROR_OK) {
1373 return ret;
1374 }
1375
1376 if (open_window) {
1378 url,
1379 NULL,
1380 NULL,
1381 NULL);
1382 }
1383 nsurl_unref(url);
1384
1385 return ret;
1386}
1387
1388
1389/**
1390 * Determine the default language to use.
1391 *
1392 * RISC OS has no standard way of determining which language the user prefers.
1393 * We have to guess from the 'Country' setting.
1394 */
1396{
1397 char path[40];
1398 const char *lang;
1399 int country;
1400 os_error *error;
1401
1402 /* choose a language from the configured country number */
1403 error = xosbyte_read(osbyte_VAR_COUNTRY_NUMBER, &country);
1404 if (error) {
1405 NSLOG(netsurf, INFO, "xosbyte_read failed: 0x%x: %s",
1406 error->errnum, error->errmess);
1407 country = 1;
1408 }
1409 switch (country) {
1410 case 7: /* Germany */
1411 case 30: /* Austria */
1412 case 35: /* Switzerland (70% German-speaking) */
1413 lang = "de";
1414 break;
1415 case 6: /* France */
1416 case 18: /* Canada2 (French Canada?) */
1417 lang = "fr";
1418 break;
1419 case 34: /* Netherlands */
1420 lang = "nl";
1421 break;
1422 default:
1423 lang = "en";
1424 break;
1425 }
1426 sprintf(path, "NetSurf:Resources.%s", lang);
1427 if (is_dir(path))
1428 return lang;
1429 return "en";
1430}
1431
1432
1433/**
1434 * Create a nsurl from a RISC OS pathname.
1435 *
1436 * Perform the necessary operations on a path to generate a nsurl.
1437 *
1438 * @param[in] path The RISC OS pathname to convert.
1439 * @param[out] url_out pointer to recive the nsurl, The returned url must be
1440 * unreferenced by the caller.
1441 * @return NSERROR_OK and the url is placed in \a url or error code on faliure.
1442 */
1443static nserror ro_path_to_nsurl(const char *path, struct nsurl **url_out)
1444{
1445 int spare;
1446 char *canonical_path; /* canonicalised RISC OS path */
1447 char *unix_path; /* unix path */
1448 char *escaped_path;
1449 os_error *error;
1450 nserror ret;
1451 int urllen;
1452 char *url; /* resulting url */
1453
1454 /* calculate the canonical risc os path */
1455 error = xosfscontrol_canonicalise_path(path, 0, 0, 0, 0, &spare);
1456 if (error) {
1457 NSLOG(netsurf, INFO,
1458 "xosfscontrol_canonicalise_path failed: 0x%x: %s",
1459 error->errnum,
1460 error->errmess);
1461 ro_warn_user("PathToURL", error->errmess);
1462 return NSERROR_NOT_FOUND;
1463 }
1464
1465 canonical_path = malloc(1 - spare);
1466 if (canonical_path == NULL) {
1467 free(canonical_path);
1468 return NSERROR_NOMEM;
1469 }
1470
1471 error = xosfscontrol_canonicalise_path(path, canonical_path, 0, 0, 1 - spare, 0);
1472 if (error) {
1473 NSLOG(netsurf, INFO,
1474 "xosfscontrol_canonicalise_path failed: 0x%x: %s",
1475 error->errnum,
1476 error->errmess);
1477 ro_warn_user("PathToURL", error->errmess);
1478 free(canonical_path);
1479 return NSERROR_NOT_FOUND;
1480 }
1481
1482 /* create a unix path from the cananocal risc os one */
1483 unix_path = __unixify(canonical_path, __RISCOSIFY_NO_REVERSE_SUFFIX, NULL, 0, 0);
1484
1485 if (unix_path == NULL) {
1486 NSLOG(netsurf, INFO, "__unixify failed: %s", canonical_path);
1487 free(canonical_path);
1488 return NSERROR_BAD_PARAMETER;
1489 }
1490 free(canonical_path);
1491
1492 /* url escape the unix path */
1493 ret = url_escape(unix_path, false, "/", &escaped_path);
1494 if (ret != NSERROR_OK) {
1495 free(unix_path);
1496 return ret;
1497 }
1498 free(unix_path);
1499
1500 /* convert the escaped unix path into a url */
1501 urllen = strlen(escaped_path) + FILE_SCHEME_PREFIX_LEN + 1;
1502 url = malloc(urllen);
1503 if (url == NULL) {
1504 NSLOG(netsurf, INFO, "Unable to allocate url");
1505 free(escaped_path);
1506 return NSERROR_NOMEM;
1507 }
1508
1509 if (*escaped_path == '/') {
1510 snprintf(url, urllen, "%s%s",
1511 FILE_SCHEME_PREFIX, escaped_path + 1);
1512 } else {
1513 snprintf(url, urllen, "%s%s",
1514 FILE_SCHEME_PREFIX, escaped_path);
1515 }
1516 free(escaped_path);
1517
1518 ret = nsurl_create(url, url_out);
1519 free(url);
1520
1521 return ret;
1522}
1523
1524
1525/**
1526 * Create a path from a nsurl using posix file handling.
1527 *
1528 * @param[in] url The url to encode.
1529 * @param[out] path_out A string containing the result path which should
1530 * be freed by the caller.
1531 * @return NSERROR_OK and the path is written to \a path or error code
1532 * on faliure.
1533 */
1534static nserror ro_nsurl_to_path(struct nsurl *url, char **path_out)
1535{
1536 lwc_string *urlpath;
1537 size_t unpath_len;
1538 char *unpath;
1539 char *path;
1540 bool match;
1541 lwc_string *scheme;
1542 nserror res;
1543 char *r;
1544
1545 if ((url == NULL) || (path_out == NULL)) {
1546 return NSERROR_BAD_PARAMETER;
1547 }
1548
1549 scheme = nsurl_get_component(url, NSURL_SCHEME);
1550
1551 if (lwc_string_caseless_isequal(scheme, corestring_lwc_file,
1552 &match) != lwc_error_ok)
1553 {
1554 return NSERROR_BAD_PARAMETER;
1555 }
1556 lwc_string_unref(scheme);
1557 if (match == false) {
1558 return NSERROR_BAD_PARAMETER;
1559 }
1560
1561 urlpath = nsurl_get_component(url, NSURL_PATH);
1562 if (urlpath == NULL) {
1563 return NSERROR_BAD_PARAMETER;
1564 }
1565
1566 res = url_unescape(lwc_string_data(urlpath),
1567 lwc_string_length(urlpath),
1568 &unpath_len,
1569 &unpath);
1570 lwc_string_unref(urlpath);
1571 if (res != NSERROR_OK) {
1572 return res;
1573 }
1574
1575 /* RISC OS path should not be more than 100 characters longer */
1576 path = malloc(unpath_len + 100);
1577 if (path == NULL) {
1578 free(unpath);
1579 return NSERROR_NOMEM;
1580 }
1581
1582 r = __riscosify(unpath, 0, __RISCOSIFY_NO_SUFFIX,
1583 path, unpath_len + 100, 0);
1584 free(unpath);
1585 if (r == NULL) {
1586 free(path);
1587 return NSERROR_NOMEM;
1588 }
1589
1590 *path_out = path;
1591
1592 return NSERROR_OK;
1593}
1594
1595
1596/**
1597 * Ensures output logging stream is correctly configured.
1598 */
1599static bool nslog_stream_configure(FILE *fptr)
1600{
1601 /* set log stream to be non-buffering */
1602 setbuf(fptr, NULL);
1603
1604 return true;
1605}
1606
1607
1608/**
1609 * Close down the gui (RISC OS).
1610 */
1611static void gui_quit(void)
1612{
1614 urldb_save(nsoption_charp(url_save));
1623 rufl_quit();
1624 free(gui_sprites);
1625 xwimp_close_down(task_handle);
1626 xhourglass_off();
1627}
1628
1629
1630/**
1631 * Handle Close_Window_Request events.
1632 */
1633static void ro_gui_close_window_request(wimp_close *close)
1634{
1635 if (ro_gui_alt_pressed())
1637 else {
1638 if (ro_gui_wimp_event_close_window(close->w))
1639 return;
1640 ro_gui_dialog_close(close->w);
1641 }
1642}
1643
1644
1645/**
1646 * Handle key press paste callback.
1647 */
1648static void ro_gui_keypress_cb(void *pw)
1649{
1650 wimp_key *key = (wimp_key *) pw;
1651
1652 if (ro_gui_wimp_event_keypress(key) == false) {
1653 os_error *error = xwimp_process_key(key->c);
1654 if (error) {
1655 NSLOG(netsurf, INFO, "xwimp_process_key: 0x%x: %s",
1656 error->errnum, error->errmess);
1657 ro_warn_user("WimpError", error->errmess);
1658 }
1659 }
1660
1661 free(key);
1662}
1663
1664
1665/**
1666 * Handle gui keypress.
1667 */
1668static void ro_gui_keypress(wimp_key *key)
1669{
1670 if (key->c == wimp_KEY_ESCAPE &&
1673
1674 /* Allow Escape key to be used for cancelling a drag
1675 * save (easier than finding somewhere safe to abort
1676 * the drag)
1677 */
1680 } else if (key->c == 22 /* Ctrl-V */) {
1681 wimp_key *copy;
1682
1683 /* Must copy the keypress as it's on the stack */
1684 copy = malloc(sizeof(wimp_key));
1685 if (copy == NULL)
1686 return;
1687 memcpy(copy, key, sizeof(wimp_key));
1688
1690 } else if (ro_gui_wimp_event_keypress(key) == false) {
1691 os_error *error = xwimp_process_key(key->c);
1692 if (error) {
1693 NSLOG(netsurf, INFO, "xwimp_process_key: 0x%x: %s",
1694 error->errnum, error->errmess);
1695 ro_warn_user("WimpError", error->errmess);
1696 }
1697 }
1698}
1699
1700
1701/**
1702 * Handle the three User_Message events.
1703 */
1704static void ro_gui_user_message(wimp_event_no event, wimp_message *message)
1705{
1706 /* attempt automatic routing */
1707 if (ro_message_handle_message(event, message))
1708 return;
1709
1710 switch (message->action) {
1711 case message_DATA_LOAD:
1712 ro_msg_terminate_filename((wimp_full_message_data_xfer*)message);
1713
1714 if (event == wimp_USER_MESSAGE_ACKNOWLEDGE) {
1716 ro_print_dataload_bounce(message);
1718 (wimp_full_message_data_xfer *) message) == false) {
1719 ro_msg_dataload(message);
1720 }
1721 break;
1722
1723 case message_DATA_LOAD_ACK:
1726 break;
1727
1728 case message_MENU_WARNING:
1729 ro_gui_menu_warning((wimp_message_menu_warning *)
1730 &message->data);
1731 break;
1732
1733 case message_MENUS_DELETED:
1734 ro_gui_menu_message_deleted((wimp_message_menus_deleted *)
1735 &message->data);
1736 break;
1737
1738 case message_CLAIM_ENTITY:
1739 ro_gui_selection_claim_entity((wimp_full_message_claim_entity*)message);
1740 break;
1741
1742 case message_DATA_REQUEST:
1743 ro_gui_selection_data_request((wimp_full_message_data_request*)message);
1744 break;
1745
1746 case message_MODE_CHANGE:
1748 rufl_invalidate_cache();
1749 break;
1750
1751 case message_PALETTE_CHANGE:
1752 break;
1753
1754 case message_FONT_CHANGED:
1756 break;
1757
1758 case message_URI_PROCESS:
1759 if (event != wimp_USER_MESSAGE_ACKNOWLEDGE)
1760 ro_uri_message_received(message);
1761 break;
1762 case message_URI_RETURN_RESULT:
1763 ro_uri_bounce(message);
1764 break;
1765 case message_INET_SUITE_OPEN_URL:
1766 if (event == wimp_USER_MESSAGE_ACKNOWLEDGE) {
1767 ro_url_bounce(message);
1768 }
1769 else {
1770 ro_url_message_received(message);
1771 }
1772 break;
1773 case message_PRINT_SAVE:
1774 if (event == wimp_USER_MESSAGE_ACKNOWLEDGE)
1775 ro_print_save_bounce(message);
1776 break;
1777 case message_PRINT_ERROR:
1778 ro_print_error(message);
1779 break;
1780 case message_PRINT_TYPE_ODD:
1781 ro_print_type_odd(message);
1782 break;
1785 break;
1786 case message_QUIT:
1787 riscos_done = true;
1788 break;
1789 }
1790}
1791
1792
1793/**
1794 * Process a Wimp_Poll event.
1795 *
1796 * \param event wimp event number
1797 * \param block parameter block
1798 */
1799static void ro_gui_handle_event(wimp_event_no event, wimp_block *block)
1800{
1801 switch (event) {
1802 case wimp_NULL_REASON_CODE:
1803 ro_gui_throb();
1804 ro_mouse_poll();
1805 break;
1806
1807 case wimp_REDRAW_WINDOW_REQUEST:
1808 ro_gui_wimp_event_redraw_window(&block->redraw);
1809 break;
1810
1811 case wimp_OPEN_WINDOW_REQUEST:
1812 ro_gui_open_window_request(&block->open);
1813 break;
1814
1815 case wimp_CLOSE_WINDOW_REQUEST:
1816 ro_gui_close_window_request(&block->close);
1817 break;
1818
1819 case wimp_POINTER_LEAVING_WINDOW:
1820 ro_mouse_pointer_leaving_window(&block->leaving);
1821 break;
1822
1823 case wimp_POINTER_ENTERING_WINDOW:
1825 break;
1826
1827 case wimp_MOUSE_CLICK:
1828 ro_gui_wimp_event_mouse_click(&block->pointer);
1829 break;
1830
1831 case wimp_USER_DRAG_BOX:
1832 ro_mouse_drag_end(&block->dragged);
1833 break;
1834
1835 case wimp_KEY_PRESSED:
1836 ro_gui_keypress(&(block->key));
1837 break;
1838
1839 case wimp_MENU_SELECTION:
1840 ro_gui_menu_selection(&(block->selection));
1841 break;
1842
1843 /* Scroll requests fall back to a generic handler because we
1844 * might get these events for any window from a scroll-wheel.
1845 */
1846
1847 case wimp_SCROLL_REQUEST:
1848 if (!ro_gui_wimp_event_scroll_window(&(block->scroll)))
1849 ro_gui_scroll(&(block->scroll));
1850 break;
1851
1852 case wimp_USER_MESSAGE:
1853 case wimp_USER_MESSAGE_RECORDED:
1854 case wimp_USER_MESSAGE_ACKNOWLEDGE:
1855 ro_gui_user_message(event, &(block->message));
1856 break;
1857 }
1858}
1859
1860
1861/**
1862 * Poll the RISC OS wimp for events.
1863 */
1864static void riscos_poll(void)
1865{
1866 wimp_event_no event;
1867 wimp_block block;
1868 const wimp_poll_flags mask = wimp_MASK_LOSE | wimp_MASK_GAIN | wimp_SAVE_FP;
1869 os_t track_poll_offset;
1870
1871 /* Poll wimp. */
1872 xhourglass_off();
1873 track_poll_offset = ro_mouse_poll_interval();
1874 if (sched_active || (track_poll_offset > 0)) {
1875 os_t t = os_read_monotonic_time();
1876
1877 if (track_poll_offset > 0) {
1878 t += track_poll_offset;
1879 } else {
1880 t += 10;
1881 }
1882
1883 if (sched_active && (sched_time - t) < 0) {
1884 t = sched_time;
1885 }
1886
1887 event = wimp_poll_idle(mask, &block, t, 0);
1888 } else {
1889 event = wimp_poll(wimp_MASK_NULL | mask, &block, 0);
1890 }
1891
1892 xhourglass_on();
1893 gui_last_poll = clock();
1894 ro_gui_handle_event(event, &block);
1895
1896 /* Only run scheduled callbacks on a null poll
1897 * We cannot do this in the null event handler, as that may be called
1898 * from gui_multitask(). Scheduled callbacks must only be run from the
1899 * top-level.
1900 */
1901 if (event == wimp_NULL_REASON_CODE) {
1902 schedule_run();
1903 }
1904
1906}
1907
1908
1909/**
1910 * Handle Open_Window_Request events.
1911 */
1912void ro_gui_open_window_request(wimp_open *open)
1913{
1914 os_error *error;
1915
1917 return;
1918
1919 error = xwimp_open_window(open);
1920 if (error) {
1921 NSLOG(netsurf, INFO, "xwimp_open_window: 0x%x: %s",
1922 error->errnum, error->errmess);
1923 ro_warn_user("WimpError", error->errmess);
1924 return;
1925 }
1926}
1927
1928
1929/**
1930 * source bounce callback.
1931 */
1932static void ro_gui_view_source_bounce(wimp_message *message)
1933{
1934 char *filename;
1935 os_error *error;
1936 char command[256];
1937
1938 /* run the file as text */
1939 filename = ((wimp_full_message_data_xfer *)message)->file_name;
1940 sprintf(command, "@RunType_FFF %s", filename);
1941 error = xwimp_start_task(command, 0);
1942 if (error) {
1943 NSLOG(netsurf, INFO, "xwimp_start_task failed: 0x%x: %s",
1944 error->errnum, error->errmess);
1945 ro_warn_user("WimpError", error->errmess);
1946 }
1947}
1948
1949
1950/**
1951 * Send the source of a content to a text editor.
1952 */
1954{
1955 os_error *error;
1956 char *temp_name;
1957 wimp_full_message_data_xfer message;
1958 int objtype;
1959 bool done = false;
1960
1961 const uint8_t *source_data;
1962 size_t source_size;
1963
1964 if (!c) {
1965 ro_warn_user("MiscError", "No document source");
1966 return;
1967 }
1968
1969 source_data = content_get_source_data(c, &source_size);
1970
1971 if (!source_data) {
1972 ro_warn_user("MiscError", "No document source");
1973 return;
1974 }
1975
1976 /* try to load local files directly. */
1978 error = xosfile_read_no_path(temp_name, &objtype, 0, 0, 0, 0);
1979 if ((!error) && (objtype == osfile_IS_FILE)) {
1980 snprintf(message.file_name, 212, "%s", temp_name);
1981 message.file_name[211] = '\0';
1982 done = true;
1983 }
1984 free(temp_name);
1985 }
1986 if (!done) {
1987 /* We cannot release the requested filename until after it
1988 * has finished being used. As we can't easily find out when
1989 * this is, we simply don't bother releasing it and simply
1990 * allow it to be re-used next time NetSurf is started. The
1991 * memory overhead from doing this is under 1 byte per
1992 * filename. */
1993 char *r;
1994 char full_name[256];
1995 const char *filename = filename_request();
1996 if (!filename) {
1997 ro_warn_user("NoMemory", 0);
1998 return;
1999 }
2000
2001 snprintf(full_name, 256, "%s/%s", TEMP_FILENAME_PREFIX,
2002 filename);
2003 full_name[255] = '\0';
2004 r = __riscosify(full_name, 0, __RISCOSIFY_NO_SUFFIX,
2005 message.file_name, 212, 0);
2006 if (r == 0) {
2007 NSLOG(netsurf, INFO, "__riscosify failed");
2008 return;
2009 }
2010 message.file_name[211] = '\0';
2011
2012 error = xosfile_save_stamped(message.file_name,
2014 (byte *) source_data,
2015 (byte *) source_data + source_size);
2016 if (error) {
2017 NSLOG(netsurf, INFO,
2018 "xosfile_save_stamped failed: 0x%x: %s",
2019 error->errnum,
2020 error->errmess);
2021 ro_warn_user("MiscError", error->errmess);
2022 return;
2023 }
2024 }
2025
2026 /* begin the DataOpen protocol */
2027 message.your_ref = 0;
2028 message.size = 44 + ((strlen(message.file_name) + 4) & (~3u));
2029 message.action = message_DATA_OPEN;
2030 message.w = 0;
2031 message.i = 0;
2032 message.pos.x = 0;
2033 message.pos.y = 0;
2034 message.est_size = 0;
2035 message.file_type = 0xfff;
2036 ro_message_send_message(wimp_USER_MESSAGE_RECORDED,
2037 (wimp_message*)&message, 0,
2039}
2040
2041
2042/**
2043 * Broadcast an URL that we can't handle.
2044 */
2045static nserror gui_launch_url(struct nsurl *url)
2046{
2047 /* Try ant broadcast */
2049 return NSERROR_OK;
2050}
2051
2052
2053/**
2054 * Choose the language to use.
2055 */
2056static void ro_gui_choose_language(void)
2057{
2058 /* if option_language exists and is valid, use that */
2059 if (nsoption_charp(language)) {
2060 char path[40];
2061 if (2 < strlen(nsoption_charp(language)))
2062 nsoption_charp(language)[2] = 0;
2063 sprintf(path, "NetSurf:Resources.%s", nsoption_charp(language));
2064
2065 if (is_dir(path)) {
2066 nsoption_setnull_charp(accept_language,
2067 strdup(nsoption_charp(language)));
2068 return;
2069 }
2070 nsoption_set_charp(language, NULL);
2071 }
2072
2073 nsoption_set_charp(language, strdup(ro_gui_default_language()));
2074 if (nsoption_charp(language) == NULL)
2075 die("Out of memory");
2076 nsoption_set_charp(accept_language, strdup(nsoption_charp(language)));
2077 if (nsoption_charp(accept_language) == NULL)
2078 die("Out of memory");
2079}
2080
2081
2082/**
2083 * Display a warning for a serious problem (eg memory exhaustion).
2084 *
2085 * \param warning message key for warning message
2086 * \param detail additional message, or 0
2087 */
2088nserror ro_warn_user(const char *warning, const char *detail)
2089{
2090 NSLOG(netsurf, INFO, "%s %s", warning, detail);
2091
2092 if (dialog_warning) {
2093 char warn_buffer[300];
2094 snprintf(warn_buffer, sizeof warn_buffer, "%s %s",
2095 messages_get(warning),
2096 detail ? detail : "");
2097 warn_buffer[sizeof warn_buffer - 1] = 0;
2099 warn_buffer, true);
2100 xwimp_set_icon_state(dialog_warning, ICON_WARNING_HELP,
2101 wimp_ICON_DELETED, wimp_ICON_DELETED);
2103 xos_bell();
2104 } else {
2105 /* probably haven't initialised (properly), use a
2106 non-multitasking error box */
2107 os_error error;
2108 snprintf(error.errmess, sizeof error.errmess, "%s %s",
2109 messages_get(warning),
2110 detail ? detail : "");
2111 error.errmess[sizeof error.errmess - 1] = 0;
2112 xwimp_report_error_by_category(&error,
2113 wimp_ERROR_BOX_OK_ICON |
2114 wimp_ERROR_BOX_GIVEN_CATEGORY |
2115 wimp_ERROR_BOX_CATEGORY_ERROR <<
2116 wimp_ERROR_BOX_CATEGORY_SHIFT,
2117 "NetSurf", "!netsurf",
2118 (osspriteop_area *) 1, 0, 0);
2119 }
2120
2121 return NSERROR_OK;
2122}
2123
2124
2125/**
2126 * Display an error and exit.
2127 *
2128 * Should only be used during initialisation.
2129 */
2130void die(const char * const error)
2131{
2132 os_error warn_error;
2133
2134 NSLOG(netsurf, INFO, "%s", error);
2135
2136 warn_error.errnum = 1; /* \todo: reasonable ? */
2137 strncpy(warn_error.errmess, messages_get(error),
2138 sizeof(warn_error.errmess)-1);
2139 warn_error.errmess[sizeof(warn_error.errmess)-1] = '\0';
2140 xwimp_report_error_by_category(&warn_error,
2141 wimp_ERROR_BOX_OK_ICON |
2142 wimp_ERROR_BOX_GIVEN_CATEGORY |
2143 wimp_ERROR_BOX_CATEGORY_ERROR <<
2144 wimp_ERROR_BOX_CATEGORY_SHIFT,
2145 "NetSurf", "!netsurf",
2146 (osspriteop_area *) 1, 0, 0);
2147 exit(EXIT_FAILURE);
2148}
2149
2150
2151/**
2152 * Test whether it's okay to shutdown, prompting the user if not.
2153 *
2154 * \return true iff it's okay to shutdown immediately
2155 */
2157{
2158 return ro_gui_download_prequit();
2159}
2160
2161
2162/**
2163 * Generate a riscos path from one or more component elemnts.
2164 *
2165 * Constructs a complete path element from passed components. The
2166 * second (and subsequent) components have a slash substituted for all
2167 * riscos directory separators.
2168 *
2169 * If a string is allocated it must be freed by the caller.
2170 *
2171 * @param[in,out] str pointer to string pointer if this is NULL enough
2172 * storage will be allocated for the complete path.
2173 * @param[in,out] size The size of the space available if \a str not
2174 * NULL on input and if not NULL set to the total
2175 * output length on output.
2176 * @param[in] nelm The number of elements.
2177 * @param[in] ap The elements of the path as string pointers.
2178 * @return NSERROR_OK and the complete path is written to str
2179 * or error code on faliure.
2180 */
2181static nserror riscos_mkpath(char **str, size_t *size, size_t nelm, va_list ap)
2182{
2183 const char *elm[16];
2184 size_t elm_len[16];
2185 size_t elm_idx;
2186 char *fname;
2187 size_t fname_len = 0;
2188 char *curp;
2189 size_t idx;
2190
2191 /* check the parameters are all sensible */
2192 if ((nelm == 0) || (nelm > 16)) {
2193 return NSERROR_BAD_PARAMETER;
2194 }
2195 if ((*str != NULL) && (size == NULL)) {
2196 /* if the caller is providing the buffer they must say
2197 * how much space is available.
2198 */
2199 return NSERROR_BAD_PARAMETER;
2200 }
2201
2202 /* calculate how much storage we need for the complete path
2203 * with all the elements.
2204 */
2205 for (elm_idx = 0; elm_idx < nelm; elm_idx++) {
2206 elm[elm_idx] = va_arg(ap, const char *);
2207 /* check the argument is not NULL */
2208 if (elm[elm_idx] == NULL) {
2209 return NSERROR_BAD_PARAMETER;
2210 }
2211 elm_len[elm_idx] = strlen(elm[elm_idx]);
2212 fname_len += elm_len[elm_idx];
2213 }
2214 fname_len += nelm; /* allow for separators and terminator */
2215
2216 /* ensure there is enough space */
2217 fname = *str;
2218 if (fname != NULL) {
2219 if (fname_len > *size) {
2220 return NSERROR_NOSPACE;
2221 }
2222 } else {
2223 fname = malloc(fname_len);
2224 if (fname == NULL) {
2225 return NSERROR_NOMEM;
2226 }
2227 }
2228
2229 /* copy the elements in with directory separator */
2230 curp = fname;
2231
2232 /* first element is not altered */
2233 memmove(curp, elm[0], elm_len[0]);
2234 curp += elm_len[0];
2235 /* ensure there is a delimiter */
2236 if (curp[-1] != DIR_SEP) {
2237 *curp = DIR_SEP;
2238 curp++;
2239 }
2240
2241 /* subsequent elemnts have slashes substituted with directory
2242 * separators.
2243 */
2244 for (elm_idx = 1; elm_idx < nelm; elm_idx++) {
2245 for (idx = 0; idx < elm_len[elm_idx]; idx++) {
2246 if (elm[elm_idx][idx] == DIR_SEP) {
2247 *curp = '/';
2248 } else {
2249 *curp = elm[elm_idx][idx];
2250 }
2251 curp++;
2252 }
2253 *curp = DIR_SEP;
2254 curp++;
2255 }
2256 curp[-1] = 0; /* NULL terminate */
2257
2258 assert((curp - fname) <= (int)fname_len);
2259
2260 *str = fname;
2261 if (size != NULL) {
2262 *size = fname_len;
2263 }
2264
2265 return NSERROR_OK;
2266
2267}
2268
2269
2270/**
2271 * Get the basename of a file using posix path handling.
2272 *
2273 * This gets the last element of a path and returns it. The returned
2274 * element has all forward slashes translated into riscos directory
2275 * separators.
2276 *
2277 * @param[in] path The path to extract the name from.
2278 * @param[in,out] str Pointer to string pointer if this is NULL enough
2279 * storage will be allocated for the path element.
2280 * @param[in,out] size The size of the space available if \a
2281 * str not NULL on input and set to the total
2282 * output length on output.
2283 * @return NSERROR_OK and the complete path is written to str
2284 * or error code on faliure.
2285 */
2286static nserror riscos_basename(const char *path, char **str, size_t *size)
2287{
2288 const char *leafname;
2289 char *fname;
2290 char *temp;
2291
2292 if (path == NULL) {
2293 return NSERROR_BAD_PARAMETER;
2294 }
2295
2296 leafname = strrchr(path, DIR_SEP);
2297 if (!leafname) {
2298 leafname = path;
2299 } else {
2300 leafname += 1;
2301 }
2302
2303 fname = strdup(leafname);
2304 if (fname == NULL) {
2305 return NSERROR_NOMEM;
2306 }
2307
2308 /** @todo check this leafname translation is actually required */
2309 /* and s/\//\./g */
2310 for (temp = fname; *temp != 0; temp++) {
2311 if (*temp == '/') {
2312 *temp = DIR_SEP;
2313 }
2314 }
2315
2316 *str = fname;
2317 if (size != NULL) {
2318 *size = strlen(fname);
2319 }
2320 return NSERROR_OK;
2321}
2322
2323
2324/**
2325 * Ensure that all directory elements needed to store a filename exist.
2326 *
2327 * Given a path of x.y.z directories x and x.y will be created.
2328 *
2329 * @param fname The filename to ensure the path to exists.
2330 * @return NSERROR_OK on success or error code on failure.
2331 */
2332static nserror riscos_mkdir_all(const char *fname)
2333{
2334 char *dname;
2335 char *cur;
2336
2337 dname = strdup(fname);
2338
2339 cur = dname;
2340 while ((cur = strchr(cur, '.'))) {
2341 *cur = '\0';
2342 xosfile_create_dir(dname, 0);
2343 *cur++ = '.';
2344 }
2345
2346 free(dname);
2347
2348 return NSERROR_OK;
2349}
2350
2351/**
2352 * Find screen size in OS units.
2353 */
2355{
2356 *width = screen_info.width;
2357 *height = screen_info.height;
2358}
2359
2360
2361/**
2362 * Send the debug dump of a content to a text editor.
2363 */
2365{
2366 os_error *error;
2367
2368 /* open file for dump */
2369 FILE *stream = fopen("<Wimp$ScrapDir>.WWW.NetSurf.dump", "w");
2370 if (!stream) {
2371 NSLOG(netsurf, INFO, "fopen: errno %i", errno);
2372 ro_warn_user("SaveError", strerror(errno));
2373 return;
2374 }
2375
2377
2378 fclose(stream);
2379
2380 /* launch file in editor */
2381 error = xwimp_start_task("Filer_Run <Wimp$ScrapDir>.WWW.NetSurf.dump",
2382 0);
2383 if (error) {
2384 NSLOG(netsurf, INFO, "xwimp_start_task failed: 0x%x: %s",
2385 error->errnum, error->errmess);
2386 ro_warn_user("WimpError", error->errmess);
2387 }
2388}
2389
2390
2393 .basename = riscos_basename,
2394 .nsurl_to_path = ro_nsurl_to_path,
2395 .path_to_nsurl = ro_path_to_nsurl,
2396 .mkdir_all = riscos_mkdir_all,
2397};
2398
2401
2402 .get_resource_url = gui_get_resource_url,
2403 .mimetype = fetch_mimetype,
2404};
2405
2408
2409 .quit = gui_quit,
2410 .launch_url = gui_launch_url,
2411 .present_cookies = ro_gui_cookies_present,
2412};
2413
2414
2415static char *get_cachepath(void)
2416{
2417 char *cachedir;
2418 char *cachepath = NULL;
2419 nserror ret;
2420
2421 cachedir = getenv("Cache$Dir");
2422 if ((cachedir == NULL) || (cachedir[0] == 0)) {
2423 NSLOG(netsurf, INFO, "cachedir was null");
2424 return NULL;
2425 }
2426 ret = netsurf_mkpath(&cachepath, NULL, 2, cachedir, "NetSurf");
2427 if (ret != NSERROR_OK) {
2428 return NULL;
2429 }
2430 return cachepath;
2431}
2432
2433/**
2434 * Normal entry point from RISC OS.
2435 */
2436int main(int argc, char** argv)
2437{
2438 char *cachepath;
2439 char path[40];
2440 int length;
2441 os_var_type type;
2442 int used = -1; /* slightly better with older OSLib versions */
2443 os_error *error;
2444 nserror ret;
2445 struct netsurf_table riscos_table = {
2447 .window = riscos_window_table,
2448 .corewindow = riscos_core_window_table,
2449 .clipboard = riscos_clipboard_table,
2450 .download = riscos_download_table,
2451 .fetch = &riscos_fetch_table,
2452 .file = &riscos_file_table,
2453 .utf8 = riscos_utf8_table,
2454 .search = riscos_search_table,
2455 .llcache = filesystem_llcache_table,
2456 .bitmap = riscos_bitmap_table,
2457 .layout = riscos_layout_table,
2458 };
2459
2460 ret = netsurf_register(&riscos_table);
2461 if (ret != NSERROR_OK) {
2462 die("NetSurf operation table failed registration");
2463 }
2464
2465 /* Consult NetSurf$Logging environment variable to decide if logging
2466 * is required. */
2467 error = xos_read_var_val_size("NetSurf$Logging", 0, os_VARTYPE_STRING,
2468 &used, NULL, &type);
2469 if (error != NULL || type != os_VARTYPE_STRING || used != -2) {
2470 verbose_log = true;
2471 } else {
2472 char logging_env[2];
2473 error = xos_read_var_val("NetSurf$Logging", logging_env,
2474 sizeof(logging_env), 0, os_VARTYPE_STRING,
2475 &used, NULL, &type);
2476 if (error != NULL || logging_env[0] != '0') {
2477 verbose_log = true;
2478 } else {
2479 verbose_log = false;
2480 }
2481 }
2482
2483 /* initialise logging. Not fatal if it fails but not much we
2484 * can do about it either.
2485 */
2486 nslog_init(nslog_stream_configure, &argc, argv);
2487
2488 /* user options setup */
2490 if (ret != NSERROR_OK) {
2491 die("Options failed to initialise");
2492 }
2493 nsoption_read("NetSurf:Choices", NULL);
2494 nsoption_commandline(&argc, argv, NULL);
2495
2496 /* Choose the interface language to use */
2498
2499 /* select language-specific Messages */
2500 if (((length = snprintf(path,
2501 sizeof(path),
2502 "NetSurf:Resources.%s.Messages",
2503 nsoption_charp(language))) < 0) ||
2504 (length >= (int)sizeof(path))) {
2505 die("Failed to locate Messages resource.");
2506 }
2507
2508 /* initialise messages */
2510
2511 /* obtain cache path */
2512 cachepath = get_cachepath();
2513
2514 /* common initialisation */
2515 ret = netsurf_init(cachepath);
2516 free(cachepath);
2517 if (ret != NSERROR_OK) {
2518 die("NetSurf failed to initialise core");
2519 }
2520
2521 artworks_init();
2522 draw_init();
2523 sprite_init();
2524
2525 /* Load some extra RISC OS specific Messages */
2526 messages_add_from_file("NetSurf:Resources.LangNames");
2527
2528 ret = gui_init(argc, argv);
2529 if (ret != NSERROR_OK) {
2531 }
2532
2533 while (!riscos_done) {
2534 riscos_poll();
2535 }
2536
2537 netsurf_exit();
2539
2540 /* finalise logging */
2542
2543 return 0;
2544}
const char * fetch_filetype(const char *unix_path)
Determine the MIME type of a local file.
Definition: filetype.c:58
int main(int argc, char **argv)
Normal entry point from OS.
Definition: gui.c:6539
Content for image/x-artworks (RISC OS interface).
static nserror artworks_init(void)
Definition: artworks.h:35
int schedule_run(void)
Process events up to current time.
Definition: schedule.c:137
Low-level source data cache backing store interface.
struct gui_llcache_table * filesystem_llcache_table
Browser window creation and manipulation interface.
nserror browser_window_navigate(struct browser_window *bw, struct nsurl *url, struct nsurl *referrer, enum browser_window_nav_flags flags, char *post_urlenc, struct fetch_multipart_data *post_multipart, struct hlcache_handle *parent)
Start fetching a page in a browser window.
nserror browser_window_create(enum browser_window_create_flags flags, struct nsurl *url, struct nsurl *referrer, struct browser_window *existing, struct browser_window **bw)
Create and open a new root browser window with the given page.
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.
@ BW_CREATE_HISTORY
this will form a new history node (don't set for back/reload/etc)
@ BW_NAVIGATE_HISTORY
this will form a new history node (don't set for back/reload/etc)
void ro_gui_buffer_close(void)
Closes any open buffer and flushes the contents to screen.
Definition: buffer.c:370
Screen buffering (interface).
@ CONTENT_DEBUG_RENDER
Debug the contents rendering.
Definition: content_type.h:32
Unified cookie database public interface.
void urldb_save_cookies(const char *filename)
Save persistent cookies to file.
Definition: urldb.c:4444
void urldb_load_cookies(const char *filename)
Load a cookie file into the database.
Definition: urldb.c:4277
Useful interned string pointers (interface).
#define FILE_SCHEME_PREFIX_LEN
File url prefix length.
Definition: corestrings.h:33
#define FILE_SCHEME_PREFIX
File url prefix.
Definition: corestrings.h:30
static nserror hotlist_save(const char *path)
Definition: hotlist.c:113
nserror hotlist_init(const char *load_path, const char *save_path)
Initialise the hotlist.
Definition: hotlist.c:1289
nserror search_web_init(const char *provider_fname)
Initialise the web search operations.
Definition: searchweb.c:531
nserror search_web_select_provider(const char *selection)
Change the currently selected web search provider.
Definition: searchweb.c:403
void ro_gui_dialog_close_persistent(wimp_w parent)
Close persistent dialogs associated with a window.
Definition: dialog.c:638
void ro_gui_dialog_open(wimp_w w)
Open a dialog box, centred on the screen.
Definition: dialog.c:297
wimp_w dialog_warning
Definition: dialog.c:77
void ro_gui_dialog_init(void)
Load and create dialogs from template file.
Definition: dialog.c:103
void ro_gui_dialog_close(wimp_w close)
Close a dialog box.
Definition: dialog.c:335
Content for image/x-drawfile (RISC OS interface).
static nserror draw_init(void)
Definition: draw.h:35
nserror
Enumeration of error codes.
Definition: errors.h:29
@ NSERROR_NOSPACE
Insufficient space.
Definition: errors.h:59
@ NSERROR_NOT_FOUND
Requested item not found.
Definition: errors.h:34
@ NSERROR_BAD_PARAMETER
Bad Parameter.
Definition: errors.h:48
@ NSERROR_NOMEM
Memory exhaustion.
Definition: errors.h:32
@ NSERROR_OK
No error.
Definition: errors.h:30
const char * filename_request(void)
Request a new, unique, filename.
Definition: filename.c:68
bool filename_initialise(void)
Initialise the filename provider.
Definition: filename.c:178
#define TEMP_FILENAME_PREFIX
Definition: filename.h:27
const char * type
Definition: filetype.cpp:44
struct gui_bitmap_table * riscos_bitmap_table
bitmap operations table
Definition: bitmap.c:818
void ro_gui_download_init(void)
Load the download window template.
Definition: download.c:189
bool ro_gui_download_prequit(void)
Respond to PreQuit message, displaying a prompt message if we need the user to confirm the shutdown.
Definition: download.c:1680
struct gui_download_table * riscos_download_table
Definition: download.c:1697
void ro_gui_download_datasave_ack(wimp_message *message)
Handle Message_DataSaveAck for a drag from a download window.
Definition: download.c:1010
void nsfont_init(void)
Initialize font handling.
Definition: font.c:116
void ro_gui_wimp_get_desktop_font(void)
Retrieve the current desktop font family, size and style from the WindowManager in a form suitable fo...
Definition: font.c:607
struct gui_layout_table * riscos_layout_table
Definition: font.c:622
RISC OS font interface.
nserror ro_gui_global_history_finalise(void)
Free any resources allocated for the global history window.
RISc OS global history interface.
void ro_gui_hotlist_add_cleanup(void)
Clean up RMA storage used by the Message_HotlistAddURL protocol.
Definition: hotlist.c:730
nserror ro_gui_hotlist_finalise(void)
Free any resources allocated for the cookie window.
Definition: hotlist.c:586
Hotlist (interface).
#define message_HOTLIST_CHANGED
Definition: hotlist.h:34
#define message_HOTLIST_ADD_URL
Definition: hotlist.h:30
nserror ro_gui_local_history_finalise(void)
Free any resources allocated for the local history window.
RISC OS local history interface.
void ro_mouse_pointer_leaving_window(wimp_leaving *leaving)
Process Wimp_PointerLeaving events by terminating an active mouse track and passing the details on to...
Definition: mouse.c:224
os_t ro_mouse_poll_interval(void)
Return the desired polling interval to allow the mouse tracking to be carried out.
Definition: mouse.c:272
void ro_mouse_drag_end(wimp_dragged *dragged)
Process Wimp_DragEnd events by terminating an active drag track and passing the details on to any reg...
Definition: mouse.c:146
void ro_mouse_poll(void)
Process Null polls for any drags and mouse trackers that are currently active.
Definition: mouse.c:71
Mouse dragging and tracking support interface for RISC OS.
void ro_print_dataload_bounce(wimp_message *m)
Handle a bounced dataload message.
Definition: print.c:488
void ro_print_cleanup(void)
Cleanup after printing.
Definition: print.c:502
void ro_print_error(wimp_message *m)
Handle message_PRINT_ERROR.
Definition: print.c:370
bool ro_print_ack(wimp_message *m)
Handle message_DATASAVE_ACK for the printing protocol.
Definition: print.c:429
struct gui_window * ro_print_current_window
Definition: print.c:79
void ro_print_save_bounce(wimp_message *m)
Handle a bounced message_PRINT_SAVE.
Definition: print.c:351
void ro_print_type_odd(wimp_message *m)
Handle message_PRINT_TYPE_ODD.
Definition: print.c:391
void ro_gui_selection_data_request(wimp_full_message_data_request *req)
Responds to DATA_REQUEST message, returning information about the clipboard contents if we own the cl...
void ro_gui_selection_claim_entity(wimp_full_message_claim_entity *claim)
Responds to CLAIM_ENTITY message notifying us that the caret and selection or clipboard have been cla...
struct gui_clipboard_table * riscos_clipboard_table
bool ro_gui_selection_prepare_paste_datasave(wimp_full_message_data_xfer *dataxfer)
Prepare to paste data from another application (step 2)
void ro_gui_selection_prepare_paste(wimp_w w, ro_gui_selection_prepare_paste_cb cb, void *pw)
Prepare to paste data from another application.
void ro_gui_selection_dragging(wimp_message *message)
Handler for Message_Dragging, used to implement auto-scrolling and ghost caret when a drag is in prog...
bool ro_gui_selection_prepare_paste_dataload(wimp_full_message_data_xfer *dataxfer)
Prepare to paste data from another application (step 3)
void ro_gui_selection_drag_claim(wimp_message *message)
Text selection import/export (interface).
Browser window handling (interface).
#define ro_gui_window_close_all
Close all browser windows.
Definition: window.h:148
void ro_gui_iconbar_initialise(void)
Initialise the iconbar menus, create an icon and register the necessary handlers to look after them a...
Definition: iconbar.c:66
Iconbar icon and menus (interface).
Public content interface.
struct nsurl * hlcache_handle_get_url(const struct hlcache_handle *handle)
Retrieve the URL associated with a high level cache handle.
const uint8_t * content_get_source_data(struct hlcache_handle *h, size_t *size)
Retrieve source of content.
Definition: content.c:1201
Interface to platform-specific fetcher operations.
Interface to platform-specific miscellaneous browser operation table.
nserror nslog_init(nslog_ensure_t *ensure, int *pargc, char **argv)
Initialise the logging system.
Definition: log.c:190
bool verbose_log
flag to enable verbose logging
Definition: log.c:31
void nslog_finalise(void)
Shut down the logging system.
Definition: log.c:299
#define NSLOG(catname, level, logmsg, args...)
Definition: log.h:116
void ro_gui_menu_init(void)
Definition: menus.c:185
void ro_gui_menu_message_deleted(wimp_message_menus_deleted *deleted)
Handle Message_MenusDeleted, removing our current record of an open menu if it matches the deleted me...
Definition: menus.c:513
void ro_gui_menu_warning(wimp_message_menu_warning *warning)
Handle Message_MenuWarning.
Definition: menus.c:452
void ro_gui_menu_selection(wimp_selection *selection)
Handle menu selection.
Definition: menus.c:397
bool ro_message_handle_message(wimp_event_no event, wimp_message *message)
Attempts to route a message.
Definition: message.c:192
bool ro_message_send_message(wimp_event_no event, wimp_message *message, wimp_t task, void(*callback)(wimp_message *message))
Sends a message and registers a return route for a bounce.
Definition: message.c:57
bool ro_message_register_route(unsigned int message_code, void(*callback)(wimp_message *message))
Registers a route for a message code.
Definition: message.c:157
Automated RISC OS message routing (interface).
nserror messages_add_from_file(const char *path)
Read keys and values from messages file into the standard Messages hash.
Definition: messages.c:177
const char * messages_get_errorcode(nserror code)
lookup of a message by errorcode from the standard Messages hash.
Definition: messages.c:263
const char * messages_get(const char *key)
Fast lookup of a message by key from the standard Messages hash.
Definition: messages.c:256
Localised message support (interface).
NetSurf core interface registration, construction and destruction.
void netsurf_exit(void)
Finalise NetSurf core.
Definition: netsurf.c:232
nserror netsurf_init(const char *store_path)
Initialise netsurf core.
Definition: netsurf.c:107
nserror netsurf_register(struct netsurf_table *table)
Register operation table.
Definition: gui_factory.c:777
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.
const char * nsurl_access(const nsurl *url)
Access a NetSurf URL object as a string.
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_SCHEME
Definition: nsurl.h:45
@ NSURL_PATH
Definition: nsurl.h:52
struct nsurl nsurl
NetSurf URL object.
Definition: nsurl.h:31
@ base
Definition: punycode.c:19
void ro_gui_query_init(void)
Definition: query.c:76
nserror ro_gui_cookies_finalise(void)
Free any resources allocated for the cookie window.
Definition: cookies.c:478
nserror ro_gui_cookies_present(const char *search_term)
make the cookie window visible.
Definition: cookies.c:449
Interface to riscos cookie viewing using riscos core window.
struct core_window_table * riscos_core_window_table
Definition: corewindow.c:974
RISC OS core window interface.
char * fetch_mimetype(const char *ro_path)
Find a MIME type for a local file.
Definition: filetype.c:154
int ro_content_filetype(struct hlcache_handle *c)
Determine the RISC OS filetype for a content.
Definition: filetype.c:243
RISC OS filetpe interface.
#define FILETYPE_HTML
Definition: filetype.h:38
#define FILETYPE_PNG
Definition: filetype.h:59
#define FILETYPE_ARTWORKS
Definition: filetype.h:65
#define FILETYPE_GIF
Definition: filetype.h:50
#define FILETYPE_CSS
Definition: filetype.h:44
#define FILETYPE_ICO
Definition: filetype.h:56
#define FILETYPE_JPEG
Definition: filetype.h:62
#define FILETYPE_WEBP
Definition: filetype.h:71
#define FILETYPE_JNG
Definition: filetype.h:41
#define FILETYPE_MNG
Definition: filetype.h:47
#define FILETYPE_BMP
Definition: filetype.h:53
#define FILETYPE_SVG
Definition: filetype.h:68
#define FILETYPE_IEURL
Definition: filetype.h:35
#define FILETYPE_ANT_URL
Definition: filetype.h:32
#define FILETYPE_ACORN_URI
Definition: filetype.h:29
void ro_gui_screen_size(int *width, int *height)
Find screen size in OS units.
Definition: gui.c:2354
static void ro_gui_cleanup(void)
Ensures the gui exits cleanly.
Definition: gui.c:393
static bool ro_gui_uri_file_parse_line(FILE *fp, char *b)
Read a "line" from an Acorn URI file.
Definition: gui.c:479
const char *const __dynamic_da_name
For UnixLib.
Definition: gui.c:101
static void ro_gui_check_resolvers(void)
Warn the user if Inet$Resolvers is not set.
Definition: gui.c:1089
ro_gui_drag_type gui_current_drag_type
Definition: gui.c:116
static void riscos_poll(void)
Poll the RISC OS wimp for events.
Definition: gui.c:1864
static nsurl * gui_get_resource_url(const char *path)
Callback to translate resource to full url for RISC OS.
Definition: gui.c:177
void ro_gui_view_source(struct hlcache_handle *c)
Send the source of a content to a text editor.
Definition: gui.c:1953
static struct gui_fetch_table riscos_fetch_table
Definition: gui.c:2399
static void ro_msg_datasave(wimp_message *message)
Handle Message_DataSave.
Definition: gui.c:892
int __dynamic_da_max_size
For UnixLib.
Definition: gui.c:102
int width
Definition: gui.c:161
static nserror gui_launch_url(struct nsurl *url)
Broadcast an URL that we can't handle.
Definition: gui.c:2045
osspriteop_area * gui_sprites
Sprite area containing pointer and hotlist sprites.
Definition: gui.c:119
static nserror riscos_mkpath(char **str, size_t *size, size_t nelm, va_list ap)
Generate a riscos path from one or more component elemnts.
Definition: gui.c:2181
bool ro_gui_prequit(void)
Test whether it's okay to shutdown, prompting the user if not.
Definition: gui.c:2156
static void ro_gui_user_message(wimp_event_no event, wimp_message *message)
Handle the three User_Message events.
Definition: gui.c:1704
const char * NETSURF_DIR
Definition: gui.c:111
#define CHOICES_PREFIX
Definition: gui.c:114
static nserror gui_init(int argc, char **argv)
Initialise the RISC OS specific GUI.
Definition: gui.c:1130
static nserror set_defaults(struct nsoption_s *defaults)
Set option defaults for riscos frontend.
Definition: gui.c:287
static void ro_gui_get_screen_properties(void)
Get screen properties following a mode change.
Definition: gui.c:1060
wimp_t task_handle
RISC OS wimp task handle.
Definition: gui.c:117
static bool nslog_stream_configure(FILE *fptr)
Ensures output logging stream is correctly configured.
Definition: gui.c:1599
nserror ro_warn_user(const char *warning, const char *detail)
Display a warning for a serious problem (eg memory exhaustion).
Definition: gui.c:2088
static void ro_msg_save_desktop(wimp_message *message)
Handle SaveDesktop message.
Definition: gui.c:1001
#define DIR_SEP
Definition: gui.c:121
static void ro_gui_close_window_request(wimp_close *close)
Handle Close_Window_Request events.
Definition: gui.c:1633
bool riscos_done
Definition: gui.c:94
static void gui_quit(void)
Close down the gui (RISC OS).
Definition: gui.c:1611
void ro_gui_dump_browser_window(struct browser_window *bw)
Send the debug dump of a content to a text editor.
Definition: gui.c:2364
static void ro_gui_keypress_cb(void *pw)
Handle key press paste callback.
Definition: gui.c:1648
static void ro_gui_handle_event(wimp_event_no event, wimp_block *block)
Process a Wimp_Poll event.
Definition: gui.c:1799
static nserror set_colour_from_wimp(struct nsoption_s *opts, wimp_colour wimp, enum nsoption_e option, colour def_colour)
Set colour option from wimp.
Definition: gui.c:252
static void ro_gui_signal(int sig)
Handles a signal.
Definition: gui.c:405
bool ro_plot_patterned_lines
One version of the A9home OS is incapable of drawing patterned lines.
Definition: plotters.c:45
static char * ro_gui_url_file_parse(const char *file_name)
Parse an ANT URL file.
Definition: gui.c:590
static void ro_msg_dataopen(wimp_message *message)
Handle Message_DataOpen (double-click on file in the Filer).
Definition: gui.c:684
void die(const char *const error)
Display an error and exit.
Definition: gui.c:2130
static nserror ro_nsurl_to_path(struct nsurl *url, char **path_out)
Create a path from a nsurl using posix file handling.
Definition: gui.c:1534
static char * get_cachepath(void)
Definition: gui.c:2415
static void ro_gui_choose_language(void)
Choose the language to use.
Definition: gui.c:2056
static nserror ro_path_to_nsurl(const char *path, struct nsurl **url_out)
Create a nsurl from a RISC OS pathname.
Definition: gui.c:1443
static nserror riscos_mkdir_all(const char *fname)
Ensure that all directory elements needed to store a filename exist.
Definition: gui.c:2332
int __feature_imagefs_is_file
For UnixLib.
Definition: gui.c:103
static void ro_msg_window_info(wimp_message *message)
Handle WindowInfo message (part of the iconising protocol)
Definition: gui.c:1037
static clock_t gui_last_poll
Time of last wimp_poll.
Definition: gui.c:118
static void ro_msg_prequit(wimp_message *message)
Handle PreQuit message.
Definition: gui.c:978
static nserror riscos_basename(const char *path, char **str, size_t *size)
Get the basename of a file using posix path handling.
Definition: gui.c:2286
void ro_gui_open_window_request(wimp_open *open)
Handle Open_Window_Request events.
Definition: gui.c:1912
static void ro_gui_keypress(wimp_key *key)
Handle gui keypress.
Definition: gui.c:1668
static void ro_msg_dataload(wimp_message *message)
Handle Message_DataLoad (file dragged in).
Definition: gui.c:763
static void ro_gui_view_source_bounce(wimp_message *message)
source bounce callback.
Definition: gui.c:1932
static void ro_gui_create_dirs(void)
Create intermediate directories for Choices and User Data files.
Definition: gui.c:357
bool os_alpha_sprite_supported
Definition: gui.c:99
int height
Definition: gui.c:162
static struct gui_misc_table riscos_misc_table
Definition: gui.c:2406
static bool ro_gui__os_alpha_sprites_supported(void)
Determine whether the OS version supports alpha channels.
Definition: gui.c:1106
static ns_wimp_message_list task_messages
Accepted wimp user messages.
Definition: gui.c:126
static void ro_msg_terminate_filename(wimp_full_message_data_xfer *message)
Ensure that the filename in a data transfer message is NULL terminated (some applications,...
Definition: gui.c:876
static const char * task_name
Definition: gui.c:113
int os_version
Definition: gui.c:98
int __riscosify_control
Definition: gui.c:105
static char * ro_gui_ieurl_file_parse(const char *file_name)
Parse an IEURL file.
Definition: gui.c:636
static struct gui_file_table riscos_file_table
Definition: gui.c:2391
const char * ro_gui_default_language(void)
Determine the default language to use.
Definition: gui.c:1395
static char * ro_gui_uri_file_parse(const char *file_name, char **uri_title)
Parse an Acorn URI file.
Definition: gui.c:525
static void ro_msg_datasave_ack(wimp_message *message)
Handle Message_DataSaveAck.
Definition: gui.c:948
static struct @46 screen_info
int __dynamic_num
os_t sched_time
Time of soonest scheduled event (valid only if sched_active is true).
Definition: schedule.c:52
nserror riscos_schedule(int t, void(*callback)(void *p), void *p)
Schedule a callback.
Definition: schedule.c:93
bool sched_active
Items have been scheduled.
Definition: schedule.c:50
#define ICON_WARNING_HELP
Definition: gui.h:197
struct gui_search_table * riscos_search_table
Definition: search.c:85
ro_gui_drag_type
Definition: gui.h:69
@ GUI_DRAG_SAVE
Definition: gui.h:69
@ GUI_DRAG_NONE
Definition: gui.h:69
@ GUI_DRAG_DOWNLOAD_SAVE
Definition: gui.h:69
#define ICON_WARNING_MESSAGE
Definition: gui.h:195
void ro_gui_interactive_help_request(wimp_message *message)
Attempts to process an interactive help message request.
Definition: help.c:89
Interactive help (interface).
nserror ro_gui_pageinfo_finalise(void)
Free any resources allocated for the page info window.
Definition: pageinfo.c:307
Interface to page info core window for RISC OS.
File/object/selection saving (Interface).
void ro_gui_theme_initialise(void)
Initialise the theme handler.
Definition: theme.c:68
void ro_toolbar_init(void)
Initialise the RISC OS toolbar widget.
Definition: toolbar.c:199
Window toolbars (interface).
void ro_gui_throb(void)
Animate the "throbbers" of all browser windows.
Definition: window.c:4778
struct gui_window * ro_gui_toolbar_lookup(wimp_w window)
Convert a toolbar RISC OS window handle to a gui_window.
Definition: window.c:4836
void ro_gui_window_update_boxes(void)
Redraw any pending update boxes.
Definition: window.c:4699
bool ro_gui_toolbar_dataload(struct gui_window *g, wimp_message *message)
Handle Message_DataLoad (file dragged in) for a toolbar.
Definition: window.c:4657
struct gui_window_table * riscos_window_table
Definition: window.c:4258
bool ro_gui_alt_pressed(void)
Returns true iff one or more Alt keys is held down.
Definition: window.c:5042
void ro_gui_window_iconise(struct gui_window *g, wimp_full_message_window_info *wi)
Window is being iconised.
Definition: window.c:4531
struct gui_window * ro_gui_window_lookup(wimp_w window)
Convert a RISC OS window handle to a gui_window.
Definition: window.c:4823
bool ro_gui_window_dataload(struct gui_window *g, wimp_message *message)
Handle Message_DataLoad (file dragged in) for a window.
Definition: window.c:4481
void ro_gui_window_quit(void)
Destroy all browser windows.
Definition: window.c:4766
void ro_gui_window_initialise(void)
Initialise the browser window module and its menus.
Definition: window.c:4262
void ro_gui_drag_box_cancel(void)
Definition: save.c:1364
void ro_gui_saveas_quit(void)
Clean-up function that releases our sprite area and memory.
Definition: save.c:216
void ro_gui_save_datasave_ack(wimp_message *message)
Handle Message_DataSaveAck for a drag from the save dialog or browser window, or Clipboard protocol.
Definition: save.c:1420
void save_complete_init(void)
Initialise save complete module.
Save HTML document with dependencies (interface).
core web search facilities interface.
Content for image/x-riscos-sprite (RISC OS interface).
static nserror sprite_init(void)
Definition: sprite.h:35
Interface to utility string handling.
Browser window data.
function table for fetcher operations.
Definition: fetch.h:33
const char *(* filetype)(const char *unix_path)
Determine the MIME type of a local file.
Definition: fetch.h:45
/brief function table for file and filename operations.
Definition: file.h:50
nserror(* mkpath)(char **str, size_t *size, size_t nemb, va_list ap)
Generate a path from one or more component elemnts.
Definition: file.h:68
Graphical user interface browser misc function table.
Definition: misc.h:39
nserror(* schedule)(int t, void(*callback)(void *p), void *p)
Schedule a callback.
Definition: misc.h:58
first entry in window list
Definition: gui.c:298
char * url
Definition: gui.h:154
char * title
Definition: gui.h:153
struct browser_window * bw
The 'content' window that is rendered in the gui_window.
Definition: gui.c:316
High-level cache handle.
Definition: hlcache.c:66
NetSurf operation function table.
Definition: gui_table.h:48
struct gui_misc_table * misc
Browser table.
Definition: gui_table.h:57
union nsoption_s::@149 value
colour c
Definition: nsoption.h:122
#define alpha_SPRITE_MODE
Definition: tinct.h:162
uint32_t colour
Colour type: XBGR.
Definition: types.h:35
struct gui_utf8_table * riscos_utf8_table
Definition: ucstables.c:725
UCS conversion tables (interface) This is only used if nothing claims Service_International,...
void ro_uri_message_received(wimp_message *msg)
Definition: uri.c:43
void ro_uri_bounce(wimp_message *msg)
Definition: uri.c:110
nserror url_escape(const char *unescaped, bool sptoplus, const char *escexceptions, char **result)
Escape a string suitable for inclusion in an URL.
Definition: url.c:131
nserror url_unescape(const char *str, size_t length, size_t *length_out, char **result_out)
Convert an escaped string to plain.
Definition: url.c:67
Interface to URL parsing and joining operations.
void ro_gui_url_bar_fini(void)
Finalise the url bar module.
Definition: url_bar.c:1603
bool ro_gui_url_bar_init(void)
Initialise the url bar module.
Definition: url_bar.c:1578
Unified URL information database public interface.
nserror urldb_save(const char *filename)
Export the current database to file.
Definition: urldb.c:3091
nserror urldb_load(const char *filename)
Import an URL database from file, replacing any existing database.
Definition: urldb.c:2874
void ro_url_broadcast(const char *url)
Broadcast an ANT URL message.
Definition: url_protocol.c:151
void ro_url_message_received(wimp_message *message)
Handle a Message_InetSuiteOpenURL.
Definition: url_protocol.c:52
void ro_url_bounce(wimp_message *message)
Handle a bounced Message_InetSuiteOpenURL.
Definition: url_protocol.c:224
ANT URL launching protocol (interface).
nserror netsurf_mkdir_all(const char *fname)
Ensure that all directory elements needed to store a filename exist.
Definition: file.c:313
nserror netsurf_nsurl_to_path(struct nsurl *url, char **path_out)
Create a path from a nsurl.
Definition: file.c:301
nserror netsurf_path_to_nsurl(const char *path, struct nsurl **url)
Create a nsurl from a path.
Definition: file.c:307
nserror netsurf_mkpath(char **str, size_t *size, size_t nelm,...)
Generate a path from one or more component elemnts.
Definition: file.c:288
Default operations table for files.
struct nsoption_s * nsoptions_default
global default option table.
Definition: nsoption.c:46
static struct nsoption_s defaults[]
The table of compiled in default options.
Definition: nsoption.c:64
nserror nsoption_dump(FILE *outf, struct nsoption_s *opts)
Write all options to a stream.
Definition: nsoption.c:834
nserror nsoption_read(const char *path, struct nsoption_s *opts)
Read choices file and set them in the passed table.
Definition: nsoption.c:698
struct nsoption_s * nsoptions
global active option table.
Definition: nsoption.c:45
nserror nsoption_commandline(int *pargc, char **argv, struct nsoption_s *opts)
Process commandline and set options approriately.
Definition: nsoption.c:858
nserror nsoption_init(nsoption_set_default_t *set_defaults, struct nsoption_s **popts, struct nsoption_s **pdefs)
Initialise option system.
Definition: nsoption.c:610
nserror nsoption_finalise(struct nsoption_s *opts, struct nsoption_s *defs)
Finalise option system.
Definition: nsoption.c:665
Option reading and saving interface.
#define nsoption_charp(OPTION)
Get the value of a string option.
Definition: nsoption.h:335
#define nsoption_setnull_charp(OPTION, VALUE)
set string option in default table if currently unset
Definition: nsoption.h:380
#define nsoption_set_int(OPTION, VALUE)
set an integer option in the default table
Definition: nsoption.h:352
nsoption_e
Definition: nsoption.h:133
@ NSOPTION_LISTEND
Definition: nsoption.h:154
#define nsoption_set_charp(OPTION, VALUE)
set string option in default table
Definition: nsoption.h:376
#define nsoption_bool(OPTION)
Get the value of a boolean option.
Definition: nsoption.h:308
#define nsoption_set_uint(OPTION, VALUE)
set an unsigned integer option in the default table
Definition: nsoption.h:355
Interface to a number of general purpose functionality.
#define SLEN(x)
Calculate length of constant C string.
Definition: utils.h:88
bool is_dir(const char *path)
Check if a directory exists.
Definition: utils.c:94
void ro_gui_set_icon_string(wimp_w w, wimp_i i, const char *text, bool is_utf8)
Set the contents of a text or sprite icon to a string.
Definition: wimp.c:269
osspriteop_area * ro_gui_load_sprite_file(const char *pathname)
Load a sprite file into memory.
Definition: wimp.c:806
void ro_gui_scroll(wimp_scroll *scroll)
Generic window scroll event handler.
Definition: wimp.c:1131
General RISC OS WIMP/OS library functions (interface).
bool ro_gui_wimp_event_mouse_click(wimp_pointer *pointer)
Handles a mouse click event in a registered window.
Definition: wimp_event.c:639
bool ro_gui_wimp_event_redraw_window(wimp_draw *redraw)
Handle any redraw window requests.
Definition: wimp_event.c:1129
bool ro_gui_wimp_event_scroll_window(wimp_scroll *scroll)
Handle any scroll window requests.
Definition: wimp_event.c:1147
bool ro_gui_wimp_event_open_window(wimp_open *open)
Handle any open window requests.
Definition: wimp_event.c:1089
bool ro_gui_wimp_event_close_window(wimp_w w)
Service any close window handlers.
Definition: wimp_event.c:1107
bool ro_gui_wimp_event_pointer_entering_window(wimp_entering *entering)
Handle any pointer entering window requests.
Definition: wimp_event.c:1165
bool ro_gui_wimp_event_keypress(wimp_key *key)
Handle any registered keypresses, and the standard RISC OS ones.
Definition: wimp_event.c:885
Automated RISC OS WIMP event handling (interface).
A collection of grubby utilities for working with OSLib's wimp API.
#define PTR_WIMP_MESSAGE_LIST(l)
Definition: wimputils.h:53
#define PTR_OS_VDU_VAR_LIST(l)
Definition: wimputils.h:66
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 line(const struct redraw_context *ctx, const plot_style_t *style, const struct rect *line)
Plots a line.
Definition: plot.c:579