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